⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 featurehandler.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		delete[] mfi;
	}
}


int CFeatureHandler::AddFeature(CFeature* feature)
{
	ASSERT_SYNCED_MODE;

	if (freeIDs.empty()) {
		feature->id = nextFreeID++;
	} else {
		feature->id = freeIDs.front();
		freeIDs.pop_front();
	}
	activeFeatures.insert(feature);
	SetFeatureUpdateable(feature);

	if(feature->def->drawType==DRAWTYPE_3DO){
		int quad = int(feature->pos.z / DRAW_QUAD_SIZE / SQUARE_SIZE) * drawQuadsX +
		           int(feature->pos.x / DRAW_QUAD_SIZE / SQUARE_SIZE);
		DrawQuad* dq=&drawQuads[quad];
		dq->features.insert(feature);
		feature->drawQuad=quad;
	}

	luaCallIns.FeatureCreated(feature);

	return feature->id ;
}


void CFeatureHandler::DeleteFeature(CFeature* feature)
{
	ASSERT_SYNCED_MODE;
	toBeRemoved.push_back(feature->id);

	luaCallIns.FeatureDestroyed(feature);
}


CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
                                          float rot, int facing, int iter, int team,
                                          int allyteam, bool emitSmoke,std::string fromUnit)
{
	ASSERT_SYNCED_MODE;
	if (name.empty()) {
		return NULL;
	}
	const FeatureDef* fd = GetFeatureDef(name);

	if (!fd) {
		return NULL;
	}

	if (iter > 1) {
		return CreateWreckage(pos, fd->deathFeature, rot, facing, iter - 1, team, allyteam, emitSmoke, "");
	}
	else {
		if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos)) {
			return NULL;
		}
		if(!fd->modelname.empty()){
			CFeature* f=SAFE_NEW CFeature;
			f->Initialize (pos, fd, (short int)rot, facing, team, fromUnit);
			// allow area-reclaiming wrecks of all units, including your own (they set allyteam = -1)
			f->allyteam = allyteam;
			if(emitSmoke && f->blocking)
				f->emitSmokeTime=300;
			return f;
		}
	}
	return NULL;
}



void CFeatureHandler::Update()
{
	ASSERT_SYNCED_MODE;
	SCOPED_TIMER("Feature::Update");

	if ((gs->frameNum & 31) == 0)	// let all areareclaimers choose a target with a different id
		freeIDs.splice(freeIDs.end(), toBeFreedIDs, toBeFreedIDs.begin(), toBeFreedIDs.end());

	while (!toBeRemoved.empty()) {
		CFeatureSet::iterator it = activeFeatures.find(toBeRemoved.back());
		toBeRemoved.pop_back();
		if (it != activeFeatures.end()) {
			CFeature* feature = *it;
			toBeFreedIDs.push_back(feature->id);
			activeFeatures.erase(feature);

			if (feature->drawQuad >= 0) {
				DrawQuad* dq = &drawQuads[feature->drawQuad];
				dq->features.erase(feature);
			}

			if (feature->inUpdateQue) {
				updateFeatures.erase(feature);
			}

			delete feature;
		}
	}

	CFeatureSet::iterator fi=updateFeatures.begin();
	while (fi != updateFeatures.end()) {
		CFeature* feature = *fi;
		++fi;

		if (!feature->Update()) {
			// remove it
			feature->inUpdateQue = false;
			updateFeatures.erase(feature);
		}
	}
}


void CFeatureHandler::UpdateDrawQuad(CFeature* feature, const float3& newPos)
{
	const int oldDrawQuad = feature->drawQuad;
	if (oldDrawQuad >= 0) {
		const int newDrawQuad =
			int(newPos.z / DRAW_QUAD_SIZE / SQUARE_SIZE) * drawQuadsX +
			int(newPos.x / DRAW_QUAD_SIZE / SQUARE_SIZE);
		if (oldDrawQuad != newDrawQuad) {
			DrawQuad* oldDQ = &drawQuads[oldDrawQuad];
			oldDQ->features.erase(feature);
			DrawQuad* newDQ = &drawQuads[newDrawQuad];
			newDQ->features.insert(feature);
			feature->drawQuad = newDrawQuad;
		}
	}
}


