bool CUnit::UseMetal(float metal) { if(metal<0) { AddMetal(-metal); return true; } bool canUse=gs->Team(team)->UseMetal(metal); if(canUse) metalUseI += metal; return canUse; }
void CFactory::StopBuild() { cob->Call("StopBuilding"); if(curBuild){ if(curBuild->beingBuilt){ AddMetal(curBuild->metalCost*curBuild->buildProgress); uh->DeleteUnit(curBuild); } DeleteDeathDependence(curBuild); } curBuild=0; quedBuild=false; }
void CFactory::StopBuild() { // cancel a build-in-progress script->StopBuilding(); if (curBuild) { if (curBuild->beingBuilt) { AddMetal(curBuild->metalCost * curBuild->buildProgress, false); curBuild->KillUnit(false, true, NULL); } DeleteDeathDependence(curBuild); } curBuild = 0; quedBuild = false; }
void CFactory::StopBuild() { // cancel a build-in-progress script->StopBuilding(); if (curBuild) { if (curBuild->beingBuilt) { AddMetal(curBuild->metalCost * curBuild->buildProgress, false); curBuild->KillUnit(false, true, NULL); } DeleteDeathDependence(curBuild, DEPENDENCE_BUILD); } curBuild = NULL; curBuildDef = NULL; finishedBuildFunc = NULL; }
void CUnit::SlowUpdate() { --nextPosErrorUpdate; if(nextPosErrorUpdate==0) { float3 newPosError(gs->randVector()); newPosError.y*=0.2; if(posErrorVector.dot(newPosError)<0) newPosError=-newPosError; posErrorDelta=(newPosError-posErrorVector)*(1.0/256); nextPosErrorUpdate=16; } for(int a=0; a<gs->activeAllyTeams; ++a) { if(losStatus[a] & LOS_INTEAM) { } else if(loshandler->InLos(this,a)) { if(!(losStatus[a]&LOS_INLOS)) { int prevLosStatus = losStatus[a]; if(mobility || beingBuilt) { losStatus[a]|=(LOS_INLOS | LOS_INRADAR); } else { losStatus[a]|=(LOS_INLOS | LOS_INRADAR | LOS_PREVLOS | LOS_CONTRADAR); } if(!(prevLosStatus&LOS_INRADAR)) { globalAI->UnitEnteredRadar(this,a); } globalAI->UnitEnteredLos(this,a); } } else if(radarhandler->InRadar(this,a)) { if((losStatus[a] & LOS_INLOS)) { globalAI->UnitLeftLos(this,a); losStatus[a]&= ~LOS_INLOS; } else if(!(losStatus[a] & LOS_INRADAR)) { losStatus[a]|= LOS_INRADAR; globalAI->UnitEnteredRadar(this,a); } } else { if((losStatus[a]&LOS_INRADAR)) { if((losStatus[a]&LOS_INLOS)) { globalAI->UnitLeftLos(this,a); globalAI->UnitLeftRadar(this,a); } else { globalAI->UnitLeftRadar(this,a); } losStatus[a]&= ~(LOS_INLOS | LOS_INRADAR | LOS_CONTRADAR); } } } if(paralyzeDamage>0) { paralyzeDamage-=maxHealth*(16.f/30.f/40.f); if(paralyzeDamage<0) paralyzeDamage=0; if(paralyzeDamage<health) stunned=false; } if(stunned) { isCloaked=false; return; } if(selfDCountdown && !stunned) { selfDCountdown--; if(selfDCountdown<=1) { if(!beingBuilt) KillUnit(true,false,0); else KillUnit(false,true,0); //avoid unfinished buildings making an explosion selfDCountdown=0; return; } ENTER_MIXED; if(selfDCountdown&1 && team==gu->myTeam) info->AddLine("%s: Self destruct in %i s",unitDef->humanName.c_str(),selfDCountdown/2); ENTER_SYNCED; } if(beingBuilt) { if(lastNanoAdd<gs->frameNum-200) { health-=maxHealth/(buildTime*0.03); buildProgress-=1/(buildTime*0.03); AddMetal(metalCost/(buildTime*0.03)); if(health<0) KillUnit(false,true,0); } return; } //below is stuff that shouldnt be run while being built lastSlowUpdate=gs->frameNum; commandAI->SlowUpdate(); moveType->SlowUpdate(); metalMake = metalMakeI + metalMakeold; metalUse = metalUseI+ metalUseold; energyMake = energyMakeI + energyMakeold; energyUse = energyUseI + energyUseold; metalMakeold = metalMakeI; metalUseold = metalUseI; energyMakeold = energyMakeI; energyUseold = energyUseI; metalMakeI=metalUseI=energyMakeI=energyUseI=0; AddMetal(unitDef->metalMake*0.5f); if(activated) { if(UseEnergy(unitDef->energyUpkeep*0.5f)) { if(unitDef->isMetalMaker) { AddMetal(unitDef->makesMetal*0.5f*uh->metalMakerEfficiency); uh->metalMakerIncome+=unitDef->makesMetal; } else { AddMetal(unitDef->makesMetal*0.5f); } if(unitDef->extractsMetal>0) AddMetal(metalExtract * 0.5f); } UseMetal(unitDef->metalUpkeep*0.5f); if(unitDef->windGenerator>0) { if(wind.curStrength > unitDef->windGenerator) { AddEnergy(unitDef->windGenerator*0.5f); } else { AddEnergy(wind.curStrength*0.5f); } } } AddEnergy(energyTickMake*0.5f); if(health<maxHealth) { health += unitDef->autoHeal; if(restTime > unitDef->idleTime) { health += unitDef->idleAutoHeal; } if(health>maxHealth) health=maxHealth; } bonusShieldSaved+=0.05f; residualImpulse*=0.6; if(wantCloak) { if(helper->GetClosestEnemyUnitNoLosTest(pos,unitDef->decloakDistance,allyteam)) { curCloakTimeout=gs->frameNum+cloakTimeout; isCloaked=false; } if(isCloaked || gs->frameNum>=curCloakTimeout) { float cloakCost=unitDef->cloakCost; if(speed.SqLength()>0.2) cloakCost=unitDef->cloakCostMoving; if(UseEnergy(cloakCost * 0.5f)) { isCloaked=true; } else { isCloaked=false; } } else { isCloaked=false; } } else { isCloaked=false; } if(uh->waterDamage && (physicalState==CSolidObject::Floating || (physicalState==CSolidObject::OnGround && pos.y<=-3 && readmap->mipHeightmap[1][int((pos.z/(SQUARE_SIZE*2))*gs->hmapx+(pos.x/(SQUARE_SIZE*2)))]<-1))) { DoDamage(DamageArray()*uh->waterDamage,0,ZeroVector); } if(unitDef->canKamikaze) { if(fireState==2) { CUnit* u=helper->GetClosestEnemyUnitNoLosTest(pos,unitDef->kamikazeDist,allyteam); if(u && u->physicalState!=CSolidObject::Flying && u->speed.dot(pos - u->pos)<=0) //self destruct when unit start moving away from mine, should maximize damage KillUnit(true,false,0); } if(userTarget && userTarget->pos.distance(pos)<unitDef->kamikazeDist) KillUnit(true,false,0); if(userAttackGround && userAttackPos.distance(pos)<unitDef->kamikazeDist) KillUnit(true,false,0); } if(!weapons.empty()) { haveTarget=false; haveUserTarget=false; //aircraft does not want this if (moveType->useHeading) { frontdir=GetVectorFromHeading(heading); if(upright || !unitDef->canmove) { updir=UpVector; rightdir=frontdir.cross(updir); } else { updir=ground->GetNormal(pos.x,pos.z); rightdir=frontdir.cross(updir); rightdir.Normalize(); frontdir=updir.cross(rightdir); } } if(!dontFire) { for(vector<CWeapon*>::iterator wi=weapons.begin(); wi!=weapons.end(); ++wi) { CWeapon* w=*wi; if(userTarget && !w->haveUserTarget && (haveDGunRequest || !unitDef->canDGun || !w->weaponDef->manualfire)) w->AttackUnit(userTarget,true); else if(userAttackGround && !w->haveUserTarget && (haveDGunRequest || !unitDef->canDGun || !w->weaponDef->manualfire)) w->AttackGround(userAttackPos,true); w->SlowUpdate(); if(w->targetType==Target_None && fireState>0 && lastAttacker && lastAttack+200>gs->frameNum) w->AttackUnit(lastAttacker,false); } } } if(moveType->progressState == CMoveType::Active) { if(/*physicalState == OnGround*/seismicSignature && !(losStatus[gu->myAllyTeam] & LOS_INLOS) && radarhandler->InSeismicDistance(this, gu->myAllyTeam)) new CSimpleGroundFlash(pos + float3(radarhandler->radarErrorSize[gu->myAllyTeam]*(0.5f-gu->usRandFloat()),0,radarhandler->radarErrorSize[gu->myAllyTeam]*(0.5f-gu->usRandFloat())), ph->seismictex, 30, 15, 0, seismicSignature, 1, float3(0.8,0.0,0.0)); } CalculateTerrainType(); UpdateTerrainType(); }