loshandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 630 行 · 第 1/2 页
CPP
630 行
}
dh+=terrainHeight[0];
ang=dh/r;
if(ang>maxAng1){
maxAng1=ang;
}
}
if(xmap-linei->x>=0 && ymap-linei->y>=0){
int square=mapSquare-linei->x-linei->y*losSizeX;
float dh=readmap->mipHeightmap[losMipLevel][square]-baseHeight;
float ang=dh/r;
if(ang>maxAng2){
instance->losSquares.push_back(square);
losMap[allyteam][square]++;
}
dh+=terrainHeight[0];
ang=dh/r;
if(ang>maxAng2){
maxAng2=ang;
}
}
if(xmap+linei->y<losSizeX && ymap-linei->x>=0){
int square=mapSquare-linei->x*losSizeX+linei->y;
float dh=readmap->mipHeightmap[losMipLevel][square]-baseHeight;
float ang=dh/r;
if(ang>maxAng3){
instance->losSquares.push_back(square);
losMap[allyteam][square]++;
}
dh+=terrainHeight[0];
ang=dh/r;
if(ang>maxAng3){
maxAng3=ang;
}
}
if(xmap-linei->y>=0 && ymap+linei->x<losSizeY){
int square=mapSquare+linei->x*losSizeX-linei->y;
float dh=readmap->mipHeightmap[losMipLevel][square]-baseHeight;
float ang=dh/r;
if(ang>maxAng4){
instance->losSquares.push_back(square);
losMap[allyteam][square]++;
}
dh+=terrainHeight[0];
ang=dh/r;
if(ang>maxAng4){
maxAng4=ang;
}
}
r++;
}
}
}
void CLosHandler::OutputTable(int Table)
{
LosTable lostable;
int Radius = Table;
char* PaintTable = SAFE_NEW char[(Radius+1)*Radius];
memset(PaintTable, 0 , (Radius+1)*Radius);
CPoint P;
int x, y, r2;
P.x = 0;
P.y = Radius;
Points.push_front(P);
// DrawLine(0, Radius, Radius);
for(float i=Radius; i>=1; i-=0.5f)
{
r2 = (int)(i * i);
y = (int)i;
x = 1;
y = (int) (sqrt((float)r2 - 1) + 0.5f);
while (x < y) {
if(!PaintTable[x+y*Radius])
{
DrawLine(PaintTable, x, y, Radius);
P.x = x;
P.y = y;
Points.push_back(P);
}
if(!PaintTable[y+x*Radius])
{
DrawLine(PaintTable, y, x, Radius);
P.x = y;
P.y = x;
Points.push_back(P);
}
x += 1;
y = (int) (sqrt((float)r2 - x*x) + 0.5f);
}
if (x == y) {
if(!PaintTable[x+y*Radius])
{
DrawLine(PaintTable, x, y, Radius);
P.x = x;
P.y = y;
Points.push_back(P);
}
}
}
Points.sort();
int Line = 1;
int Size = Points.size();
for(int j=0; j<Size; j++)
{
lostable.push_back(OutputLine(Points.back().x, Points.back().y, Line));
Points.pop_back();
Line++;
}
lostables.push_back(lostable);
delete[] PaintTable;
}
CLosHandler::LosLine CLosHandler::OutputLine(int x, int y, int Line)
{
LosLine losline;
int x0 = 0;
int y0 = 0;
int dx = x;
int dy = y;
if (abs(dx) > abs(dy)) { // slope <1
float m = (float) dy / (float) dx; // compute slope
float b = y0 - m*x0;
dx = (dx < 0) ? -1 : 1;
while (x0 != x) {
x0 += dx;
losline.push_back(CPoint(x0,Round(m*x0 + b)));
}
} else
if (dy != 0) { // slope = 1
float m = (float) dx / (float) dy; // compute slope
float b = x0 - m*y0;
dy = (dy < 0) ? -1 : 1;
while (y0 != y) {
y0 += dy;
losline.push_back(CPoint(Round(m*y0 + b),y0));
}
}
return losline;
}
void CLosHandler::DrawLine(char* PaintTable, int x, int y, int Size)
{
int x0 = 0;
int y0 = 0;
int dx = x;
int dy = y;
if (abs(dx) > abs(dy)) { // slope <1
float m = (float) dy / (float) dx; // compute slope
float b = y0 - m*x0;
dx = (dx < 0) ? -1 : 1;
while (x0 != x) {
x0 += dx;
PaintTable[x0+Round(m*x0 + b)*Size] = 1;
}
} else {
if (dy != 0) { // slope = 1
float m = (float) dx / (float) dy; // compute slope
float b = x0 - m*y0;
dy = (dy < 0) ? -1 : 1;
while (y0 != y) {
y0 += dy;
PaintTable[Round(m*y0 + b)+y0*Size] = 1;
}
}
}
}
int CLosHandler::Round(float Num)
{
if((Num - (int)Num) <0.5f)
return (int)Num;
else
return (int)Num+1;
}
void CLosHandler::FreeInstance(LosInstance* instance)
{
if(instance==0)
return;
instance->refCount--;
if(instance->refCount==0){
CleanupInstance(instance);
if(!instance->toBeDeleted){
instance->toBeDeleted=true;
toBeDeleted.push_back(instance);
}
if(instance->hashNum>=2310 || instance->hashNum<0){
logOutput.Print("bad los");
}
if(toBeDeleted.size()>500){
LosInstance* i=toBeDeleted.front();
toBeDeleted.pop_front();
// logOutput.Print("del %i",i->hashNum);
if(i->hashNum>=2310 || i->hashNum<0){
logOutput.Print("bad los 2");
return;
}
i->toBeDeleted=false;
if(i->refCount==0){
std::list<LosInstance*>::iterator lii;
for(lii=instanceHash[i->hashNum].begin();lii!=instanceHash[i->hashNum].end();++lii){
if((*lii)==i){
instanceHash[i->hashNum].erase(lii);
i->_DestructInstance(i);
mempool.Free(i,sizeof(LosInstance));
break;
}
}
}
}
}
}
int CLosHandler::GetHashNum(CUnit* unit)
{
unsigned int t=unit->mapSquare*unit->losRadius+unit->allyteam;
t^=*(unsigned int*)&unit->losHeight;
return t%2309;
}
void CLosHandler::AllocInstance(LosInstance* instance)
{
if(instance->refCount==0){
std::vector<int>::iterator lsi;
for(lsi=instance->losSquares.begin();lsi!=instance->losSquares.end();++lsi){
++losMap[instance->allyteam][*lsi];
}
LosAddAir(instance);
}
instance->refCount++;
}
void CLosHandler::CleanupInstance(LosInstance* instance)
{
for(std::vector<int>::iterator lsi=instance->losSquares.begin();lsi!=instance->losSquares.end();++lsi){
--losMap[instance->allyteam][*lsi];
}
int by=(instance->baseAirSquare/airSizeX);
int bx=(instance->baseAirSquare-by*airSizeX);
int sx=max(0,bx-instance->airLosSize);
int ex=min(airSizeX-1,bx+instance->airLosSize);
int sy=max(0,by-instance->airLosSize);
int ey=min(airSizeY-1,by+instance->airLosSize);
int rr=instance->airLosSize*instance->airLosSize;
for(int y=sy;y<=ey;++y){
int rrx=rr-(by-y)*(by-y);
for(int x=sx;x<=ex;++x){
if((bx-x)*(bx-x)<=rrx){
--airLosMap[instance->allyteam][y*airSizeX+x];
}
}
}
}
void CLosHandler::LosAddAir(LosInstance* instance)
{
/*int by=(instance->baseSquare/gs->hmapx);
int bx=(instance->baseSquare-by*gs->hmapx)/2;
by/=2;*/
int by=(instance->baseAirSquare/airSizeX);
int bx=(instance->baseAirSquare-by*airSizeX);
int sx=max(0,bx-instance->airLosSize);
int ex=min(airSizeX-1,bx+instance->airLosSize);
int sy=max(0,by-instance->airLosSize);
int ey=min(airSizeY-1,by+instance->airLosSize);
int rr=instance->airLosSize*instance->airLosSize;
if (instance->allyteam < 0)
return;
for(int y=sy;y<=ey;++y){
int rrx=rr-(by-y)*(by-y);
for(int x=sx;x<=ex;++x){
if((bx-x)*(bx-x)<=rrx){
++airLosMap[instance->allyteam][y*airSizeX+x];
}
}
}
}
void CLosHandler::Update(void)
{
while(!delayQue.empty() && delayQue.front().timeoutTime<gs->frameNum){
FreeInstance(delayQue.front().instance);
delayQue.pop_front();
}
}
void CLosHandler::DelayedFreeInstance(LosInstance* instance)
{
DelayedInstance di;
di.instance=instance;
di.timeoutTime=gs->frameNum+45;
delayQue.push_back(di);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?