void CBuilderCAI::ExecuteResurrect(Command& c) { // not all builders are resurrect-capable by default if (!owner->unitDef->canResurrect) return; if (c.params.size() == 1) { unsigned int id = (unsigned int) c.params[0]; if (id >= unitHandler->MaxUnits()) { // resurrect feature CFeature* feature = featureHandler->GetFeature(id - unitHandler->MaxUnits()); if (feature && feature->udef != NULL) { if (((c.options & INTERNAL_ORDER) && !(c.options & CONTROL_KEY) && IsFeatureBeingReclaimed(feature->id, owner)) || !ResurrectObject(feature)) { StopMove(); RemoveUnitFromResurrecters(owner); FinishCommand(); } else { AddUnitToResurrecters(owner); } } else { RemoveUnitFromResurrecters(owner); if (ownerBuilder->lastResurrected && unitHandler->GetUnitUnsafe(ownerBuilder->lastResurrected) != NULL && owner->unitDef->canRepair) { // resurrection finished, start repair (by overwriting the current order) c = Command(CMD_REPAIR, c.options | INTERNAL_ORDER, ownerBuilder->lastResurrected); ownerBuilder->lastResurrected = 0; inCommand = false; SlowUpdate(); return; } StopMove(); FinishCommand(); } } else { // resurrect unit RemoveUnitFromResurrecters(owner); FinishCommand(); } } else if (c.params.size() == 4) { // area resurrect const float3 pos = c.GetPos(0); const float radius = c.params[3]; if (FindResurrectableFeatureAndResurrect(pos, radius, c.options, (c.options & META_KEY))) { inCommand = false; SlowUpdate(); return; } if (!(c.options & ALT_KEY)) { FinishCommand(); } } else { // wrong number of parameters RemoveUnitFromResurrecters(owner); FinishCommand(); } }
void CBuilderCAI::ExecuteGuard(Command& c) { if (!owner->unitDef->canGuard) return; CBuilder* builder = (CBuilder*) owner; CUnit* guardee = uh->GetUnit(c.params[0]); if (guardee == NULL) { FinishCommand(); return; } if (guardee == owner) { FinishCommand(); return; } if (UpdateTargetLostTimer(guardee->id) == 0) { FinishCommand(); return; } if (guardee->outOfMapTime > (GAME_SPEED * 5)) { FinishCommand(); return; } if (CBuilder* b = dynamic_cast<CBuilder*>(guardee)) { if (b->terraforming) { if (MoveInBuildRange(b->terraformCenter, b->terraformRadius * 0.7f)) { builder->HelpTerraform(b); } else { StopSlowGuard(); } return; } else if (b->curReclaim && owner->unitDef->canReclaim) { StopSlowGuard(); if (!ReclaimObject(b->curReclaim)) { StopMove(); } return; } else if (b->curResurrect && owner->unitDef->canResurrect) { StopSlowGuard(); if (!ResurrectObject(b->curResurrect)) { StopMove(); } return; } else { builder->StopBuild(); } const bool pushRepairCommand = ( b->curBuild != NULL) && ( b->curBuild->soloBuilder == NULL || b->curBuild->soloBuilder == owner) && (( b->curBuild->beingBuilt && owner->unitDef->canAssist) || ( !b->curBuild->beingBuilt && owner->unitDef->canRepair)); if (pushRepairCommand) { StopSlowGuard(); Command nc(CMD_REPAIR, c.options); nc.params.push_back(b->curBuild->id); commandQue.push_front(nc); inCommand = false; SlowUpdate(); return; } } if (CFactory* fac = dynamic_cast<CFactory*>(guardee)) { const bool pushRepairCommand = ( fac->curBuild != NULL) && ( fac->curBuild->soloBuilder == NULL || fac->curBuild->soloBuilder == owner) && (( fac->curBuild->beingBuilt && owner->unitDef->canAssist) || (!fac->curBuild->beingBuilt && owner->unitDef->canRepair)); if (pushRepairCommand) { StopSlowGuard(); Command nc(CMD_REPAIR, c.options); nc.params.push_back(fac->curBuild->id); commandQue.push_front(nc); inCommand = false; // SlowUpdate(); return; } } if (!(c.options & CONTROL_KEY) && IsUnitBeingReclaimed(guardee, owner)) return; const float3 pos = guardee->pos; const float radius = (guardee->immobile) ? guardee->radius : guardee->radius * 0.8f; // in case of mobile units reduce radius a bit if (MoveInBuildRange(pos, radius)) { StartSlowGuard(guardee->moveType->GetMaxSpeed()); const bool pushRepairCommand = ( guardee->health < guardee->maxHealth) && ( guardee->soloBuilder == NULL || guardee->soloBuilder == owner) && (( guardee->beingBuilt && owner->unitDef->canAssist) || (!guardee->beingBuilt && owner->unitDef->canRepair)); if (pushRepairCommand) { StopSlowGuard(); Command nc(CMD_REPAIR, c.options); nc.params.push_back(guardee->id); commandQue.push_front(nc); inCommand = false; return; } else { NonMoving(); } } else { StopSlowGuard(); } }