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 + -
显示快捷键?