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

📄 builder.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Builder.cpp: implementation of the CBuilder class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include <assert.h>
#include <algorithm>
#include "Builder.h"
#include "Building.h"
#include "Game/GameHelper.h"
#include "Game/Team.h"
#include "LogOutput.h"
#include "Lua/LuaCallInHandler.h"
#include "Map/Ground.h"
#include "Map/MapDamage.h"
#include "myMath.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "Sim/Misc/Feature.h"
#include "Sim/Misc/FeatureHandler.h"
#include "Sim/ModInfo.h"
#include "Sim/Projectiles/ProjectileHandler.h"
#include "Sim/Projectiles/Unsynced/GfxProjectile.h"
#include "Sim/Units/COB/CobInstance.h"
#include "Sim/Units/UnitDefHandler.h"
#include "Sim/Units/UnitHandler.h"
#include "Sim/Units/UnitLoader.h"
#include "Sound.h"
#include "mmgr.h"

using namespace std;


CR_BIND_DERIVED(CBuilder, CUnit, );

CR_REG_METADATA(CBuilder, (
				CR_MEMBER(range3D),
				CR_MEMBER(buildDistance),
				CR_MEMBER(buildSpeed),
				CR_MEMBER(repairSpeed),
				CR_MEMBER(reclaimSpeed),
				CR_MEMBER(resurrectSpeed),
				CR_MEMBER(captureSpeed),
				CR_MEMBER(terraformSpeed),
				CR_MEMBER(curResurrect),
				CR_MEMBER(lastResurrected),
				CR_MEMBER(curBuild),
				CR_MEMBER(curCapture),
				CR_MEMBER(curReclaim),
				CR_MEMBER(helpTerraform),
				CR_MEMBER(terraforming),
				CR_MEMBER(myTerraformLeft),
				CR_MEMBER(terraformHelp),
				CR_MEMBER(tx1), CR_MEMBER(tx2), CR_MEMBER(tz1), CR_MEMBER(tz2),
				CR_MEMBER(terraformCenter),
				CR_MEMBER(terraformRadius),
				CR_MEMBER(nextBuildType),
				CR_MEMBER(nextBuildPos),
				CR_ENUM_MEMBER(terraformType),
				CR_RESERVED(12),
				CR_POSTLOAD(PostLoad)
				));


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBuilder::CBuilder()
:	range3D(true),
  buildDistance(16),
  buildSpeed(100),
  repairSpeed(100),
  reclaimSpeed(100),
  resurrectSpeed(100),
  captureSpeed(100),
  terraformSpeed(100),
  curBuild(0),
  curReclaim(0),
  terraforming(false),
  myTerraformLeft(0),
  terraformType(Terraform_Building),
  tx1(0),
  tx2(0),
  tz1(0),
  tz2(0),
  terraformCenter(0,0,0),
  terraformRadius(0),
  nextBuildPos(0,0,0),
  terraformHelp(0),
  helpTerraform(0),
  curResurrect(0),
  lastResurrected(0),
  curCapture(0)
{
}


CBuilder::~CBuilder()
{
}

void CBuilder::PostLoad()
{
	if (curResurrect)  SetBuildStanceToward(curResurrect->pos);
	if (curBuild)      SetBuildStanceToward(curBuild->pos);
	if (curCapture)    SetBuildStanceToward(curCapture->pos);
	if (curReclaim)    SetBuildStanceToward(curReclaim->pos);
	if (terraforming)  SetBuildStanceToward(terraformCenter);
	if (helpTerraform) SetBuildStanceToward(helpTerraform->terraformCenter);
}


void CBuilder::UnitInit(const UnitDef* def, int team, const float3& position)
{
	range3D = def->buildRange3D;
	buildDistance  = def->buildDistance;

	const float scale = (1.0f / 32.0f);
	buildSpeed     = scale * def->buildSpeed;
	repairSpeed    = scale * def->repairSpeed;
	reclaimSpeed   = scale * def->reclaimSpeed;
	resurrectSpeed = scale * def->resurrectSpeed;
	captureSpeed   = scale * def->captureSpeed;
	terraformSpeed = scale * def->terraformSpeed;

	CUnit::UnitInit (def, team, position);
}


