Hooks
static bool BeforeCvCity_Purchase(CvCity* self, UnitTypes eUnitType, BuildingTypes eBuildingType, ProjectTypes eProjectType, YieldTypes ePurchaseYield);static void AfterCvCity_Purchase(CvCity* self, UnitTypes eUnitType, BuildingTypes eBuildingType, ProjectTypes eProjectType, YieldTypes ePurchaseYield);static void ReplaceCvCity_Purchase(void (*original)(CvCity*, UnitTypes, BuildingTypes, ProjectTypes, YieldTypes), CvCity* self, UnitTypes eUnitType, BuildingTypes eBuildingType, ProjectTypes eProjectType, YieldTypes ePurchaseYield);CivRegisterBefore<CivHooks::CvCity_Purchase>(host, &BeforeCvCity_Purchase);CivRegisterAfter<CivHooks::CvCity_Purchase>(host, &AfterCvCity_Purchase);CivRegisterReplace<CivHooks::CvCity_Purchase>(host, &ReplaceCvCity_Purchase);
Code
14191// purchase something at the city14192void CvCity::Purchase(UnitTypes eUnitType, BuildingTypes eBuildingType, ProjectTypes eProjectType, YieldTypes ePurchaseYield)14193{14194 VALIDATE_OBJECT1419514196 CvPlayer& kPlayer = GET_PLAYER(getOwner());1419714198 switch(ePurchaseYield)14199 {14200 case YIELD_GOLD:14201 {14202 // Can we actually buy this thing?14203 if(!IsCanPurchase(/*bTestPurchaseCost*/ true, /*bTestTrainable*/ true, eUnitType, eBuildingType, eProjectType, YIELD_GOLD))14204 return;1420514206 int iGoldCost = 0;14207 14208 kPlayer.GetTreasury();1420914210 // Unit14211 if(eUnitType != NO_UNIT){14212 iGoldCost = GetPurchaseCost(eUnitType);14213 CvUnitEntry* pGameUnit = GC.getUnitInfo(eUnitType);14214 if(pGameUnit != NULL)14215 {14216 kPlayer.GetTreasury()->LogExpenditure((CvString)pGameUnit->GetText(), iGoldCost, 2);14217 }14218 // Building14219 }else if(eBuildingType != NO_BUILDING){14220 iGoldCost = GetPurchaseCost(eBuildingType);14221 CvBuildingEntry* pGameBuilding = GC.getBuildingInfo(eBuildingType);14222 if(pGameBuilding != NULL)14223 {14224 kPlayer.GetTreasury()->LogExpenditure((CvString)pGameBuilding->GetText(), iGoldCost, 2);14225 }14226 // Project14227 } else if(eProjectType != NO_PROJECT){14228 iGoldCost = GetPurchaseCost(eProjectType);14229 kPlayer.GetTreasury()->LogExpenditure((CvString)GC.getProjectInfo(eProjectType)->GetText(), iGoldCost, 2);14230 }1423114232 GET_PLAYER(getOwner()).GetTreasury()->ChangeGold(-iGoldCost);1423314234 bool bResult = false;14235 if(eUnitType >= 0)14236 {14237 int iResult = CreateUnit(eUnitType);14238 CvAssertMsg(iResult != FFreeList::INVALID_INDEX, "Unable to create unit");14239 if (iResult != FFreeList::INVALID_INDEX)14240 {14241 CvUnit* pUnit = kPlayer.getUnit(iResult);14242 if (!pUnit->getUnitInfo().CanMoveAfterPurchase())14243 {14244 pUnit->setMoves(0);14245 }1424614247#if defined(MOD_EVENTS_CITY)14248 if (MOD_EVENTS_CITY) {14249 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityTrained, getOwner(), GetID(), pUnit->GetID(), true, false);14250 } else {14251#endif14252 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();14253 if (pkScriptSystem) 14254 {14255 CvLuaArgsHandle args;14256 args->Push(getOwner());14257 args->Push(GetID());14258 args->Push(pUnit->GetID());14259 args->Push(true); // bGold14260 args->Push(false); // bFaith/bCulture1426114262 bool bScriptResult;14263 LuaSupport::CallHook(pkScriptSystem, "CityTrained", args.get(), bScriptResult);14264 }14265#if defined(MOD_EVENTS_CITY)14266 }14267#endif14268 }14269 }14270 else if(eBuildingType >= 0)14271 {14272 bResult = CreateBuilding(eBuildingType);1427314274#if defined(MOD_EVENTS_CITY)14275 if (MOD_EVENTS_CITY) {14276 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityConstructed, getOwner(), GetID(), eBuildingType, true, false);14277 } else {14278#endif14279 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();14280 if (pkScriptSystem) 14281 {14282 CvLuaArgsHandle args;14283 args->Push(getOwner());14284 args->Push(GetID());14285 args->Push(eBuildingType);14286 args->Push(true); // bGold14287 args->Push(false); // bFaith/bCulture1428814289 bool bScriptResult;14290 LuaSupport::CallHook(pkScriptSystem, "CityConstructed", args.get(), bScriptResult);14291 }14292#if defined(MOD_EVENTS_CITY)14293 }14294#endif1429514296 CleanUpQueue(); // cleans out items from the queue that may be invalidated by the recent construction14297 CvAssertMsg(bResult, "Unable to create building");14298 }14299 else if(eProjectType >= 0)14300 {14301 bResult = CreateProject(eProjectType);14302 CvAssertMsg(bResult, "Unable to create project");1430314304#if defined(MOD_EVENTS_CITY)14305 if (MOD_EVENTS_CITY) {14306 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityCreated, getOwner(), GetID(), eProjectType, true, false);14307 } else {14308#endif14309 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();14310 if (pkScriptSystem) 14311 {14312 CvLuaArgsHandle args;14313 args->Push(getOwner());14314 args->Push(GetID());14315 args->Push(eProjectType);14316 args->Push(true); // bGold14317 args->Push(false); // bFaith/bCulture1431814319 bool bScriptResult;14320 LuaSupport::CallHook(pkScriptSystem, "CityCreated", args.get(), bScriptResult);14321 }14322#if defined(MOD_EVENTS_CITY)14323 }14324#endif14325 }14326 }14327 break;14328 case YIELD_FAITH:14329 {14330 int iFaithCost = 0;1433114332 // Can we actually buy this thing?14333 if(!IsCanPurchase(/*bTestPurchaseCost*/ true, /*bTestTrainable*/ true, eUnitType, eBuildingType, eProjectType, YIELD_FAITH))14334 return;1433514336 // Unit14337 if(eUnitType != NO_UNIT)14338 iFaithCost = GetFaithPurchaseCost(eUnitType, true /*bIncludeBeliefDiscounts*/);14339 // Building14340 else if(eBuildingType != NO_BUILDING)14341 iFaithCost = GetFaithPurchaseCost(eBuildingType);1434214343 if(eUnitType >= 0)14344 {14345 int iResult = CreateUnit(eUnitType);14346 CvAssertMsg(iResult != FFreeList::INVALID_INDEX, "Unable to create unit");14347 if (iResult == FFreeList::INVALID_INDEX)14348 return; // Can't create the unit, most likely we have no place for it. We have not deducted the cost yet so just exit.1434914350 CvUnit* pUnit = kPlayer.getUnit(iResult);14351#if defined(MOD_BUGFIX_MOVE_AFTER_PURCHASE)14352 if (!pUnit->getUnitInfo().CanMoveAfterPurchase())14353 {14354#endif14355 pUnit->setMoves(0);14356#if defined(MOD_BUGFIX_MOVE_AFTER_PURCHASE)14357 }14358#endif1435914360#if defined(MOD_EVENTS_CITY)14361 if (MOD_EVENTS_CITY) {14362 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityTrained, getOwner(), GetID(), pUnit->GetID(), false, true);14363 } else {14364#endif14365 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();14366 if (pkScriptSystem) 14367 {14368 CvLuaArgsHandle args;14369 args->Push(getOwner());14370 args->Push(GetID());14371 args->Push(pUnit->GetID());14372 args->Push(false); // bGold14373 args->Push(true); // bFaith/bCulture1437414375 bool bResult;14376 LuaSupport::CallHook(pkScriptSystem, "CityTrained", args.get(), bResult);14377 }14378#if defined(MOD_EVENTS_CITY)14379 }14380#endif1438114382 // Prophets are always of the religion the player founded14383 ReligionTypes eReligion;14384 if(pUnit->getUnitInfo().IsFoundReligion())14385 {14386 eReligion = kPlayer.GetReligions()->GetReligionCreatedByPlayer();14387 }14388 else14389 {14390 eReligion = GetCityReligions()->GetReligiousMajority();14391 }14392 pUnit->GetReligionData()->SetReligion(eReligion);1439314394 int iReligionSpreads = pUnit->getUnitInfo().GetReligionSpreads();14395 int iReligiousStrength = pUnit->getUnitInfo().GetReligiousStrength();1439614397 // Missionary strength14398 if(iReligionSpreads > 0 && eReligion > RELIGION_PANTHEON)14399 {14400 pUnit->GetReligionData()->SetSpreadsLeft(iReligionSpreads + GetCityBuildings()->GetMissionaryExtraSpreads());14401 pUnit->GetReligionData()->SetReligiousStrength(iReligiousStrength);14402 }1440314404 if (pUnit->getUnitInfo().GetOneShotTourism() > 0)14405 {14406 pUnit->SetTourismBlastStrength(kPlayer.GetCulture()->GetTourismBlastStrength(pUnit->getUnitInfo().GetOneShotTourism()));14407 }1440814409 kPlayer.ChangeFaith(-iFaithCost);1441014411 UnitClassTypes eUnitClass = pUnit->getUnitClassType();14412 if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_WRITER"))14413 {14414 kPlayer.incrementWritersFromFaith();14415 }14416 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_ARTIST"))14417 {14418 kPlayer.incrementArtistsFromFaith();14419 }14420 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_MUSICIAN"))14421 {14422 kPlayer.incrementMusiciansFromFaith();14423 }14424 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_SCIENTIST"))14425 {14426 kPlayer.incrementScientistsFromFaith();14427 }14428 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_MERCHANT"))14429 {14430 kPlayer.incrementMerchantsFromFaith();14431 }14432 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_ENGINEER"))14433 {14434 kPlayer.incrementEngineersFromFaith();14435 }14436 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_GREAT_GENERAL"))14437 {14438 kPlayer.incrementGeneralsFromFaith();14439 }14440 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_GREAT_ADMIRAL"))14441 {14442 kPlayer.incrementAdmiralsFromFaith();14443 CvPlot *pSpawnPlot = kPlayer.GetGreatAdmiralSpawnPlot(pUnit);14444 if (pUnit->plot() != pSpawnPlot)14445 {14446 pUnit->setXY(pSpawnPlot->getX(), pSpawnPlot->getY());14447 }14448 }14449 else if (eUnitClass == GC.getInfoTypeForString("UNITCLASS_PROPHET"))14450 {14451#if defined(MOD_GLOBAL_TRULY_FREE_GP)14452 kPlayer.GetReligions()->ChangeNumProphetsSpawned(1, false);14453#else14454 kPlayer.GetReligions()->ChangeNumProphetsSpawned(1);14455#endif14456 }1445714458 if(GC.getLogging())14459 {14460 CvString strLogMsg;14461 CvString temp;14462 strLogMsg = kPlayer.getCivilizationShortDescription();14463 strLogMsg += ", FAITH UNIT PURCHASE, ";14464 strLogMsg += pUnit->getName();14465 strLogMsg += ", ";14466 strLogMsg += getName();14467 strLogMsg += ", Faith Cost: ";14468 temp.Format("%d", iFaithCost);14469 strLogMsg += temp;14470 strLogMsg += ", Faith Left: ";14471 temp.Format("%d", kPlayer.GetFaith());14472 strLogMsg += temp;14473 GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);14474 }14475 }1447614477 else if(eBuildingType >= 0)14478 {14479 bool bResult = false;14480 bResult = CreateBuilding(eBuildingType);14481 CleanUpQueue(); // cleans out items from the queue that may be invalidated by the recent construction14482 CvAssertMsg(bResult, "Unable to create building");1448314484#if defined(MOD_EVENTS_CITY)14485 if (MOD_EVENTS_CITY) {14486 GAMEEVENTINVOKE_HOOK(GAMEEVENT_CityConstructed, getOwner(), GetID(), eBuildingType, false, true);14487 } else {14488#endif14489 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();14490 if (pkScriptSystem)14491 {14492 CvLuaArgsHandle args;14493 args->Push(getOwner());14494 args->Push(GetID());14495 args->Push(eBuildingType);14496 args->Push(false); // bGold14497 args->Push(true); // bFaith/bCulture1449814499 bool bScriptResult;14500 LuaSupport::CallHook(pkScriptSystem, "CityConstructed", args.get(), bScriptResult);14501 }14502#if defined(MOD_EVENTS_CITY)14503 }14504#endif1450514506 kPlayer.ChangeFaith(-iFaithCost);1450714508 if(GC.getLogging())14509 {14510 CvString strLogMsg;14511 CvString temp;14512 strLogMsg = kPlayer.getCivilizationShortDescription();14513 strLogMsg += ", FAITH BUILDING PURCHASE, ";1451414515 CvBuildingXMLEntries* pGameBuildings = GC.GetGameBuildings();14516 if(pGameBuildings != NULL)14517 {14518 CvBuildingEntry* pBuildingEntry = pGameBuildings->GetEntry(eBuildingType);14519 if(pBuildingEntry != NULL)14520 {14521 strLogMsg += pBuildingEntry->GetDescription();14522 strLogMsg += ", ";14523 }14524 }14525 strLogMsg += getName();14526 strLogMsg += ", Faith Cost: ";14527 temp.Format("%d", iFaithCost);14528 strLogMsg += temp;14529 strLogMsg += ", Faith Left: ";14530 temp.Format("%d", kPlayer.GetFaith());14531 strLogMsg += temp;14532 GC.getGame().GetGameReligions()->LogReligionMessage(strLogMsg);14533 }14534 }14535 }14536 break;14537 }14538}