Hooks
static bool BeforeCvPlot_setImprovementType(CvPlot* self, ImprovementTypes eNewValue, PlayerTypes eBuilder);static void AfterCvPlot_setImprovementType(CvPlot* self, ImprovementTypes eNewValue, PlayerTypes eBuilder);static void ReplaceCvPlot_setImprovementType(void (*original)(CvPlot*, ImprovementTypes, PlayerTypes), CvPlot* self, ImprovementTypes eNewValue, PlayerTypes eBuilder);CivRegisterBefore<CivHooks::CvPlot_setImprovementType>(host, &BeforeCvPlot_setImprovementType);CivRegisterAfter<CivHooks::CvPlot_setImprovementType>(host, &AfterCvPlot_setImprovementType);CivRegisterReplace<CivHooks::CvPlot_setImprovementType>(host, &ReplaceCvPlot_setImprovementType);
Code
6653void CvPlot::setImprovementType(ImprovementTypes eNewValue, PlayerTypes eBuilder)6654{6655 int iI;6656 ImprovementTypes eOldImprovement = getImprovementType();6657 bool bGiftFromMajor = false;66586659#if defined(MOD_BUGFIX_PLOT_VALIDATION)6660 if (eNewValue < NO_IMPROVEMENT) return;6661 if (eNewValue > NO_IMPROVEMENT && GC.getImprovementInfo(eNewValue) == NULL) return;6662#endif66636664 if (eBuilder != NO_PLAYER)6665 {6666 if (getOwner() != eBuilder && !GET_PLAYER(eBuilder).isMinorCiv())6667 {6668 bGiftFromMajor = true;6669 }6670 }6671 bool bIgnoreResourceTechPrereq = bGiftFromMajor; // If it is a gift from a major civ, our tech limitations do not apply66726673 if(eOldImprovement != eNewValue)6674 {6675 PlayerTypes owningPlayerID = getOwner();6676 if(eOldImprovement != NO_IMPROVEMENT)6677 {6678 CvImprovementEntry& oldImprovementEntry = *GC.getImprovementInfo(eOldImprovement);66796680#if defined(MOD_BUGFIX_MINOR)6681 DomainTypes eTradeRouteDomain = NO_DOMAIN;6682 if (oldImprovementEntry.IsAllowsWalkWater()) {6683 eTradeRouteDomain = DOMAIN_LAND;6684#if defined(MOD_GLOBAL_PASSABLE_FORTS)6685 }6686 else if (oldImprovementEntry.IsMakesPassable()) {6687 eTradeRouteDomain = DOMAIN_SEA;6688#endif6689 }6690#endif669166926693#if defined(MOD_BUGFIX_MINOR)6694 if (eTradeRouteDomain != NO_DOMAIN) {6695 // Take away any trade routes of this domain that pass through the plot6696 CvGameTrade* pTrade = GC.getGame().GetGameTrade();6697 int iPlotX = getX();6698 int iPlotY = getY();66996700 for (uint uiConnection = 0; uiConnection < pTrade->m_aTradeConnections.size(); uiConnection++) {6701 if (!pTrade->IsTradeRouteIndexEmpty(uiConnection)) {6702 TradeConnection* pConnection = &(pTrade->m_aTradeConnections[uiConnection]);67036704 if (pConnection->m_eDomain == eTradeRouteDomain) {6705 TradeConnectionPlotList aPlotList = pConnection->m_aPlotList;67066707 for (uint uiPlotIndex = 0; uiPlotIndex < aPlotList.size(); uiPlotIndex++) {6708 if (aPlotList[uiPlotIndex].m_iX == iPlotX && aPlotList[uiPlotIndex].m_iY == iPlotY) {6709 CUSTOMLOG("Cancelling trade route for domain %i in plot (%i, %i) as enabling improvement destroyed", eTradeRouteDomain, iPlotX, iPlotY);6710 pConnection->m_iCircuitsCompleted = pConnection->m_iCircuitsToComplete;6711 break;6712 }6713 }6714 }6715 }6716 }6717 }6718#endif67196720 // If this improvement can add culture to nearby improvements, update them as well6721#if defined(MOD_API_UNIFIED_YIELDS)6722 for(iI = 0; iI < NUM_YIELD_TYPES; iI++)6723 {6724 if(oldImprovementEntry.GetYieldAdjacentSameType((YieldTypes) iI) > 0)6725#else6726 if(oldImprovementEntry.GetCultureAdjacentSameType() > 0)6727#endif6728 {6729 for(iI = 0; iI < NUM_DIRECTION_TYPES; iI++)6730 {6731 CvPlot* pAdjacentPlot = plotDirection(getX(), getY(), ((DirectionTypes)iI));6732 if(pAdjacentPlot && pAdjacentPlot->getImprovementType() == eOldImprovement)6733 {6734 pAdjacentPlot->updateYield();6735 }6736 }6737 }6738#if defined(MOD_API_UNIFIED_YIELDS)6739 }6740#endif67416742 if(area())6743 {6744 area()->changeNumImprovements(eOldImprovement, -1);6745 }6746 // Someone owns this plot6747 if(owningPlayerID != NO_PLAYER)6748 {6749 CvPlayer& owningPlayer = GET_PLAYER(owningPlayerID);6750 owningPlayer.changeImprovementCount(eOldImprovement, -1);67516752 // Maintenance change!6753 if(MustPayMaintenanceHere(owningPlayerID))6754 {6755 GET_PLAYER(owningPlayerID).GetTreasury()->ChangeBaseImprovementGoldMaintenance(-GC.getImprovementInfo(getImprovementType())->GetGoldMaintenance());6756 }67576758 // Siphon resource changes6759 PlayerTypes eOldBuilder = GetPlayerThatBuiltImprovement();6760 if(oldImprovementEntry.GetLuxuryCopiesSiphonedFromMinor() > 0 && eOldBuilder != NO_PLAYER)6761 {6762 if (owningPlayer.isMinorCiv())6763 {6764 GET_PLAYER(eOldBuilder).changeSiphonLuxuryCount(owningPlayerID, -1 * oldImprovementEntry.GetLuxuryCopiesSiphonedFromMinor());6765 }6766 }67676768 // Update the amount of a Resource used up by the previous Improvement that is being removed6769 int iNumResourceInfos= GC.getNumResourceInfos();6770 for(int iResourceLoop = 0; iResourceLoop < iNumResourceInfos; iResourceLoop++)6771 {6772 if(oldImprovementEntry.GetResourceQuantityRequirement(iResourceLoop) > 0)6773 {6774 owningPlayer.changeNumResourceUsed((ResourceTypes) iResourceLoop, -oldImprovementEntry.GetResourceQuantityRequirement(iResourceLoop));6775 }6776 }6777 }67786779 // Someone had built something here in an unowned plot, remove effects of the old improvement6780 if(GetPlayerResponsibleForImprovement() != NO_PLAYER)6781 {6782 // Maintenance change!6783 if(MustPayMaintenanceHere(GetPlayerResponsibleForImprovement()))6784 {6785 GET_PLAYER(GetPlayerResponsibleForImprovement()).GetTreasury()->ChangeBaseImprovementGoldMaintenance(-GC.getImprovementInfo(getImprovementType())->GetGoldMaintenance());6786 }67876788 SetPlayerResponsibleForImprovement(NO_PLAYER);6789 }6790 }67916792 m_eImprovementType = eNewValue;6793#if defined(MOD_GLOBAL_STACKING_RULES)6794 calculateAdditionalUnitsFromImprovement();6795#endif67966797 if(getImprovementType() == NO_IMPROVEMENT)6798 {6799 setImprovementDuration(0);6800 }68016802 // Reset who cleared a Barb camp here last (if we're putting a new one down)6803 if(eNewValue == GC.getBARBARIAN_CAMP_IMPROVEMENT())6804 {6805 SetPlayerThatClearedBarbCampHere(NO_PLAYER);6806 6807#if defined(MOD_BUGFIX_BARB_CAMP_SPAWNING)6808 // Alert the barbarian spawning code to this new camp6809 CvBarbarians::DoCampActivationNotice(this);6810#endif68116812#if defined(MOD_EVENTS_BARBARIANS)6813 if (MOD_EVENTS_BARBARIANS) {6814 GAMEEVENTINVOKE_HOOK(GAMEEVENT_BarbariansCampFounded, getX(), getY());6815 }6816#endif6817 }68186819 setUpgradeProgress(0);68206821 // make sure this plot is not disabled6822#if defined(MOD_EVENTS_TILE_IMPROVEMENTS)6823 SetImprovementPillaged(false, false);6824#else6825 SetImprovementPillaged(false);6826#endif68276828 for(iI = 0; iI < MAX_TEAMS; ++iI)6829 {6830 if(GET_TEAM((TeamTypes)iI).isAlive())6831 {6832 if(isVisible((TeamTypes)iI))6833 {6834 setRevealedImprovementType((TeamTypes)iI, eNewValue);6835 }6836 }6837 }68386839 if(m_eImprovementType != NO_IMPROVEMENT)6840 {6841 CvImprovementEntry& newImprovementEntry = *GC.getImprovementInfo(eNewValue);68426843 // If this improvement can add culture to nearby improvements, update them as well6844#if defined(MOD_API_UNIFIED_YIELDS)6845 for(int iYield = 0; iYield < NUM_YIELD_TYPES; iYield++)6846 {6847 if(newImprovementEntry.GetYieldAdjacentSameType((YieldTypes) iYield) > 0)6848#else6849 if(newImprovementEntry.GetCultureAdjacentSameType() > 0)6850#endif6851 {6852 for(iI = 0; iI < NUM_DIRECTION_TYPES; iI++)6853 {6854 CvPlot* pAdjacentPlot = plotDirection(getX(), getY(), ((DirectionTypes)iI));6855 if(pAdjacentPlot && pAdjacentPlot->getImprovementType() == eNewValue)6856 {6857 pAdjacentPlot->updateYield();6858 }6859 }6860 }6861#if defined(MOD_API_UNIFIED_YIELDS)6862 }6863#endif68646865 if(area())6866 {6867 area()->changeNumImprovements(eNewValue, 1);6868 }6869 if(isOwned())6870 {6871 CvPlayer& owningPlayer = GET_PLAYER(owningPlayerID);6872 owningPlayer.changeImprovementCount(eNewValue, 1);68736874#if !defined(NO_ACHIEVEMENTS)6875 //DLC_04 Achievement6876 if(owningPlayerID == GC.getGame().getActivePlayer() && strncmp(newImprovementEntry.GetType(), "IMPROVEMENT_MOTTE_BAILEY", 64) == 0)6877 {6878 //string compares are faster than testing if the mod is activated, so perform this after the compare test.6879 if(gDLL->IsModActivated(CIV5_DLC_04_SCENARIO_MODID))6880 {6881 gDLL->UnlockAchievement(ACHIEVEMENT_SCENARIO_04_BUILD_MOTTE);6882 }6883 }6884 6885 // XP2 Achievement6886 if (eBuilder != NO_PLAYER && !GC.getGame().isGameMultiPlayer())6887 {6888 if (GET_PLAYER(eBuilder).isHuman() && GET_PLAYER(eBuilder).isLocalPlayer() && strncmp(newImprovementEntry.GetType(), "IMPROVEMENT_FEITORIA", 64) == 0)6889 {6890 if (owningPlayer.isMinorCiv())6891 {6892 PlayerTypes eAlly = owningPlayer.GetMinorCivAI()->GetAlly();6893 if (eAlly != NO_PLAYER && eAlly != eBuilder)6894 {6895 gDLL->UnlockAchievement(ACHIEVEMENT_XP2_24);6896 }6897 }6898 }6899 }6900#endif69016902 // Maintenance6903 if(MustPayMaintenanceHere(owningPlayerID))6904 {6905 GET_PLAYER(owningPlayerID).GetTreasury()->ChangeBaseImprovementGoldMaintenance(newImprovementEntry.GetGoldMaintenance());6906 }69076908 // Siphon resource changes6909 if(newImprovementEntry.GetLuxuryCopiesSiphonedFromMinor() > 0 && eBuilder != NO_PLAYER)6910 {6911 if (owningPlayer.isMinorCiv())6912 {6913 GET_PLAYER(eBuilder).changeSiphonLuxuryCount(owningPlayerID, newImprovementEntry.GetLuxuryCopiesSiphonedFromMinor());6914 }6915 }69166917 // Add Resource Quantity to total6918 if(getResourceType() != NO_RESOURCE)6919 {6920 if(bIgnoreResourceTechPrereq || GET_TEAM(getTeam()).GetTeamTechs()->HasTech((TechTypes) GC.getResourceInfo(getResourceType())->getTechCityTrade()))6921 {6922 if(newImprovementEntry.IsImprovementResourceTrade(getResourceType()))6923 {6924 owningPlayer.changeNumResourceTotal(getResourceType(), getNumResourceForPlayer(owningPlayerID));69256926 // Activate Resource city link?6927 if(GetResourceLinkedCity() != NULL && !IsResourceLinkedCityActive())6928 SetResourceLinkedCityActive(true);6929 }6930 }6931 }69326933 ResourceTypes eResource = getResourceType(getTeam());6934 if(bIgnoreResourceTechPrereq)6935 eResource = getResourceType();69366937 if(eResource != NO_RESOURCE)6938 {6939 if(newImprovementEntry.IsImprovementResourceTrade(eResource))6940 {6941 if(GC.getResourceInfo(eResource)->getResourceUsage() == RESOURCEUSAGE_LUXURY)6942 {6943 owningPlayer.DoUpdateHappiness();6944 }6945 }6946 }69476948 }6949 }69506951 // If we're removing an Improvement that hooked up a resource then we need to take away the bonus6952 if(eOldImprovement != NO_IMPROVEMENT && !isCity())6953 {6954 if(isOwned())6955 {6956 CvPlayer& owningPlayer = GET_PLAYER(owningPlayerID);6957 // Remove Resource Quantity from total6958 if(getResourceType() != NO_RESOURCE)6959 {6960 if(IsImprovedByGiftFromMajor() || // If old improvement was a gift, it ignored our tech limits, so be sure to remove resources properly6961 GET_TEAM(getTeam()).GetTeamTechs()->HasTech((TechTypes) GC.getResourceInfo(getResourceType())->getTechCityTrade()))6962 {6963 if(GC.getImprovementInfo(eOldImprovement)->IsImprovementResourceTrade(getResourceType()))6964 {6965 owningPlayer.changeNumResourceTotal(getResourceType(), -getNumResourceForPlayer(owningPlayerID));69666967 // Disconnect resource link6968 if(GetResourceLinkedCity() != NULL)6969 SetResourceLinkedCityActive(false);6970 }6971 }6972 }69736974 ResourceTypes eResource = getResourceType(getTeam());69756976 if(eResource != NO_RESOURCE)6977 {6978 if(GC.getImprovementInfo(eOldImprovement)->IsImprovementResourceTrade(eResource))6979 {6980 if(GC.getResourceInfo(eResource)->getResourceUsage() == RESOURCEUSAGE_LUXURY)6981 {6982 owningPlayer.DoUpdateHappiness();6983 }6984 }6985 }6986 }6987 }69886989 updateYield();69906991 // Update the amount of a Resource used up by this Improvement6992 if(isOwned() && eNewValue != NO_IMPROVEMENT)6993 {6994 CvPlayer& owningPlayer = GET_PLAYER(owningPlayerID);6995 CvImprovementEntry& newImprovementEntry = *GC.getImprovementInfo(eNewValue);6996 int iNumResourceInfos = GC.getNumResourceInfos();6997 for(int iResourceLoop = 0; iResourceLoop < iNumResourceInfos; iResourceLoop++)6998 {6999 if(newImprovementEntry.GetResourceQuantityRequirement(iResourceLoop) > 0)7000 {7001 owningPlayer.changeNumResourceUsed((ResourceTypes) iResourceLoop, newImprovementEntry.GetResourceQuantityRequirement(iResourceLoop));7002 }7003 }7004 }70057006 // Update the most recent builder7007 if (GetPlayerThatBuiltImprovement() != eBuilder)7008 {7009 SetPlayerThatBuiltImprovement(eBuilder);7010 }70117012 SetImprovedByGiftFromMajor(bGiftFromMajor); // Assumes that only one tile improvement can be on this plot at a time70137014 if(GC.getGame().isDebugMode())7015 {7016 setLayoutDirty(true);7017 }7018 7019#if defined(MOD_EVENTS_TILE_IMPROVEMENTS)7020 if (MOD_EVENTS_TILE_IMPROVEMENTS) {7021 GAMEEVENTINVOKE_HOOK(GAMEEVENT_TileImprovementChanged, getX(), getY(), getOwner(), eOldImprovement, eNewValue, IsImprovementPillaged());7022 }7023#endif7024 }7025}