unithandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 642 行 · 第 1/2 页
CPP
642 行
int ysize=buildInfo.GetYSize();
float3 pos=buildInfo.pos;
int x1 = (int) (pos.x-(xsize*0.5f*SQUARE_SIZE));
int x2 = x1+xsize*SQUARE_SIZE;
int z1 = (int) (pos.z-(ysize*0.5f*SQUARE_SIZE));
int z2 = z1+ysize*SQUARE_SIZE;
float h=GetBuildHeight(pos,buildInfo.def);
int canBuild=2;
if(buildInfo.def->needGeo){
canBuild=0;
std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(xsize,ysize)*6);
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<xsize*4-4 && fabs((*fi)->pos.z-pos.z)<ysize*4-4){
canBuild=2;
break;
}
}
}
for(int x=x1; x<x2; x+=SQUARE_SIZE){
for(int z=z1; z<z2; z+=SQUARE_SIZE){
int tbs=TestBuildSquare(float3(x,h,z),buildInfo.def,feature,allyteam);
canBuild=min(canBuild,tbs);
if(canBuild==0)
return 0;
}
}
return canBuild;
}
int CUnitHandler::TestBuildSquare(const float3& pos, const UnitDef *unitdef, CFeature *&feature, int allyteam)
{
int ret=2;
if(pos.x<0 || pos.x>=gs->mapx*SQUARE_SIZE || pos.z<0 || pos.z>=gs->mapy*SQUARE_SIZE)
return 0;
int yardxpos=int(pos.x+4)/SQUARE_SIZE;
int yardypos=int(pos.z+4)/SQUARE_SIZE;
CSolidObject* s;
if ((s = readmap->GroundBlocked(yardypos*gs->mapx+yardxpos))) {
if (dynamic_cast<CFeature*>(s)) {
feature = (CFeature*)s;
}
else if (!dynamic_cast<CUnit*>(s) || (allyteam < 0) ||
(((CUnit*)s)->losStatus[allyteam] & LOS_INLOS)) {
if (s->immobile) {
return 0;
} else {
ret = 1;
}
}
}
if(!unitdef->floater)
{
float* heightmap=readmap->GetHeightmap();
int x=(int) (pos.x/SQUARE_SIZE);
int z=(int) (pos.z/SQUARE_SIZE);
float orgh=readmap->orgheightmap[z*(gs->mapx+1)+x];
float h=heightmap[z*(gs->mapx+1)+x];
float hdif=unitdef->maxHeightDif;
if(pos.y>orgh+hdif && pos.y>h+hdif)
return 0;
if(pos.y<orgh-hdif && pos.y<h-hdif)
return 0;
}
float groundheight = ground->GetHeight2(pos.x,pos.z);
if(!unitdef->floater && groundheight<-unitdef->maxWaterDepth)
return 0;
if(groundheight>-unitdef->minWaterDepth)
return 0;
return ret;
}
int CUnitHandler::ShowUnitBuildSquare(const BuildInfo& buildInfo)
{
return ShowUnitBuildSquare(buildInfo, std::vector<Command>());
}
int CUnitHandler::ShowUnitBuildSquare(const BuildInfo& buildInfo, const std::vector<Command> &cv)
{
glDisable(GL_DEPTH_TEST );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
int xsize=buildInfo.GetXSize();
int ysize=buildInfo.GetYSize();
const float3& pos = buildInfo.pos;
int x1 = (int) (pos.x-(xsize*0.5f*SQUARE_SIZE));
int x2 = x1+xsize*SQUARE_SIZE;
int z1 = (int) (pos.z-(ysize*0.5f*SQUARE_SIZE));
int z2 = z1+ysize*SQUARE_SIZE;
float h=GetBuildHeight(pos,buildInfo.def);
int canbuild=2;
if(buildInfo.def->needGeo)
{
canbuild=0;
std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(xsize,ysize)*6);
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<xsize*4-4 && fabs((*fi)->pos.z-pos.z)<ysize*4-4){
canbuild=2;
break;
}
}
}
std::vector<float3> canbuildpos;
std::vector<float3> featurepos;
std::vector<float3> nobuildpos;
for(int x=x1; x<x2; x+=SQUARE_SIZE){
for(int z=z1; z<z2; z+=SQUARE_SIZE){
CFeature* feature=0;
int tbs=TestBuildSquare(float3(x,pos.y,z),buildInfo.def,feature,gu->myAllyTeam);
if(tbs){
std::vector<Command>::const_iterator ci = cv.begin();
for(;ci != cv.end() && tbs; ci++){
BuildInfo bc(*ci);
if(max(bc.pos.x-x-SQUARE_SIZE,x-bc.pos.x)*2 < bc.GetXSize()*SQUARE_SIZE
&& max(bc.pos.z-z-SQUARE_SIZE,z-bc.pos.z)*2 < bc.GetYSize()*SQUARE_SIZE){
tbs=0;
}
}
if(!tbs){
nobuildpos.push_back(float3(x,h,z));
canbuild = 0;
} else if(feature || tbs==1)
featurepos.push_back(float3(x,h,z));
else
canbuildpos.push_back(float3(x,h,z));
canbuild=min(canbuild,tbs);
} else {
nobuildpos.push_back(float3(x,h,z));
//glColor4f(0.8f,0.0f,0,0.4f);
canbuild = 0;
}
}
}
if(canbuild)
glColor4f(0,0.8f,0,1.0f);
else
glColor4f(0.5f,0.5f,0,1.0f);
for(unsigned int i=0; i<canbuildpos.size(); i++)
{
glVertexf3(canbuildpos[i]);
glVertexf3(canbuildpos[i]+float3(SQUARE_SIZE,0,0));
glVertexf3(canbuildpos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE));
glVertexf3(canbuildpos[i]+float3(0,0,SQUARE_SIZE));
}
glColor4f(0.5f,0.5f,0,1.0f);
for(unsigned int i=0; i<featurepos.size(); i++)
{
glVertexf3(featurepos[i]);
glVertexf3(featurepos[i]+float3(SQUARE_SIZE,0,0));
glVertexf3(featurepos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE));
glVertexf3(featurepos[i]+float3(0,0,SQUARE_SIZE));
}
glColor4f(0.8f,0.0f,0,1.0f);
for(unsigned int i=0; i<nobuildpos.size(); i++)
{
glVertexf3(nobuildpos[i]);
glVertexf3(nobuildpos[i]+float3(SQUARE_SIZE,0,0));
glVertexf3(nobuildpos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE));
glVertexf3(nobuildpos[i]+float3(0,0,SQUARE_SIZE));
}
glEnd();
if (h < 0.0f) {
const float s[4] = { 0.0f, 0.0f, 1.0f, 0.5f }; // start color
const float e[4] = { 0.0f, 0.5f, 1.0f, 1.0f }; // end color
glBegin(GL_LINES);
glColor4fv(s); glVertex3f(x1, h, z1); glColor4fv(e); glVertex3f(x1, 0.0f, z1);
glColor4fv(s); glVertex3f(x2, h, z1); glColor4fv(e); glVertex3f(x2, 0.0f, z1);
glColor4fv(s); glVertex3f(x1, h, z2); glColor4fv(e); glVertex3f(x1, 0.0f, z2);
glColor4fv(s); glVertex3f(x2, h, z2); glColor4fv(e); glVertex3f(x2, 0.0f, z2);
glEnd();
// using the last end color
glBegin(GL_LINE_LOOP);
glVertex3f(x1, 0.0f, z1);
glVertex3f(x1, 0.0f, z2);
glVertex3f(x2, 0.0f, z2);
glVertex3f(x2, 0.0f, z1);
glEnd();
}
glEnable(GL_DEPTH_TEST );
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glDisable(GL_BLEND);
return canbuild;
}
void CUnitHandler::PushNewWind(float x, float z, float strength)
{
ASSERT_SYNCED_MODE;
//todo: fixa en lista med enbart windgenerators kanske blir lite snabbare
list<CUnit*>::iterator usi;
for(usi=activeUnits.begin();usi!=activeUnits.end();usi++)
{
if((*usi)->unitDef->windGenerator)
(*usi)->PushWind(x,z,strength);
}
}
void CUnitHandler::AddBuilderCAI(CBuilderCAI* b)
{
builderCAIs.insert(builderCAIs.end(),b);
}
void CUnitHandler::RemoveBuilderCAI(CBuilderCAI* b)
{
ListErase<CBuilderCAI*>(builderCAIs, b);
}
void CUnitHandler::LoadSaveUnits(CLoadSaveInterface* file, bool loading)
{
/* for(int a=0;a<MAX_UNITS;++a){
bool exists=!!units[a];
file->lsBool(exists);
if(exists){
if(loading){
overrideId=a;
float3 pos;
file->lsFloat3(pos);
string name;
file->lsString(name);
int team;
file->lsInt(team);
bool build;
file->lsBool(build);
unitLoader.LoadUnit(name,pos,team,build);
} else {
file->lsFloat3(units[a]->pos);
file->lsString(units[a]->unitDef->name);
file->lsInt(units[a]->team);
file->lsBool(units[a]->beingBuilt);
}
} else {
if(loading)
freeIDs.push_back(a);
}
}
for(int a=0;a<MAX_UNITS;++a){
if(units[a])
units[a]->LoadSave(file,loading);
}
overrideId=-1;*/
}
bool CUnitHandler::CanCloseYard(CUnit* unit)
{
for(int z=unit->mapPos.y;z<unit->mapPos.y+unit->ysize;++z){
for(int x=unit->mapPos.x;x<unit->mapPos.x+unit->xsize;++x){
CSolidObject* c=readmap->groundBlockingObjectMap[z*gs->mapx+x];
if(c!=0 && c!=unit)
return false;
}
}
return true;
}
/**
* returns a build Command that intersects the ray described by pos and dir from the command queues of the
* units units on team number team
* @breif returns a build Command that intersects the ray described by pos and dir
* @return the build Command, or 0 if one is not found
*/
Command CUnitHandler::GetBuildCommand(float3 pos, float3 dir){
float3 tempF1 = pos;
std::list<CUnit*>::iterator ui = this->activeUnits.begin();
CCommandQueue::iterator ci;
for(; ui != this->activeUnits.end(); ui++){
if((*ui)->team == gu->myTeam){
ci = (*ui)->commandAI->commandQue.begin();
for(; ci != (*ui)->commandAI->commandQue.end(); ci++){
if((*ci).id < 0 && (*ci).params.size() >= 3){
BuildInfo bi(*ci);
tempF1 = pos + dir*((bi.pos.y - pos.y)/dir.y) - bi.pos;
if(bi.def && bi.GetXSize()/2*SQUARE_SIZE > fabs(tempF1.x) && bi.GetYSize()/2*SQUARE_SIZE > fabs(tempF1.z)){
return (*ci);
}
}
}
}
}
Command c;
c.id = 0;
return c;
}
bool CUnitHandler::CanBuildUnit(const UnitDef* unitdef, int team)
{
if (gs->Team(team)->units.size() >= uh->maxUnits) {
return false;
}
if (unitsByDefs[team][unitdef->id].size() >= unitdef->maxThisUnit) {
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?