Hooks
static bool BeforeCvCity_DoPickResourceDemanded(CvCity* self, bool bCurrentResourceInvalid);static void AfterCvCity_DoPickResourceDemanded(CvCity* self, bool bCurrentResourceInvalid);static void ReplaceCvCity_DoPickResourceDemanded(void (*original)(CvCity*, bool), CvCity* self, bool bCurrentResourceInvalid);CivRegisterBefore<CivHooks::CvCity_DoPickResourceDemanded>(host, &BeforeCvCity_DoPickResourceDemanded);CivRegisterAfter<CivHooks::CvCity_DoPickResourceDemanded>(host, &AfterCvCity_DoPickResourceDemanded);CivRegisterReplace<CivHooks::CvCity_DoPickResourceDemanded>(host, &ReplaceCvCity_DoPickResourceDemanded);
Code
3551/// Picks a Resource for this City to want3552void CvCity::DoPickResourceDemanded(bool bCurrentResourceInvalid)3553{3554 VALIDATE_OBJECT3555 AI_PERF_FORMAT("City-AI-perf.csv", ("CvCity::DoPickResourceDemanded, Turn %03d, %s, %s", GC.getGame().getElapsedGameTurns(), GetPlayer()->getCivilizationShortDescription(), getName().c_str()) );3556 // Create the list of invalid Luxury Resources3557 FStaticVector<ResourceTypes, 64, true, c_eCiv5GameplayDLL, 0> veInvalidLuxuryResources;3558 CvPlot* pLoopPlot;3559 ResourceTypes eResource;35603561 // Loop through all resource infos and invalidate resources that only come from minor civs3562 for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)3563 {3564 eResource = (ResourceTypes) iResourceLoop;3565 CvResourceInfo* pkResource = GC.getResourceInfo(eResource);3566 if (pkResource && pkResource->getResourceUsage() == RESOURCEUSAGE_LUXURY)3567 {3568 if (pkResource->isOnlyMinorCivs())3569 {3570 veInvalidLuxuryResources.push_back(eResource);3571 }3572 }3573 }35743575 // Loop through all Plots near this City to see if there's Luxuries we should invalidate3576#if defined(MOD_GLOBAL_CITY_WORKING)3577 for(int iPlotLoop = 0; iPlotLoop < GetNumWorkablePlots(); iPlotLoop++)3578#else3579 for(int iPlotLoop = 0; iPlotLoop < NUM_CITY_PLOTS; iPlotLoop++)3580#endif3581 {3582 pLoopPlot = plotCity(getX(), getY(), iPlotLoop);35833584 if(pLoopPlot != NULL)3585 {3586 eResource = pLoopPlot->getResourceType();35873588 if(eResource != NO_RESOURCE)3589 {3590 if(GC.getResourceInfo(eResource)->getResourceUsage() == RESOURCEUSAGE_LUXURY)3591 {3592 veInvalidLuxuryResources.push_back(eResource);3593 }3594 }3595 }3596 }35973598 // Current Resource demanded may not be a valid choice3599 ResourceTypes eCurrentResource = GetResourceDemanded(false);3600 if(bCurrentResourceInvalid && eCurrentResource != NO_RESOURCE)3601 {3602 veInvalidLuxuryResources.push_back(eCurrentResource);3603 }36043605 // Create list of valid Luxuries3606 FStaticVector<ResourceTypes, 64, true, c_eCiv5GameplayDLL, 0> veValidLuxuryResources;3607 for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)3608 {3609 eResource = (ResourceTypes) iResourceLoop;36103611 // Is this a Luxury Resource?3612 CvResourceInfo* pkResource = GC.getResourceInfo(eResource);3613 if(pkResource && pkResource->getResourceUsage() == RESOURCEUSAGE_LUXURY)3614 {3615 // Is the Resource actually on the map?3616 if(GC.getMap().getNumResources(eResource) > 0)3617 {3618 // Can't be a minor civ only resource!3619 if(!GC.getResourceInfo(eResource)->isOnlyMinorCivs())3620 {3621 // We must not have this already3622 if(GET_PLAYER(getOwner()).getNumResourceAvailable(eResource) == 0)3623 veValidLuxuryResources.push_back(eResource);3624 }3625 }3626 }3627 }36283629 // Is there actually anything in our vector? - 0 can be valid if we already have everything, for example3630 if(veValidLuxuryResources.size() == 0)3631 {3632 return;3633 }36343635 // Now pick a Luxury we can use3636 int iNumAttempts = 0;3637 int iVectorLoop;3638 int iVectorIndex;3639 bool bResourceValid;36403641 do3642 {3643 iVectorIndex = GC.getGame().getJonRandNum(veValidLuxuryResources.size(), "Picking random Luxury for City to demand.");3644 eResource = (ResourceTypes) veValidLuxuryResources[iVectorIndex];3645 bResourceValid = true;36463647 // Look at all invalid Resources found to see if our randomly-picked Resource matches any3648 for(iVectorLoop = 0; iVectorLoop < (int) veInvalidLuxuryResources.size(); iVectorLoop++)3649 {3650 if(eResource == veInvalidLuxuryResources[iVectorLoop])3651 {3652 bResourceValid = false;3653 break;3654 }3655 }36563657 // Not found nearby?3658 if(bResourceValid)3659 {3660 SetResourceDemanded(eResource);36613662 // Notification3663 CvNotifications* pNotifications = GET_PLAYER(getOwner()).GetNotifications();3664 if(pNotifications)3665 {3666 Localization::String strText = Localization::Lookup("TXT_KEY_NOTIFICATION_CITY_RESOURCE_DEMAND");3667 strText << getNameKey() << GC.getResourceInfo(eResource)->GetTextKey();3668 Localization::String strSummary = Localization::Lookup("TXT_KEY_NOTIFICATION_SUMMARY_CITY_RESOURCE_DEMAND");3669 strSummary << getNameKey() << GC.getResourceInfo(eResource)->GetTextKey();3670 pNotifications->Add(NOTIFICATION_REQUEST_RESOURCE, strText.toUTF8(), strSummary.toUTF8(), getX(), getY(), eResource);3671 }36723673 return;3674 }36753676 iNumAttempts++;3677 }3678 while(iNumAttempts < 500);36793680 // If we're on the debug map it's too small for us to care3681 if(GC.getMap().getWorldSize() != WORLDSIZE_DEBUG)3682 {3683 CvAssertMsg(false, "Gameplay: Didn't find a Luxury for City to demand.");3684 }3685}