void CFeatureHandler::SetFeatureUpdateable(CFeature* feature)
{
	if (feature->inUpdateQue) {
		return;
	}
	updateFeatures.insert(feature);
	feature->inUpdateQue = true;
}


void CFeatureHandler::TerrainChanged(int x1, int y1, int x2, int y2)
{
	ASSERT_SYNCED_MODE;
	vector<int> quads=qf->GetQuadsRectangle(float3(x1*SQUARE_SIZE,0,y1*SQUARE_SIZE),
	                                        float3(x2*SQUARE_SIZE,0,y2*SQUARE_SIZE));
//	logOutput.Print("Checking feature pos %i",quads.size());

	for(vector<int>::iterator qi=quads.begin();qi!=quads.end();++qi){
		list<CFeature*>::iterator fi;
		list<CFeature*>& features = qf->baseQuads[*qi].features;
		for(fi = features.begin(); fi != features.end(); ++fi) {
			CFeature* feature = *fi;
			float3& fpos = feature->pos;
			if (fpos.y > ground->GetHeight(fpos.x, fpos.z)) {
				SetFeatureUpdateable(feature);

				if (feature->def->floating){
					feature->finalHeight = ground->GetHeight(fpos.x, fpos.z);
				} else {
					feature->finalHeight = ground->GetHeight2(fpos.x, fpos.z);
				}

				feature->CalculateTransform ();
			}
		}
	}
}


void CFeatureHandler::Draw()
{
	ASSERT_UNSYNCED_MODE;
	vector<CFeature*> drawFar;

	unitDrawer->SetupForUnitDrawing();
	DrawRaw(0, &drawFar);
	unitDrawer->CleanUpUnitDrawing();

	unitDrawer->DrawQuedS3O();

	CVertexArray* va=GetVertexArray();
	va->Initialize();
	glAlphaFunc(GL_GREATER,0.8f);
	glEnable(GL_ALPHA_TEST);
	glBindTexture(GL_TEXTURE_2D,fartextureHandler->farTexture);
	glColor3f(1,1,1);
	glEnable(GL_FOG);
	for(vector<CFeature*>::iterator usi=drawFar.begin();usi!=drawFar.end();usi++){
		DrawFar(*usi,va);
	}
	va->DrawArrayTN(GL_QUADS);
}


void CFeatureHandler::DrawShadowPass()
{
	ASSERT_UNSYNCED_MODE;
	glBindProgramARB( GL_VERTEX_PROGRAM_ARB, unitDrawer->unitShadowGenVP );
	glEnable( GL_VERTEX_PROGRAM_ARB );
	glPolygonOffset(1,1);
	glEnable(GL_POLYGON_OFFSET_FILL);

	unitDrawer->SetupForUnitDrawing();
	DrawRaw(1, NULL);
	unitDrawer->CleanUpUnitDrawing();

	unitDrawer->DrawQuedS3O();

	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisable( GL_VERTEX_PROGRAM_ARB );
}

class CFeatureDrawer : public CReadMap::IQuadDrawer
{
public:
	void DrawQuad (int x,int y);

	CFeatureHandler *fh;
//	CFeatureHandler::DrawQuad *drawQuads;
	std::vector<CFeatureHandler::DrawQuad> *drawQuads;
	int drawQuadsX;
	bool drawReflection, drawRefraction;
	float unitDrawDist;
	std::vector<CFeature*>* farFeatures;
};