void CBuilder::Update()
{
	if (beingBuilt) {
		return;
	}

	if(terraforming && inBuildStance){
		float* heightmap = readmap->GetHeightmap();
		assert(!mapDamage->disabled); // The map should not be deformed in the first place.
		float terraformScale = 0.1;
		switch(terraformType) {
		    case Terraform_Building:
				if(curBuild) {
					terraformScale = (terraformSpeed + terraformHelp) / curBuild->terraformLeft;
					curBuild->terraformLeft -= (terraformSpeed + terraformHelp);
					terraformHelp = 0;
					if (terraformScale > 1.0f) {
						terraformScale = 1.0f;
					}
					curBuild->AddBuildPower(0.0f,this); //prevent building from timing out while terraforming for it
					for(int z=tz1; z<=tz2; z++){
						for(int x=tx1; x<=tx2; x++){
							float ch=heightmap[z*(gs->mapx+1)+x];
							heightmap[z*(gs->mapx+1)+x] += (curBuild->pos.y - ch) * terraformScale;
						}
					}
					if(curBuild->terraformLeft<=0){
						terraforming=false;
						mapDamage->RecalcArea(tx1,tx2,tz1,tz2);
						curBuild->groundLevelled = true;
					}
				}
				break;
			case Terraform_Restore:
				terraformScale = (terraformSpeed + terraformHelp) / myTerraformLeft;
				myTerraformLeft -= (terraformSpeed + terraformHelp);
				terraformHelp = 0;
				if (terraformScale > 1.0f) {
					terraformScale = 1.0f;
				}
				for(int z=tz1; z<=tz2; z++){
					for(int x=tx1; x<=tx2; x++){
						float ch=heightmap[z*(gs->mapx+1)+x];
						float oh=readmap->orgheightmap[z*(gs->mapx+1)+x];
						heightmap[z*(gs->mapx+1)+x] += (oh-ch) * terraformScale;
					}
				}
				if(myTerraformLeft<=0){
					terraforming=false;
					mapDamage->RecalcArea(tx1,tx2,tz1,tz2);
					StopBuild();
				}
				break;
		}
		CreateNanoParticle(terraformCenter,terraformRadius*0.5f,false);
		for(int z=tz1; z<=tz2; z++){		//smooth the borders x
			for(int x=1; x<=3; x++){
				if(tx1-3>=0){
					float ch3=heightmap[z*(gs->mapx+1)+tx1];
					float ch=heightmap[z*(gs->mapx+1)+tx1-x];
					float ch2=heightmap[z*(gs->mapx+1)+tx1-3];
					heightmap[z*(gs->mapx+1)+tx1-x] += ((ch3*(3-x)+ch2*x)/3-ch) * terraformScale;
				}
				if(tx2+3<gs->mapx){
					float ch3=heightmap[z*(gs->mapx+1)+tx2];
					float ch=heightmap[z*(gs->mapx+1)+tx2+x];
					float ch2=heightmap[z*(gs->mapx+1)+tx2+3];
					heightmap[z*(gs->mapx+1)+tx2+x] += ((ch3*(3-x)+ch2*x)/3-ch) * terraformScale;
				}
			}
		}
		for(int z=1; z<=3; z++){		//smooth the borders z
			for(int x=tx1; x<=tx2; x++){
				if(tz1-3>=0){
					float ch3=heightmap[(tz1)*(gs->mapx+1)+x];
					float ch=heightmap[(tz1-z)*(gs->mapx+1)+x];
					float ch2=heightmap[(tz1-3)*(gs->mapx+1)+x];
					heightmap[(tz1-z)*(gs->mapx+1)+x] += ((ch3*(3-z)+ch2*z)/3-ch) * terraformScale;
				}
				if(tz2+3<gs->mapy){
					float ch3=heightmap[(tz2)*(gs->mapx+1)+x];
					float ch=heightmap[(tz2+z)*(gs->mapx+1)+x];
					float ch2=heightmap[(tz2+3)*(gs->mapx+1)+x];
					heightmap[(tz2+z)*(gs->mapx+1)+x] += ((ch3*(3-z)+ch2*z)/3-ch) * terraformScale;
				}
			}
		}
	}
	else if (helpTerraform && inBuildStance) {
		if (helpTerraform->terraforming) {
			helpTerraform->terraformHelp += terraformSpeed;
			CreateNanoParticle(helpTerraform->terraformCenter,helpTerraform->terraformRadius*0.5f,false);
		} else {
			DeleteDeathDependence(helpTerraform);
			helpTerraform=0;
			StopBuild(true);
		}
	}
	else if (curBuild && f3Dist(curBuild->pos, pos) < buildDistance + curBuild->radius) {
		if (curBuild->soloBuilder && (curBuild->soloBuilder != this)) {
			StopBuild();
		} else {
			if (!inBuildStance) {
				curBuild->AddBuildPower(0.0f, this); //prevent building timing out
			} else {
				if (scriptCloak <= 2) {
					if (isCloaked) {
						isCloaked = false;
						luaCallIns.UnitDecloaked(this);
					}
					curCloakTimeout = gs->frameNum + cloakTimeout;
				}

  			float adjBuildSpeed; // adjusted build speed
  			if (curBuild->buildProgress < 1.0f) {
  				adjBuildSpeed = buildSpeed;  // new build
  			} else {
  				adjBuildSpeed = repairSpeed; // repair
				}

				if (curBuild->AddBuildPower(adjBuildSpeed, this)) {
					CreateNanoParticle(curBuild->midPos, curBuild->radius * 0.5f, false);
				} else {
					if(!curBuild->beingBuilt && curBuild->health >= curBuild->maxHealth) {
						StopBuild();
					}
				}
			}
		}
	}
	else if(curReclaim && f3Dist(curReclaim->pos, pos)<buildDistance+curReclaim->radius && inBuildStance){
		if (scriptCloak <= 2) {
			if (isCloaked) {
				isCloaked = false;
				luaCallIns.UnitDecloaked(this);
			}
			curCloakTimeout = gs->frameNum + cloakTimeout;
		}
		if (curReclaim->AddBuildPower(-reclaimSpeed, this)) {
			CreateNanoParticle(curReclaim->midPos, curReclaim->radius * 0.7f, true);
		}
	}
	else if(curResurrect && f3Dist(curResurrect->pos, pos)<buildDistance+curResurrect->radius && inBuildStance){
		const UnitDef* ud=unitDefHandler->GetUnitByName(curResurrect->createdFromUnit);
		if(ud){
			if ((modInfo.reclaimMethod != 1) && (curResurrect->reclaimLeft < 1)) {
				// This corpse has been reclaimed a little, need to restore the resources
				// before we can let the player resurrect it.
				curResurrect->AddBuildPower(repairSpeed, this);
			}
			else {
				// Corpse has been restored, begin resurrection
				if (UseEnergy(ud->energyCost * resurrectSpeed / ud->buildTime * 0.5f)) {
					curResurrect->resurrectProgress+=resurrectSpeed/ud->buildTime;
					CreateNanoParticle(curResurrect->midPos,curResurrect->radius*0.7f,gs->randInt()&1);
				}
				if(curResurrect->resurrectProgress>1){		//resurrect finished
					curResurrect->UnBlock();
					CUnit* u = unitLoader.LoadUnit(curResurrect->createdFromUnit, curResurrect->pos,
					                               team, false, curResurrect->buildFacing, this);
					if (!this->unitDef->canBeAssisted) {
						u->soloBuilder = this;
						u->AddDeathDependence(this);
					}
					u->health*=0.05f;
					u->lineage = this->lineage;
					lastResurrected=u->id;
					curResurrect->resurrectProgress=0;
					featureHandler->DeleteFeature(curResurrect);
					StopBuild(true);
				}
			}
		} else {
			StopBuild(true);
		}
	}
	else if(curCapture && f3Dist(curCapture->pos, pos)<buildDistance+curCapture->radius && inBuildStance){
		if(curCapture->team!=team){
			curCapture->captureProgress+=1.0f/(150+curCapture->buildTime/captureSpeed*(curCapture->health+curCapture->maxHealth)/curCapture->maxHealth*0.4f);
			CreateNanoParticle(curCapture->midPos,curCapture->radius*0.7f,false);
			if(curCapture->captureProgress > 1.0f){
				if (!curCapture->ChangeTeam(team, CUnit::ChangeCaptured)) {
					// capture failed
					ENTER_MIXED;
					if (team == gu->myTeam) {
						logOutput.Print("%s: Capture failed, unit type limit reached", unitDef->humanName.c_str());
						logOutput.SetLastMsgPos(pos);
					}
					ENTER_SYNCED;
				} else {
					// capture succesful
					int oldLineage = curCapture->lineage;
					curCapture->lineage = this->lineage;
					gs->Team(oldLineage)->LeftLineage(curCapture);
				}
				curCapture->captureProgress=0.5f;	//make units somewhat easier to capture back after first capture
				StopBuild(true);
			}
		} else {
			StopBuild(true);
		}
	}
	CUnit::Update();
}


void CBuilder::SlowUpdate(void)
{
	if(terraforming){
		mapDamage->RecalcArea(tx1,tx2,tz1,tz2);
	}
	CUnit::SlowUpdate();
}

⌨️ 快捷键说明

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