Hooks
static bool BeforeCvGame_handleAction(CvGame* self, int iAction);static void AfterCvGame_handleAction(CvGame* self, int iAction);static void ReplaceCvGame_handleAction(void (*original)(CvGame*, int), CvGame* self, int iAction);CivRegisterBefore<CivHooks::CvGame_handleAction>(host, &BeforeCvGame_handleAction);CivRegisterAfter<CivHooks::CvGame_handleAction>(host, &AfterCvGame_handleAction);CivRegisterReplace<CivHooks::CvGame_handleAction>(host, &ReplaceCvGame_handleAction);
Code
3007// Handle an action initiated by the local human player3008void CvGame::handleAction(int iAction)3009{3010 bool bAlt;3011 bool bShift;3012 bool bSkip;30133014 bAlt = gDLL->altKey();3015 bShift = false;//gDLL->shiftKey();30163017 auto_ptr<ICvUnit1> pHeadSelectedUnit(GC.GetEngineUserInterface()->GetHeadSelectedUnit());30183019 if(!(canHandleAction(iAction)))3020 {3021 return;3022 }30233024 // Control3025 CvActionInfo* pkActionInfo = GC.getActionInfo(iAction);3026 if(pkActionInfo->getControlType() != NO_CONTROL)3027 {3028 doControl((ControlTypes)(pkActionInfo->getControlType()));3029 }30303031 // Interface Mode3032 if(GC.GetEngineUserInterface()->CanDoInterfaceMode((InterfaceModeTypes)pkActionInfo->getInterfaceModeType()))3033 {3034 if(pHeadSelectedUnit.get() != NULL)3035 {3036 if(GC.getInterfaceModeInfo((InterfaceModeTypes)pkActionInfo->getInterfaceModeType())->getSelectAll())3037 {3038 GC.GetEngineUserInterface()->selectGroup(pHeadSelectedUnit.get(), false, false, true);3039 }3040 else if(GC.getInterfaceModeInfo((InterfaceModeTypes)pkActionInfo->getInterfaceModeType())->getSelectType())3041 {3042 GC.GetEngineUserInterface()->selectGroup(pHeadSelectedUnit.get(), false, true, false);3043 }3044 }30453046 GC.GetEngineUserInterface()->setInterfaceMode((InterfaceModeTypes)pkActionInfo->getInterfaceModeType());3047 }30483049 // Mission3050 int iMissionType = pkActionInfo->getMissionType();3051 if(iMissionType != NO_MISSION)3052 {3053 bool bSkipMissionAdd = false;30543055 if(iMissionType == CvTypes::getMISSION_BUILD() || iMissionType == CvTypes::getMISSION_FOUND())3056 {3057 bool bShowConfirmPopup = false;3058 // If we're going to build over an existing Improvement/Route, ask the player to confirm3059 if(iMissionType == CvTypes::getMISSION_BUILD())3060 {3061 int iBuild = pkActionInfo->getMissionData();3062 CvBuildInfo* pBuildInfo = GC.getBuildInfo((BuildTypes)iBuild);30633064 // Let them Repair, it's fine3065 if(!pBuildInfo->isRepair())3066 {3067 // Let them build a Route, it's fine3068 if(pBuildInfo->getRoute() == NO_ROUTE)3069 {3070 // Let them build over an improvement if the new improvement REQUIRES the old one3071 CvImprovementEntry *pImprovementInfo = GC.getImprovementInfo((ImprovementTypes)pBuildInfo->getImprovement());3072 if (!pImprovementInfo || !pImprovementInfo->IsRequiresImprovement())3073 {3074 if(pHeadSelectedUnit.get() != NULL)3075 {3076 CvUnit* pkHeadSelectedUnit = GC.UnwrapUnitPointer(pHeadSelectedUnit.get());3077 CvPlot* pPlot = pkHeadSelectedUnit->plot();3078 if(pPlot != NULL)3079 {3080 if(pPlot->getImprovementType() != NO_IMPROVEMENT && !(pPlot->getFeatureType() == FEATURE_FALLOUT && pBuildInfo->isFeatureRemove(FEATURE_FALLOUT)))3081 {3082 bShowConfirmPopup = true;3083 }3084 }3085 }3086 }3087 }3088 }3089 }3090 else3091 if(iMissionType == CvTypes::getMISSION_FOUND())3092 {3093 if(pHeadSelectedUnit.get() != NULL)3094 {3095 CvUnit* pkHeadSelectedUnit = GC.UnwrapUnitPointer(pHeadSelectedUnit.get());3096 CvPlot* pPlot = pkHeadSelectedUnit->plot();3097 if(pPlot != NULL)3098 {3099 ResourceTypes eArtifactResourceType = static_cast<ResourceTypes>(GC.getARTIFACT_RESOURCE());3100 ResourceTypes eHiddenArtifactResourceType = static_cast<ResourceTypes>(GC.getARTIFACT_RESOURCE());3101 if (pPlot->getResourceType() == eArtifactResourceType || pPlot->getResourceType() == eHiddenArtifactResourceType)3102 {3103 bShowConfirmPopup = true;3104 }3105 }3106 }3107 }31083109 if(bShowConfirmPopup)3110 {3111 int iBuild = pkActionInfo->getMissionData();3112 CvPopupInfo kPopupInfo(BUTTONPOPUP_CONFIRM_IMPROVEMENT_REBUILD, iAction, iBuild);3113 kPopupInfo.bOption1 = bAlt;3114 GC.GetEngineUserInterface()->AddPopup(kPopupInfo);3115 bSkipMissionAdd = true; // Skip the mission add, the popup will do it3116 }3117 }3118 else3119 if (iMissionType == CvTypes::getMISSION_ESTABLISH_TRADE_ROUTE())3120 {3121 if(pHeadSelectedUnit.get() != NULL)3122 {3123 CvUnit* pkHeadSelectedUnit = GC.UnwrapUnitPointer(pHeadSelectedUnit.get());3124 if (pkHeadSelectedUnit)3125 {3126 CvPopupInfo kPopup(BUTTONPOPUP_CHOOSE_INTERNATIONAL_TRADE_ROUTE, pkHeadSelectedUnit->getOwner());3127 kPopup.iData2 = pkHeadSelectedUnit->getIndex();3128 GC.GetEngineUserInterface()->AddPopup(kPopup);3129 }3130 }3131 bSkipMissionAdd = true; // Skip no matter what, if there is no unit, there is no mission3132 }3133 else3134 if (iMissionType == CvTypes::getMISSION_CHANGE_TRADE_UNIT_HOME_CITY())3135 {3136 if(pHeadSelectedUnit.get() != NULL)3137 {3138 CvUnit* pkHeadSelectedUnit = GC.UnwrapUnitPointer(pHeadSelectedUnit.get());3139 if (pkHeadSelectedUnit)3140 {3141 CvPopupInfo kPopup(BUTTONPOPUP_CHOOSE_TRADE_UNIT_NEW_HOME);3142 kPopup.iData1 = pkHeadSelectedUnit->getIndex();3143 GC.GetEngineUserInterface()->AddPopup(kPopup);3144 }3145 }3146 bSkipMissionAdd = true; // Skip no matter what, if there is no unit, there is no mission3147 }3148 if (iMissionType == CvTypes::getMISSION_CHANGE_ADMIRAL_PORT())3149 {3150 if(pHeadSelectedUnit.get() != NULL)3151 {3152 CvUnit* pkHeadSelectedUnit = GC.UnwrapUnitPointer(pHeadSelectedUnit.get());3153 if (pkHeadSelectedUnit)3154 {3155 CvPopupInfo kPopup(BUTTONPOPUP_CHOOSE_ADMIRAL_PORT);3156 kPopup.iData1 = pkHeadSelectedUnit->getIndex();3157 GC.GetEngineUserInterface()->AddPopup(kPopup);3158 }3159 }3160 bSkipMissionAdd = true; // Skip no matter what, if there is no unit, there is no mission3161 }31623163 if (!bSkipMissionAdd)3164 {3165 selectionListGameNetMessage(GAMEMESSAGE_PUSH_MISSION, iMissionType, pkActionInfo->getMissionData(), -1, 0, false, bShift);3166 GC.GetEngineUserInterface()->setInterfaceMode(INTERFACEMODE_SELECTION);3167 }3168 }31693170 // Command3171 if(pkActionInfo->getCommandType() != NO_COMMAND)3172 {3173 bSkip = false;31743175 if(!bSkip)3176 {3177 if(pkActionInfo->isConfirmCommand())3178 {3179 CvPopupInfo kPopupInfo(BUTTONPOPUP_CONFIRMCOMMAND, iAction);3180 kPopupInfo.bOption1 = bAlt;3181 GC.GetEngineUserInterface()->AddPopup(kPopupInfo);3182 }3183 else3184 {3185 selectionListGameNetMessage(GAMEMESSAGE_DO_COMMAND, pkActionInfo->getCommandType(), pkActionInfo->getCommandData(), -1, 0, bAlt);3186 }3187 }3188 }3189}