Bazaar developer reference

CvCity::popOrder(int, bool, bool)

Defined in
CvCity.cpp, line 12950
Class
CvCity
Hook name
CivHooks::CvCity_popOrder
Lua events
GameEvents.CityTrained, GameEvents.CityConstructed, GameEvents.CityCreated, GameEvents.CityPrepared

Hooks

static bool BeforeCvCity_popOrder(CvCity* self, int iNum, bool bFinish, bool bChoose);static void AfterCvCity_popOrder(CvCity* self, int iNum, bool bFinish, bool bChoose);static void ReplaceCvCity_popOrder(void (*original)(CvCity*, int, bool, bool), CvCity* self, int iNum, bool bFinish, bool bChoose);CivRegisterBefore<CivHooks::CvCity_popOrder>(host, &BeforeCvCity_popOrder);CivRegisterAfter<CivHooks::CvCity_popOrder>(host, &AfterCvCity_popOrder);CivRegisterReplace<CivHooks::CvCity_popOrder>(host, &ReplaceCvCity_popOrder);

Code

12950void CvCity::popOrder(int iNum, bool bFinish, bool bChoose)12951{12952	VALIDATE_OBJECT1295312954	CvPlayerAI& kOwner = GET_PLAYER(getOwner());	//Used often later on1295512956	OrderData* pOrderNode;12957	SpecialistTypes eSpecialist;12958	ProjectTypes eCreateProject;12959	BuildingTypes eConstructBuilding;12960	UnitTypes eTrainUnit;12961	UnitAITypes eTrainAIUnit;12962	bool bWasFoodProduction;12963	bool bStart;12964	bool bMessage;12965	int iCount;12966	int iProductionNeeded;1296712968	bWasFoodProduction = isFoodProduction();1296912970	if(iNum == -1)12971	{12972		iNum = (getOrderQueueLength() - 1);12973	}1297412975	iCount = 0;1297612977	pOrderNode = headOrderQueueNode();1297812979	while(pOrderNode != NULL)12980	{12981		if(iCount == iNum)12982		{12983			break;12984		}1298512986		iCount++;1298712988		pOrderNode = nextOrderQueueNode(pOrderNode);12989	}1299012991	if(pOrderNode == NULL)12992	{12993		return;12994	}1299512996	if(bFinish)12997	{12998		m_iThingsProduced++;12999	}1300013001	if(bFinish && pOrderNode->bSave)13002	{13003		pushOrder(pOrderNode->eOrderType, pOrderNode->iData1, pOrderNode->iData2, true, false, true);13004	}1300513006	eTrainUnit = NO_UNIT;13007	eConstructBuilding = NO_BUILDING;13008	eCreateProject = NO_PROJECT;13009	eSpecialist = NO_SPECIALIST;1301013011	switch(pOrderNode->eOrderType)13012	{13013	case ORDER_TRAIN:13014		eTrainUnit = ((UnitTypes)(pOrderNode->iData1));13015		eTrainAIUnit = ((UnitAITypes)(pOrderNode->iData2));13016		CvAssertMsg(eTrainUnit != NO_UNIT, "eTrainUnit is expected to be assigned a valid unit type");13017		CvAssertMsg(eTrainAIUnit != NO_UNITAI, "eTrainAIUnit is expected to be assigned a valid unit AI type");1301813019		kOwner.changeUnitClassMaking(((UnitClassTypes)(GC.getUnitInfo(eTrainUnit)->GetUnitClassType())), -1);1302013021		if(bFinish)13022		{13023			int iResult = CreateUnit(eTrainUnit, eTrainAIUnit);13024			if(iResult != FFreeList::INVALID_INDEX)13025			{13026#if defined(MOD_EVENTS_CITY)13027				if (MOD_EVENTS_CITY) {13028					GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityTrained, getOwner(), GetID(), iResult, false, false);13029				} else {13030#endif13031				ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();13032				if (pkScriptSystem) 13033				{13034					CvLuaArgsHandle args;13035					args->Push(getOwner());13036					args->Push(GetID());13037					args->Push(GET_PLAYER(getOwner()).getUnit(iResult)->GetID()); // This is probably just iResult13038					args->Push(false); // bGold13039					args->Push(false); // bFaith/bCulture1304013041					bool bResult;13042					LuaSupport::CallHook(pkScriptSystem, "CityTrained", args.get(), bResult);13043				}13044#if defined(MOD_EVENTS_CITY)13045				}13046#endif1304713048				iProductionNeeded = getProductionNeeded(eTrainUnit) * 100;1304913050				// max overflow is the value of the item produced (to eliminate prebuild exploits)13051				int iOverflow = getUnitProductionTimes100(eTrainUnit) - iProductionNeeded;13052				int iMaxOverflow = std::max(iProductionNeeded, getCurrentProductionDifferenceTimes100(false, false));13053				int iLostProduction = std::max(0, iOverflow - iMaxOverflow);13054				iOverflow = std::min(iMaxOverflow, iOverflow);13055				if(iOverflow > 0)13056				{13057					changeOverflowProductionTimes100(iOverflow);13058				}13059				setUnitProduction(eTrainUnit, 0);1306013061				int iProductionGold = ((iLostProduction * GC.getMAXED_UNIT_GOLD_PERCENT()) / 100);13062				if(iProductionGold > 0)13063				{13064					kOwner.GetTreasury()->ChangeGoldTimes100(iProductionGold);13065				}13066			}13067			else13068			{13069				// create notification13070				setUnitProduction(eTrainUnit, getProductionNeeded(eTrainUnit) - 1);1307113072				CvNotifications* pNotifications = kOwner.GetNotifications();13073				if(pNotifications)13074				{13075					Localization::String strText = Localization::Lookup("TXT_KEY_NOTIFICATION_REMOVED_UNIT");13076					strText << getNameKey();13077					strText << GC.getUnitInfo(eTrainUnit)->GetDescription();13078					Localization::String strSummary = Localization::Lookup("TXT_KEY_NOTIFICATION_SUMMARY_REMOVED_UNIT");13079					pNotifications->Add(NOTIFICATION_GENERIC, strText.toUTF8(), strSummary.toUTF8(), getX(), getY(), -1);13080				}13081			}13082		}13083		break;1308413085	case ORDER_CONSTRUCT:13086	{13087		eConstructBuilding = ((BuildingTypes)(pOrderNode->iData1));1308813089		CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eConstructBuilding);1309013091		if(pkBuildingInfo)13092		{13093			kOwner.changeBuildingClassMaking(((BuildingClassTypes)(pkBuildingInfo->GetBuildingClassType())), -1);1309413095			if(bFinish)13096			{13097				bool bResult = CreateBuilding(eConstructBuilding);13098				DEBUG_VARIABLE(bResult);13099				CvAssertMsg(bResult, "CreateBuilding failed");1310013101#if defined(MOD_EVENTS_CITY)13102				if (MOD_EVENTS_CITY) {13103					GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityConstructed, getOwner(), GetID(), eConstructBuilding, false, false);13104				} else {13105#endif13106				ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();13107				if (pkScriptSystem) 13108				{13109					CvLuaArgsHandle args;13110					args->Push(getOwner());13111					args->Push(GetID());13112					args->Push(eConstructBuilding);13113					args->Push(false); // bGold13114					args->Push(false); // bFaith/bCulture1311513116					bool bScriptResult;13117					LuaSupport::CallHook(pkScriptSystem, "CityConstructed", args.get(), bScriptResult);13118				}13119#if defined(MOD_EVENTS_CITY)13120				}13121#endif1312213123				iProductionNeeded = getProductionNeeded(eConstructBuilding) * 100;13124				// max overflow is the value of the item produced (to eliminate prebuild exploits)13125				int iOverflow = m_pCityBuildings->GetBuildingProductionTimes100(eConstructBuilding) - iProductionNeeded;13126				int iMaxOverflow = std::max(iProductionNeeded, getCurrentProductionDifferenceTimes100(false, false));13127				int iLostProduction = std::max(0, iOverflow - iMaxOverflow);13128				iOverflow = std::min(iMaxOverflow, iOverflow);13129				if(iOverflow > 0)13130				{13131					changeOverflowProductionTimes100(iOverflow);13132				}13133				m_pCityBuildings->SetBuildingProduction(eConstructBuilding, 0);1313413135				int iProductionGold = ((iLostProduction * GC.getMAXED_BUILDING_GOLD_PERCENT()) / 100);13136				if(iProductionGold > 0)13137				{13138					kOwner.GetTreasury()->ChangeGoldTimes100(iProductionGold);13139				}13140				13141#if defined(MOD_TRADE_WONDER_RESOURCE_ROUTES)13142				if (MOD_TRADE_WONDER_RESOURCE_ROUTES) {13143					// If the AI has just finished building a World Wonder, cancel any marble trade routes into this city13144					if (!GetPlayer()->isHuman()) {13145						const BuildingClassTypes eBuildingClass = (BuildingClassTypes)pkBuildingInfo->GetBuildingClassType();13146						CvBuildingClassInfo* pBuildingClass = GC.getBuildingClassInfo(eBuildingClass);13147						if (pBuildingClass && ::isWorldWonderClass(*pBuildingClass)) {13148							CvGameTrade* pGameTrade = GC.getGame().GetGameTrade();13149							for (uint ui = 0; ui < pGameTrade->m_aTradeConnections.size(); ui++) {13150								if (pGameTrade->IsTradeRouteIndexEmpty(ui)) {13151									continue;13152								}1315313154								TradeConnection kConnection = pGameTrade->m_aTradeConnections[ui];1315513156								if (kConnection.m_eConnectionType == TRADE_CONNECTION_WONDER_RESOURCE) {13157									CvCity* pDestCity = CvGameTrade::GetDestCity(kConnection);1315813159									if (pDestCity->getX() == getX() && pDestCity->getY() == getY()) {13160										kConnection.m_iCircuitsCompleted = kConnection.m_iCircuitsToComplete;13161									}13162								}13163							}13164						}13165					}13166				}13167#endif1316813169				if(GC.getLogging() && GC.getAILogging())13170				{13171					CvBuildingEntry* pkConstructBuildingInfo = GC.getBuildingInfo(eConstructBuilding);13172					if(pkConstructBuildingInfo)13173					{13174						if(kOwner.GetWonderProductionAI()->IsWonder(*pkConstructBuildingInfo))13175						{13176							CvString playerName;13177							FILogFile* pLog;13178							CvString strBaseString;13179							CvString strOutBuf;13180							playerName = kOwner.getCivilizationShortDescription();13181							pLog = LOGFILEMGR.GetLog(kOwner.GetCitySpecializationAI()->GetLogFileName(playerName), FILogFile::kDontTimeStamp);13182							strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());13183							strBaseString += playerName + ", ";13184							strOutBuf.Format("%s, WONDER - Finished %s", getName().GetCString(), pkConstructBuildingInfo->GetDescription());13185							strBaseString += strOutBuf;13186							pLog->Msg(strBaseString);13187						}13188					}1318913190				}13191			}13192		}13193		break;13194	}1319513196	case ORDER_CREATE:13197		eCreateProject = ((ProjectTypes)(pOrderNode->iData1));1319813199		GET_TEAM(getTeam()).changeProjectMaking(eCreateProject, -1);13200		kOwner.changeProjectMaking(eCreateProject, -1);1320113202		if(bFinish)13203		{13204			bool bResult = CreateProject(eCreateProject);13205			DEBUG_VARIABLE(bResult);13206			CvAssertMsg(bResult, "Failed to create project");1320713208#if defined(MOD_EVENTS_CITY)13209			if (MOD_EVENTS_CITY) {13210				GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityCreated, getOwner(), GetID(), eCreateProject, false, false);13211			} else {13212#endif13213			ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();13214			if (pkScriptSystem) 13215			{13216				CvLuaArgsHandle args;13217				args->Push(getOwner());13218				args->Push(GetID());13219				args->Push(eCreateProject);13220				args->Push(false); // bGold13221				args->Push(false); // bFaith/bCulture1322213223				bool bScriptResult;13224				LuaSupport::CallHook(pkScriptSystem, "CityCreated", args.get(), bScriptResult);13225			}13226#if defined(MOD_EVENTS_CITY)13227			}13228#endif1322913230			iProductionNeeded = getProductionNeeded(eCreateProject) * 100;13231			// max overflow is the value of the item produced (to eliminate prebuild exploits)13232			int iOverflow = getProjectProductionTimes100(eCreateProject) - iProductionNeeded;13233			int iMaxOverflow = std::max(iProductionNeeded, getCurrentProductionDifferenceTimes100(false, false));13234			int iLostProduction = std::max(0, iOverflow - iMaxOverflow);13235			iOverflow = std::min(iMaxOverflow, iOverflow);13236			if(iOverflow > 0)13237			{13238				changeOverflowProductionTimes100(iOverflow);13239			}13240			setProjectProduction(eCreateProject, 0);1324113242			int iProductionGold = ((iLostProduction * GC.getMAXED_PROJECT_GOLD_PERCENT()) / 100);13243			if(iProductionGold > 0)13244			{13245				kOwner.GetTreasury()->ChangeGoldTimes100(iProductionGold);13246			}13247		}13248		break;1324913250	case ORDER_PREPARE:1325113252		if(bFinish)13253		{13254			eSpecialist = ((SpecialistTypes)(pOrderNode->iData1));1325513256#if defined(MOD_EVENTS_CITY)13257			if (MOD_EVENTS_CITY) {13258				GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityPrepared, getOwner(), GetID(), eSpecialist, false, false);13259			}13260#endif1326113262			iProductionNeeded = getProductionNeeded(eSpecialist) * 100;1326313264			// max overflow is the value of the item produced (to eliminate prebuild exploits)13265			int iOverflow = getSpecialistProductionTimes100(eSpecialist) - iProductionNeeded;13266			int iMaxOverflow = std::max(iProductionNeeded, getCurrentProductionDifferenceTimes100(false, false));13267			iOverflow = std::min(iMaxOverflow, iOverflow);13268			if(iOverflow > 0)13269			{13270				changeOverflowProductionTimes100(iOverflow);13271			}1327213273			setSpecialistProduction(eSpecialist, 0);13274		}1327513276		break;1327713278	case ORDER_MAINTAIN:13279		break;1328013281	default:13282		CvAssertMsg(false, "pOrderNode->eOrderType is not a valid option");13283		break;13284	}1328513286	if(m_unitBeingBuiltForOperation.IsValid())13287	{13288		kOwner.CityUncommitToBuildUnitForOperationSlot(m_unitBeingBuiltForOperation);13289		m_unitBeingBuiltForOperation.Invalidate();13290	}1329113292	if(pOrderNode == headOrderQueueNode())13293	{13294		bStart = true;13295		stopHeadOrder();13296	}13297	else13298	{13299		bStart = false;13300	}1330113302	m_orderQueue.deleteNode(pOrderNode);13303	pOrderNode = NULL;13304	if(bFinish)13305	{13306		CleanUpQueue(); // cleans out items from the queue that may be invalidated by the recent construction13307	}1330813309	if(bStart)13310	{13311		startHeadOrder();13312	}1331313314	if((getTeam() == GC.getGame().getActiveTeam()) || GC.getGame().isDebugMode())13315	{13316		if(isCitySelected())13317		{13318			DLLUI->setDirty(SelectionButtons_DIRTY_BIT, true);13319			DLLUI->setDirty(CityScreen_DIRTY_BIT, true);13320		}13321	}1332213323	bMessage = false;1332413325	if(bChoose)13326	{13327		if(getOrderQueueLength() == 0)13328		{13329			if(!isHuman() || isProductionAutomated())13330			{13331				AI_chooseProduction(false /*bInterruptWonders*/);13332			}13333			else13334			{13335				chooseProduction(eTrainUnit, eConstructBuilding, eCreateProject, bFinish);1333613337				bMessage = true;13338			}13339		}13340	}1334113342	if(bFinish && !bMessage)13343	{13344		if(getOwner() == GC.getGame().getActivePlayer())13345		{13346			Localization::String localizedText;13347			if(eTrainUnit != NO_UNIT)13348			{13349				CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eTrainUnit);13350				if(pkUnitInfo)13351				{13352					localizedText = Localization::Lookup(((isLimitedUnitClass((UnitClassTypes)(pkUnitInfo->GetUnitClassType()))) ? "TXT_KEY_MISC_TRAINED_UNIT_IN_LIMITED" : "TXT_KEY_MISC_TRAINED_UNIT_IN"));13353					localizedText << pkUnitInfo->GetTextKey() << getNameKey();13354				}13355			}13356			else if(eConstructBuilding != NO_BUILDING)13357			{13358				CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eConstructBuilding);13359				if(pkBuildingInfo)13360				{13361					localizedText = Localization::Lookup(((isLimitedWonderClass(pkBuildingInfo->GetBuildingClassInfo())) ? "TXT_KEY_MISC_CONSTRUCTED_BUILD_IN_LIMITED" : "TXT_KEY_MISC_CONSTRUCTED_BUILD_IN"));13362					localizedText << pkBuildingInfo->GetTextKey() << getNameKey();13363				}13364			}13365			else if(eCreateProject != NO_PROJECT)13366			{13367				localizedText = Localization::Lookup(((isLimitedProject(eCreateProject)) ? "TXT_KEY_MISC_CREATED_PROJECT_IN_LIMITED" : "TXT_KEY_MISC_CREATED_PROJECT_IN"));13368				localizedText << GC.getProjectInfo(eCreateProject)->GetTextKey() << getNameKey();13369			}13370			if(isProduction())13371			{13372				localizedText = Localization::Lookup(((isProductionLimited()) ? "TXT_KEY_MISC_WORK_HAS_BEGUN_LIMITED" : "TXT_KEY_MISC_WORK_HAS_BEGUN"));13373				localizedText << getProductionNameKey();13374			}13375			DLLUI->AddCityMessage(0, GetIDInfo(), getOwner(), false, GC.getEVENT_MESSAGE_TIME(), localizedText.toUTF8()/*, szSound, MESSAGE_TYPE_MINOR_EVENT, szIcon, (ColorTypes)GC.getInfoTypeForString("COLOR_WHITE"), getX(), getY(), true, true*/);13376		}13377	}1337813379	if((getTeam() == GC.getGame().getActiveTeam()) || GC.getGame().isDebugMode())13380	{13381		if(isCitySelected())13382		{13383			DLLUI->setDirty(SelectionButtons_DIRTY_BIT, true);13384			DLLUI->setDirty(CityScreen_DIRTY_BIT, true);13385			DLLUI->setDirty(PlotListButtons_DIRTY_BIT, true);13386		}13387		DLLUI->setDirty(CityInfo_DIRTY_BIT, true);13388	}13389}

Calls

Called by