void CFactory::FinishBuild(CUnit* buildee) { if (buildee->beingBuilt) { return; } if (unitDef->fullHealthFactory && buildee->health < buildee->maxHealth) { return; } { GML_RECMUTEX_LOCK(group); // FinishBuild if (group && buildee->group == 0) { buildee->SetGroup(group, true); } } const CCommandAI* bcai = buildee->commandAI; const bool assignOrders = bcai->commandQue.empty() || (dynamic_cast<const CMobileCAI*>(bcai) && static_cast<const CMobileCAI*>(bcai)->unimportantMove); if (assignOrders) { AssignBuildeeOrders(buildee); waitCommandsAI.AddLocalUnit(buildee, this); } // inform our commandAI finishedBuildFunc(this, finishedBuildCommand); finishedBuildFunc = NULL; eventHandler.UnitFromFactory(buildee, this, !assignOrders); StopBuild(); }
void CFactory::FinishBuild(CUnit* buildee) { if (buildee->beingBuilt) { return; } if (unitDef->fullHealthFactory && buildee->health < buildee->maxHealth) { return; } { if (group && !buildee->group) { buildee->SetGroup(group, true); } } const CCommandAI* bcai = buildee->commandAI; // if not idle, the buildee already has user orders const bool buildeeIdle = (bcai->commandQue.empty()); const bool buildeeMobile = (dynamic_cast<const CMobileCAI*>(bcai) != NULL); if (buildeeIdle || buildeeMobile) { AssignBuildeeOrders(buildee); waitCommandsAI.AddLocalUnit(buildee, this); } // inform our commandAI finishedBuildFunc(this, finishedBuildCommand); finishedBuildFunc = NULL; eventHandler.UnitFromFactory(buildee, this, !buildeeIdle); StopBuild(); }
void CFactory::Update() { if (beingBuilt) { // factory under construction CUnit::Update(); return; } if (quedBuild && !opening && !stunned) { script->Activate(); groundBlockingObjectMap->OpenBlockingYard(this, curYardMap); opening = true; } if (quedBuild && inBuildStance && !stunned) { // start building a unit const float3 buildPos = CalcBuildPos(); const CSolidObject* solidObj = groundBlockingObjectMap->GroundBlocked(buildPos); if (solidObj == NULL || (dynamic_cast<const CUnit*>(solidObj) == this)) { quedBuild = false; CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team, true, buildFacing, this); if (!unitDef->canBeAssisted) { b->soloBuilder = this; b->AddDeathDependence(this); } AddDeathDependence(b); curBuild = b; script->StartBuilding(); int soundIdx = unitDef->sounds.build.getRandomIdx(); if (soundIdx >= 0) { Channels::UnitReply.PlaySample( unitDef->sounds.build.getID(soundIdx), pos, unitDef->sounds.build.getVolume(0)); } } else { helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8, true, true, NULL); } } if (curBuild && !beingBuilt) { if (!stunned) { // factory not under construction and // nanolathing unit: continue building lastBuild = gs->frameNum; // buildPiece is the rotating platform const int buildPiece = GetBuildPiece(); const CMatrix44f& mat = script->GetPieceMatrix(buildPiece); const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z // rotate unit nanoframe with platform curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535; const float3 buildPos = CalcBuildPos(buildPiece); curBuild->pos = buildPos; if (curBuild->floatOnWater) { float waterline = ground->GetHeight(buildPos.x, buildPos.z) - curBuild->unitDef->waterline; if (waterline > curBuild->pos.y) curBuild->pos.y = waterline; } curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y); const CCommandQueue& queue = commandAI->commandQue; if(!queue.empty() && (queue.front().id == CMD_WAIT)) { curBuild->AddBuildPower(0, this); } else { if (curBuild->AddBuildPower(buildSpeed, this)) { CreateNanoParticle(); } } } if (!curBuild->beingBuilt && (!unitDef->fullHealthFactory || (curBuild->health >= curBuild->maxHealth))) { if (group && curBuild->group == 0) { curBuild->SetGroup(group); } bool userOrders = true; if (curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) { userOrders = false; AssignBuildeeOrders(curBuild); waitCommandsAI.AddLocalUnit(curBuild, this); } eventHandler.UnitFromFactory(curBuild, this, userOrders); StopBuild(); } } if (((lastBuild + 200) < gs->frameNum) && !stunned && !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this, curYardMap); opening = false; script->Deactivate(); } CBuilding::Update(); }