Bazaar developer reference

CvUnit::build(BuildTypes)

Defined in
CvUnit.cpp, line 10388
Class
CvUnit
Hook name
CivHooks::CvUnit_build
Lua events
GameEvents.PlayerBuilding, GameEvents.PlayerBuilt

Hooks

static bool BeforeCvUnit_build(CvUnit* self, BuildTypes eBuild, bool& result);static void AfterCvUnit_build(CvUnit* self, BuildTypes eBuild, bool& result);static bool ReplaceCvUnit_build(bool (*original)(CvUnit*, BuildTypes), CvUnit* self, BuildTypes eBuild);CivRegisterBefore<CivHooks::CvUnit_build>(host, &BeforeCvUnit_build);CivRegisterAfter<CivHooks::CvUnit_build>(host, &AfterCvUnit_build);CivRegisterReplace<CivHooks::CvUnit_build>(host, &ReplaceCvUnit_build);

Code

10387// Returns true if build finished...10388bool CvUnit::build(BuildTypes eBuild)10389{10390	VALIDATE_OBJECT10391	bool bFinished;1039210393	CvAssertMsg(eBuild < GC.getNumBuildInfos(), "Invalid Build");10394	CvPlayer& kPlayer = GET_PLAYER(getOwner());1039510396	CvBuildInfo* pkBuildInfo = NULL;10397	if(eBuild != NO_BUILD)10398	{10399		pkBuildInfo = GC.getBuildInfo(eBuild);10400	}10401	CvPlot* pPlot = plot();1040210403	// Don't test Gold10404	if(!canBuild(pPlot, eBuild, false, false))10405	{10406		return false;10407	}1040810409	if(GC.getLogging() && GC.getAILogging())10410	{10411		if(pPlot->getBuildProgress(eBuild) == 0)10412		{10413			LogWorkerEvent(eBuild, true);10414		}10415	}1041610417	int iStartedYet = pPlot->getBuildProgress(eBuild);10418#if defined(MOD_BUGFIX_MINOR)10419	int iWorkRateFactor = 1;10420#endif1042110422	// if we are starting something new wipe out the old thing immediately10423	if(iStartedYet == 0)10424	{10425		ImprovementTypes eImprovement = NO_IMPROVEMENT;1042610427		if(pkBuildInfo)10428		{10429			eImprovement = (ImprovementTypes) pkBuildInfo->getImprovement();10430		}1043110432		if(eImprovement != NO_IMPROVEMENT)10433		{10434			if(pPlot->getImprovementType() != NO_IMPROVEMENT)10435			{10436				CvImprovementEntry *pkImprovementEntry = GC.getImprovementInfo(eImprovement);10437				if (!pkImprovementEntry || !pkImprovementEntry->IsRequiresImprovement())10438				{10439					pPlot->setImprovementType(NO_IMPROVEMENT);10440				}10441			}10442		}1044310444#if defined(MOD_BUGFIX_MINOR)10445		/*10446		 * This appears to be a bug, in that we drop out of the if into an exact duplicate of the call below.10447		 * However, this is so long established that if we fix it, we'll get howls of complaints from 999 out of 1000 players10448		 * that build times have increased under some circumstances, or, more likely, "it's broken".10449		 *10450		 * The double call is only a problem if the build takes one turn, ie instantaneous.10451		 * There are no standard builds where this is the case.10452		 *10453		 * The double call is also only an issue if you a) care about the BuildFinished event being duplicated or b)10454		 * have set a maintenance cost on the improvement and are building it outside your territory, in which case you get charged twice10455		 * but will only receive one refund if the improvement is destroyed or the territory captured.10456		 *10457		 * The simple solution is "don't do this!"10458		 *10459		 * The coding solution is to avoid the call and just double the workrate (to allow for the double call),10460		 * dirty but a win-win solution!10461		*/10462		iWorkRateFactor = 2;10463#else10464		// wipe out all build progress also10465		bFinished = pPlot->changeBuildProgress(eBuild, workRate(false), getOwner());10466#endif10467	}1046810469#if defined(MOD_BUGFIX_MINOR)10470	bFinished = pPlot->changeBuildProgress(eBuild, workRate(false) * iWorkRateFactor, getOwner());10471#else10472	bFinished = pPlot->changeBuildProgress(eBuild, workRate(false), getOwner());10473#endif1047410475#if defined(MOD_EVENTS_PLOT)10476	if (MOD_EVENTS_PLOT) {10477		GAMEEVENTINVOKE_HOOK(GAMEEVENT_PlayerBuilding, getOwner(), GetID(), getX(), getY(), eBuild, (iStartedYet == 0));10478	}10479#endif1048010481	finishMoves(); // needs to be at bottom because movesLeft() can affect workRate()...1048210483	if(bFinished)10484	{10485		// Update Resource info10486		if(pkBuildInfo)10487		{10488			ImprovementTypes eImprovement = NO_IMPROVEMENT;10489			RouteTypes eRoute = NO_ROUTE;1049010491			if(pkBuildInfo->getImprovement() != NO_IMPROVEMENT)10492			{10493				eImprovement = (ImprovementTypes) pkBuildInfo->getImprovement();1049410495				CvImprovementEntry* pkImprovementInfo = GC.getImprovementInfo(eImprovement);10496				if(pkImprovementInfo)10497				{10498					if (pkImprovementInfo->GetCultureBombRadius() > 0)10499					{10500						PerformCultureBomb(pkImprovementInfo->GetCultureBombRadius());10501					}10502				}10503			}10504#if defined(GLOBAL_ALPINE_PASSES)10505			// Can be both an improvement and a route10506			if(pkBuildInfo->getRoute() != NO_ROUTE)10507#else10508			else if(pkBuildInfo->getRoute() != NO_ROUTE)10509#endif10510			{10511				eRoute = (RouteTypes) pkBuildInfo->getRoute();10512			}1051310514			int iNumResource = 0;1051510516			// Update the amount of a Resource used up by popped Build10517			for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)10518			{10519				if(eImprovement != NO_IMPROVEMENT)10520				{10521					CvImprovementEntry* pkImprovementInfo = GC.getImprovementInfo(eImprovement);10522					if(pkImprovementInfo)10523					{10524						iNumResource = pkImprovementInfo->GetResourceQuantityRequirement(iResourceLoop);10525					}10526				}10527#if defined(GLOBAL_ALPINE_PASSES)10528				// Can be both an improvement and a route10529				if(eRoute != NO_ROUTE)10530#else10531				else if(eRoute != NO_ROUTE)10532#endif10533				{10534					CvRouteInfo* pkRouteInfo = GC.getRouteInfo(eRoute);10535					if(pkRouteInfo)10536					{10537#if defined(GLOBAL_ALPINE_PASSES)10538						iNumResource += pkRouteInfo->getResourceQuantityRequirement(iResourceLoop);10539#else10540						iNumResource = pkRouteInfo->getResourceQuantityRequirement(iResourceLoop);10541#endif10542					}10543				}1054410545				if(iNumResource > 0)10546				{10547					kPlayer.changeNumResourceUsed((ResourceTypes) iResourceLoop, -iNumResource);10548				}10549			}1055010551			if(pkBuildInfo->isKill())10552			{10553				if (pPlot->isActiveVisible(false))10554				{10555					auto_ptr<ICvUnit1> pDllUnit(new CvDllUnit(this));10556					gDLL->GameplayUnitActivate(pDllUnit.get());10557				}1055810559				if(IsGreatPerson())10560				{10561#if defined(MOD_EVENTS_GREAT_PEOPLE)10562					kPlayer.DoGreatPersonExpended(getUnitType(), this);10563#else10564					kPlayer.DoGreatPersonExpended(getUnitType());10565#endif10566				}1056710568				kill(true);10569			}1057010571			// Add to player's Improvement count, which will increase cost of future Improvements10572			if(pkBuildInfo->getImprovement() != NO_IMPROVEMENT || pkBuildInfo->getRoute() != NO_ROUTE)	// Prevents chopping Forest or Jungle from counting10573			{10574				kPlayer.changeTotalImprovementsBuilt(1);10575			}1057610577			if(GC.getLogging() && GC.getAILogging())10578			{10579				LogWorkerEvent(eBuild, false);10580			}10581		}1058210583#if defined(MOD_EVENTS_PLOT)10584		if (MOD_EVENTS_PLOT) {10585			GAMEEVENTINVOKE_HOOK(GAMEEVENT_PlayerBuilt, getOwner(), GetID(), getX(), getY(), eBuild);10586		}10587#endif10588	}10589	else // we are not done doing this10590	{10591		if(pkBuildInfo)10592		{10593			ImprovementTypes eImprovement = NO_IMPROVEMENT;10594			RouteTypes eRoute = NO_ROUTE;1059510596			if(pkBuildInfo->getImprovement() != NO_IMPROVEMENT)10597			{10598				eImprovement = (ImprovementTypes) pkBuildInfo->getImprovement();10599			}10600			else if(pkBuildInfo->getRoute() != NO_ROUTE)10601			{10602				eRoute = (RouteTypes) pkBuildInfo->getRoute();10603			}1060410605			if(iStartedYet == 0)10606			{10607				if(pPlot->isVisible(GC.getGame().getActiveTeam(), true))10608				{10609					if(eImprovement != NO_IMPROVEMENT)10610					{10611						pPlot->setLayoutDirty(true);1061210613					}10614					else if(eRoute != NO_ROUTE)10615					{10616						pPlot->setLayoutDirty(true);10617					}10618				}10619			}10620		}10621	}1062210623	return bFinished;10624}

Calls

Called by