void CFeatureDrawer::DrawQuad (int x,int y)
{
	CFeatureHandler::DrawQuad* dq=&(*drawQuads)[y*drawQuadsX+x];

	for (CFeatureSet::iterator fi = dq->features.begin(); fi != dq->features.end(); ++fi) {
		CFeature* f = (*fi);
		const FeatureDef* def = f->def;

		if((f->allyteam==-1 || f->allyteam==gu->myAllyTeam ||
		    loshandler->InLos(f->pos,gu->myAllyTeam) || gu->spectatingFullView)
		   && def->drawType==DRAWTYPE_3DO){
			if(drawReflection){
				float3 zeroPos;
				if(f->midPos.y<0){
					zeroPos=f->midPos;
				}else{
					float dif=f->midPos.y-camera->pos.y;
					zeroPos=camera->pos*(f->midPos.y/dif) + f->midPos*(-camera->pos.y/dif);
				}
				if(ground->GetApproximateHeight(zeroPos.x,zeroPos.z)>f->radius){
					continue;
				}
			}
			if(drawRefraction){
				if(f->pos.y>0)
					continue;
			}
			float sqDist=(f->pos-camera->pos).SqLength2D();
			float farLength=f->sqRadius*unitDrawDist*unitDrawDist;
			if(sqDist<farLength){
				if(!f->model->textureType) {
					f->DrawS3O ();
				} else {
					unitDrawer->QueS3ODraw(f,f->model->textureType);
				}
			} else {
				if(farFeatures)
					farFeatures->push_back(f);
			}
		}
	}
}


void CFeatureHandler::DrawRaw(int extraSize, std::vector<CFeature*>* farFeatures)
{
	float featureDist=3000;
	if(!extraSize)
		featureDist=6000;		//farfeatures wont be drawn for shadowpass anyway

	CFeatureDrawer drawer;
	drawer.drawQuads = &drawQuads;
	drawer.fh = this;
	drawer.drawQuadsX = drawQuadsX;
	drawer.drawReflection=water->drawReflection;
	drawer.drawRefraction=water->drawRefraction;
	drawer.unitDrawDist=unitDrawer->unitDrawDist;
	drawer.farFeatures = farFeatures;

	readmap->GridVisibility (camera, DRAW_QUAD_SIZE, featureDist, &drawer, extraSize);
}


void CFeatureHandler::DrawFar(CFeature* feature, CVertexArray* va)
{
	float3 interPos=feature->pos+UpVector*feature->model->height*0.5f;
	int snurr=-feature->heading+GetHeadingFromVector(camera->pos.x-feature->pos.x,camera->pos.z-feature->pos.z)+(0xffff>>4);
	if(snurr<0)
		snurr+=0xffff;
	if(snurr>0xffff)
		snurr-=0xffff;
	snurr=snurr>>13;
	float tx=(feature->model->farTextureNum%8)*(1.0f/8.0f)+snurr*(1.0f/64);
	float ty=(feature->model->farTextureNum/8)*(1.0f/64.0f);
	float offset=0;
	va->AddVertexTN(interPos-(camera->up*feature->radius*1.4f-offset)+camera->right*feature->radius,tx,ty,unitDrawer->camNorm);
	va->AddVertexTN(interPos+(camera->up*feature->radius*1.4f+offset)+camera->right*feature->radius,tx,ty+(1.0f/64.0f),unitDrawer->camNorm);
	va->AddVertexTN(interPos+(camera->up*feature->radius*1.4f+offset)-camera->right*feature->radius,tx+(1.0f/64.0f),ty+(1.0f/64.0f),unitDrawer->camNorm);
	va->AddVertexTN(interPos-(camera->up*feature->radius*1.4f-offset)-camera->right*feature->radius,tx+(1.0f/64.0f),ty,unitDrawer->camNorm);
}


S3DOModel* FeatureDef::LoadModel(int team) const
{
	if (!useCSOffset) {
		return modelParser->Load3DO(modelname.c_str(),
		                            collisionSphereScale, team);
	} else {
		return modelParser->Load3DO(modelname.c_str(),
		                            collisionSphereScale, team,
		                            collisionSphereOffset);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -