unitloader.cpp

来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 494 行 · 第 1/2 页

CPP
494
字号
		if(!unit->beingBuilt)
			unit->mass=ud->mass; //otherwise set this when finished building instead

		if ((type == "Builder") || ud->hoverAttack || ud->transportCapacity) {
			CTAAirMoveType *mt = SAFE_NEW CTAAirMoveType(unit);

			mt->turnRate = ud->turnRate;
			mt->maxSpeed = ud->speed / GAME_SPEED;
			mt->accRate = ud->maxAcc;
			mt->decRate = ud->maxDec;
			mt->wantedHeight = ud->wantedHeight+gs->randFloat()*5;
			mt->orgWantedHeight=mt->wantedHeight;
			mt->dontLand = ud->DontLand ();
			mt->collide = ud->collide;

			unit->moveType = mt;
		}
		else {
			CAirMoveType *mt = SAFE_NEW CAirMoveType(unit);

			if(type=="Fighter")
				mt->isFighter=true;

			mt->collide = ud->collide;

			mt->wingAngle = ud->wingAngle;
			mt->invDrag = 1 - ud->drag;
			mt->frontToSpeed = ud->frontToSpeed;
			mt->speedToFront = ud->speedToFront;
			mt->myGravity = ud->myGravity;

			mt->maxBank = ud->maxBank;
			mt->maxPitch = ud->maxPitch;
			mt->turnRadius = ud->turnRadius;
			mt->wantedHeight = ud->wantedHeight*1.5f+(gs->randFloat()-0.3f)*15*(mt->isFighter?2:1);;

			mt->maxAcc = ud->maxAcc;
			mt->maxAileron = ud->maxAileron;
			mt->maxElevator = ud->maxElevator;
			mt->maxRudder = ud->maxRudder;

			unit->moveType = mt;
		}
	} else {
		unit->moveType=SAFE_NEW CMoveType(unit);
		unit->upright=true;
	}

	unit->energyTickMake = ud->energyMake;
	if(ud->tidalGenerator>0)
		unit->energyTickMake += ud->tidalGenerator*readmap->tidalStrength;

	unit->model = ud->LoadModel(side);
	unit->SetRadius(unit->model->radius);

	if(ud->floater)
		unit->pos.y = max(-ud->waterline,ground->GetHeight2(unit->pos.x,unit->pos.z));
	else
		unit->pos.y=ground->GetHeight2(unit->pos.x,unit->pos.z);

	unit->cob = SAFE_NEW CCobInstance(GCobEngine.GetCobFile("scripts/" + name+".cob"), unit);
	unit->localmodel = modelParser->CreateLocalModel(unit->model, &unit->cob->pieces);

	for (unsigned int i = 0; i < ud->weapons.size(); i++) {
		unit->weapons.push_back(LoadWeapon(ud->weapons[i].def, unit, &ud->weapons[i]));
	}

	// Calculate the max() of the available weapon reloadtimes
	int relMax = 0;
	for (vector<CWeapon*>::iterator i = unit->weapons.begin(); i != unit->weapons.end(); ++i) {
		if ((*i)->reloadTime > relMax)
			relMax = (*i)->reloadTime;
		if(dynamic_cast<CBeamLaser*>(*i))
			relMax=150;
	}
	relMax *= 30;		// convert ticks to milliseconds

	// TA does some special handling depending on weapon count
	if (unit->weapons.size() > 1)
		relMax = max(relMax, 3000);

	// Call initializing script functions
	unit->cob->Call(COBFN_Create);
	unit->cob->Call("SetMaxReloadTime", relMax);

	unit->heading = facing*16*1024;
	unit->frontdir=GetVectorFromHeading(unit->heading);
	unit->updir=UpVector;
	unit->rightdir=unit->frontdir.cross(unit->updir);

	unit->Init(builder);

	unit->yardMap = ud->yardmaps[facing];

	if(!build)
		unit->FinishedBuilding();

	return unit;
}

CWeapon* CUnitLoader::LoadWeapon(const WeaponDef *weapondef, CUnit* owner, const UnitDef::UnitDefWeapon* udw)
{
	CWeapon* weapon;

	if(!weapondef){
		logOutput.Print("Error: No weapon def?");
	}

	if(udw->name=="NOWEAPON"){
		weapon=SAFE_NEW CNoWeapon(owner);
	} else if(weapondef->type=="Cannon"){
		weapon=SAFE_NEW CCannon(owner);
		((CCannon*)weapon)->selfExplode=weapondef->selfExplode;
	} else if(weapondef->type=="Rifle"){
		weapon=SAFE_NEW CRifle(owner);
	} else if(weapondef->type=="Melee"){
		weapon=SAFE_NEW CMeleeWeapon(owner);
	} else if(weapondef->type=="AircraftBomb"){
		weapon=SAFE_NEW CBombDropper(owner,false);
	} else if(weapondef->type=="Shield"){
		weapon=SAFE_NEW CPlasmaRepulser(owner);
	} else if(weapondef->type=="Flame"){
		weapon=SAFE_NEW CFlameThrower(owner);
	} else if(weapondef->type=="MissileLauncher"){
		weapon=SAFE_NEW CMissileLauncher(owner);
	} else if(weapondef->type=="TorpedoLauncher"){
		if(owner->unitDef->canfly && !weapondef->submissile){
			weapon=SAFE_NEW CBombDropper(owner,true);
			if(weapondef->tracks)
				((CBombDropper*)weapon)->tracking=weapondef->turnrate;
			((CBombDropper*)weapon)->bombMoveRange=weapondef->range;
		} else {
			weapon=SAFE_NEW CTorpedoLauncher(owner);
			if(weapondef->tracks)
				((CTorpedoLauncher*)weapon)->tracking=weapondef->turnrate;
		}
	} else if(weapondef->type=="LaserCannon"){
		weapon=SAFE_NEW CLaserCannon(owner);
		((CLaserCannon*)weapon)->color=weapondef->visuals.color;
	} else if(weapondef->type=="BeamLaser"){
		weapon=SAFE_NEW CBeamLaser(owner);
		((CBeamLaser*)weapon)->color=weapondef->visuals.color;
	} else if(weapondef->type=="LightingCannon"){
		weapon=SAFE_NEW CLightingCannon(owner);
		((CLightingCannon*)weapon)->color=weapondef->visuals.color;
	} else if(weapondef->type=="EmgCannon"){
		weapon=SAFE_NEW CEmgCannon(owner);
	} else if(weapondef->type=="DGun"){
		weapon=SAFE_NEW CDGunWeapon(owner);
	} else if(weapondef->type=="StarburstLauncher"){
		weapon=SAFE_NEW CStarburstLauncher(owner);
		if(weapondef->tracks)
			((CStarburstLauncher*)weapon)->tracking=weapondef->turnrate;
		else
			((CStarburstLauncher*)weapon)->tracking=0;
		((CStarburstLauncher*)weapon)->uptime=weapondef->uptime*GAME_SPEED;
	}else {
		logOutput << "Unknown weapon type " << weapondef->type.c_str() << "\n";
		return 0;
	}
	weapon->weaponDef = weapondef;

	weapon->reloadTime= (int) (weapondef->reload*GAME_SPEED);
	if(weapon->reloadTime==0)
		weapon->reloadTime=1;
	weapon->range=weapondef->range;
//	weapon->baseRange=weapondef->range;
	weapon->heightMod=weapondef->heightmod;
	weapon->projectileSpeed=weapondef->projectilespeed;
//	weapon->baseProjectileSpeed=weapondef->projectilespeed/GAME_SPEED;

	weapon->areaOfEffect=weapondef->areaOfEffect;
	weapon->accuracy=weapondef->accuracy;
	weapon->sprayangle=weapondef->sprayangle;

	weapon->salvoSize=weapondef->salvosize;
	weapon->salvoDelay=(int) (weapondef->salvodelay*GAME_SPEED);

	weapon->metalFireCost=weapondef->metalcost;
	weapon->energyFireCost=weapondef->energycost;


	weapon->fireSoundId = weapondef->firesound.getID(0);
	weapon->fireSoundVolume = weapondef->firesound.getVolume(0);


	weapon->onlyForward = weapondef->onlyForward;
	if (owner->unitDef->type == "Fighter" && !owner->unitDef->hoverAttack)	// fighter aircraft have too big tolerance in TA
		weapon->maxAngleDif = cos(weapondef->maxAngle * 0.4f / 180 * PI);
	else
		weapon->maxAngleDif = cos(weapondef->maxAngle / 180 * PI);

	weapon->SetWeaponNum(owner->weapons.size());

	weapon->badTargetCategory=udw->badTargetCat;
	weapon->onlyTargetCategory=weapondef->onlyTargetCategory & udw->onlyTargetCat;

	if (udw->slavedTo) {
		const int index = (udw->slavedTo - 1);
		if ((index < 0) || (index >= owner->weapons.size())) {
			throw content_error("Bad weapon slave in " + owner->unitDef->name);
		}
		weapon->slavedTo = owner->weapons[index];
	}

	weapon->mainDir=udw->mainDir;
	weapon->maxMainDirAngleDif=udw->maxAngleDif;

	weapon->fuelUsage = udw->fuelUsage;
	weapon->avoidFriendly = weapondef->avoidFriendly;
	weapon->avoidFeature = weapondef->avoidFeature;
	weapon->targetBorder = weapondef->targetBorder;
	weapon->cylinderTargetting = weapondef->cylinderTargetting;
	weapon->minIntensity = weapondef->minIntensity;
	weapon->heightBoostFactor = weapondef->heightBoostFactor;
	weapon->collisionFlags = weapondef->collisionFlags;
	weapon->Init();

	return weapon;
}


void CUnitLoader::FlattenGround(const CUnit* unit)
{
	const UnitDef* unitDef = unit->unitDef;
	if (!mapDamage->disabled && unitDef->levelGround && !unitDef->floater &&
	    !(unitDef->canmove && (unitDef->speed > 0.0f))) {
		BuildInfo bi(unitDef, unit->pos, unit->buildFacing);
		bi.pos = helper->Pos2BuildPos(bi);
		const float hss = 0.5f * SQUARE_SIZE;
		const int tx1 = (int)max(0.0f ,(bi.pos.x - (bi.GetXSize() * hss)) / SQUARE_SIZE);
		const int tz1 = (int)max(0.0f ,(bi.pos.z - (bi.GetYSize() * hss)) / SQUARE_SIZE);
		const int tx2 = min(gs->mapx, tx1 + bi.GetXSize());
		const int tz2 = min(gs->mapy, tz1 + bi.GetYSize());
		float* heightmap = readmap->GetHeightmap();
		for(int z = tz1; z <= tz2; z++){
			for(int x = tx1; x <= tx2; x++){
				heightmap[z * (gs->mapx + 1) + x] = bi.pos.y;
			}
		}
		mapDamage->RecalcArea(tx1, tx2, tz1, tz2);
	}
}



⌨️ 快捷键说明

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