Hooks
static bool BeforeCvUnit_PerformCultureBomb(CvUnit* self, int iRadius);static void AfterCvUnit_PerformCultureBomb(CvUnit* self, int iRadius);static void ReplaceCvUnit_PerformCultureBomb(void (*original)(CvUnit*, int), CvUnit* self, int iRadius);CivRegisterBefore<CivHooks::CvUnit_PerformCultureBomb>(host, &BeforeCvUnit_PerformCultureBomb);CivRegisterAfter<CivHooks::CvUnit_PerformCultureBomb>(host, &AfterCvUnit_PerformCultureBomb);CivRegisterReplace<CivHooks::CvUnit_PerformCultureBomb>(host, &ReplaceCvUnit_PerformCultureBomb);
Code
9816void CvUnit::PerformCultureBomb(int iRadius)9817{9818 CvPlot* pThisPlot = plot();98199820 CvPlayerAI& kPlayer = GET_PLAYER(getOwner());98219822 // Figure out which City gets ownership of these plots9823 int iBestCityID = -1;98249825 // Plot we're standing on belongs to a city already9826 if(pThisPlot->getOwner() == getOwner() && pThisPlot->GetCityPurchaseID() != -1)9827 {9828 iBestCityID = pThisPlot->GetCityPurchaseID();9829 }9830 // Find closest city9831 else9832 {9833 int iBestCityDistance = -1;98349835 int iDistance;98369837 CvCity* pLoopCity = NULL;9838 int iLoop = 0;9839 for(pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))9840 {9841 CvPlot* pPlot = pLoopCity->plot();9842 if(pPlot)9843 {9844 iDistance = plotDistance(getX(), getY(), pLoopCity->getX(), pLoopCity->getY());98459846 if(iBestCityDistance == -1 || iDistance < iBestCityDistance)9847 {9848 iBestCityID = pLoopCity->GetID();9849 iBestCityDistance = iDistance;9850 }9851 }9852 }9853 }98549855 // Keep track of got hit by this so we can figure the diplo ramifications later9856 FStaticVector<bool, MAX_CIV_PLAYERS, true, c_eCiv5GameplayDLL, 0> vePlayersBombed;9857 for(int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)9858 {9859 vePlayersBombed.push_back(false);9860 }98619862 // Change ownership of nearby plots9863 int iBombRange = iRadius;9864 CvPlot* pLoopPlot;9865 for(int i = -iBombRange; i <= iBombRange; ++i)9866 {9867 for(int j = -iBombRange; j <= iBombRange; ++j)9868 {9869 pLoopPlot = ::plotXYWithRangeCheck(getX(), getY(), i, j, iBombRange);98709871 if(pLoopPlot == NULL)9872 continue;98739874 // Can't be our plot9875 if(pLoopPlot->getOwner() == getOwner())9876 continue;98779878 // Can't flip Cities, sorry9879 if(pLoopPlot->isCity())9880 continue;98819882 if(pLoopPlot->getOwner() != NO_PLAYER){9883 // Notify plot owner9884 if(pLoopPlot->getOwner() != getOwner() && !vePlayersBombed[pLoopPlot->getOwner()]){9885 CvNotifications* pNotifications = GET_PLAYER(pLoopPlot->getOwner()).GetNotifications();9886 if(pNotifications){9887 CvString strBuffer = GetLocalizedText("TXT_KEY_NOTIFICATION_GREAT_ARTIST_STOLE_PLOT", GET_PLAYER(getOwner()).getNameKey());9888 CvString strSummary = GetLocalizedText("TXT_KEY_NOTIFICATION_SUMMARY_GREAT_ARTIST_STOLE_PLOT", GET_PLAYER(getOwner()).getNameKey());9889 pNotifications->Add(NOTIFICATION_GENERIC, strBuffer, strSummary, pLoopPlot->getX(), pLoopPlot->getY(), -1);9890 }9891 }9892 vePlayersBombed[pLoopPlot->getOwner()] = true;9893 }98949895 // Have to set owner after we do the above stuff9896 pLoopPlot->setOwner(getOwner(), iBestCityID);9897 }9898 }98999900 bool bAlreadyShownLeader = false;99019902 // Now that we know who was hit, figure the diplo ramifications9903 CvPlayer* pPlayer;9904 for(int iSlotLoop = 0; iSlotLoop < MAX_CIV_PLAYERS; iSlotLoop++)9905 {9906 if(vePlayersBombed[iSlotLoop])9907 {9908 pPlayer = &GET_PLAYER((PlayerTypes) iSlotLoop);9909 TeamTypes eOtherTeam = pPlayer->getTeam();99109911 // Humans can handle their own diplo9912 if(pPlayer->isHuman())9913 continue;99149915 // Minor civ response9916 if(pPlayer->isMinorCiv())9917 {9918 int iFriendship = /*-50*/ GC.getCULTURE_BOMB_MINOR_FRIENDSHIP_CHANGE();9919 pPlayer->GetMinorCivAI()->ChangeFriendshipWithMajor(getOwner(), iFriendship);9920 }9921 // Major civ response9922 else9923 {9924 pPlayer->GetDiplomacyAI()->ChangeNumTimesCultureBombed(getOwner(), 1);99259926 // Message for human9927 if(getTeam() != eOtherTeam && !GET_TEAM(eOtherTeam).isAtWar(getTeam()) && !CvPreGame::isNetworkMultiplayerGame() && GC.getGame().getActivePlayer() == getOwner() && !bAlreadyShownLeader)9928 {9929 bAlreadyShownLeader = true;99309931 DLLUI->SetForceDiscussionModeQuitOnBack(true); // Set force quit so that when discuss mode pops up the Back button won't go to leader root9932#if defined(MOD_DIPLOMACY_STFU)9933 pPlayer->GetDiplomacyAI()->DisplayAILeaderMessage(pPlayer->GetID(), DIPLO_UI_STATE_BLANK_DISCUSSION, DIPLO_MESSAGE_CULTURE_BOMBED, LEADERHEAD_ANIM_HATE_NEGATIVE);9934#else9935 const char* strText = pPlayer->GetDiplomacyAI()->GetDiploStringForMessage(DIPLO_MESSAGE_CULTURE_BOMBED);9936 gDLL->GameplayDiplomacyAILeaderMessage(pPlayer->GetID(), DIPLO_UI_STATE_BLANK_DISCUSSION, strText, LEADERHEAD_ANIM_HATE_NEGATIVE);9937#endif9938 }9939 }9940 }9941 }9942}