From 07c998c6bad1a05044aed3d9035d692db9fcc88c Mon Sep 17 00:00:00 2001 From: Gynt Date: Wed, 14 Oct 2026 10:14:58 +0200 Subject: [PATCH 01/10] reduce file list to AICState methods and status file --- .../AI/AICState/Constructor_AICState.cpp | 14 + .../AI/AICState/abortAttackAndGoIdle.cpp | 23 ++ .../addBuildingToTargetableBuildings.cpp | 30 ++ .../AI/AICState/addEngineersToSelection.cpp | 44 +++ .../AICState/addUnitToSmallestPatrolTribe.cpp | 27 ++ .../aiChoiceAttForceRallyPercentage.cpp | 45 +++ .../AICState/aiCommandSiegeEngineTribes.cpp | 105 ++++++ .../aiCommandTribe11StandGroundToGate.cpp | 36 ++ .../aiCommandTribe13DefensiveWave.cpp | 33 ++ src/OpenSHC/AI/AICState/aiFarmChoice.cpp | 18 + .../AI/AICState/aiOfTypeInCurrentGame.cpp | 25 ++ .../AI/AICState/aiRecruitEngineers.cpp | 39 ++ .../AI/AICState/aiRequiresExtraOxtethers.cpp | 63 ++++ .../AI/AICState/aiUpdateTaxesAndRations.cpp | 91 +++++ .../assignRequiredIdleEngineersToNewTribe.cpp | 49 +++ .../AI/AICState/assignUnitToATribe.cpp | 41 ++ .../checkTribeActivityPercentages.cpp | 25 ++ ...GenerateAITribesForPlayerIfNotExisting.cpp | 43 +++ .../AI/AICState/clearOutdatedAITribes.cpp | 39 ++ .../AI/AICState/computeNervousness.cpp | 47 +++ .../AI/AICState/countSiegeEngineUnits.cpp | 36 ++ .../AICState/destroyAnyBuildingInCategory.cpp | 97 +++++ .../AI/AICState/destroyBuildingIfNoWorker.cpp | 45 +++ ...determineAIPlayerAttackRequestResponse.cpp | 36 ++ .../AI/AICState/determineAIPlayerHelp.cpp | 35 ++ ...ndAttackTribePositionAndPathToDefenses.cpp | 58 +++ .../generateSiegeCreationInformation.cpp | 55 +++ .../AI/AICState/getAIBuildInterval.cpp | 12 +- .../getCurrentDesiredAttackRaidUnitCount.cpp | 24 ++ .../AI/AICState/getResourceRebuildDelay.cpp | 18 + .../AI/AICState/getSmallestPatrolTribe.cpp | 49 +++ .../getTargetableBuildingForPlayerID.cpp | 47 +++ .../getUnitTypeForUnitBehaviourType.cpp | 58 +++ .../AI/AICState/getUnitTypeIndexForUnitID.cpp | 60 +++ .../AICState/giveMoveCommandToSortieUnits.cpp | 71 ++++ .../AICState/hasNoTroopsOrAllAreDiggers.cpp | 43 +++ .../AI/AICState/hasNotEnoughSupplies.cpp | 30 ++ .../AICState/ifHasTribe0SendUnitsToKeep.cpp | 22 ++ .../AI/AICState/instructTribe166ToMove.cpp | 60 +++ ...qualThanMinimumGoodsRequiredAfterTrade.cpp | 25 ++ .../AI/AICState/makeOutpostTribesAttack.cpp | 22 ++ ...eUnitsGoDefensiveAndBackToSomeLocation.cpp | 47 +++ ...erIsWoodCuttersHutWhileNoWoodAvailable.cpp | 19 + .../AICState/moveAttackTribesToLocations.cpp | 47 +++ .../moveAttackingUnitsToNextRallyPoint.cpp | 71 ++++ ...rcentageNonMovingTribesGTEAICSpecified.cpp | 59 +++ .../AI/AICState/playAnger1BikFromPlayer.cpp | 41 ++ .../playAnger2BikFromPlayerToPlayer.cpp | 36 ++ .../playFriendlyVictoryBikFromPlayer.cpp | 23 ++ .../playGoodsNotSentBikFromPlayer.cpp | 23 ++ .../playGoodsRequestBikFromPlayerToPlayer.cpp | 32 ++ .../playGoodsSentBikFromPlayerToPlayer.cpp | 27 ++ .../AI/AICState/playJokeBikFromAIToHuman.cpp | 22 ++ .../AI/AICState/playNervous1BikFromPlayer.cpp | 27 ++ .../AI/AICState/playNoHelpBikFromPlayer.cpp | 23 ++ ...yerKilledBiksFromKilledAndKillerPlayer.cpp | 73 ++++ .../AICState/playRequestHelpBikFromPlayer.cpp | 39 ++ ...playTauntToAttackedPlayerBikFromPlayer.cpp | 41 ++ .../AICState/playTeamWinningBikFromPlayer.cpp | 29 ++ .../playThanksBikFromPlayerToPlayer.cpp | 43 +++ .../playVictory2BikFromPlayerToPlayer.cpp | 43 +++ .../playWillAttackBikFromPlayerToPlayer.cpp | 27 ++ .../playWillHelpBikFromPlayerToPlayer.cpp | 27 ++ ...layWillNotAttack1BikFromPlayerToPlayer.cpp | 27 ++ ...layWillNotAttack2BikFromPlayerToPlayer.cpp | 27 ++ .../playWillNotHelp1BikFromPlayerToPlayer.cpp | 27 ++ .../playWillNotHelp2BikFromPlayerToPlayer.cpp | 27 ++ .../processAttForceRallyPercentage.cpp | 68 ++++ .../randomlySelectAttackUnitTypeToRecruit.cpp | 138 +++++++ .../recomputeAIPathCostToAttackedKeep.cpp | 59 +++ .../AI/AICState/recomputeAIZonerLayer.cpp | 31 ++ .../AI/AICState/recomputeAttackAIZone.cpp | 48 +++ .../AI/AICState/recreateEngineersTribe.cpp | 25 ++ ...oveOrganismsAndSetMoveDestinationPairs.cpp | 49 +++ src/OpenSHC/AI/AICState/requestGoods.cpp | 70 ++++ ...selectBuildingFromAListOfBuildingTypes.cpp | 35 ++ ...andomBuildingIDFromListOfBuildingTypes.cpp | 25 ++ src/OpenSHC/AI/AICState/sellGoods.cpp | 1 - .../sendAITribe_0xf_toAttackPatrol.cpp | 39 ++ ...oAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp | 64 ++++ ...sendOilMenForOilPickupOrToAIVLocations.cpp | 62 +++ ...gedUnitTribesToAIVSlotsOrKeepIfNervous.cpp | 58 +++ .../AICState/sendTribeAtOffset1ToCampfire.cpp | 21 ++ .../AICState/sendTribeToAIVLocationSlot.cpp | 48 +++ src/OpenSHC/AI/AICState/sendTribeToAttack.cpp | 38 ++ .../sendUnitsToAttackBreachedCastle.cpp | 110 ++++++ .../AI/AICState/sendUnitsToCampfire.cpp | 24 ++ src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp | 24 ++ .../sendUnitsToPlayerIDsKeepIfPossible.cpp | 79 ++++ .../AI/AICState/setAICParameters_01.cpp | 150 ++++++++ .../AI/AICState/setAICParameters_02.cpp | 148 ++++++++ .../AI/AICState/setAICParameters_03.cpp | 148 ++++++++ .../AI/AICState/setAICParameters_04.cpp | 149 ++++++++ .../AI/AICState/setAICParameters_05.cpp | 148 ++++++++ .../AI/AICState/setAICParameters_06.cpp | 150 ++++++++ .../AI/AICState/setAICParameters_07.cpp | 147 ++++++++ .../AI/AICState/setAICParameters_08.cpp | 149 ++++++++ .../AI/AICState/setAICParameters_09.cpp | 146 ++++++++ .../AI/AICState/setAICParameters_10.cpp | 147 ++++++++ .../AI/AICState/setAICParameters_11.cpp | 145 +++++++ .../AI/AICState/setAICParameters_12.cpp | 146 ++++++++ .../AI/AICState/setAICParameters_13.cpp | 142 +++++++ .../AI/AICState/setAICParameters_14.cpp | 150 ++++++++ .../AI/AICState/setAICParameters_15.cpp | 142 +++++++ .../AI/AICState/setAICParameters_16.cpp | 144 +++++++ .../AICState/setAttackCoordinationLevel.cpp | 33 ++ .../AI/AICState/setAttackPrimeInfo.cpp | 25 ++ .../AI/AICState/setCurrentAttackStrength.cpp | 37 ++ ...htTribe0xc0TribesToAggressiveAndAttack.cpp | 38 ++ src/OpenSHC/AI/AICState/setFoodBuyPlan.cpp | 26 +- src/OpenSHC/AI/AICState/setInitialAIC.cpp | 45 +++ .../AI/AICState/setNextFarmTypeToBuild.cpp | 25 ++ .../AICState/setNextMoveLocationForUnits.cpp | 38 ++ ...TargetForTribeBasedOnTargetChoiceLogic.cpp | 106 ++++++ ...x11ToAggressiveAndAttackIfConditionMet.cpp | 42 +++ .../setTribe0xCtoAggressiveAndAttack.cpp | 38 ++ .../setTribe0xbToAggressiveAndAttack.cpp | 38 ++ .../AICState/setupWorkshopProductionType.cpp | 85 +++++ .../AI/AICState/shareGoldAmongTeamMembers.cpp | 77 ++++ .../AICState/shouldDestroyWoodCutterUnk.cpp | 52 +++ .../AICState/shouldNotBeBuildingArmoury.cpp | 18 + .../AICState/shouldNotBeBuildingGranary.cpp | 18 + .../AI/AICState/shouldNotBeBuildingHovel.cpp | 36 ++ .../AI/AICState/shouldNotBuildKillingPits.cpp | 18 + ...rketArmoryGranaryBarracksMercenarypost.cpp | 29 ++ ...uldWaitWithBuildingAPositiveFearFactor.cpp | 50 +++ ...ouldWaitWithBuildingNegativeFearFactor.cpp | 39 ++ .../AI/AICState/someChatMessageSelection.cpp | 127 +++++++ .../AI/AICState/teamIsWeakRelativeToEnemy.cpp | 52 +++ .../AI/AICState/unitIDIsRangedOrArmored.cpp | 27 ++ src/OpenSHC/AI/AICState/updateAIBehaviour.cpp | 94 +++++ .../AI/AICState/updateTribeLocations.cpp | 58 +++ ...12_toPlaceSiegeTentsAndAssignEngineers.cpp | 105 ++++++ .../useAITribe_0xe_toPlaceTunnels.cpp | 67 ++++ src/OpenSHC/AI/AICState/wipeAICMemory.cpp | 18 + src/OpenSHC/AI/AICState/yieldCowThrow.cpp | 29 ++ status/addresses-SHC-3BB0A8C1.txt | 354 +++++++++--------- 137 files changed, 7780 insertions(+), 198 deletions(-) create mode 100644 src/OpenSHC/AI/AICState/Constructor_AICState.cpp create mode 100644 src/OpenSHC/AI/AICState/abortAttackAndGoIdle.cpp create mode 100644 src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp create mode 100644 src/OpenSHC/AI/AICState/addEngineersToSelection.cpp create mode 100644 src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp create mode 100644 src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp create mode 100644 src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp create mode 100644 src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp create mode 100644 src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp create mode 100644 src/OpenSHC/AI/AICState/aiFarmChoice.cpp create mode 100644 src/OpenSHC/AI/AICState/aiOfTypeInCurrentGame.cpp create mode 100644 src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp create mode 100644 src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp create mode 100644 src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp create mode 100644 src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp create mode 100644 src/OpenSHC/AI/AICState/assignUnitToATribe.cpp create mode 100644 src/OpenSHC/AI/AICState/checkTribeActivityPercentages.cpp create mode 100644 src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp create mode 100644 src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp create mode 100644 src/OpenSHC/AI/AICState/computeNervousness.cpp create mode 100644 src/OpenSHC/AI/AICState/countSiegeEngineUnits.cpp create mode 100644 src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp create mode 100644 src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp create mode 100644 src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp create mode 100644 src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp create mode 100644 src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp create mode 100644 src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp create mode 100644 src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp create mode 100644 src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp create mode 100644 src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp create mode 100644 src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp create mode 100644 src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp create mode 100644 src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp create mode 100644 src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp create mode 100644 src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp create mode 100644 src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp create mode 100644 src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp create mode 100644 src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp create mode 100644 src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp create mode 100644 src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp create mode 100644 src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp create mode 100644 src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp create mode 100644 src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp create mode 100644 src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp create mode 100644 src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp create mode 100644 src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp create mode 100644 src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp create mode 100644 src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp create mode 100644 src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp create mode 100644 src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp create mode 100644 src/OpenSHC/AI/AICState/recomputeAIZonerLayer.cpp create mode 100644 src/OpenSHC/AI/AICState/recomputeAttackAIZone.cpp create mode 100644 src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp create mode 100644 src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp create mode 100644 src/OpenSHC/AI/AICState/requestGoods.cpp create mode 100644 src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp create mode 100644 src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp create mode 100644 src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp create mode 100644 src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp create mode 100644 src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp create mode 100644 src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp create mode 100644 src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp create mode 100644 src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp create mode 100644 src/OpenSHC/AI/AICState/sendTribeToAttack.cpp create mode 100644 src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp create mode 100644 src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp create mode 100644 src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp create mode 100644 src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_01.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_02.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_03.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_04.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_05.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_06.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_07.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_08.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_09.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_10.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_11.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_12.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_13.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_14.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_15.cpp create mode 100644 src/OpenSHC/AI/AICState/setAICParameters_16.cpp create mode 100644 src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp create mode 100644 src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp create mode 100644 src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp create mode 100644 src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp create mode 100644 src/OpenSHC/AI/AICState/setInitialAIC.cpp create mode 100644 src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp create mode 100644 src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp create mode 100644 src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp create mode 100644 src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp create mode 100644 src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp create mode 100644 src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp create mode 100644 src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp create mode 100644 src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp create mode 100644 src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp create mode 100644 src/OpenSHC/AI/AICState/someChatMessageSelection.cpp create mode 100644 src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp create mode 100644 src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp create mode 100644 src/OpenSHC/AI/AICState/updateAIBehaviour.cpp create mode 100644 src/OpenSHC/AI/AICState/updateTribeLocations.cpp create mode 100644 src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp create mode 100644 src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp create mode 100644 src/OpenSHC/AI/AICState/wipeAICMemory.cpp create mode 100644 src/OpenSHC/AI/AICState/yieldCowThrow.cpp diff --git a/src/OpenSHC/AI/AICState/Constructor_AICState.cpp b/src/OpenSHC/AI/AICState/Constructor_AICState.cpp new file mode 100644 index 0000000000..2eedf70e12 --- /dev/null +++ b/src/OpenSHC/AI/AICState/Constructor_AICState.cpp @@ -0,0 +1,14 @@ +#include "../AICState.func.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D3940 + AICState* AICState::Constructor_AICState() + { + MACRO_CALL_MEMBER(AICState_Func::setInitialAIC, this)(); + this->aiTauntResponseTimeWindow = 0; + return this; + } +} +} diff --git a/src/OpenSHC/AI/AICState/abortAttackAndGoIdle.cpp b/src/OpenSHC/AI/AICState/abortAttackAndGoIdle.cpp new file mode 100644 index 0000000000..bdd9f7312d --- /dev/null +++ b/src/OpenSHC/AI/AICState/abortAttackAndGoIdle.cpp @@ -0,0 +1,23 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D45E0 + void AICState::abortAttackAndGoIdle(int playerID) + { + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::removeSiegeBuildings, DAT_BuildingsState::ptr)( + DAT_GameState::instance.playerDataArray[playerID].currentAttackWave, playerID); + MACRO_CALL_MEMBER(AICState_Func::disbandAIPlayerSiegeUnits, this)(playerID); + MACRO_CALL_MEMBER(AICState_Func::addEngineersToTribe, this)(playerID); + MACRO_CALL_MEMBER(AICState_Func::aiReassignTunnelersToTribe, this)(playerID); + DAT_GameState::instance.playerDataArray[playerID].aiPlayerState = 0; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp b/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp new file mode 100644 index 0000000000..bd48cbe1c0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp @@ -0,0 +1,30 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameMode.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDA50 + void AICState::addBuildingToTargetableBuildings(int buildingID) + { + int owner = DAT_BuildingsState::instance.buildings[buildingID].owner; + if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) + return; + if (DAT_GameState::instance.playerDataArray[owner].top100TargetableBuildingsTracker >= 100) + return; + if (DAT_BuildingsState::instance.buildings[buildingID].fireDuration != 0) + return; + + DAT_GameState::instance.playerDataArray[owner] + .top100TargetableBuildings[DAT_GameState::instance.playerDataArray[owner].top100TargetableBuildingsTracker] + = buildingID; + DAT_GameState::instance.playerDataArray[owner].top100TargetableBuildingsTracker++; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp b/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp new file mode 100644 index 0000000000..ce614c0985 --- /dev/null +++ b/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp @@ -0,0 +1,44 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/States/UnitState.hpp" +#include "OpenSHC/Map/Units/UnitLogicState.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC680 + int AICState::addEngineersToSelection(int playerID, int unitCount) + { + int tribeID + = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); + for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) { + if (unitCount <= 0) + break; + if (DAT_UnitsState::instance.units[unitID].logicalState != Map::Units::ULS_NORMAL) + continue; + if (DAT_UnitsState::instance.units[unitID].owner != playerID) + continue; + if (DAT_UnitsState::instance.units[unitID].dying != 0) + continue; + if (DAT_UnitsState::instance.units[unitID].unitType != Map::Units::UT_E_ENGINEER) + continue; + if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType != 10) + continue; + if (DAT_UnitsState::instance.units[unitID].tribeID != 0) + continue; + if (DAT_UnitsState::instance.units[unitID].state.generic == Map::Units::States::US_STAND_UPUnk) + continue; + + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID); + unitCount--; + } + return tribeID; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp b/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp new file mode 100644 index 0000000000..e92b28080d --- /dev/null +++ b/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp @@ -0,0 +1,27 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2730 + void AICState::addUnitToSmallestPatrolTribe(int unitID) + { + int owner = DAT_UnitsState::instance.units[unitID].owner; + if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL) + return; + int aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; + + DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 4; + int tribeID = MACRO_CALL_MEMBER(AICState_Func::getSmallestPatrolTribe, this)( + owner, this->aics[aicIndex].OuterPatrolGroupsCount); + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp b/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp new file mode 100644 index 0000000000..890450502e --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp @@ -0,0 +1,45 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CEC80 + BOOLEnum AICState::aiChoiceAttForceRallyPercentage(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) + return FALSE; + int aicIndex = aiType - 1; + + int activeTribes = 0; + int rallyingTribes = 0; + for (int i = 0; i < 11; i++) { + int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) + continue; + + activeTribes++; + if (DAT_TribesState::instance.tribes[tribeID].percentageMovingUnk < 20) + rallyingTribes++; + } + } + + if (activeTribes <= 0) + return FALSE; + return rallyingTribes * 100 / activeTribes >= this->aics[aicIndex].AttForceRallyPercentage; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp new file mode 100644 index 0000000000..a7da318069 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp @@ -0,0 +1,105 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/DirectionAlgorithmState.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" +#include "OpenSHC/Map/Units/UnitLogicState.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_DirectionAlgorithmState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + using namespace OpenSHC::Map::Units; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CFCD0 + void AICState::aiCommandSiegeEngineTribes(int playerID) + { + int shieldTargetTribeIDs[3]; + shieldTargetTribeIDs[0] = 0; + shieldTargetTribeIDs[1] = 0; + shieldTargetTribeIDs[2] = 0; + int targetCount = 0; + for (int i = 186; i < 189; i++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[i]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[i]) + continue; + shieldTargetTribeIDs[targetCount] = tribeID; + targetCount++; + } + + int shieldCount = 0; + for (int unitID = 1; unitID < 2500; unitID++) { + if (DAT_UnitsState::instance.units[unitID].logicalState == ULS_INVISIBLE) + continue; + if (DAT_UnitsState::instance.units[unitID].unitType != UT_S_TOWER + && DAT_UnitsState::instance.units[unitID].unitType != UT_S_BATTERINGRAM + && DAT_UnitsState::instance.units[unitID].unitType != UT_S_SHIELD) + continue; + if (DAT_UnitsState::instance.units[unitID].unknownSiegeTentRelated02 != 3) + continue; + if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType == 21) + continue; + + if (DAT_UnitsState::instance.units[unitID].unitType == UT_S_TOWER) { + int tribeID = DAT_UnitsState::instance.units[unitID].tribeID; + if (tribeID == 0) + continue; + if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.wideValuesArray + playerID * 0x177bc - 4) + != 0) + MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, STBT_0x414); + } else if (DAT_UnitsState::instance.units[unitID].unitType == UT_S_BATTERINGRAM) { + int tribeID = DAT_UnitsState::instance.units[unitID].tribeID; + if (tribeID == 0) + continue; + if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.gateValuesArray + playerID * 0x177bc - 4) + != 0) + MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, STBT_0x3f6); + else if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.wideValuesArray + playerID * 0x177bc - 4) + != 0) + MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, STBT_0x413); + } else if (DAT_UnitsState::instance.units[unitID].unitType == UT_S_SHIELD) { + int tribeID = DAT_UnitsState::instance.units[unitID].tribeID; + if (tribeID == 0) + continue; + if (shieldCount >= 3) + continue; + + int targetTribeID = shieldTargetTribeIDs[shieldCount]; + DAT_TribesState::instance.tribes[tribeID].field56_0x1f2 = targetTribeID; + DAT_TribesState::instance.tribes[tribeID].uid2 = DAT_TribesState::instance.tribes[targetTribeID].uid; + DAT_TribesState::instance.tribes[targetTribeID].tribeID = tribeID; + int targetUnitID = DAT_TribesState::instance.tribes[targetTribeID].selectionTargetUnitID; + int tile = DAT_UnitsState::instance.units[targetUnitID].tile; + shieldCount++; + if (tile <= 0) + continue; + + int y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + MACRO_CALL_MEMBER(TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( + tribeID, x, y, 0, 0, Instructions::UMSE_0); + MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::DirectionAlgorithmState_Func::calculatePreferredRelativeOrientation, + DAT_DirectionAlgorithmState::ptr)(DAT_UnitsState::instance.units[targetUnitID].x, + DAT_UnitsState::instance.units[targetUnitID].y, x, y); + DAT_TribesState::instance.tribes[tribeID].orientation + = DAT_DirectionAlgorithmState::instance.orientation; + } + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp new file mode 100644 index 0000000000..265f1d75dd --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp @@ -0,0 +1,36 @@ +#include "OpenSHC/Map/Units/TroopValueState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF470 + void AICState::aiCommandTribe11StandGroundToGate(int playerID) + { + int tribeIndex = 11; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) + return; + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) + return; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) + return; + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) + return; + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_STAND_GROUND; + if (MACRO_CALL_MEMBER(Map::Units::TroopValueState_Func::moveTribeToNearbyGatehouse, DAT_TroopValueState::ptr)( + tribeID) + == 0) + MACRO_CALL_MEMBER(Map::Units::TroopValueState_Func::moveTowardsParticularUnits, DAT_TroopValueState::ptr)( + tribeID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp new file mode 100644 index 0000000000..fe85393295 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp @@ -0,0 +1,33 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF270 + void AICState::aiCommandTribe13DefensiveWave(int playerID) + { + int tribeIndex = 13; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) + return; + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) + return; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) + return; + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) + return; + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_DEFENSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3f4); + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp new file mode 100644 index 0000000000..46898001b6 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB180 + int AICState::aiFarmChoice(PlayerID playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) + return 0; + return (&this->aics[aiType - 1].farm1)[DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex]; + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiOfTypeInCurrentGame.cpp b/src/OpenSHC/AI/AICState/aiOfTypeInCurrentGame.cpp new file mode 100644 index 0000000000..835f96773f --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiOfTypeInCurrentGame.cpp @@ -0,0 +1,25 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0580 + BOOLEnum AICState::aiOfTypeInCurrentGame(int aicIndex) + { + for (int playerID = 1; playerID < 9; playerID++) { + if (DAT_GameSynchronyState::instance.currentAIArray[playerID] == 0) + continue; + if (DAT_GameState::instance.playerDataArray[playerID].lordKilledByPlayerID != 0) + continue; + if (aicIndex != DAT_GameState::instance.playerDataArray[playerID].aiType - 1) + continue; + return TRUE; + } + return FALSE; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp new file mode 100644 index 0000000000..ba7ee99f22 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp @@ -0,0 +1,39 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC520 + void AICState::aiRecruitEngineers(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) + return; + if (DAT_GameState::instance.playerDataArray[playerID].isEngineerRequired == FALSE) + return; + if (DAT_GameState::instance.playerDataArray[playerID].canStartSpending == 0) + return; + if (this->aics[aiType - 1].defSiegeEngineGoldThreshold + + DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] + < 30) + return; + int guildID = DAT_GameState::instance.playerDataArray[playerID].engineersGuild.id; + if (guildID <= 0) + return; + if (DAT_BuildingsState::instance.buildings[guildID].buildingType != Map::Buildings::BT_ENGINEERSGUILD) + return; + + MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::nonEuroRecruit, DAT_UnitsState::ptr)( + Map::Units::UT_E_ENGINEER, guildID, playerID, 0); + DAT_GameState::instance.playerDataArray[playerID].isEngineerRequired = FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp new file mode 100644 index 0000000000..799e96e0c4 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp @@ -0,0 +1,63 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB3A0 + undefined4 AICState::aiRequiresExtraOxtethers(int playerID) + { + int quarryID + = MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::findFirstBuildingIDForPlayerAndType, + DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_QUARRY); + int highestQuarryID = 0; + int highestStonePerTether = 0; + if (MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::countBuildingsForPlayer, + DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_OXTETHER, 1) + >= 10) + return 0; + + DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = 0; + for (; quarryID != 0; + quarryID = MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::findNextBuildingForPlayerAndType, + DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_QUARRY, quarryID)) { + int stone = DAT_BuildingsState::instance + .buildings[(short)DAT_BuildingsState::instance.buildings[quarryID].quarryStockpileID] + .resources[Game::Resources::RT_STONE]; + int tetherCount = 0; + for (int i = 0; i < 3; i++) { + int tetherID = DAT_BuildingsState::instance.buildings[quarryID].quarryLinkedOxTethers[i]; + if (tetherID == 0) + continue; + if (DAT_BuildingsState::instance.buildings[tetherID].buildingType + == OpenSHC::Map::Buildings::BT_OXTETHER + && DAT_BuildingsState::instance.buildings[tetherID].oxtetherLinkedQuarryID == quarryID) + tetherCount++; + else + DAT_BuildingsState::instance.buildings[quarryID].quarryLinkedOxTethers[i] = 0; + } + + if (tetherCount <= 0) { + DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = quarryID; + return 1; + } + if (stone / tetherCount > highestStonePerTether) { + highestQuarryID = quarryID; + highestStonePerTether = stone / tetherCount; + } + } + + if (highestStonePerTether > 20) { + DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = highestQuarryID; + return 1; + } + return 0; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp b/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp new file mode 100644 index 0000000000..cd1b580356 --- /dev/null +++ b/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp @@ -0,0 +1,91 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CAEA0 + void AICState::aiUpdateTaxesAndRations(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) + return; + int aicIndex = aiType - 1; + + int popularity = DAT_GameState::instance.playerDataArray[playerID].popularity; + if (popularity <= this->aics[aicIndex].criticalPopularity) + DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue = 2; + else if (popularity <= this->aics[aicIndex].lowestPopularity) + DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue = 1; + else if (popularity >= this->aics[aicIndex].highestPopularity) + DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue = 0; + + if (DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue == 2) { + DAT_GameState::instance.playerDataArray[playerID].taxesSetting = 2; + if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 0) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 0; + else if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 4) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 2; + else if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 8) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 3; + else + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 4; + } else if (DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue == 1) { + if (DAT_GameState::instance.playerDataArray[playerID].taxesSetting > this->aics[aicIndex].taxesMin) + DAT_GameState::instance.playerDataArray[playerID].taxesSetting--; + else + DAT_GameState::instance.playerDataArray[playerID].taxesSetting = this->aics[aicIndex].taxesMin; + + if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 0) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 0; + else if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 10) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 2; + else + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 3; + if (this->aics[aicIndex].doubleRationsFoodThreshold != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalFood + >= this->aics[aicIndex].doubleRationsFoodThreshold) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 4; + } else if (DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue == 0) { + if (DAT_GameState::instance.playerDataArray[playerID].taxesSetting < this->aics[aicIndex].taxesMax) { + int lowerTaxesLimit; + if (DAT_GameState::instance.playerDataArray[playerID].previousAvailablePeasants >= 15) + lowerTaxesLimit = 6; + else if (DAT_GameState::instance.playerDataArray[playerID].previousAvailablePeasants >= 10) + lowerTaxesLimit = 5; + else + lowerTaxesLimit = 4; + + if (DAT_GameState::instance.playerDataArray[playerID].storedPopularityPercent <= popularity) + DAT_GameState::instance.playerDataArray[playerID].taxesSetting++; + else if (DAT_GameState::instance.playerDataArray[playerID].taxesSetting > lowerTaxesLimit) + DAT_GameState::instance.playerDataArray[playerID].taxesSetting--; + } else { + DAT_GameState::instance.playerDataArray[playerID].taxesSetting = this->aics[aicIndex].taxesMax; + } + + if (DAT_GameState::instance.playerDataArray[playerID].totalFood <= 10) { + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 0; + } else { + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 2; + if (this->aics[aicIndex].doubleRationsFoodThreshold != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalFood + >= this->aics[aicIndex].doubleRationsFoodThreshold) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 4; + } + } + + if (DAT_GameState::instance.playerDataArray[playerID].taxesSetting < 0) + DAT_GameState::instance.playerDataArray[playerID].taxesSetting = 0; + if (DAT_GameState::instance.playerDataArray[playerID].taxesSetting > 11) + DAT_GameState::instance.playerDataArray[playerID].taxesSetting = 11; + if (DAT_GameState::instance.playerDataArray[playerID].rationsSetting < 0) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 0; + if (DAT_GameState::instance.playerDataArray[playerID].rationsSetting > 4) + DAT_GameState::instance.playerDataArray[playerID].rationsSetting = 4; + } +} +} diff --git a/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp new file mode 100644 index 0000000000..2418ab3e9b --- /dev/null +++ b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp @@ -0,0 +1,49 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Map/Units/States/UnitState.hpp" +#include "OpenSHC/Map/Units/UnitLogicState.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC5A0 + int AICState::assignRequiredIdleEngineersToNewTribe(int playerID, int count) + { + int tribeID + = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); + for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) { + if (count <= 0) + break; + if (DAT_UnitsState::instance.units[unitID].logicalState != Map::Units::ULS_NORMAL) + continue; + if (DAT_UnitsState::instance.units[unitID].owner != playerID) + continue; + if (DAT_UnitsState::instance.units[unitID].dying != 0) + continue; + if (DAT_UnitsState::instance.units[unitID].unitType != Map::Units::UT_E_ENGINEER) + continue; + if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType == 22) + continue; + if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType == 10) + continue; + if (DAT_UnitsState::instance.units[unitID].engineerRelatedUnk != 0) + continue; + if (DAT_UnitsState::instance.units[unitID].state.generic != 105 + && DAT_UnitsState::instance.units[unitID].state.generic != 2 + && DAT_UnitsState::instance.units[unitID].state.generic != Map::Units::States::US_IDLEUnk) + continue; + + if (DAT_UnitsState::instance.units[unitID].tribeID != 0) + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::removeUnitFromTribe, DAT_TribesState::ptr)( + unitID, DAT_UnitsState::instance.units[unitID].tribeID); + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID); + count--; + } + return tribeID; + } +} +} diff --git a/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp b/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp new file mode 100644 index 0000000000..547e164cf0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp @@ -0,0 +1,41 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2660 + void AICState::assignUnitToATribe(int unitID) + { + int owner = DAT_UnitsState::instance.units[unitID].owner; + if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL) + return; + + AIVUnitType aivUnitType; + if (DAT_GameState::instance.playerDataArray[owner].aivCurrentPauseIndex == 1 + && DAT_GameState::instance.playerDataArray[owner] + .aivPauses[DAT_GameState::instance.playerDataArray[owner].aivCurrentPauseIndex] + > 0) + aivUnitType = MACRO_CALL_MEMBER(AICState_Func::getUnitTypeIndexForUnitID, this)(unitID, 1); + else + aivUnitType = MACRO_CALL_MEMBER(AICState_Func::getUnitTypeIndexForUnitID, this)(unitID, 0); + DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 1; + int tribeID; + if (DAT_GameState::instance.playerDataArray[owner].aivUnitLocationSlotLocationCount[aivUnitType] <= 0) { + if (MACRO_CALL_MEMBER(AICState_Func::unitIDIsRangedOrArmored, this)(unitID) != 0) + tribeID = MACRO_CALL_MEMBER(AICState_Func::createTribeForUnitType, this)(owner, 0); + else + tribeID = MACRO_CALL_MEMBER(AICState_Func::createTribeForUnitType, this)(owner, 1); + } else { + tribeID = MACRO_CALL_MEMBER(AICState_Func::smallestTribeOfUnitType, this)(owner, aivUnitType); + } + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/checkTribeActivityPercentages.cpp b/src/OpenSHC/AI/AICState/checkTribeActivityPercentages.cpp new file mode 100644 index 0000000000..8bf0b88837 --- /dev/null +++ b/src/OpenSHC/AI/AICState/checkTribeActivityPercentages.cpp @@ -0,0 +1,25 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CD070 + BOOLEnum AICState::checkTribeActivityPercentages(int tribeID, BOOLEnum ignoreShooting, BOOLEnum includeMoving) + { + if (includeMoving != FALSE && DAT_TribesState::instance.tribes[tribeID].percentageMovingUnk > 10) { + return TRUE; + } + if (DAT_TribesState::instance.tribes[tribeID].percentageShootingUnk > 10 && ignoreShooting != TRUE) { + return TRUE; + } + return DAT_TribesState::instance.tribes[tribeID].percentageAttackingUnk > 10; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp new file mode 100644 index 0000000000..00347b8466 --- /dev/null +++ b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp @@ -0,0 +1,43 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CCFB0 + int AICState::checksAndGenerateAITribesForPlayerIfNotExisting(int playerID, int maxAmount, BOOLEnum checkOnly) + { + int offset = 0; + int baseOffset = DAT_SkirmishDefinedData::instance.AITribeIDOffsetForAIVUnitType[1]; + for (; offset < maxAmount; offset++) { + if (offset >= 10) { + return 0; + } + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[baseOffset + offset]; + if (tribeID == 0 + || DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[baseOffset + offset]) { + if (checkOnly != FALSE) { + return 1; + } + int newTribeID = MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); + DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[baseOffset + offset] = (short)newTribeID; + DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[baseOffset + offset] + = DAT_TribesState::instance.tribes[newTribeID].uid; + return newTribeID; + } + } + return 0; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp b/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp new file mode 100644 index 0000000000..8e7e231788 --- /dev/null +++ b/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp @@ -0,0 +1,39 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF870 + void AICState::clearOutdatedAITribes(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + + for (int i = 0; i < 11; i++) { + if (i == 8) + continue; + + int tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; + int tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + == DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) + continue; + + DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j] = 0; + DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType] = 0; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/computeNervousness.cpp b/src/OpenSHC/AI/AICState/computeNervousness.cpp new file mode 100644 index 0000000000..65e1fe7bc4 --- /dev/null +++ b/src/OpenSHC/AI/AICState/computeNervousness.cpp @@ -0,0 +1,47 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D3780 + void AICState::computeNervousness(int playerID) + { + int troopValueNearKeep + = DAT_TroopValueState::instance.attackInfo.playerTotalTroopValueOfTroopsNearKeep[playerID]; + int enemyTroopValue = DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; + + int isNotNervous = 1; + int margin; + if (enemyTroopValue < 50) + margin = -20; + else if (enemyTroopValue < 100) + margin = 0; + else if (enemyTroopValue < 200) + margin = 20; + else if (enemyTroopValue < 400) + margin = 100; + else if (enemyTroopValue < 600) + margin = 200; + else if (enemyTroopValue < 800) + margin = 300; + else + margin = 500; + + if (troopValueNearKeep > enemyTroopValue + margin) { + isNotNervous = 0; + } else if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue == 0) { + if (DAT_GameState::instance.playerDataArray[playerID] + .totalEnemyTroopValueByPlayerID[DAT_GameSynchronyState::instance.currentPlayerSlotID] + > troopValueNearKeep) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::playNervous1BikFromPlayer, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::playRequestHelpBikFromPlayer, this)(playerID); + } + DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue = isNotNervous; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/countSiegeEngineUnits.cpp b/src/OpenSHC/AI/AICState/countSiegeEngineUnits.cpp new file mode 100644 index 0000000000..4cad5f5edc --- /dev/null +++ b/src/OpenSHC/AI/AICState/countSiegeEngineUnits.cpp @@ -0,0 +1,36 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/UnitLogicState.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CFBC0 + int AICState::countSiegeEngineUnits(int playerID) + { + int count = 0; + for (int unitID = 1; unitID < 2500; unitID++) { + if (DAT_UnitsState::instance.units[unitID].logicalState == OpenSHC::Map::Units::ULS_INVISIBLE) + continue; + if (DAT_UnitsState::instance.units[unitID].owner != playerID) + continue; + if (DAT_UnitsState::instance.units[unitID].unknownSiegeTentRelated02 != 3) + continue; + if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType == 21) + continue; + + if (DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_CATAPULT + || DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_TREBUCHET + || DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_TOWER + || DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_BATTERINGRAM + || DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_FBALLISTA) + count++; + } + return count; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp b/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp new file mode 100644 index 0000000000..4ce6d8fee6 --- /dev/null +++ b/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp @@ -0,0 +1,97 @@ +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Map/Buildings/BuildingLogicalState.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" + +namespace OpenSHC { +namespace AI { + + using namespace OpenSHC::Map::Buildings; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0280 + void AICState::destroyAnyBuildingInCategory(int playerID, AINervousDestroyBuildingCategory buildingCategory) + { + for (int buildingID = 1; buildingID < DAT_BuildingsState::instance.maxBuildingsCount; buildingID++) { + if (DAT_BuildingsState::instance.buildings[buildingID].logicalState == 0) + continue; + if (DAT_BuildingsState::instance.buildings[buildingID].logicalState == BLS_REMOVE) + continue; + if (DAT_BuildingsState::instance.buildings[buildingID].owner != playerID) + continue; + + bool matches = true; + if (buildingCategory == AINDBC_FEAR_FACTOR_BUILDINGS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_CESSPIT + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_BURNINGSTAKE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_GIBBET + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DUNGEON + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_STRETCHINGRACK + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_RACKFLOGGING + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_CHOPPINGBLOCK + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DUNKINGSTOOL + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DOGCAGE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_STATUE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_SHRINE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DANCINGBEAR + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_POND + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_GALLOWS + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_STOCKS + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_WITCHHOIST + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_MAYPOLE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_GARDEN; + else if (buildingCategory == AINDBC_WORKSHOPS_AND_RELIGIOUS_BUILDINGS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_FLETCHER + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_BLACKSMITH + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_POLETURNER + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_ARMOURER + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TANNER + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_INN + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_APOTHECARY + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_CHAPEL + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_CHURCH + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_CATHEDRAL; + else if (buildingCategory == AINDBC_GATEHOUSES_TOWERS_GUILDS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_GATEHOUSELARGE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_GATEHOUSESMALL + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DRAWBRIDGE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TOWER1 + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TOWER2 + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TOWER3 + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TOWER4 + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TOWER5 + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_ENGINEERSGUILD + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_TUNNELERSGUILD + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_OILSMELTER; + else if (buildingCategory == AINDBC_BARRACKS_MERCPOST_STABLES) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_MERCENARYPOST + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_BARRACKS + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_STABLES; + else if (buildingCategory == AINDBC_WATER_BUILDINGS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_WELL + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_WATERPOT; + else if (buildingCategory == AINDBC_RESOURCE_BUILDINGS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_OXTETHER + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_IRONMINE + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_PITCHRIG + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_BAKERY + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_BREWERY + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_QUARRY + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_MILL; + else if (buildingCategory == AINDBC_FARMS) + matches = DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_WHEATFARM + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_HOPFARM + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_APPLEFARM + || DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DAIRYFARM; + + if (!matches) + continue; + + MACRO_CALL_MEMBER(BuildingsState_Func::giveBackResourceForDestroyedBuilding, DAT_BuildingsState::ptr)( + buildingID, playerID, 50); + MACRO_CALL_MEMBER(BuildingsState_Func::destroyBuilding, DAT_BuildingsState::ptr)(buildingID); + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp new file mode 100644 index 0000000000..afa234ad5a --- /dev/null +++ b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp @@ -0,0 +1,45 @@ +#include "OpenSHC/AI/AIVState.func.hpp" +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Game/GameMode.hpp" + +#include "OpenSHC/Globals/DAT_AIVState.hpp" +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB940 + undefined4 AICState::destroyBuildingIfNoWorker(int buildingID) + { + short countdown = DAT_BuildingsState::instance.buildings[buildingID].unknownTickRelatedValue; + int owner = DAT_BuildingsState::instance.buildings[buildingID].owner; + if (countdown <= 0) + return 0; + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[owner] != -1) + return 0; + if (DAT_GameSynchronyState::instance.currentAIArray[owner] == 0) + return 0; + if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) + return 0; + + if (DAT_BuildingsState::instance.buildings[buildingID].workers[0] != 0) { + if (DAT_GameState::instance.mapAndTime.monthTicks == owner) + DAT_BuildingsState::instance.buildings[buildingID].unknownTickRelatedValue = countdown - 1; + return 0; + } + if (countdown < 20) + return 0; + + MACRO_CALL_MEMBER(AIVState_Func::resetCountdownInHeatMap, DAT_AIVState::ptr)( + (short)DAT_BuildingsState::instance.buildings[buildingID].x, + (short)DAT_BuildingsState::instance.buildings[buildingID].y); + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::giveBackResourceForDestroyedBuilding, + DAT_BuildingsState::ptr)(buildingID, owner, 50); + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::destroyBuilding, DAT_BuildingsState::ptr)(buildingID); + return 1; + } +} +} diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp new file mode 100644 index 0000000000..2ec92a0c93 --- /dev/null +++ b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp @@ -0,0 +1,36 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D38C0 + BOOLEnum AICState::determineAIPlayerAttackRequestResponse(int playerID, undefined4 param_2, int requestedByPlayerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return FALSE; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + + if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue != 0) { + MACRO_CALL_MEMBER(AICState_Func::playWillNotAttack1BikFromPlayerToPlayer, this)( + playerID, requestedByPlayerID); + return FALSE; + } + + if (DAT_GameState::instance.playerDataArray[playerID].totalAttackTroops + - DAT_GameState::instance.playerDataArray[playerID].totalAttackingEngineerTroops + < this->aics[aicIndex].AttForceSupportAllyThreshold) { + MACRO_CALL_MEMBER(AICState_Func::playWillNotAttack2BikFromPlayerToPlayer, this)( + playerID, requestedByPlayerID); + return FALSE; + } + + MACRO_CALL_MEMBER(AICState_Func::playWillAttackBikFromPlayerToPlayer, this)(playerID, requestedByPlayerID); + return TRUE; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp new file mode 100644 index 0000000000..46df0cb275 --- /dev/null +++ b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp @@ -0,0 +1,35 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D3850 + BOOLEnum AICState::determineAIPlayerHelp(int playerID, int requestedByPlayerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return FALSE; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + + if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue != 0) { + MACRO_CALL_MEMBER(AICState_Func::playWillNotHelp1BikFromPlayerToPlayer, this)( + playerID, requestedByPlayerID); + return FALSE; + } + + if (DAT_GameState::instance.playerDataArray[playerID].totalAttackTroops + < this->aics[aicIndex].AttForceSupportAllyThreshold) { + MACRO_CALL_MEMBER(AICState_Func::playWillNotHelp2BikFromPlayerToPlayer, this)( + playerID, requestedByPlayerID); + return FALSE; + } + + MACRO_CALL_MEMBER(AICState_Func::playWillHelpBikFromPlayerToPlayer, this)(playerID, requestedByPlayerID); + return TRUE; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp b/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp new file mode 100644 index 0000000000..803bd3d6c1 --- /dev/null +++ b/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp @@ -0,0 +1,58 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE930 + void AICState::findAttackTribePositionAndPathToDefenses(int playerID) + { + int x = 0; + int y = 0; + for (int i = 0; i < 11; i++) { + int targetUnitID = 0; + int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) + continue; + + targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + x = DAT_UnitsState::instance.units[targetUnitID].x; + y = DAT_UnitsState::instance.units[targetUnitID].y; + break; + } + if (targetUnitID != 0) + break; + } + + DAT_GameState::instance.playerDataArray[playerID].someTile = 0; + if (x == 0) + return; + + int tile = MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::PathFindingState_Func::tracePathToFriendlyDefensesAndReturnTileUnk, + DAT_PathFindingState::ptr)(playerID, x, y); + if (tile <= 0) + return; + + int tileY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + DAT_GameState::instance.playerDataArray[playerID].someTile = tile; + DAT_GameState::instance.playerDataArray[playerID].someY = tileY; + DAT_GameState::instance.playerDataArray[playerID].someX + = tile - DAT_ViewportRenderState::instance.translationMatrix[tileY].addXgetTile; + } +} +} diff --git a/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp new file mode 100644 index 0000000000..dbc9260e1c --- /dev/null +++ b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp @@ -0,0 +1,55 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Game/GameMode.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC420 + void AICState::generateSiegeCreationInformation(int playerID, int buildingID, int unitID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + int i = 0; + if (DAT_GameSynchronyState::instance.currentGameMode == OpenSHC::Game::GM_SOLITARY) + return; + + int siegeIndex; + if (DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_TREBUCHET) + siegeIndex = 2; + else if (DAT_UnitsState::instance.units[unitID].unitType == OpenSHC::Map::Units::UT_S_FBALLISTA) + siegeIndex = 3; + else + return; + + int slot = DAT_SkirmishDefinedData::instance.SiegeEngineMetaInfoArray[siegeIndex].slot; + int locationCount = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[slot]; + while (i < locationCount) { + int index = i; + i++; + if (DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[slot][index] > 0 + && buildingID + == DAT_GameState::instance.playerDataArray[playerID] + .aiSiegeCreationInformation[siegeIndex][index] + .buildingID) { + DAT_GameState::instance.playerDataArray[playerID].aiSiegeCreationInformation[siegeIndex][index].unitID + = unitID; + DAT_GameState::instance.playerDataArray[playerID].aiSiegeCreationInformation[siegeIndex][index].uid + = DAT_UnitsState::instance.units[unitID].uid; + DAT_GameState::instance.playerDataArray[playerID] + .aiSiegeCreationInformation[siegeIndex][index] + .buildingID = 0; + return; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp index b76f6d0d08..de9383a306 100644 --- a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp +++ b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp @@ -1,5 +1,4 @@ -#include "../AICState.hpp" - +#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" @@ -9,14 +8,11 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB120 int AICState::getAIBuildInterval(int playerID) - { - int const aiType = DAT_GameState::ptr->playerDataArray[playerID].aiType; - if (aiType == AITA_NULL) { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) return 0; - } - - return this->aics[(aiType - 1)].buildInterval; + return this->aics[aiType - 1].buildInterval; } } } diff --git a/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp b/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp new file mode 100644 index 0000000000..c4ad3be311 --- /dev/null +++ b/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp @@ -0,0 +1,24 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Game/GameMode2.hpp" +#include "OpenSHC/Game/TrailType.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D12A0 + int AICState::getCurrentDesiredAttackRaidUnitCount(int aiType, int playerID) + { + if (DAT_GameCore::instance.gameMode_2 == Game::GM_SKIRMISH_AND_MULTIPLAYER + && DAT_GameCore::instance.isSkirmishTrail == TRUE + && DAT_GameCore::instance.currentTrailType == Game::TT_EXTREME) + return (DAT_GameState::instance.playerDataArray[playerID].currentAttackRaidParameter + + this->aics[aiType].RaidUnitsBase) + * 4 / 3; + return DAT_GameState::instance.playerDataArray[playerID].currentAttackRaidParameter + + this->aics[aiType].RaidUnitsBase; + } +} +} diff --git a/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp new file mode 100644 index 0000000000..5ab4f3163c --- /dev/null +++ b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB150 + int AICState::getResourceRebuildDelay(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) + return 0; + return this->aics[aiType - 1].resourceRebuildDelay; + } +} +} diff --git a/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp b/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp new file mode 100644 index 0000000000..09ce8c0d59 --- /dev/null +++ b/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp @@ -0,0 +1,49 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CCAF0 + int AICState::getSmallestPatrolTribe(int playerID, int tribeCount) + { + int i = 0; + int selectedTribeID = 0; + int selectedIndex = 0; + int lowestSize = 1000; + + for (;; i++) { + if (i >= tribeCount) { + if (selectedTribeID == 0) + return 0; + break; + } + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[170 + i]; + if (tribeID == 0 + || DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[i + 170]) { + selectedTribeID = MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); + selectedIndex = i; + break; + } + + if (DAT_TribesState::instance.tribes[tribeID].size < lowestSize) { + lowestSize = DAT_TribesState::instance.tribes[tribeID].size; + selectedTribeID = tribeID; + selectedIndex = i; + } + } + + DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[selectedIndex + 170] = selectedTribeID; + DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[selectedIndex + 170] + = DAT_TribesState::instance.tribes[selectedTribeID].uid; + return selectedTribeID; + } +} +} diff --git a/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp new file mode 100644 index 0000000000..83fa94d22d --- /dev/null +++ b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp @@ -0,0 +1,47 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDBC0 + int AICState::getTargetableBuildingForPlayerID(int playerID, int param_2) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == 0) + return 0; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + if (this->aics[aicIndex].OuterPatrolGroupsCount <= 0) + return 0; + if (DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker <= 0) + return 0; + + int step = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker + / this->aics[aicIndex].OuterPatrolGroupsCount; + DAT_GameState::instance.playerDataArray[playerID].someCounter2++; + if (DAT_GameState::instance.playerDataArray[playerID].someCounter2 + >= DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker) + DAT_GameState::instance.playerDataArray[playerID].someCounter2 = 0; + int index = (step * param_2 + DAT_GameState::instance.playerDataArray[playerID].someCounter2) + % DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; + for (int i = 0; i < DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; i++) { + int buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; + index++; + if (index >= DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker) + index = 0; + if (buildingID == 0) + continue; + + for (int j = 0; j < 8; j++) { + if (DAT_BuildingsState::instance.buildings[buildingID].buildingType + == DAT_SkirmishDefinedData::instance.BuildingTargetPrioritySet1[j]) + return buildingID; + } + } + return 0; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp b/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp new file mode 100644 index 0000000000..fd1ea735fc --- /dev/null +++ b/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp @@ -0,0 +1,58 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AIUnitBehaviourType.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC250 + UnitType AICState::getUnitTypeForUnitBehaviourType(int playerID, AIUnitBehaviourType unitBehaviourType) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) + return (UnitType)0; + int aicIndex = aiType - 1; + + if (unitBehaviourType == OpenSHC::AI::AIUBT_ENGINEERING) + return OpenSHC::Map::Units::UT_E_ENGINEER; + if (unitBehaviourType == OpenSHC::AI::AIUBT_DIGGING) + return (UnitType)this->aics[aicIndex].AttDiggingUnit; + if (unitBehaviourType == OpenSHC::AI::AIUBT_ASSASSINATION) + return OpenSHC::Map::Units::UT_A_ASSASSIN; + if (unitBehaviourType == OpenSHC::AI::AIUBT_ATTUNIT2) + return (UnitType)this->aics[aicIndex].AttUnit2; + if (unitBehaviourType == OpenSHC::AI::AIUBT_LADDERING) + return OpenSHC::Map::Units::UT_E_LADDER; + if (unitBehaviourType == OpenSHC::AI::AIUBT_TUNNELING) + return OpenSHC::Map::Units::UT_TUNNELER; + if (unitBehaviourType == OpenSHC::AI::AIUBT_PATROLLING) + return (UnitType)this->aics[aicIndex].AttUnitPatrol; + if (unitBehaviourType == OpenSHC::AI::AIUBT_BACKUPING) + return (UnitType)this->aics[aicIndex].AttUnitBackup; + if (unitBehaviourType == OpenSHC::AI::AIUBT_ENGAGING) + return (UnitType)this->aics[aicIndex].AttUnitEngage; + if (unitBehaviourType == OpenSHC::AI::AIUBT_SIEGEDEFENSE) + return (UnitType)this->aics[aicIndex].AttUnitSiegeDef; + if (unitBehaviourType == OpenSHC::AI::AIUBT_ATTUNITMAIN) { + if ((&this->aics[aicIndex] + .AttUnitMain1)[DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex] + == 0) + DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex = 0; + if (DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex >= 4) + DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex = 0; + + int choice = DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex; + UnitType unitType = (UnitType)(&this->aics[aicIndex].AttUnitMain1)[choice]; + DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex = choice + 1; + return unitType; + } + + return (UnitType)this->aics[aicIndex].AttUnitMain1; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp new file mode 100644 index 0000000000..1c29a67df2 --- /dev/null +++ b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp @@ -0,0 +1,60 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIVUnitType.hpp" +#include "OpenSHC/Map/Units/UnitType.hpp" +#include "OpenSHC/Map/Units/UnitTypeInt.hpp" +#include "OpenSHC/Map/Units/UnitTypeShort.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIVUnitType; + using OpenSHC::Map::Units::UnitTypeInt; + using OpenSHC::Map::Units::UnitTypeShort; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC390 + AIVUnitType AICState::getUnitTypeIndexForUnitID(int unitID, int param_2) + { + UnitTypeShort _unitType = DAT_UnitsState::instance.units[unitID].unitType; + int _playerID = DAT_UnitsState::instance.units[unitID].owner; + UnitTypeInt _unitType2; + if (_unitType == OpenSHC::Map::Units::UT_PEASANT) { + _unitType2 = DAT_UnitsState::instance.units[unitID].unitTypeToChangeInto; + } else { + _unitType2 = _unitType; + } + + // 6 is the Caliph's AIC index: he fields slaves rather than the ranged units listed below + if (DAT_GameState::instance.playerDataArray[_playerID].aiType - 1 != 6 && param_2 != 0 + && DAT_GameState::instance.playerDataArray[_playerID].aivUnitLocationSlotLocationCount[0xd] > 0) { + if (_unitType2 == OpenSHC::Map::Units::UT_E_ARCHER) { + return OpenSHC::AI::AIVUT_SLAVE; + } + if (_unitType2 == OpenSHC::Map::Units::UT_E_XBOW) { + return OpenSHC::AI::AIVUT_SLAVE; + } + if (_unitType2 == OpenSHC::Map::Units::UT_A_ARCHER) { + return OpenSHC::AI::AIVUT_SLAVE; + } + if (_unitType2 == OpenSHC::Map::Units::UT_A_SLINGER) { + return OpenSHC::AI::AIVUT_SLAVE; + } + if (_unitType2 == OpenSHC::Map::Units::UT_A_FIRETHROWER) { + return OpenSHC::AI::AIVUT_SLAVE; + } + } + + for (int someUnitTypeIndex = 0; someUnitTypeIndex < 0x14; someUnitTypeIndex++) { + if (DAT_SkirmishDefinedData::instance.SomeAIUnitTypeArray[someUnitTypeIndex] == _unitType2) { + return (AIVUnitType)someUnitTypeIndex; + } + } + return OpenSHC::AI::AIVUT_NONE; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp b/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp new file mode 100644 index 0000000000..5423d33399 --- /dev/null +++ b/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp @@ -0,0 +1,71 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CD8F0 + void AICState::giveMoveCommandToSortieUnits(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) + return; + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[167]; + int aicIndex = aiType - 1; + if (tribeID == 0) + return; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[167]) + return; + + if (DAT_TribesState::instance.tribes[tribeID].size + < DAT_GameState::instance.playerDataArray[playerID].totalTroopsType7 - 1) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::syncBehaviourType7UnitTribes, this)(playerID); + + int targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + bool sendToKeep = true; + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker <= 0) { + if (DAT_TribesState::instance.tribes[tribeID].size < this->aics[aicIndex].SortieUnitMeleeMin) { + sendToKeep = false; + } else { + int unitID = DAT_GameState::instance.playerDataArray[playerID].lastEncounteredTroopUnitID; + if (unitID != 0 + && DAT_GameState::instance.playerDataArray[playerID].lastEncounteredTroopUnitUID + == DAT_UnitsState::instance.units[unitID].uid + && MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func:: + calculateCanPlayerUnitsNavigateToAreaFromArea, + DAT_PathFindingState::ptr)(playerID, + (short)DAT_TileMapState::instance + .PathConnectionLayer[DAT_UnitsState::instance.units[targetUnitID].tile], + (short)DAT_TileMapState::instance + .PathConnectionLayer[DAT_UnitsState::instance.units[unitID].tile], + 0) + != 0) { + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::unsetRallyRelatedFlagOnUnits, + DAT_TribesState::ptr)(tribeID); + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, + DAT_TribesState::ptr)(tribeID, DAT_UnitsState::instance.units[unitID].x, + DAT_UnitsState::instance.units[unitID].y, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); + sendToKeep = false; + } + } + } + if (sendToKeep) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp b/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp new file mode 100644 index 0000000000..b009cbc8a7 --- /dev/null +++ b/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp @@ -0,0 +1,43 @@ +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CFFD0 + BOOLEnum AICState::hasNoTroopsOrAllAreDiggers(int playerID) + { + int totalTroops = DAT_GameState::instance.playerDataArray[playerID].totalAssassinTroops + + DAT_GameState::instance.playerDataArray[playerID].totalUnit2Troops + + DAT_GameState::instance.playerDataArray[playerID].totalUnitPatrolTroops; + int halfOfDiggingTroops = 0; + + if (DAT_GameState::instance.playerDataArray[playerID].aiPlayerState == 6) { + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalDiggingUnitTroops; + if (DAT_GameState::instance.playerDataArray[playerID].attackTicker > 16) + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitBackupTroops / 8; + else + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitBackupTroops; + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitEngageTroops + + DAT_GameState::instance.playerDataArray[playerID].totalUnitSiegeDefTroops + + DAT_GameState::instance.playerDataArray[playerID].totalMaxDefaultTroops; + } else { + halfOfDiggingTroops = DAT_GameState::instance.playerDataArray[playerID].totalDiggingUnitTroops / 2; + if (DAT_GameState::instance.playerDataArray[playerID].attackTicker > 12) + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitBackupTroops / 8; + else + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitBackupTroops; + totalTroops += DAT_GameState::instance.playerDataArray[playerID].totalUnitEngageTroops + + DAT_GameState::instance.playerDataArray[playerID].totalUnitSiegeDefTroops + + DAT_GameState::instance.playerDataArray[playerID].totalMaxDefaultTroops; + } + + if (totalTroops <= 1) + return TRUE; + if (totalTroops <= 4 && halfOfDiggingTroops > totalTroops * 2) + return TRUE; + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp b/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp new file mode 100644 index 0000000000..96e8e3c36a --- /dev/null +++ b/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp @@ -0,0 +1,30 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D00A0 + BOOLEnum AICState::hasNotEnoughSupplies(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].marketplace.id == 0 + && DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_WOOD] + < DAT_BuildingsState::instance.buildingCosts[Map::Buildings::BT_MARKETPLACE].requiredWood + && DAT_GameState::instance.playerDataArray[playerID].noLabourerBuildingCount < 1) + return TRUE; + if (DAT_GameState::instance.playerDataArray[playerID].granary.id == 0 + && DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_WOOD] + < DAT_BuildingsState::instance.buildingCosts[Map::Buildings::BT_GRANARY].requiredWood + && DAT_GameState::instance.playerDataArray[playerID].noLabourerBuildingCount <= 1) + return TRUE; + if (DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] <= 0 + && DAT_GameState::instance.playerDataArray[playerID].popularity <= 25 + && DAT_GameState::instance.playerDataArray[playerID].totalFood <= 0) + return TRUE; + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp b/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp new file mode 100644 index 0000000000..95b2d1aeb0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp @@ -0,0 +1,22 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2830 + void AICState::ifHasTribe0SendUnitsToKeep(int playerID) + { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0]; + if (tribeID <= 0) + return; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0]) + return; + + MACRO_CALL_MEMBER(AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp b/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp new file mode 100644 index 0000000000..f7d69ad605 --- /dev/null +++ b/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp @@ -0,0 +1,60 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CD7B0 + void AICState::instructTribe166ToMove(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) + return; + int aicIndex = aiType - 1; + + if (DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 > 0) + DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01--; + if (DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 > 50) + DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 = 50; + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[166]; + BOOLEnum keepEnclosed = MACRO_CALL_MEMBER( + OpenSHC::Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID); + if (tribeID == 0) + return; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[166]) + return; + + if (DAT_TribesState::instance.tribes[tribeID].size + < DAT_GameState::instance.playerDataArray[playerID].totalTroopsType6 - 5) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addUnitsToTribe166, this)(playerID); + + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker > 0 && keepEnclosed == FALSE) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } else if (DAT_TribesState::instance.tribes[tribeID].size >= this->aics[aicIndex].SortieUnitRangedMin) { + if (DAT_GameState::instance.playerDataArray[playerID].someXPosition <= 0 + || DAT_GameState::instance.playerDataArray[playerID].someYPosition <= 0) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } else { + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::unsetRallyRelatedFlagOnUnits, DAT_TribesState::ptr)(tribeID); + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, + DAT_TribesState::ptr)(tribeID, DAT_GameState::instance.playerDataArray[playerID].someXPosition, + DAT_GameState::instance.playerDataArray[playerID].someYPosition, 0, 0, + OpenSHC::Map::Units::Instructions::UMSE_0); + } + } + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp b/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp new file mode 100644 index 0000000000..d4224026c0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp @@ -0,0 +1,25 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0520 + BOOLEnum AICState::isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade( + int playerID, ResourceType resourceType, int buffer) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) + return TRUE; + if (resourceType == Game::Resources::RT_GOLD) + return FALSE; + if (DAT_GameState::instance.playerDataArray[playerID].currentResources[resourceType] + < this->aics[DAT_GameState::instance.playerDataArray[playerID].aiType - 1].minimumGoodsRequiredAfterTrade + + buffer) + return FALSE; + return TRUE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp b/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp new file mode 100644 index 0000000000..243d4828c6 --- /dev/null +++ b/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp @@ -0,0 +1,22 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D3960 + void AICState::makeOutpostTribesAttack() + { + for (int i = 0; i < 1000; i++) { + int tribeID = this->tribeIDArray[i]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid != this->tribeUIDArray[i]) + continue; + + MACRO_CALL_MEMBER(AICState_Func::decideOnTribeAttackLocation, this)(tribeID); + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp b/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp new file mode 100644 index 0000000000..d4f23d1641 --- /dev/null +++ b/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp @@ -0,0 +1,47 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CEA50 + void AICState::makeUnitsGoDefensiveAndBackToSomeLocation(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + if (DAT_GameState::instance.playerDataArray[playerID].someTile == 0) + return; + + for (int i = 0; i < 11; i++) { + int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) + continue; + + int x = DAT_GameState::instance.playerDataArray[playerID].someX; + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; + int y = DAT_GameState::instance.playerDataArray[playerID].someY; + uint result = MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, + DAT_TribesState::ptr)(tribeID, x, y, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); + if (result == 0) + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::removeAllTribeUnits, DAT_TribesState::ptr)( + tribeID); + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp b/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp new file mode 100644 index 0000000000..41ac2d5150 --- /dev/null +++ b/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp @@ -0,0 +1,19 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_AIVState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004ECAB0 + BOOLEnum AICState::mapperIsWoodCuttersHutWhileNoWoodAvailable( + undefined4 playerID, Commands::MappersEnum commandBuildingType) + { + if (commandBuildingType == Commands::M_MAPPER_WOODSMAN + && DAT_AIVState::instance.mapExtraInfo.totalWoodAvailable <= 0) + return TRUE; + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp b/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp new file mode 100644 index 0000000000..ee8e3ad579 --- /dev/null +++ b/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp @@ -0,0 +1,47 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE830 + void AICState::moveAttackTribesToLocations(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + + int destIndex = 0; + for (int i = 0; i < 11; i++) { + int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) + continue; + + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)(tribeID, + DAT_GameState::instance.mapAndTime.aiTribeMoveDestinationXYPairArray1[playerID * 5][destIndex] + .xOffset, + DAT_GameState::instance.mapAndTime.aiTribeMoveDestinationXYPairArray1[playerID * 5][destIndex] + .yOffset, + 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); + destIndex++; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp b/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp new file mode 100644 index 0000000000..04aa9c19d7 --- /dev/null +++ b/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp @@ -0,0 +1,71 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/DirectionAlgorithmState.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_DirectionAlgorithmState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2F80 + void AICState::moveAttackingUnitsToNextRallyPoint(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + + for (int i = 0; i < 2; i++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[190 + i]; + if (tribeID == 0) + continue; + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[i + 190]) + continue; + + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + if (MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::allUnitsReachedTheirDestination, + DAT_TribesState::ptr)(tribeID) + == FALSE) + continue; + + DAT_TribesState::instance.tribes[tribeID].unknownAttackRelatedUpdateCounter = 0; + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addRallyPointForTribe, this)(tribeID); + + short rallyPointCount = DAT_TribesState::instance.tribes[tribeID].rallyPointCount; + int rallyPointIndex = DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex + 1; + if (rallyPointIndex >= rallyPointCount) + rallyPointIndex = 0; + + int x = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][0]; + int y = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][1]; + int targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = rallyPointIndex; + + if (rallyPointCount <= 0) + continue; + + if (rallyPointCount <= 1) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::DirectionAlgorithmState_Func::setAxisBasedDistanceResult, + DAT_DirectionAlgorithmState::ptr)(DAT_UnitsState::instance.units[targetUnitID].x, + DAT_UnitsState::instance.units[targetUnitID].y, x, y); + if (DAT_DirectionAlgorithmState::instance.distanceHigh <= 5) + continue; + } else { + if (DAT_UnitsState::instance.units[targetUnitID].closestEnemyMicroDistance <= 96) + continue; + } + + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( + tribeID, x, y, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp b/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp new file mode 100644 index 0000000000..a7af36538b --- /dev/null +++ b/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp @@ -0,0 +1,59 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CED90 + BOOLEnum AICState::percentageNonMovingTribesGTEAICSpecified(int playerID) + { + AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) { + return FALSE; + } + + int aicIndex = aiType - 1; + int tribeTotal = 0; + int notReallyMoving = 0; + + for (int i = 0; i < 11; i++) { + int tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex + j]) { + continue; + } + + tribeTotal++; + if (DAT_TribesState::instance.tribes[tribeID].percentageMovingUnk < 20) { + notReallyMoving++; + } + } + } + + if (tribeTotal <= 0) { + return FALSE; + } + + return notReallyMoving * 100 / tribeTotal >= this->aics[aicIndex].AttMovingTribesThreshold; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp new file mode 100644 index 0000000000..c2f18af591 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp @@ -0,0 +1,41 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" +#include "OpenSHC/Globals/INT_ARRAY_00eb0af0.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0830 + void AICState::playAnger1BikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + if (DAT_GameState::instance.mapAndTime.playerTeams[playerID] + == DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID + != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + DWORD now = timeGetTime(); + if (INT_ARRAY_00eb0af0::instance[playerID] != 0 && now - INT_ARRAY_00eb0af0::instance[playerID] < 600000) { + return; + } + + INT_ARRAY_00eb0af0::instance[playerID] = now; + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, aicIndex, 5); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..df0b308ad6 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp @@ -0,0 +1,36 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0C00 + void AICState::playAnger2BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown3 != 0) { + return; + } + + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown3 = 96; + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 6); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp new file mode 100644 index 0000000000..64249dc9ce --- /dev/null +++ b/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp @@ -0,0 +1,23 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0FC0 + void AICState::playFriendlyVictoryBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 10); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp new file mode 100644 index 0000000000..ca55ee528e --- /dev/null +++ b/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp @@ -0,0 +1,23 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0B70 + void AICState::playGoodsNotSentBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 28); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..acb064856d --- /dev/null +++ b/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp @@ -0,0 +1,32 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0A20 + void AICState::playGoodsRequestBikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + if (DAT_GameState::instance.playerDataArray[DAT_GameSynchronyState::instance.currentPlayerSlotID] + .lordKilledByPlayerID + != 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 14); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..7b807ddfc0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0BB0 + void AICState::playGoodsSentBikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 29); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp b/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp new file mode 100644 index 0000000000..639186e16a --- /dev/null +++ b/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp @@ -0,0 +1,22 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0F90 + void AICState::playJokeBikFromAIToHuman(int playerID, int aiType) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, aiType, 20); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp new file mode 100644 index 0000000000..0bdd24ea65 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0CF0 + void AICState::playNervous1BikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown5 != 0) { + return; + } + + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown5 = 48; + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 8); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp new file mode 100644 index 0000000000..07b38053e9 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp @@ -0,0 +1,23 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D1050 + void AICState::playNoHelpBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 31); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp b/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp new file mode 100644 index 0000000000..a652216ca2 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp @@ -0,0 +1,73 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D08B0 + void AICState::playPlayerKilledBiksFromKilledAndKillerPlayer(int killerPlayerID, int killedPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(killerPlayerID) + == 0) { + return; + } + + if (killedPlayerID == DAT_GameSynchronyState::instance.currentPlayerSlotID) { + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killerPlayerID, DAT_GameState::instance.playerDataArray[killerPlayerID].aiType - 1, 12); + return; + } + + if (killerPlayerID == DAT_GameSynchronyState::instance.currentPlayerSlotID) { + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killedPlayerID, DAT_GameState::instance.playerDataArray[killedPlayerID].aiType - 1, 7); + + for (int i = 1; i < 9; i++) { + if (DAT_GameState::instance.playerDataArray[i].aiType == AITA_NULL) { + continue; + } + if (DAT_GameState::instance.mapAndTime.playerTeams[i] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + continue; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(i) + == 0) { + continue; + } + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + i, DAT_GameState::instance.playerDataArray[i].aiType - 1, 17); + } + return; + } + + if (DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID] + == DAT_GameState::instance.mapAndTime.playerTeams[killedPlayerID]) { + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killedPlayerID, DAT_GameState::instance.playerDataArray[killedPlayerID].aiType - 1, 16); + return; + } + + if (DAT_GameState::instance.mapAndTime.playerTeams[killerPlayerID] + == DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killedPlayerID, DAT_GameState::instance.playerDataArray[killedPlayerID].aiType - 1, 7); + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killerPlayerID, DAT_GameState::instance.playerDataArray[killerPlayerID].aiType - 1, 18); + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killedPlayerID, DAT_GameState::instance.playerDataArray[killedPlayerID].aiType - 1, 7); + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + killerPlayerID, DAT_GameState::instance.playerDataArray[killerPlayerID].aiType - 1, 13); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp new file mode 100644 index 0000000000..5f1cee729f --- /dev/null +++ b/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp @@ -0,0 +1,39 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0D40 + void AICState::playRequestHelpBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown6 != 0) { + return; + } + + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown6 = 48; + + if (DAT_GameState::instance.mapAndTime.playerTeams[playerID] + != DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + return; + } + if (DAT_GameState::instance.playerDataArray[DAT_GameSynchronyState::instance.currentPlayerSlotID] + .lordKilledByPlayerID + != 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 19); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp new file mode 100644 index 0000000000..f498395747 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp @@ -0,0 +1,41 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D07C0 + void AICState::playTauntToAttackedPlayerBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + int bik = 0; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + if (DAT_GameState::instance.mapAndTime.playerTeams[playerID] + == DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + bik = 23; + } + + if (DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID + != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + if (bik == 0) { + bik = (SEC_RNG::instance.currentNumber2 & 3) + 1; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, aicIndex, bik); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp new file mode 100644 index 0000000000..4295184961 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp @@ -0,0 +1,29 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D1000 + void AICState::playTeamWinningBikFromPlayer(int playerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].aiBuildingDestroyChoiceTracker != 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker != 0) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 30); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..823e435e96 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp @@ -0,0 +1,43 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" +#include "OpenSHC/Globals/DWORD_00eb0b18.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0A80 + void AICState::playThanksBikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + DAT_GameState::instance.playerDataArray[playerID].aiRequestDelay = this->aics[aicIndex].aiRequestDelay; + + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + if (DAT_GameState::instance.playerDataArray[DAT_GameSynchronyState::instance.currentPlayerSlotID] + .lordKilledByPlayerID + != 0) { + return; + } + + DWORD now = timeGetTime(); + if (DWORD_00eb0b18::instance != 0 && now - DWORD_00eb0b18::instance < 1200000) { + return; + } + + DWORD_00eb0b18::instance = now; + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, aicIndex, 15); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..0d11e93d4d --- /dev/null +++ b/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp @@ -0,0 +1,43 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0C70 + void AICState::playVictory2BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (DAT_GameState::instance.playerDataArray[targetPlayerID].aiType == AITA_NULL) { + return; + } + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[playerID] == -1) { + return; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(targetPlayerID) + == 0) { + return; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[targetPlayerID].someAiCountdown4 != 0) { + return; + } + + DAT_GameState::instance.playerDataArray[targetPlayerID].someAiCountdown4 = 48; + if (playerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + targetPlayerID, DAT_GameState::instance.playerDataArray[targetPlayerID].aiType - 1, 11); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..6898bcfdf9 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0F40 + void AICState::playWillAttackBikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x21); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..1cca496c95 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0E50 + void AICState::playWillHelpBikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x20); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..a89b2faeb8 --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0EA0 + void AICState::playWillNotAttack1BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x18); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..7de2373fdc --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0EF0 + void AICState::playWillNotAttack2BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x19); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..5c7ab00f7f --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0DB0 + void AICState::playWillNotHelp1BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x1a); + } +} +} diff --git a/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp new file mode 100644 index 0000000000..164826d3fd --- /dev/null +++ b/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp @@ -0,0 +1,27 @@ +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" +#include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0E00 + void AICState::playWillNotHelp2BikFromPlayerToPlayer(int playerID, int targetPlayerID) + { + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + return; + } + if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { + return; + } + + MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].aiType - 1, 0x1b); + } +} +} diff --git a/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp b/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp new file mode 100644 index 0000000000..302c38a63f --- /dev/null +++ b/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp @@ -0,0 +1,68 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" +#include "OpenSHC/AI/Tribes/AITribeIndex.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + using OpenSHC::Map::Units::Behavior::UnitStanceEnum; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CEEA0 + BOOLEnum AICState::processAttForceRallyPercentage(int playerID) + { + AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) { + return FALSE; + } + + int aicIndex = aiType - 1; + int tribeTotal = 0; + int notReallyMoving = 0; + + for (int i = 0; i < 11; i++) { + int tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + if (tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_BASIC_07_01 + || tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_10_01 + || tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_BASIC_05_01) { + continue; + } + + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex + j]) { + continue; + } + + tribeTotal++; + if (DAT_TribesState::instance.tribes[tribeID].percentageMovingUnk < 20) { + notReallyMoving++; + } + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_STAND_GROUND; + } + } + + if (tribeTotal <= 0) { + return FALSE; + } + + return (BOOLEnum)(notReallyMoving * 100 / tribeTotal >= this->aics[aicIndex].AttForceRallyPercentage); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp b/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp new file mode 100644 index 0000000000..4b0108c3d5 --- /dev/null +++ b/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp @@ -0,0 +1,138 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Random/RNG.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" +#include "OpenSHC/AI/AIUnitBehaviourType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + using OpenSHC::AI::AIUnitBehaviourType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC070 + AIUnitBehaviourType AICState::randomlySelectAttackUnitTypeToRecruit(int playerID) + { + AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) { + return OpenSHC::AI::AIUBT_ATTUNITMAIN; + } + + int attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; + int aicIndex = aiType - 1; + int requiredCount = 0; + + // clear out flags + for (int i = 0; i < 11; i++) { + DAT_SkirmishDefinedData::instance.attackUnitRequired[i].required = 0; + } + + int engineersCount = DAT_GameState::instance.playerDataArray[playerID].currentAttackWave * 4; + if (engineersCount > (int)this->aics[aicIndex].AttMaxEngineers) { + engineersCount = this->aics[aicIndex].AttMaxEngineers; + } + if (this->aics[aicIndex].AttMaxEngineers != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalAttackingEngineerTroops < engineersCount) { + requiredCount = 1; + DAT_SkirmishDefinedData::instance.attackUnitRequired[0].required = 1; + } + + if (this->aics[aicIndex].AttDiggingUnitMax != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalDiggingUnitTroops + < (int)this->aics[aicIndex].AttDiggingUnitMax + && DAT_GameState::instance.playerDataArray[attackedPlayerID].moatsOwned > 5) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[1].required = 1; + } + + if (this->aics[aicIndex].AttMaxAssassins != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalAssassinTroops + < (int)this->aics[aicIndex].AttMaxAssassins) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[2].required = 1; + } + + if (this->aics[aicIndex].AttUnit2Max != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalUnit2Troops + < (int)this->aics[aicIndex].AttUnit2Max) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[3].required = 1; + } + + if (this->aics[aicIndex].AttMaxLaddermen != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalLaddermenTroops + < (int)this->aics[aicIndex].AttMaxLaddermen) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[4].required = 1; + } + + if (this->aics[aicIndex].AttMaxTunnelers != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalTunnelerTroops + < (int)this->aics[aicIndex].AttMaxTunnelers) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[5].required = 1; + } + + if (this->aics[aicIndex].AttUnitPatrolMax != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalUnitPatrolTroops + < (int)this->aics[aicIndex].AttUnitPatrolMax) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[6].required = 1; + } + + if (this->aics[aicIndex].AttUnitBackupMax != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalUnitBackupTroops + < (int)this->aics[aicIndex].AttUnitBackupMax) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[7].required = 1; + } + + if (this->aics[aicIndex].AttUnitEngageMax != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalUnitEngageTroops + < (int)this->aics[aicIndex].AttUnitEngageMax) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[8].required = 1; + } + + if (this->aics[aicIndex].AttUnitSiegeDefMax != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalUnitSiegeDefTroops + < (int)this->aics[aicIndex].AttUnitSiegeDefMax) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[9].required = 1; + } + + if (this->aics[aicIndex].AttMaxDefault != 0 + && DAT_GameState::instance.playerDataArray[playerID].totalMaxDefaultTroops + < (int)this->aics[aicIndex].AttMaxDefault) { + requiredCount++; + DAT_SkirmishDefinedData::instance.attackUnitRequired[10].required = 1; + } + + if (requiredCount <= 0) { + return OpenSHC::AI::AIUBT_ATTUNITMAIN; + } + + int selection = (int)SEC_RNG::instance.currentNumber2 % requiredCount; + MACRO_CALL_MEMBER(OpenSHC::Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); + + for (int i = 0; i < 11; i++) { + if (DAT_SkirmishDefinedData::instance.attackUnitRequired[i].required == 0) { + continue; + } + if (selection == 0) { + return (AIUnitBehaviourType)DAT_SkirmishDefinedData::instance.attackUnitRequired[i].unitBehaviourType; + } + selection--; + } + + return OpenSHC::AI::AIUBT_ATTUNITMAIN; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp new file mode 100644 index 0000000000..5fae78c3f3 --- /dev/null +++ b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp @@ -0,0 +1,59 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/IO/LowLevelMemory.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE040 + void AICState::recomputeAIPathCostToAttackedKeep(int playerID, int useBorderDistance) + { + int attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; + int keepArea = (short)DAT_TileMapState::instance + .PathConnectionLayer[DAT_GameState::instance.playerDataArray[playerID].campground.tileEntry]; + + int borderDistance; + if (DAT_GameState::instance.playerDataArray[attackedPlayerID].unknownPathBorderDistanceRelated > 120) { + borderDistance = 98; + } else { + borderDistance + = DAT_GameState::instance.playerDataArray[attackedPlayerID].unknownPathBorderDistanceRelated > 90 ? 70 + : 50; + } + if (useBorderDistance == 0) { + borderDistance = 0; + } + + DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].currentPlayerID_OR_attackedPlayerID_OR_one + = attackedPlayerID; + + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 80400, '\0', DAT_TileMapState::instance.AIZoneLayer); + + if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::canNavigateFromKeepToKeep, DAT_GameState::ptr)( + playerID, DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID) + != FALSE) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::computeAIZoneLayer, + DAT_PathFindingState::ptr)(DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID, 1, 1); + } else { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::computeAIZoneLayer, + DAT_PathFindingState::ptr)(DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID, 0, 1); + } + + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::updateWalkLayerAndAIPathCostLayer, + DAT_PathFindingState::ptr)(110, borderDistance, keepArea, playerID); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/recomputeAIZonerLayer.cpp b/src/OpenSHC/AI/AICState/recomputeAIZonerLayer.cpp new file mode 100644 index 0000000000..2478afb942 --- /dev/null +++ b/src/OpenSHC/AI/AICState/recomputeAIZonerLayer.cpp @@ -0,0 +1,31 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE1A0 + void AICState::recomputeAIZonerLayer() + { + DAT_TroopValueState::instance.attackInfo.playerInfo[0].currentPlayerID_OR_attackedPlayerID_OR_one = 1; + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 80400, '\0', DAT_TileMapState::instance.AIZoneLayer); + MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::PathFindingState_Func::computeAIZoneLayer, DAT_PathFindingState::ptr)(1, 2, 1); + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::updateWalkLayerAndAIPathCostLayer, + DAT_PathFindingState::ptr)(252, 0, 1, 1); + DAT_GameState::instance.playerDataArray[1].unknownPathBorderDistanceRelated + = DAT_PathFindingState::instance.distance; + DAT_TroopValueState::instance.attackInfo.playerInfo[0].currentPlayerID_OR_attackedPlayerID_OR_one = 1; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/recomputeAttackAIZone.cpp b/src/OpenSHC/AI/AICState/recomputeAttackAIZone.cpp new file mode 100644 index 0000000000..905549bece --- /dev/null +++ b/src/OpenSHC/AI/AICState/recomputeAttackAIZone.cpp @@ -0,0 +1,48 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/Map/AttackInfoSubElement.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::Map::AttackInfoSubElement; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE110 + void AICState::recomputeAttackAIZone() + { + for (int playerID = 1; playerID < 9; playerID++) { + int fullID = DAT_GameSynchronyState::instance.currentPlayerFullIDArray[playerID]; + DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].currentPlayerID_OR_attackedPlayerID_OR_one + = playerID; + if (fullID == -1 + && DAT_GameSynchronyState::instance.currentAIArray[playerID] == 0 + // fixme: this comparison looks dumb since fullID is already known to be the value, so a cmp eax eax + // is generated, but we need it for the 100% match. + && fullID == DAT_GameSynchronyState::instance.currentPlayerFullIDArray[playerID]) { + continue; + } + + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 80400, '\0', DAT_TileMapState::instance.AIZoneLayer); + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::computeAIZoneLayer, + DAT_PathFindingState::ptr)(playerID, 2, 1); + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::updateWalkLayerAndAIPathCostLayer, + DAT_PathFindingState::ptr)(252, 0, 1, playerID); + DAT_GameState::instance.playerDataArray[playerID].unknownPathBorderDistanceRelated + = DAT_PathFindingState::instance.distance; + DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].currentPlayerID_OR_attackedPlayerID_OR_one + = 1; + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp new file mode 100644 index 0000000000..ea0aff1d74 --- /dev/null +++ b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp @@ -0,0 +1,25 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D4630 + void AICState::recreateEngineersTribe(int playerID) + { + if (0 >= DAT_GameState::instance.playerDataArray[playerID].totalAttackingEngineerTroops) { + return; + } + int _tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + if (_tribeID != 0) { + if (DAT_TribesState::instance.tribes[_tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0x12]) { + DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12] = 0; + } + } + MACRO_CALL_MEMBER(AICState_Func::addEngineersToTribe, this)(playerID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp b/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp new file mode 100644 index 0000000000..8d50e0976c --- /dev/null +++ b/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp @@ -0,0 +1,49 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/LandscapeState.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_LandscapeState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE430 + void AICState::removeOrganismsAndSetMoveDestinationPairs(int playerID) + { + // Clear a tree standing on the target tile + int organismID + = (short)DAT_TileMapState::instance.OrganismLayer + [DAT_ViewportRenderState::instance + .translationMatrix[DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY] + .addXgetTile + + DAT_GameState::instance.playerDataArray[playerID].shortestDistanceX]; + if (organismID != 0) { + MACRO_CALL_MEMBER(OpenSHC::Map::LandscapeState_Func::removeTree, DAT_LandscapeState::ptr)(organismID); + } + + // Hardcoded exception: the Sultan keeps a smaller distance than all other AIs + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int extraDistance = aicIndex == OpenSHC::AI::AIT_SULTAN - 1 ? 8 : 20; + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findLinkageBasedPathOrWalkRadius, + DAT_PathFindingState::ptr)(DAT_GameState::instance.playerDataArray[playerID].shortestDistanceX, + DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY, -1, -1, 10000, FALSE); + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::setMoveDestinationPairs, + DAT_PathFindingState::ptr)(playerID - 1, DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID, + DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].someMinimumDistance + extraDistance); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/requestGoods.cpp b/src/OpenSHC/AI/AICState/requestGoods.cpp new file mode 100644 index 0000000000..2c10772ed7 --- /dev/null +++ b/src/OpenSHC/AI/AICState/requestGoods.cpp @@ -0,0 +1,70 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::Game::Resources::ResourceType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D1F00 + void AICState::requestGoods(int playerID, ResourceType resourceType, int amount) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].aiRequestDelay != 0) { + return; + } + // Never request raw farm goods or ale + if (resourceType == OpenSHC::Game::Resources::RT_WHEAT || resourceType == OpenSHC::Game::Resources::RT_HOPS + || resourceType == OpenSHC::Game::Resources::RT_ALE) { + return; + } + // Only request food when almost out of it + if ((resourceType == OpenSHC::Game::Resources::RT_BREAD || resourceType == OpenSHC::Game::Resources::RT_CHEESE + || resourceType == OpenSHC::Game::Resources::RT_MEAT + || resourceType == OpenSHC::Game::Resources::RT_APPLE) + && DAT_GameState::instance.playerDataArray[playerID].totalFood >= 5) { + return; + } + // fixme: NOTE: the original performs the exact same food check a second time, it cannot be removed + if ((resourceType == OpenSHC::Game::Resources::RT_BREAD || resourceType == OpenSHC::Game::Resources::RT_CHEESE + || resourceType == OpenSHC::Game::Resources::RT_MEAT + || resourceType == OpenSHC::Game::Resources::RT_APPLE) + && DAT_GameState::instance.playerDataArray[playerID].totalFood >= 5) { + return; + } + + // Ask every human teammate that has no pending request from this player + for (int i = 1; i < 9; i++) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[i] == -1) { + continue; + } + if (DAT_GameState::instance.mapAndTime.playerTeams[i] + != DAT_GameState::instance.mapAndTime.playerTeams[playerID]) { + continue; + } + if (MACRO_CALL_MEMBER(OpenSHC::Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(i) + == 0) { + continue; + } + if (DAT_GameState::instance.playerDataArray[i].requestedGoodsArray1Unk[playerID] != 0) { + continue; + } + + DAT_GameState::instance.playerDataArray[i].requestedGoodsArray1Unk[playerID] = resourceType; + DAT_GameState::instance.playerDataArray[i].requestedGoodsArray2Unk[playerID] = amount; + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::playGoodsRequestBikFromPlayerToPlayer, this)(playerID, i); + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp b/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp new file mode 100644 index 0000000000..11008c4533 --- /dev/null +++ b/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp @@ -0,0 +1,35 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDAB0 + int AICState::selectBuildingFromAListOfBuildingTypes(int playerID) + { + // Pick the targetable building whose type comes first in BuildingTargetPrioritySet1 + int selectedBuildingID = 0; + int bestPriority = 46; + for (int i = 0; i < DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; i++) { + int buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[i]; + if (buildingID == 0) { + continue; + } + for (int j = 0; j < bestPriority; j++) { + if ((short)DAT_BuildingsState::instance.buildings[buildingID].buildingType + == DAT_SkirmishDefinedData::instance.BuildingTargetPrioritySet1[j]) { + // Found a better match; lowering the bound also ends this loop + bestPriority = j; + selectedBuildingID = buildingID; + } + } + } + + return selectedBuildingID; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp new file mode 100644 index 0000000000..c5845f0bb8 --- /dev/null +++ b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp @@ -0,0 +1,25 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Random/RNG.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDCA0 + int AICState::selectRandomBuildingIDFromListOfBuildingTypes(int playerID, undefined4 param_2) + { + int count = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; + if (count <= 0) { + return 0; + } + + int index = SEC_RNG::instance.currentNumber2 % count; + MACRO_CALL_MEMBER(OpenSHC::Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); + return DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/sellGoods.cpp b/src/OpenSHC/AI/AICState/sellGoods.cpp index 5ebd21d63c..c830f93eac 100644 --- a/src/OpenSHC/AI/AICState/sellGoods.cpp +++ b/src/OpenSHC/AI/AICState/sellGoods.cpp @@ -23,6 +23,5 @@ namespace AI { MACRO_CALL_MEMBER(Game::GameStateStructures_Func::displayPlayerTradeVisualEffect, DAT_GameState::ptr)( playerID, 1, -amount, resourceType); } - } } diff --git a/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp new file mode 100644 index 0000000000..ccea764295 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp @@ -0,0 +1,39 @@ +#include "OpenSHC/Map/Units/TroopValueState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF4F0 + void AICState::sendAITribe_0xf_toAttackPatrol(int playerID) + { + int tribeIndex = 15; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + // Bug: only tribe 15 is sent, although tribe 16 can also exist if 'AIC: AttUnitPatrolGroupsCount' is 2 + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + return; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_DEFENSIVE; + MACRO_CALL_MEMBER(Map::Units::TroopValueState_Func::sendAttackingPatrolTribeToComputedDestination, + DAT_TroopValueState::ptr)(tribeID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp new file mode 100644 index 0000000000..abe6c64a13 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp @@ -0,0 +1,64 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/AI/AIVUnitType.hpp" +#include "OpenSHC/AI/AIVUnitTypeInt.hpp" +#include "OpenSHC/AI/Tribes/AIVUnitTypeMaxLocationPair.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIVUnitType; + using OpenSHC::AI::AIVUnitTypeInt; + using OpenSHC::AI::Tribes::AIVUnitTypeMaxLocationPair; + using OpenSHC::Map::Units::Behavior::UnitStanceEnum; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D4220 + void AICState::sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed(int playerID) + { + BOOLEnum enclosed = MACRO_CALL_MEMBER( + OpenSHC::Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID); + + for (int i = 0; i < 6; i++) { + int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount + [DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].aivUnitType]; + for (int j = 0; j < count; j++) { + int tribeID + = DAT_GameState::instance.playerDataArray[playerID] + .aiTribeIDs[DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].tribeArrayOffset + + j]; + if (tribeID != 0 + && DAT_TribesState::instance.tribes[tribeID].uid + == DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs + [DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].tribeArrayOffset + j]) { + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker <= 0 + || enclosed != FALSE) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendTribeToAIVLocationSlot, this)(tribeID, + (AIVUnitType)DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].aivUnitType, + j); + } else { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } + } + + // NOTE: the original sets the stance even when the tribe is invalid (tribeID may be 0) + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker <= 0 + || enclosed != FALSE) { + DAT_TribesState::instance.tribes[tribeID].unitStance + = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + } else { + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; + } + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp b/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp new file mode 100644 index 0000000000..5fc7b54b3c --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp @@ -0,0 +1,62 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/AI/AIVUnitType.hpp" +#include "OpenSHC/Map/Units/UnitInstructionType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIVUnitType; + using OpenSHC::Map::Units::UnitInstructionType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D44E0 + void AICState::sendOilMenForOilPickupOrToAIVLocations(int playerID) + { + int oilSmelterID = DAT_GameState::instance.playerDataArray[playerID].oilSmelter.id; + int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[1]; + if (count < 1) { + return; + } + if (count == 10) { + count = 9; + } + + // Oil men tribes start at offset 71 in the tribe ID array + for (int i = 1; i <= count; i++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[70 + i]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[70 + i]) { + continue; + } + + if (DAT_UnitsState::instance.units[DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID] + .resourceToDeposit + != 0) { + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::unsetRallyRelatedFlagOnUnits, DAT_TribesState::ptr)(tribeID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendTribeToAIVLocationSlot, this)( + tribeID, OpenSHC::AI::AIVUT_ENGINEER, i - 1); + continue; + } + + // Send for oil duty + if (oilSmelterID != 0) { + MACRO_CALL_MEMBER(OpenSHC::Map::Units::UnitsState_Func::relayTribeInstruction, DAT_UnitsState::ptr)( + tribeID, OpenSHC::Map::Units::UIT_CONSTRUCT_SIEGE_EQUIPMENTOIL_DUTYENGINEERRELATED, oilSmelterID, + DAT_BuildingsState::instance.buildings[oilSmelterID].uid, 0); + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp new file mode 100644 index 0000000000..0110e7fed0 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp @@ -0,0 +1,58 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIVUnitType.hpp" +#include "OpenSHC/AI/AIVUnitTypeInt.hpp" +#include "OpenSHC/AI/Tribes/AIVUnitTypeMaxLocationPair.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIVUnitType; + using OpenSHC::AI::AIVUnitTypeInt; + using OpenSHC::AI::Tribes::AIVUnitTypeMaxLocationPair; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D4130 + void AICState::sendRangedUnitTribesToAIVSlotsOrKeepIfNervous(int playerID) + { + for (int i = 0; i < 5; i++) { + int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount + [DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].aivUnitType]; + for (int j = 0; j < count; j++) { + int tribeID + = DAT_GameState::instance.playerDataArray[playerID] + .aiTribeIDs[DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].tribeArrayOffset + + j]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID] + .aiTribeUIDs[DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].tribeArrayOffset + + j]) { + continue; + } + + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker > 0) { + if ((DAT_TileMapState::instance.LogicLayer[DAT_UnitsState::instance + .units[DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID] + .tile] + & 0x10000100U) + == 0) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); + } + } else { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendTribeToAIVLocationSlot, this)(tribeID, + (AIVUnitType)DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].aivUnitType, j); + } + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp new file mode 100644 index 0000000000..272c3b113d --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp @@ -0,0 +1,21 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2870 + void AICState::sendTribeAtOffset1ToCampfire(int playerID) + { + int _tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[1]; + if (_tribeID <= 0) + return; + if (DAT_TribesState::instance.tribes[_tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[1]) + return; + MACRO_CALL_MEMBER(AICState_Func::sendUnitsToCampfire, this)(_tribeID, playerID); + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp b/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp new file mode 100644 index 0000000000..a93f91fa05 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp @@ -0,0 +1,48 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AIVUnitType.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIVUnitType; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D2E00 + void AICState::sendTribeToAIVLocationSlot(int tribeID, AIVUnitType aivUnitType, int slotIndex) + { + int owner = DAT_TribesState::instance.tribes[tribeID].owner; + + // Find the slotIndex-th non-empty slot + int tile = 0; + for (int i = 0; i < 10; i++) { + if (DAT_GameState::instance.playerDataArray[owner].aivUnitLocationSlots[aivUnitType][i] == 0) { + continue; + } + slotIndex--; + if (slotIndex < 0) { + tile = DAT_GameState::instance.playerDataArray[owner].aivUnitLocationSlots[aivUnitType][i]; + break; + } + } + + int y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + + if (MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::canNavigateUnitsFromTileToTargetTile, this)(tribeID, tile) + != FALSE) { + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::commandUnitsToLocation, DAT_TribesState::ptr)( + tribeID, x, y, 0); + return; + } + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, owner); + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp new file mode 100644 index 0000000000..7ceb0cfef3 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp @@ -0,0 +1,38 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF750 + void AICState::sendTribeToAttack(int playerID) + { + int tribeIndex = 0xbd; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + return; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3fb); + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp new file mode 100644 index 0000000000..026d0d65f8 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp @@ -0,0 +1,110 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/DirectionAlgorithmState.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_DirectionAlgorithmState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::Map::Units::SomeTribeBehaviorType; + using OpenSHC::Map::Units::Behavior::UnitStanceEnum; + using OpenSHC::Map::Units::Instructions::UnitMatchSpeedEnum; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D30E0 + undefined4 AICState::sendUnitsToAttackBreachedCastle(int attackingPlayerIndex) + { + int vector = 0; + if (DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiType == OpenSHC::AI::AIT_NULL) { + return 1; + } + + BOOLEnum sentUnitsToAttackLord = FALSE; + int defendingLordID = MACRO_CALL_MEMBER(OpenSHC::Map::Units::UnitsState_Func::getAliveLordForPlayer, + DAT_UnitsState::ptr)(DAT_GameState::instance.playerDataArray[attackingPlayerIndex].attackedPlayerID); + + for (int i = 0; i < 11; i++) { + int tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; + if (tribeType == 18 || tribeType == 14 || tribeType == 13) { + continue; + } + + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeIDs[tribeType + j]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeUIDs[j + tribeType]) { + continue; + } + + int targetUnitID = (short)DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; + + if (sentUnitsToAttackLord != FALSE || defendingLordID == 0 || tribeType == 186) { + if (MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::giveSomeRaidCommand, this)(tribeID, tribeType) + != 0) { + continue; + } + + if (tribeType == 186) { + vector += 4; + } + DAT_TribesState::instance.tribes[tribeID].tribeBehaviorType = OpenSHC::Map::Units::STBT_8; + DAT_TribesState::instance.tribes[tribeID].unitStance + = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + + int attackedPlayerID + = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].attackedPlayerID; + MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::DirectionAlgorithmState_Func::setAxisBasedDistanceResult, + DAT_DirectionAlgorithmState::ptr)(DAT_UnitsState::instance.units[targetUnitID].x, + DAT_UnitsState::instance.units[targetUnitID].y, + DAT_GameState::instance.mapAndTime.attackVectors[attackedPlayerID][vector].x, + DAT_GameState::instance.mapAndTime.attackVectors[attackedPlayerID][vector].y); + + if (DAT_DirectionAlgorithmState::instance.distanceHigh > 4) { + attackedPlayerID + = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].attackedPlayerID; + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, + DAT_TribesState::ptr)(tribeID, + DAT_GameState::instance.mapAndTime.attackVectors[attackedPlayerID][vector].x, + DAT_GameState::instance.mapAndTime.attackVectors[attackedPlayerID][vector].y, 0, 0, + OpenSHC::Map::Units::Instructions::UMSE_0); + } + vector += 1; + } else { + // Send units to attack lord + int lordY = DAT_UnitsState::instance.units[defendingLordID].y; + int lordX = DAT_UnitsState::instance.units[defendingLordID].x; + if (MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( + tribeID, lordX, lordY, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0) + == 0) { + return 0; + } + sentUnitsToAttackLord = TRUE; + } + } + } + + return 1; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp b/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp new file mode 100644 index 0000000000..c824f5d752 --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp @@ -0,0 +1,24 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CD110 + void AICState::sendUnitsToCampfire(int tribeID, int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].campground.id <= 0) { + return; + } + + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::commandUnitsToLocation, DAT_TribesState::ptr)(tribeID, + DAT_GameState::instance.playerDataArray[playerID].campground.xEntry, + DAT_GameState::instance.playerDataArray[playerID].campground.yEntry, 0); + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp new file mode 100644 index 0000000000..fcb585017e --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp @@ -0,0 +1,24 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CD0C0 + void AICState::sendUnitsToKeep(int tribeID, int playerID) + { + int keepID = DAT_GameState::instance.playerDataArray[playerID].keep.id; + if (keepID <= 0) { + return; + } + + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::commandUnitsToLocation, DAT_TribesState::ptr)(tribeID, + (short)DAT_BuildingsState::instance.buildings[keepID].x + 3, + (short)DAT_BuildingsState::instance.buildings[keepID].y + 4, 0); + } +} +} diff --git a/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp new file mode 100644 index 0000000000..be3532ffbc --- /dev/null +++ b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp @@ -0,0 +1,79 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/Instructions/UnitMatchSpeedEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + using OpenSHC::Map::Units::Behavior::UnitStanceEnum; + using OpenSHC::Map::Units::Instructions::UnitMatchSpeedEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE5F0 + void AICState::sendUnitsToPlayerIDsKeepIfPossible(int playerID1, int playerID2) + { + uint campfireX = DAT_GameState::instance.playerDataArray[playerID1].campground.xEntry; + uint campfireY = DAT_GameState::instance.playerDataArray[playerID1].campground.yEntry; + + uint gatehouseX; + uint gatehouseY; + if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::canNavigateFromKeepToKeep, DAT_GameState::ptr)( + playerID1, playerID2) + == FALSE) { + uint gatehouseTile = MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findOwnedGatehouse, + DAT_PathFindingState::ptr)(playerID2, campfireX, campfireY); + if (gatehouseTile != 0) { + gatehouseY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[gatehouseTile]; + gatehouseX + = gatehouseTile - DAT_ViewportRenderState::instance.translationMatrix[gatehouseY].addXgetTile; + } else { + DAT_GameState::instance.playerDataArray[playerID1].requestStateUnk = 0; + return; + } + } + + for (int i = 0; i < 11; i++) { + int tribeTypeStart = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + for (int j = 0; j < tribeCount; j++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID1].aiTribeIDs[tribeTypeStart + j]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID1].aiTribeUIDs[j + tribeTypeStart]) { + continue; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_AGGRESSIVE; + + if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::canNavigateFromKeepToKeep, + DAT_GameState::ptr)(playerID1, playerID2) + != FALSE) { + if (tribeTypeStart == 0xbe) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToCampfire, this)(tribeID, playerID2); + } else if (MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::selectionContainsHorses, + DAT_TribesState::ptr)(tribeID) + != FALSE) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToCampfire, this)(tribeID, playerID2); + } else { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID2); + } + } else { + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( + tribeID, gatehouseX, gatehouseY, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); + } + } + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_01.cpp b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp new file mode 100644 index 0000000000..6da83f2a3e --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp @@ -0,0 +1,150 @@ +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/AI/AICState.hpp" + +namespace OpenSHC { +namespace AI { + + using AIC::AITC_ANY; + using AIC::AITC_BALANCED; + using AIC::AITC_CLOSEST; + using AIC::AITC_GOLD; + using AIC::AITC_PLAYER; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C6D60 + void AICState::setAICParameters_01(int aicIndex) + { + this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5500; + this->aics[aicIndex].highestPopularity = 7500; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 10; + this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].populationPerFarm = 6; + this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 2; + this->aics[aicIndex].aiRequestDelay = 0x12; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; + this->aics[aicIndex].doubleRationsFoodThreshold = 0; + this->aics[aicIndex].maxWood = 0x1e; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 0x14; + this->aics[aicIndex].maxEquipment = 0x14; + this->aics[aicIndex].maxBeer = 0x14; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 8; + this->aics[aicIndex].populationPerQuarry = 0x12; + this->aics[aicIndex].populationPerIronmine = 0; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 1; + this->aics[aicIndex].maxIronmines = 1; + this->aics[aicIndex].maxWoodcutters = 6; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 6; + this->aics[aicIndex].buildInterval = 1; + this->aics[aicIndex].resourceRebuildDelay = 10; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 0x14; + this->aics[aicIndex].defWallPatrolGroups = 1; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; + this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].unknown072 = 800; + this->aics[aicIndex].unknown073 = 0x50; + this->aics[aicIndex].recruitProbDefWeak = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMelee = 0x18; + this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 10; + this->aics[aicIndex].DefUnit1 = 0x18; + this->aics[aicIndex].DefUnit2 = 0x18; + this->aics[aicIndex].DefUnit3 = 0x16; + this->aics[aicIndex].DefUnit4 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 10; + this->aics[aicIndex].RaidUnit1 = 0x18; + this->aics[aicIndex].RaidUnit2 = 0x18; + this->aics[aicIndex].RaidUnit3 = 0x16; + this->aics[aicIndex].recruitProbDefDefault = 0; + this->aics[aicIndex].recruitProbDefStrong = 0; + this->aics[aicIndex].recruitProbRaidWeak = 0x32; + this->aics[aicIndex].recruitProbRaidDefault = 0x32; + this->aics[aicIndex].recruitProbRaidStrong = 0; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x32; + this->aics[aicIndex].recruitProbAttackStrong = 100; + this->aics[aicIndex].SortieUnitRangedMin = 5; + this->aics[aicIndex].SortieUnitMeleeMin = 6; + this->aics[aicIndex].DefDiggingUnitMax = 0; + this->aics[aicIndex].DefWalls = 0x14; + this->aics[aicIndex].DefTotal = 0x1e; + this->aics[aicIndex].OuterPatrolGroupsMove = 0; + this->aics[aicIndex].RaidUnitsRandom = 0xf; + this->aics[aicIndex].HarassingSiegeEnginesMax = 0; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 0x14; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0xf; + this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x19; + this->aics[aicIndex].AttCoordinationPreference = 0x14; + this->aics[aicIndex].SiegeEngine1 = 0; + this->aics[aicIndex].CowThrowInterval = 1000; + this->aics[aicIndex].AttMaxEngineers = 0; + this->aics[aicIndex].AttDiggingUnit = 0x18; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0x16; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x16; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x16; + this->aics[aicIndex].AttUnitBackupMax = 0x10; + this->aics[aicIndex].AttUnitBackupGroupsCount = 0; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x18; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x18; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 1; + this->aics[aicIndex].TargetChoice = AITC_PLAYER; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_02.cpp b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp new file mode 100644 index 0000000000..339becf6f8 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp @@ -0,0 +1,148 @@ +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/AI/AICState.hpp" + +namespace OpenSHC { +namespace AI { + + using AIC::AITC_ANY; + using AIC::AITC_BALANCED; + using AIC::AITC_CLOSEST; + using AIC::AITC_GOLD; + using AIC::AITC_PLAYER; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C7120 + void AICState::setAICParameters_02(int aicIndex) + { + this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xb; + this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 0xf; + this->aics[aicIndex].maxFood = 0x96; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = 0x14; + this->aics[aicIndex].minimumBread = 0xffffffff; + this->aics[aicIndex].minimumWheat = 0xffffffff; + this->aics[aicIndex].minimumHop = 0xffffffff; + this->aics[aicIndex].tradeAmountFood = 5; + this->aics[aicIndex].tradeAmountEquipment = 6; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x50; + this->aics[aicIndex].maxWood = 0x30; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 0xf; + this->aics[aicIndex].maxEquipment = 0xc; + this->aics[aicIndex].maxBeer = 5; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 5; + this->aics[aicIndex].populationPerQuarry = 0xf; + this->aics[aicIndex].populationPerIronmine = 0; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 2; + this->aics[aicIndex].maxIronmines = 1; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 10; + this->aics[aicIndex].buildInterval = 2; + this->aics[aicIndex].resourceRebuildDelay = 0xc; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 4; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 500; + this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].unknown072 = 400; + this->aics[aicIndex].unknown073 = 0x3c; + this->aics[aicIndex].recruitProbDefWeak = 0x46; + this->aics[aicIndex].recruitProbDefDefault = 0x1e; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0x1e; + this->aics[aicIndex].recruitProbRaidDefault = 0x28; + this->aics[aicIndex].recruitProbRaidStrong = 0x28; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].recruitProbAttackStrong = 0x28; + this->aics[aicIndex].RecruitIntervalWeak = 0; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRangedMin = 2; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMeleeMin = 8; + this->aics[aicIndex].SortieUnitMelee = 0x18; + this->aics[aicIndex].DefDiggingUnitMax = 0x14; + this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].DefWalls = 0x32; + this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].OuterPatrolGroupsCount = 3; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].RaidUnitsRandom = 10; + this->aics[aicIndex].RaidUnit1 = 0x47; + this->aics[aicIndex].RaidUnit2 = 0x47; + this->aics[aicIndex].RaidUnit3 = 0x47; + this->aics[aicIndex].RaidUnit4 = 0x48; + this->aics[aicIndex].HarassingSiegeEnginesMax = 1; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; + this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x19; + this->aics[aicIndex].AttCoordinationPreference = 0x28; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].CowThrowInterval = 1000; + this->aics[aicIndex].AttMaxEngineers = 2; + this->aics[aicIndex].AttDiggingUnit = 0x18; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0x16; + this->aics[aicIndex].AttUnit2Max = 0x14; + this->aics[aicIndex].AttMaxLaddermen = 10; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x48; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x46; + this->aics[aicIndex].AttUnitBackupMax = 0x32; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x16; + this->aics[aicIndex].AttUnitSiegeDefMax = 0x1e; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x18; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 1; + this->aics[aicIndex].TargetChoice = AITC_BALANCED; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_03.cpp b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp new file mode 100644 index 0000000000..d4429b581a --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp @@ -0,0 +1,148 @@ +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/AI/AICState.hpp" + +namespace OpenSHC { +namespace AI { + + using AIC::AITC_ANY; + using AIC::AITC_BALANCED; + using AIC::AITC_CLOSEST; + using AIC::AITC_GOLD; + using AIC::AITC_PLAYER; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C7520 + void AICState::setAICParameters_03(int aicIndex) + { + this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 5000; + this->aics[aicIndex].lowestPopularity = 7000; + this->aics[aicIndex].highestPopularity = 0x2134; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xb; + this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].maxFood = 400; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = 10; + this->aics[aicIndex].minimumBread = 10; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 5; + this->aics[aicIndex].tradeAmountEquipment = 4; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 100; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x3c; + this->aics[aicIndex].maxWood = 0x46; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 10; + this->aics[aicIndex].maxBeer = 5; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 6; + this->aics[aicIndex].populationPerQuarry = 0x19; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0x14; + this->aics[aicIndex].maxQuarries = 2; + this->aics[aicIndex].maxIronmines = 4; + this->aics[aicIndex].maxWoodcutters = 8; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 0x32; + this->aics[aicIndex].blacksmithSetting = 0x15; + this->aics[aicIndex].fletcherSetting = 0x12; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 10; + this->aics[aicIndex].defWallPatrolGroups = 4; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x28; + this->aics[aicIndex].recruitProbDefWeak = 100; + this->aics[aicIndex].recruitProbDefDefault = 0x3c; + this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0; + this->aics[aicIndex].recruitProbRaidStrong = 0; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x28; + this->aics[aicIndex].recruitProbAttackStrong = 0x46; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 4; + this->aics[aicIndex].SortieUnitRanged = 0x17; + this->aics[aicIndex].SortieUnitMeleeMin = 5; + this->aics[aicIndex].SortieUnitMelee = 0x1a; + this->aics[aicIndex].DefDiggingUnitMax = 0; + this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].DefWalls = 0x1e; + this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].OuterPatrolGroupsCount = 2; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 0x14; + this->aics[aicIndex].DefUnit1 = 0x17; + this->aics[aicIndex].DefUnit2 = 0x17; + this->aics[aicIndex].RaidUnitsBase = 10; + this->aics[aicIndex].RaidUnitsRandom = 5; + this->aics[aicIndex].DefUnit3 = 0x17; + this->aics[aicIndex].RaidUnit1 = 0x1a; + this->aics[aicIndex].HarassingSiegeEnginesMax = 2; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 10; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 10; + this->aics[aicIndex].AttForceRallyPercentage = 0x3c; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 5; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0xf; + this->aics[aicIndex].AttCoordinationPreference = 0x14; + this->aics[aicIndex].CowThrowInterval = 0x1e; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x27; + this->aics[aicIndex].SiegeEngine3 = 0x27; + this->aics[aicIndex].SiegeEngine4 = 0x3b; + this->aics[aicIndex].AttMaxEngineers = 10; + this->aics[aicIndex].AttDiggingUnit = 0x1a; + this->aics[aicIndex].AttDiggingUnitMax = 10; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x17; + this->aics[aicIndex].AttUnitBackupMax = 5; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x1a; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x1a; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = AITC_GOLD; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_04.cpp b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp new file mode 100644 index 0000000000..2bcec1b88a --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp @@ -0,0 +1,149 @@ +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/AI/AICState.hpp" + +namespace OpenSHC { +namespace AI { + + using AIC::AITC_ANY; + using AIC::AITC_BALANCED; + using AIC::AITC_CLOSEST; + using AIC::AITC_GOLD; + using AIC::AITC_PLAYER; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C7910 + void AICState::setAICParameters_04(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].lowestPopularity = 6000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xb; + this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].farm3 = 0x1f; + this->aics[aicIndex].farm4 = 0x20; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].maxFood = 200; + this->aics[aicIndex].minimumApples = 5; + this->aics[aicIndex].minimumCheese = 5; + this->aics[aicIndex].minimumBread = 5; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 4; + this->aics[aicIndex].aiRequestDelay = 0x14; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x28; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x1e; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 10; + this->aics[aicIndex].maxBeer = 0xf; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 4; + this->aics[aicIndex].populationPerQuarry = 9; + this->aics[aicIndex].populationPerIronmine = 0xd; + this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].maxQuarries = 6; + this->aics[aicIndex].maxIronmines = 3; + this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxPitchrigs = 2; + this->aics[aicIndex].maxFarms = 10; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 0x14; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x12; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].defWallPatrolRallyTime = 4; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 0xfa; + this->aics[aicIndex].defSiegeEngineBuildDelay = 2; + this->aics[aicIndex].unknown072 = 100; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x5a; + this->aics[aicIndex].recruitProbDefDefault = 0x3c; + this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidWeak = 10; + this->aics[aicIndex].recruitProbRaidDefault = 0x1e; + this->aics[aicIndex].recruitProbRaidStrong = 10; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 10; + this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 4; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 8; + this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitMeleeMin = 6; + this->aics[aicIndex].SortieUnitMelee = 0x19; + this->aics[aicIndex].DefDiggingUnitMax = 8; + this->aics[aicIndex].DefDiggingUnit = 0x19; + this->aics[aicIndex].DefWalls = 0x50; + this->aics[aicIndex].DefTotal = 100; + this->aics[aicIndex].OuterPatrolGroupsCount = 4; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 3; + this->aics[aicIndex].DefUnit1 = 0x17; + this->aics[aicIndex].DefUnit2 = 0x17; + this->aics[aicIndex].RaidUnitsRandom = 0x14; + this->aics[aicIndex].DefUnit3 = 0x16; + this->aics[aicIndex].DefUnit4 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 5; + this->aics[aicIndex].RaidUnit1 = 0x4a; + this->aics[aicIndex].RaidUnit2 = 0x4a; + this->aics[aicIndex].HarassingSiegeEnginesMax = 4; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 5; + this->aics[aicIndex].AttForceBase = 0x28; + this->aics[aicIndex].AttForceRandom = 0xf; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0xc; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].CowThrowInterval = 8; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x28; + this->aics[aicIndex].SiegeEngine3 = 0x4d; + this->aics[aicIndex].SiegeEngine4 = 0x28; + this->aics[aicIndex].AttMaxEngineers = 0xc; + this->aics[aicIndex].AttDiggingUnit = 0x19; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x17; + this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackupGroupsCount = 3; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x1b; + this->aics[aicIndex].AttUnitSiegeDefMax = 5; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; + this->aics[aicIndex].AttUnitMain1 = 0x1b; + this->aics[aicIndex].AttUnitMain2 = 0x19; + this->aics[aicIndex].AttUnitMain3 = 0x19; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 3; + this->aics[aicIndex].TargetChoice = AITC_CLOSEST; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_05.cpp b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp new file mode 100644 index 0000000000..b87465a089 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp @@ -0,0 +1,148 @@ +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/AI/AICState.hpp" + +namespace OpenSHC { +namespace AI { + + using AIC::AITC_ANY; + using AIC::AITC_BALANCED; + using AIC::AITC_CLOSEST; + using AIC::AITC_GOLD; + using AIC::AITC_PLAYER; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C7D20 + void AICState::setAICParameters_05(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x1f; + this->aics[aicIndex].farm2 = 0x1e; + this->aics[aicIndex].farm3 = 0x1e; + this->aics[aicIndex].farm4 = 0x20; + this->aics[aicIndex].populationPerFarm = 3; + this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].maxFood = 0x32; + this->aics[aicIndex].minimumApples = 5; + this->aics[aicIndex].minimumCheese = 5; + this->aics[aicIndex].minimumBread = 5; + this->aics[aicIndex].minimumWheat = 5; + this->aics[aicIndex].minimumHop = 5; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0x28; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x14; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x14; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 5; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 2; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 6; + this->aics[aicIndex].populationPerQuarry = 10; + this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerPitchrig = 0x14; + this->aics[aicIndex].maxQuarries = 4; + this->aics[aicIndex].maxIronmines = 4; + this->aics[aicIndex].maxWoodcutters = 0xe; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0xf; + this->aics[aicIndex].buildInterval = 2; + this->aics[aicIndex].resourceRebuildDelay = 0x28; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x12; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].defWallPatrolRallyTime = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 0x14; + this->aics[aicIndex].defSiegeEngineBuildDelay = 8; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].defWallPatrolGroups = 4; + this->aics[aicIndex].unknown072 = 100; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 100; + this->aics[aicIndex].recruitProbDefDefault = 0x22; + this->aics[aicIndex].recruitProbDefStrong = 0x19; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0x21; + this->aics[aicIndex].recruitProbRaidStrong = 0x19; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x21; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRangedMin = 10; + this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitMeleeMin = 7; + this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x47; + this->aics[aicIndex].DefWalls = 0x32; + this->aics[aicIndex].DefTotal = 0x46; + this->aics[aicIndex].OuterPatrolGroupsCount = 2; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 10; + this->aics[aicIndex].DefUnit1 = 0x4b; + this->aics[aicIndex].DefUnit2 = 0x46; + this->aics[aicIndex].RaidUnitsBase = 10; + this->aics[aicIndex].RaidUnitsRandom = 5; + this->aics[aicIndex].DefUnit3 = 0x46; + this->aics[aicIndex].DefUnit4 = 0x46; + this->aics[aicIndex].DefUnit5 = 0x4c; + this->aics[aicIndex].RaidUnit1 = 0x4a; + this->aics[aicIndex].HarassingSiegeEnginesMax = 5; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 0x32; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 8; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 4; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 1; + this->aics[aicIndex].AttCoordinationPreference = 0x3c; + this->aics[aicIndex].CowThrowInterval = 2000; + this->aics[aicIndex].SiegeEngine1 = 0x4d; + this->aics[aicIndex].SiegeEngine2 = 0x4d; + this->aics[aicIndex].SiegeEngine3 = 0x27; + this->aics[aicIndex].SiegeEngine4 = 0x27; + this->aics[aicIndex].AttMaxEngineers = 10; + this->aics[aicIndex].AttDiggingUnit = 0x47; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 5; + this->aics[aicIndex].AttUnit2 = 0x4a; + this->aics[aicIndex].AttUnit2Max = 0x14; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x4a; + this->aics[aicIndex].AttUnitPatrolMax = 0x14; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 1; + this->aics[aicIndex].AttUnitBackup = 0x46; + this->aics[aicIndex].AttUnitBackupMax = 0x14; + this->aics[aicIndex].AttUnitBackupGroupsCount = 3; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0x4c; + this->aics[aicIndex].AttUnitSiegeDef = 0x4c; + this->aics[aicIndex].AttUnitSiegeDefMax = 6; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; + this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 3; + this->aics[aicIndex].TargetChoice = AITC_GOLD; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_06.cpp b/src/OpenSHC/AI/AICState/setAICParameters_06.cpp new file mode 100644 index 0000000000..f9b06cf09f --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_06.cpp @@ -0,0 +1,150 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C8110 + void AICState::setAICParameters_06(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].farm2 = 0x1f; + this->aics[aicIndex].farm3 = 0x20; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x32; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; + this->aics[aicIndex].maxWood = 0x32; + this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 5; + this->aics[aicIndex].maxBeer = 0xf; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 10; + this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerPitchrig = 7; + this->aics[aicIndex].maxQuarries = 2; + this->aics[aicIndex].maxIronmines = 1; + this->aics[aicIndex].maxWoodcutters = 8; + this->aics[aicIndex].maxPitchrigs = 10; + this->aics[aicIndex].maxFarms = 10; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 0x3c; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x12; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].defWallPatrolRallyTime = 5; + this->aics[aicIndex].defWallPatrolGroups = 2; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 0x78; + this->aics[aicIndex].defSiegeEngineBuildDelay = 8; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].unknown072 = 100; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x50; + this->aics[aicIndex].recruitProbDefDefault = 0x28; + this->aics[aicIndex].recruitProbDefStrong = 0x28; + this->aics[aicIndex].recruitProbRaidWeak = 0x14; + this->aics[aicIndex].recruitProbRaidDefault = 0x28; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x14; + this->aics[aicIndex].recruitProbAttackStrong = 0x1e; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 0; + this->aics[aicIndex].RecruitIntervalStrong = 0; + this->aics[aicIndex].SortieUnitRangedMin = 7; + this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitMeleeMin = 5; + this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x47; + this->aics[aicIndex].DefWalls = 0x3c; + this->aics[aicIndex].DefTotal = 0x3c; + this->aics[aicIndex].OuterPatrolGroupsCount = 2; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 10; + this->aics[aicIndex].DefUnit1 = 0x4c; + this->aics[aicIndex].DefUnit2 = 0x46; + this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].RaidUnitsRandom = 0x1e; + this->aics[aicIndex].DefUnit3 = 0x46; + this->aics[aicIndex].DefUnit4 = 0x46; + this->aics[aicIndex].RaidUnit1 = 0x47; + this->aics[aicIndex].HarassingSiegeEnginesMax = 2; + this->aics[aicIndex].HarassingSiegeEngine1 = 0x166; + this->aics[aicIndex].HarassingSiegeEngine2 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 0xf; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x46; + this->aics[aicIndex].AttForceRallyPercentage = 100; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 2; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 10; + this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].CowThrowInterval = 7; + this->aics[aicIndex].SiegeEngine1 = 0x4d; + this->aics[aicIndex].SiegeEngine2 = 0x4d; + this->aics[aicIndex].SiegeEngine3 = 0x4d; + this->aics[aicIndex].AttMaxEngineers = 6; + this->aics[aicIndex].AttDiggingUnit = 0x47; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0x4b; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x4a; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x4a; + this->aics[aicIndex].AttUnitBackupMax = 0x28; + this->aics[aicIndex].AttUnitBackupGroupsCount = 2; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x46; + this->aics[aicIndex].AttUnitSiegeDefMax = 10; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; + this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 5; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_07.cpp b/src/OpenSHC/AI/AICState/setAICParameters_07.cpp new file mode 100644 index 0000000000..101537122c --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_07.cpp @@ -0,0 +1,147 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C8530 + void AICState::setAICParameters_07(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 0; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 5000; + this->aics[aicIndex].lowestPopularity = 6000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 1; + this->aics[aicIndex].taxesMax = 8; + this->aics[aicIndex].farm1 = 0; + this->aics[aicIndex].populationPerFarm = 100; + this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].maxFood = 500; + this->aics[aicIndex].minimumApples = 0x14; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0x1e; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; + this->aics[aicIndex].doubleRationsFoodThreshold = 0; + this->aics[aicIndex].maxWood = 0x1e; + this->aics[aicIndex].maxStone = 0x14; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 5; + this->aics[aicIndex].maxBeer = 0x14; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 2; + this->aics[aicIndex].populationPerQuarry = 5; + this->aics[aicIndex].populationPerIronmine = 0; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 2; + this->aics[aicIndex].maxIronmines = 1; + this->aics[aicIndex].maxWoodcutters = 0xf; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 6; + this->aics[aicIndex].buildInterval = 5; + this->aics[aicIndex].resourceRebuildDelay = 0x50; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 10; + this->aics[aicIndex].defWallPatrolGroups = 2; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; + this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].unknown072 = 800; + this->aics[aicIndex].unknown073 = 0x50; + this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidWeak = 10; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].DefDiggingUnitMax = 2; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 10; + this->aics[aicIndex].RaidUnitsRandom = 10; + this->aics[aicIndex].recruitProbDefWeak = 0x46; + this->aics[aicIndex].recruitProbDefDefault = 0x32; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbAttackWeak = 0x14; + this->aics[aicIndex].recruitProbAttackStrong = 0x28; + this->aics[aicIndex].RecruitIntervalWeak = 8; + this->aics[aicIndex].RecruitInterval = 8; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 0; + this->aics[aicIndex].SortieUnitRanged = 0x48; + this->aics[aicIndex].SortieUnitMeleeMin = 3; + this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].DefDiggingUnit = 0x47; + this->aics[aicIndex].DefWalls = 0x28; + this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].OuterPatrolGroupsMove = 0; + this->aics[aicIndex].DefUnit1 = 0x48; + this->aics[aicIndex].DefUnit2 = 0x48; + this->aics[aicIndex].DefUnit3 = 0x4b; + this->aics[aicIndex].RaidUnitsBase = 0x14; + this->aics[aicIndex].RaidUnit1 = 0x48; + this->aics[aicIndex].HarassingSiegeEnginesMax = 0; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 3; + this->aics[aicIndex].AttForceBase = 10; + this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceSupportAllyThreshold = 5; + this->aics[aicIndex].AttForceRallyPercentage = 0x1e; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x28; + this->aics[aicIndex].AttCoordinationPreference = 0x14; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0; + this->aics[aicIndex].AttMaxEngineers = 0; + this->aics[aicIndex].AttDiggingUnit = 0; + this->aics[aicIndex].AttDiggingUnitMax = 0; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x46; + this->aics[aicIndex].AttUnitBackupMax = 0x78; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 1; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_08.cpp b/src/OpenSHC/AI/AICState/setAICParameters_08.cpp new file mode 100644 index 0000000000..28cef0fd50 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_08.cpp @@ -0,0 +1,149 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + // FUNCTION: STRONGHOLDCRUSADER 0x004C8920 + void AICState::setAICParameters_08(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 0; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 10; + this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].farm3 = 0x20; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].maxFood = 200; + this->aics[aicIndex].minimumApples = 5; + this->aics[aicIndex].minimumCheese = 5; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 5; + this->aics[aicIndex].tradeAmountEquipment = 2; + this->aics[aicIndex].aiRequestDelay = 0x16; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; + this->aics[aicIndex].maxWood = 0x32; + this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 10; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 10; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 3; + this->aics[aicIndex].maxIronmines = 4; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0xf; + this->aics[aicIndex].buildInterval = 4; + this->aics[aicIndex].resourceRebuildDelay = 0x14; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].defWallPatrolRallyTime = 8; + this->aics[aicIndex].defWallPatrolGroups = 4; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; + this->aics[aicIndex].defSiegeEngineBuildDelay = 2; + this->aics[aicIndex].unknown072 = 100; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x5a; + this->aics[aicIndex].recruitProbDefDefault = 0x1e; + this->aics[aicIndex].recruitProbDefStrong = 10; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0; + this->aics[aicIndex].recruitProbRaidStrong = 0; + this->aics[aicIndex].recruitProbAttackWeak = 10; + this->aics[aicIndex].recruitProbAttackDefault = 0x46; + this->aics[aicIndex].recruitProbAttackStrong = 0x5a; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRangedMin = 6; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMeleeMin = 6; + this->aics[aicIndex].SortieUnitMelee = 0x19; + this->aics[aicIndex].DefDiggingUnitMax = 0; + this->aics[aicIndex].DefDiggingUnit = 0x19; + this->aics[aicIndex].DefWalls = 0x14; + this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].OuterPatrolGroupsCount = 2; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 5; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 10; + this->aics[aicIndex].RaidUnitsRandom = 4; + this->aics[aicIndex].DefUnit3 = 0x19; + this->aics[aicIndex].RaidUnit1 = 0x16; + this->aics[aicIndex].HarassingSiegeEnginesMax = 2; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 5; + this->aics[aicIndex].AttForceBase = 0x14; + this->aics[aicIndex].AttForceRandom = 5; + this->aics[aicIndex].AttForceSupportAllyThreshold = 10; + this->aics[aicIndex].AttForceRallyPercentage = 10; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0x14; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 2; + this->aics[aicIndex].AttCoordinationPreference = 10; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x27; + this->aics[aicIndex].SiegeEngine3 = 0x27; + this->aics[aicIndex].SiegeEngine4 = 0x3b; + this->aics[aicIndex].SiegeEngine5 = 0x28; + this->aics[aicIndex].SiegeEngine6 = 0x28; + this->aics[aicIndex].AttMaxEngineers = 0x10; + this->aics[aicIndex].AttDiggingUnit = 0x19; + this->aics[aicIndex].AttDiggingUnitMax = 6; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 3; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x16; + this->aics[aicIndex].AttUnitBackupMax = 0x14; + this->aics[aicIndex].AttUnitBackupGroupsCount = 2; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x1b; + this->aics[aicIndex].AttUnitSiegeDefMax = 4; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 2; + this->aics[aicIndex].AttUnitMain1 = 0x1b; + this->aics[aicIndex].AttUnitMain2 = 0x19; + this->aics[aicIndex].AttUnitMain3 = 0x19; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 3; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_09.cpp b/src/OpenSHC/AI/AICState/setAICParameters_09.cpp new file mode 100644 index 0000000000..082d66a3a3 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_09.cpp @@ -0,0 +1,146 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + // FUNCTION: STRONGHOLDCRUSADER 0x004C8D20 + void AICState::setAICParameters_09(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 0x157c; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 10; + this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].farm3 = 0x1f; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].maxFood = 200; + this->aics[aicIndex].minimumApples = 5; + this->aics[aicIndex].minimumCheese = 5; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0x16; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].maxResourceOther = 0xf; + this->aics[aicIndex].maxEquipment = 0x14; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 0xc; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 4; + this->aics[aicIndex].maxIronmines = 5; + this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].buildInterval = 4; + this->aics[aicIndex].resourceRebuildDelay = 0x1e; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = -999; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].defWallPatrolRallyTime = 8; + this->aics[aicIndex].defWallPatrolGroups = 2; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; + this->aics[aicIndex].defSiegeEngineBuildDelay = 2; + this->aics[aicIndex].unknown072 = 100; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 100; + this->aics[aicIndex].recruitProbDefDefault = 0x32; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 4; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 0xc; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMeleeMin = 4; + this->aics[aicIndex].SortieUnitMelee = 0x1b; + this->aics[aicIndex].DefDiggingUnitMax = 10; + this->aics[aicIndex].DefDiggingUnit = 0x16; + this->aics[aicIndex].DefWalls = 0x32; + this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].OuterPatrolGroupsCount = 2; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 10; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 4; + this->aics[aicIndex].DefUnit3 = 0x17; + this->aics[aicIndex].RaidUnitsRandom = 0; + this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].HarassingSiegeEnginesMax = 2; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 6; + this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].AttForceRandom = 4; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x14; + this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0x14; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x28; + this->aics[aicIndex].SiegeEngine2 = 0x28; + this->aics[aicIndex].SiegeEngine3 = 0x28; + this->aics[aicIndex].SiegeEngine4 = 0x28; + this->aics[aicIndex].SiegeEngine5 = 0x28; + this->aics[aicIndex].SiegeEngine6 = 0x28; + this->aics[aicIndex].AttMaxEngineers = 0x12; + this->aics[aicIndex].AttDiggingUnit = 0x16; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x17; + this->aics[aicIndex].AttUnitPatrolMax = 0x14; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 1; + this->aics[aicIndex].AttUnitBackup = 0x16; + this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackupGroupsCount = 2; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x17; + this->aics[aicIndex].AttUnitSiegeDefMax = 10; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; + this->aics[aicIndex].AttUnitMain1 = 0x1b; + this->aics[aicIndex].AttUnitMain2 = 0x1b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 4; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_GOLD; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_10.cpp b/src/OpenSHC/AI/AICState/setAICParameters_10.cpp new file mode 100644 index 0000000000..99dc276f8e --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_10.cpp @@ -0,0 +1,147 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C9120 + void AICState::setAICParameters_10(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 10; + this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = 10; + this->aics[aicIndex].minimumBread = 10; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountEquipment = 2; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].maxResourceOther = 0xf; + this->aics[aicIndex].maxEquipment = 6; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 0; + this->aics[aicIndex].populationPerIronmine = 7; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 1; + this->aics[aicIndex].maxIronmines = 3; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 8; + this->aics[aicIndex].buildInterval = 4; + this->aics[aicIndex].resourceRebuildDelay = 0x3c; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x46; + this->aics[aicIndex].recruitProbDefDefault = 0x28; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0x14; + this->aics[aicIndex].recruitProbRaidDefault = 0x28; + this->aics[aicIndex].recruitProbRaidStrong = 0x14; + this->aics[aicIndex].recruitProbAttackWeak = 10; + this->aics[aicIndex].recruitProbAttackDefault = 0x14; + this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].RecruitIntervalWeak = 4; + this->aics[aicIndex].RecruitInterval = 4; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 2; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMeleeMin = 0x14; + this->aics[aicIndex].SortieUnitMelee = 0x18; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].DefWalls = 4; + this->aics[aicIndex].DefTotal = 0x14; + this->aics[aicIndex].OuterPatrolGroupsCount = 4; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x1c; + this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 4; + this->aics[aicIndex].RaidUnitsRandom = 4; + this->aics[aicIndex].DefUnit3 = 0x16; + this->aics[aicIndex].DefUnit4 = 0x16; + this->aics[aicIndex].DefUnit5 = 0x16; + this->aics[aicIndex].DefUnit6 = 0x16; + this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].HarassingSiegeEnginesMax = 1; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].AttForceBase = 10; + this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x28; + this->aics[aicIndex].AttForceRallyPercentage = 0x28; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x46; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0; + this->aics[aicIndex].AttMaxEngineers = 0; + this->aics[aicIndex].AttDiggingUnit = 0x18; + this->aics[aicIndex].AttDiggingUnitMax = 0x3c; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0x18; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0; + this->aics[aicIndex].AttUnitBackupMax = 0; + this->aics[aicIndex].AttUnitBackupGroupsCount = 0; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x18; + this->aics[aicIndex].AttUnitMain2 = 0x18; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_11.cpp b/src/OpenSHC/AI/AICState/setAICParameters_11.cpp new file mode 100644 index 0000000000..57e5e6c3ba --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_11.cpp @@ -0,0 +1,145 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + // FUNCTION: STRONGHOLDCRUSADER 0x004C94F0 + void AICState::setAICParameters_11(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x1e; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = -1; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = 2; + this->aics[aicIndex].minimumHop = -1; + this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0x16; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x1e; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 4; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 100; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 6; + this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerPitchrig = 6; + this->aics[aicIndex].maxQuarries = 3; + this->aics[aicIndex].maxIronmines = 1; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 4; + this->aics[aicIndex].maxFarms = 8; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 0x32; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource02 = 3; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource06 = 0xe; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x46; + this->aics[aicIndex].recruitProbDefDefault = 0x1e; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbRaidStrong = 0x14; + this->aics[aicIndex].recruitProbAttackWeak = 0x1e; + this->aics[aicIndex].recruitProbAttackDefault = 0x32; + this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRangedMin = 6; + this->aics[aicIndex].SortieUnitRanged = 0x4a; + this->aics[aicIndex].SortieUnitMeleeMin = 10; + this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x47; + this->aics[aicIndex].DefWalls = 0x28; + this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x46; + this->aics[aicIndex].DefUnit2 = 0x4c; + this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].RaidUnitsRandom = 10; + this->aics[aicIndex].RaidUnit1 = 0x4a; + this->aics[aicIndex].HarassingSiegeEnginesMax = 4; + this->aics[aicIndex].HarassingSiegeEngine1 = 0x166; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].AttForceBase = 0x28; + this->aics[aicIndex].AttForceRandom = 5; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 4; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x5a; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x28; + this->aics[aicIndex].SiegeEngine2 = 0x4d; + this->aics[aicIndex].SiegeEngine3 = 0x4d; + this->aics[aicIndex].SiegeEngine4 = 0x4d; + this->aics[aicIndex].AttMaxEngineers = 9; + this->aics[aicIndex].AttDiggingUnit = 0x47; + this->aics[aicIndex].AttDiggingUnitMax = 0xf; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x4a; + this->aics[aicIndex].AttUnitBackupMax = 0x50; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 10; + this->aics[aicIndex].AttUnitEngage = 0x4c; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_12.cpp b/src/OpenSHC/AI/AICState/setAICParameters_12.cpp new file mode 100644 index 0000000000..887cf7c843 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_12.cpp @@ -0,0 +1,146 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004C9900 + void AICState::setAICParameters_12(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x1e; + this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].farm3 = 0x1e; + this->aics[aicIndex].farm4 = 0x1f; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 0x50; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = 2; + this->aics[aicIndex].minimumHop = 2; + this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 4; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 6; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 4; + this->aics[aicIndex].maxIronmines = 3; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0x10; + this->aics[aicIndex].buildInterval = 2; + this->aics[aicIndex].resourceRebuildDelay = 0x28; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x50; + this->aics[aicIndex].recruitProbDefDefault = 0x28; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 10; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 10; + this->aics[aicIndex].recruitProbAttackDefault = 0x28; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 0; + this->aics[aicIndex].RecruitIntervalStrong = 0; + this->aics[aicIndex].SortieUnitRangedMin = 4; + this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitMeleeMin = 0x14; + this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x16; + this->aics[aicIndex].DefWalls = 0x32; + this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].DefUnit2 = 0x46; + this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].RaidUnitsRandom = 10; + this->aics[aicIndex].RaidUnit1 = 0x4b; + this->aics[aicIndex].HarassingSiegeEnginesMax = 3; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine2 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].HarassingSiegeEngine3 = 0x166; + this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x14; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x50; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x27; + this->aics[aicIndex].SiegeEngine3 = 0x3d; + this->aics[aicIndex].AttMaxEngineers = 6; + this->aics[aicIndex].AttDiggingUnit = 0x16; + this->aics[aicIndex].AttDiggingUnitMax = 0xf; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x4a; + this->aics[aicIndex].AttUnitBackupMax = 0x50; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_GOLD; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_13.cpp b/src/OpenSHC/AI/AICState/setAICParameters_13.cpp new file mode 100644 index 0000000000..afea2e4b06 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_13.cpp @@ -0,0 +1,142 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + // FUNCTION: STRONGHOLDCRUSADER 0x004C9CF0 + void AICState::setAICParameters_13(int aicIndex) + { + this->aics[aicIndex].flagType = 10; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x1e; + this->aics[aicIndex].farm2 = 0x1e; + this->aics[aicIndex].farm3 = 0x1e; + this->aics[aicIndex].farm4 = 0x1f; + this->aics[aicIndex].populationPerFarm = 3; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = 5; + this->aics[aicIndex].minimumHop = 5; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x1e; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x1e; + this->aics[aicIndex].maxWood = 0x32; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 4; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 100; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 0x14; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].maxQuarries = 1; + this->aics[aicIndex].maxIronmines = 2; + this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 0x10; + this->aics[aicIndex].buildInterval = 1; + this->aics[aicIndex].resourceRebuildDelay = 0x14; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x50; + this->aics[aicIndex].recruitProbDefDefault = 0x32; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 0x14; + this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 8; + this->aics[aicIndex].RecruitInterval = 4; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRangedMin = 5; + this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitMeleeMin = 0xf; + this->aics[aicIndex].SortieUnitMelee = 0x46; + this->aics[aicIndex].DefDiggingUnitMax = 0x3c; + this->aics[aicIndex].DefDiggingUnit = 0x47; + this->aics[aicIndex].DefWalls = 0x50; + this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x46; + this->aics[aicIndex].RaidUnitsBase = 5; + this->aics[aicIndex].RaidUnitsRandom = 5; + this->aics[aicIndex].RaidUnit1 = 0x49; + this->aics[aicIndex].HarassingSiegeEnginesMax = 0; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].AttForceBase = 0x28; + this->aics[aicIndex].AttForceRandom = 0; + this->aics[aicIndex].AttForceSupportAllyThreshold = 10; + this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].AttMaxEngineers = 0; + this->aics[aicIndex].AttDiggingUnit = 0x47; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0x28; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x4a; + this->aics[aicIndex].AttUnitBackupMax = 0; + this->aics[aicIndex].AttUnitBackupGroupsCount = 0; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x49; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 4; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_14.cpp b/src/OpenSHC/AI/AICState/setAICParameters_14.cpp new file mode 100644 index 0000000000..64c2099b75 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_14.cpp @@ -0,0 +1,150 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CA0C0 + void AICState::setAICParameters_14(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 6000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 3; + this->aics[aicIndex].taxesMax = 0xb; + this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].farm2 = 0x1f; + this->aics[aicIndex].farm3 = 0x21; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 300; + this->aics[aicIndex].minimumApples = 0x14; + this->aics[aicIndex].minimumCheese = 0x14; + this->aics[aicIndex].minimumBread = 0xffffffff; + this->aics[aicIndex].minimumWheat = 0xffffffff; + this->aics[aicIndex].minimumHop = 2; + this->aics[aicIndex].tradeAmountFood = 10; + this->aics[aicIndex].tradeAmountEquipment = 2; + this->aics[aicIndex].aiRequestDelay = 0x28; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x28; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; + this->aics[aicIndex].maxWood = 0x32; + this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 10; + this->aics[aicIndex].maxBeer = 10; + this->aics[aicIndex].maxResourceVariance = 5; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 10; + this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].maxQuarries = 3; + this->aics[aicIndex].maxIronmines = 6; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 4; + this->aics[aicIndex].maxFarms = 10; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 8; + this->aics[aicIndex].blacksmithSetting = 0x15; + this->aics[aicIndex].fletcherSetting = 0x12; + this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource08 = 0x11; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 8; + this->aics[aicIndex].defWallPatrolGroups = 2; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x1e; + this->aics[aicIndex].recruitProbDefWeak = 100; + this->aics[aicIndex].recruitProbDefDefault = 0x32; + this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidWeak = 0; + this->aics[aicIndex].recruitProbRaidDefault = 0x1e; + this->aics[aicIndex].recruitProbRaidStrong = 0x32; + this->aics[aicIndex].recruitProbAttackWeak = 0; + this->aics[aicIndex].recruitProbAttackDefault = 0x14; + this->aics[aicIndex].recruitProbAttackStrong = 0x14; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 4; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 10; + this->aics[aicIndex].SortieUnitRanged = 0x17; + this->aics[aicIndex].SortieUnitMeleeMin = 10; + this->aics[aicIndex].SortieUnitMelee = 0x1a; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x1a; + this->aics[aicIndex].DefWalls = 0x28; + this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 5; + this->aics[aicIndex].DefUnit1 = 0x17; + this->aics[aicIndex].DefUnit2 = 0x17; + this->aics[aicIndex].RaidUnitsBase = 10; + this->aics[aicIndex].RaidUnitsRandom = 4; + this->aics[aicIndex].DefUnit3 = 0x17; + this->aics[aicIndex].DefUnit4 = 0x4c; + this->aics[aicIndex].DefUnit5 = 0x49; + this->aics[aicIndex].RaidUnit1 = 0x1a; + this->aics[aicIndex].HarassingSiegeEnginesMax = 5; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine2 = 0x166; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].AttForceBase = 0x32; + this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x32; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 5; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 8; + this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].CowThrowInterval = 6; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x27; + this->aics[aicIndex].SiegeEngine3 = 0x4d; + this->aics[aicIndex].SiegeEngine4 = 0x4d; + this->aics[aicIndex].SiegeEngine5 = 0x4d; + this->aics[aicIndex].AttMaxEngineers = 10; + this->aics[aicIndex].AttDiggingUnit = 0x47; + this->aics[aicIndex].AttDiggingUnitMax = 0x50; + this->aics[aicIndex].AttMaxAssassins = 10; + this->aics[aicIndex].AttUnit2 = 0x1a; + this->aics[aicIndex].AttUnit2Max = 10; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0x4c; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x17; + this->aics[aicIndex].AttUnitBackupMax = 0x32; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0x1a; + this->aics[aicIndex].AttUnitSiegeDefMax = 6; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; + this->aics[aicIndex].AttUnitMain1 = 0x1a; + this->aics[aicIndex].AttUnitMain2 = 0x1a; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 3; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_15.cpp b/src/OpenSHC/AI/AICState/setAICParameters_15.cpp new file mode 100644 index 0000000000..856ba40695 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_15.cpp @@ -0,0 +1,142 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + // FUNCTION: STRONGHOLDCRUSADER 0x004CA4D0 + void AICState::setAICParameters_15(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 4000; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 8000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 10; + this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].farm2 = 0x1f; + this->aics[aicIndex].farm3 = 0x21; + this->aics[aicIndex].farm4 = 0x21; + this->aics[aicIndex].populationPerFarm = 5; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = 10; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = 5; + this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x50; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].maxResourceOther = 0xc; + this->aics[aicIndex].maxEquipment = 10; + this->aics[aicIndex].maxBeer = 6; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 200; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 7; + this->aics[aicIndex].populationPerIronmine = 7; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 1; + this->aics[aicIndex].maxIronmines = 3; + this->aics[aicIndex].maxWoodcutters = 8; + this->aics[aicIndex].maxPitchrigs = 1; + this->aics[aicIndex].maxFarms = 9; + this->aics[aicIndex].buildInterval = 3; + this->aics[aicIndex].resourceRebuildDelay = 0x28; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource04 = 7; + this->aics[aicIndex].sellResource05 = 9; + this->aics[aicIndex].sellResource07 = 0x10; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x32; + this->aics[aicIndex].recruitProbDefDefault = 0x1e; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 0x28; + this->aics[aicIndex].recruitProbRaidDefault = 0x28; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 10; + this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 4; + this->aics[aicIndex].SortieUnitRangedMin = 4; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitMeleeMin = 4; + this->aics[aicIndex].SortieUnitMelee = 0x1c; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefDiggingUnit = 0x16; + this->aics[aicIndex].DefWalls = 0x1e; + this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].RaidUnitsBase = 0x10; + this->aics[aicIndex].RaidUnitsRandom = 4; + this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].HarassingSiegeEnginesMax = 1; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].AttForceBase = 10; + this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceSupportAllyThreshold = 10; + this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x46; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x28; + this->aics[aicIndex].SiegeEngine2 = 0x28; + this->aics[aicIndex].AttMaxEngineers = 6; + this->aics[aicIndex].AttDiggingUnit = 0x16; + this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x16; + this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackupGroupsCount = 3; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x1b; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAICParameters_16.cpp b/src/OpenSHC/AI/AICState/setAICParameters_16.cpp new file mode 100644 index 0000000000..2ce895b500 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAICParameters_16.cpp @@ -0,0 +1,144 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIC::AITargetChoice; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CA8A0 + void AICState::setAICParameters_16(int aicIndex) + { + this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].unknown002 = 0; + this->aics[aicIndex].unknown001 = 0; + this->aics[aicIndex].unknown003 = 0; + this->aics[aicIndex].unknown004 = 1; + this->aics[aicIndex].unknown005 = 1; + this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].lowestPopularity = 5000; + this->aics[aicIndex].highestPopularity = 9000; + this->aics[aicIndex].taxesMin = 2; + this->aics[aicIndex].taxesMax = 0xc; + this->aics[aicIndex].farm1 = 0x1f; + this->aics[aicIndex].farm2 = 0x1e; + this->aics[aicIndex].farm3 = 0x1e; + this->aics[aicIndex].populationPerFarm = 4; + this->aics[aicIndex].unknown011 = 10; + this->aics[aicIndex].maxFood = 100; + this->aics[aicIndex].minimumApples = 10; + this->aics[aicIndex].minimumCheese = -1; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = 2; + this->aics[aicIndex].minimumHop = 2; + this->aics[aicIndex].tradeAmountFood = 5; + this->aics[aicIndex].tradeAmountEquipment = 0; + this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; + this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; + this->aics[aicIndex].maxWood = 0x3c; + this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].maxResourceOther = 10; + this->aics[aicIndex].maxEquipment = 4; + this->aics[aicIndex].maxBeer = 5; + this->aics[aicIndex].maxResourceVariance = 4; + this->aics[aicIndex].recruitGoldThreshold = 0x32; + this->aics[aicIndex].populationPerWoodcutter = 7; + this->aics[aicIndex].populationPerQuarry = 6; + this->aics[aicIndex].populationPerIronmine = 10; + this->aics[aicIndex].populationPerPitchrig = 0; + this->aics[aicIndex].maxQuarries = 4; + this->aics[aicIndex].maxIronmines = 2; + this->aics[aicIndex].maxWoodcutters = 10; + this->aics[aicIndex].maxPitchrigs = 0; + this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].buildInterval = 2; + this->aics[aicIndex].resourceRebuildDelay = 0x28; + this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].fletcherSetting = 0x11; + this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].sellResource03 = 6; + this->aics[aicIndex].sellResource09 = 0x12; + this->aics[aicIndex].sellResource10 = 0x13; + this->aics[aicIndex].sellResource11 = 0x14; + this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource13 = 0x16; + this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].defWallPatrolRallyTime = 2; + this->aics[aicIndex].defWallPatrolGroups = 3; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; + this->aics[aicIndex].defSiegeEngineBuildDelay = 4; + this->aics[aicIndex].unknown072 = 200; + this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].recruitProbDefWeak = 0x50; + this->aics[aicIndex].recruitProbDefDefault = 0x28; + this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbRaidWeak = 10; + this->aics[aicIndex].RecruitIntervalWeak = 1; + this->aics[aicIndex].RecruitInterval = 1; + this->aics[aicIndex].RecruitIntervalStrong = 1; + this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].DefDiggingUnit = 0x16; + this->aics[aicIndex].OuterPatrolGroupsCount = 1; + this->aics[aicIndex].OuterPatrolGroupsMove = 1; + this->aics[aicIndex].OuterPatrolRallyDelay = 2; + this->aics[aicIndex].DefUnit1 = 0x16; + this->aics[aicIndex].recruitProbRaidDefault = 0x14; + this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackWeak = 10; + this->aics[aicIndex].recruitProbAttackDefault = 0x28; + this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].SortieUnitRangedMin = 4; + this->aics[aicIndex].SortieUnitMeleeMin = 0x14; + this->aics[aicIndex].SortieUnitMelee = 0x25; + this->aics[aicIndex].DefDiggingUnitMax = 4; + this->aics[aicIndex].DefWalls = 0x1e; + this->aics[aicIndex].DefTotal = 0x1e; + this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].RaidUnitsRandom = 10; + this->aics[aicIndex].RaidUnit1 = 0x25; + this->aics[aicIndex].HarassingSiegeEnginesMax = 5; + this->aics[aicIndex].RaidRetargetDelay = 4; + this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].AttForceBase = 0x32; + this->aics[aicIndex].AttForceRandom = 10; + this->aics[aicIndex].AttForceSupportAllyThreshold = 0x28; + this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttMovingTribesThreshold = 100; + this->aics[aicIndex].AttAssaultDelay = 0; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; + this->aics[aicIndex].AttCoordinationPreference = 0x50; + this->aics[aicIndex].CowThrowInterval = 10000; + this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine2 = 0x27; + this->aics[aicIndex].SiegeEngine3 = 0x27; + this->aics[aicIndex].SiegeEngine4 = 0x27; + this->aics[aicIndex].AttMaxEngineers = 8; + this->aics[aicIndex].AttDiggingUnit = 0x16; + this->aics[aicIndex].AttDiggingUnitMax = 10; + this->aics[aicIndex].AttMaxAssassins = 0; + this->aics[aicIndex].AttUnit2 = 0; + this->aics[aicIndex].AttUnit2Max = 0; + this->aics[aicIndex].AttMaxLaddermen = 0; + this->aics[aicIndex].AttMaxTunnelers = 0; + this->aics[aicIndex].AttUnitPatrol = 0; + this->aics[aicIndex].AttUnitPatrolMax = 0; + this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; + this->aics[aicIndex].AttUnitBackup = 0x16; + this->aics[aicIndex].AttUnitBackupMax = 0x28; + this->aics[aicIndex].AttUnitBackupGroupsCount = 1; + this->aics[aicIndex].AttUnitEngageMax = 0; + this->aics[aicIndex].AttUnitEngage = 0; + this->aics[aicIndex].AttUnitSiegeDef = 0; + this->aics[aicIndex].AttUnitSiegeDefMax = 0; + this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; + this->aics[aicIndex].AttUnitMain1 = 0x25; + this->aics[aicIndex].AttMaxDefault = 200; + this->aics[aicIndex].AttMainGroupsCount = 2; + this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; + return; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp new file mode 100644 index 0000000000..b6a98e4894 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp @@ -0,0 +1,33 @@ +#include "OpenSHC/Random/RNG.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0110 + void AICState::setAttackCoordinationLevel(int playerID) + { + int const _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (_aiType == AITA_NULL) { + return; + } + int _willingnessPercentage = this->aics[_aiType - 1].AttCoordinationPreference + + DAT_GameState::instance.playerDataArray[playerID].currentAttackWave * 4; + if (90 < _willingnessPercentage) { + _willingnessPercentage = 90; + } + int _rngMod100 = SEC_RNG::instance.currentNumber2 % 100; + MACRO_CALL_MEMBER(Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); + if (_rngMod100 < _willingnessPercentage / 2) { + DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel = 2; + return; + } + DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel + = _rngMod100 < _willingnessPercentage; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp new file mode 100644 index 0000000000..db0febac56 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp @@ -0,0 +1,25 @@ +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDFD0 + void AICState::setAttackPrimeInfo(int playerID, int attackedPlayerID) + { + int tile = DAT_GameState::instance.playerDataArray[playerID].shortestDistanceTile; + DAT_TroopValueState::instance.attackInfo.startZone = (char)DAT_TileMapState::instance.AIZoneLayer[tile]; + DAT_TroopValueState::instance.attackInfo.startCon = (short)DAT_TileMapState::instance.PathConnectionLayer[tile]; + DAT_TroopValueState::instance.attackInfo.zoneSize + = DAT_PathFindingState::instance.zoneSizesArray[DAT_TroopValueState::instance.attackInfo.startCon]; + DAT_TroopValueState::instance.attackInfo.unknownOne_0x20f90 = 1; + DAT_TroopValueState::instance.attackInfo.keepCon + = (short)DAT_TileMapState::instance + .PathConnectionLayer[DAT_GameState::instance.playerDataArray[attackedPlayerID].campground.tileEntry]; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp new file mode 100644 index 0000000000..879635162f --- /dev/null +++ b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp @@ -0,0 +1,37 @@ +#include "OpenSHC/Random/RNG.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CDE60 + void AICState::setCurrentAttackStrength(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) + return; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int randomPercent = SEC_RNG::instance.currentNumber2 % 100; + MACRO_CALL_MEMBER(Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); + + DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength + = (this->aics[aicIndex].AttForceRandom * randomPercent) / 100; + DAT_GameState::instance.playerDataArray[playerID].currentAttackWave++; + + if (DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] > 10000) { + DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength + += DAT_GameState::instance.playerDataArray[playerID].currentAttackWave * 7; + } else { + DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength + += DAT_GameState::instance.playerDataArray[playerID].currentAttackWave * 5; + } + + if (DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength > 200) { + DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength = 200; + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp new file mode 100644 index 0000000000..bf1b2a003d --- /dev/null +++ b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp @@ -0,0 +1,38 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF5E0 + void AICState::setEightTribe0xc0TribesToAggressiveAndAttack(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + for (int i = 0; i < 8; i++) { + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[i + 0xc0]; + if (tribeID == 0) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[i + 0xc0]) { + continue; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + continue; + } + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3f2); + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/setFoodBuyPlan.cpp b/src/OpenSHC/AI/AICState/setFoodBuyPlan.cpp index d556d1026f..780b9a3d4a 100644 --- a/src/OpenSHC/AI/AICState/setFoodBuyPlan.cpp +++ b/src/OpenSHC/AI/AICState/setFoodBuyPlan.cpp @@ -9,14 +9,16 @@ namespace OpenSHC { namespace AI { + using OpenSHC::AI::AITypeA; + using OpenSHC::Game::Resources::ResourceType; + // FUNCTION: STRONGHOLDCRUSADER 0x004CB060 void AICState::setFoodBuyPlan(int playerID) { - int const aiType = DAT_GameState::ptr->playerDataArray[playerID].aiType; // Early return if not an AI player (human player has aiType == 0) - if (aiType == AITA_NULL) { + if (aiType == AITypeA::AITA_NULL) { return; } @@ -28,36 +30,36 @@ namespace AI { // Apples: special handling with >= 0 check (allows -1 to disable) int const minimumApples = this->aics[aiConfigIndex].minimumApples; int* currentResources = DAT_GameState::ptr->playerDataArray[playerID].currentResources; - if (minimumApples >= 0 && currentResources[Game::Resources::RT_APPLE] < minimumApples) { - DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[Game::Resources::RT_APPLE] + if (minimumApples >= 0 && currentResources[ResourceType::RT_APPLE] < minimumApples) { + DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[ResourceType::RT_APPLE] = this->aics[aiConfigIndex].tradeAmountFood; } // Cheese: standard check with > 0 int const minimumCheese = this->aics[aiConfigIndex].minimumCheese; - if (minimumCheese > 0 && currentResources[Game::Resources::RT_CHEESE] < minimumCheese) { - DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[Game::Resources::RT_CHEESE] + if (minimumCheese > 0 && currentResources[ResourceType::RT_CHEESE] < minimumCheese) { + DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[ResourceType::RT_CHEESE] = this->aics[aiConfigIndex].tradeAmountFood; } // Bread: standard check with > 0 int const minimumBread = this->aics[aiConfigIndex].minimumBread; - if (minimumBread > 0 && currentResources[Game::Resources::RT_BREAD] < minimumBread) { - DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[Game::Resources::RT_BREAD] + if (minimumBread > 0 && currentResources[ResourceType::RT_BREAD] < minimumBread) { + DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[ResourceType::RT_BREAD] = this->aics[aiConfigIndex].tradeAmountFood; } // Wheat: standard check with > 0 int const minimumWheat = this->aics[aiConfigIndex].minimumWheat; - if (minimumWheat > 0 && currentResources[Game::Resources::RT_WHEAT] < minimumWheat) { - DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[Game::Resources::RT_WHEAT] + if (minimumWheat > 0 && currentResources[ResourceType::RT_WHEAT] < minimumWheat) { + DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[ResourceType::RT_WHEAT] = this->aics[aiConfigIndex].tradeAmountFood; } // Hops: standard check with > 0 int const minimumHop = this->aics[aiConfigIndex].minimumHop; - if (minimumHop > 0 && currentResources[Game::Resources::RT_HOPS] < minimumHop) { - DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[Game::Resources::RT_HOPS] + if (minimumHop > 0 && currentResources[ResourceType::RT_HOPS] < minimumHop) { + DAT_GameState::ptr->playerDataArray[playerID].resourcesToAcquireArray[ResourceType::RT_HOPS] = this->aics[aiConfigIndex].tradeAmountFood; } } diff --git a/src/OpenSHC/AI/AICState/setInitialAIC.cpp b/src/OpenSHC/AI/AICState/setInitialAIC.cpp new file mode 100644 index 0000000000..9ab0b2c856 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setInitialAIC.cpp @@ -0,0 +1,45 @@ +#include "../AICState.func.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D18B0 + void AICState::setInitialAIC() + { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::wipeAICMemory, this)(); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_01, this)(1); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_02, this)(2); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_03, this)(3); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_04, this)(4); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_05, this)(5); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_06, this)(6); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_07, this)(7); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_08, this)(8); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_09, this)(9); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_10, this)(10); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_11, this)(0xb); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_12, this)(0xc); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_13, this)(0xd); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_14, this)(0xe); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_15, this)(0xf); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setAICParameters_16, this)(0x10); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp new file mode 100644 index 0000000000..01b79f53fc --- /dev/null +++ b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp @@ -0,0 +1,25 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB1B0 + int AICState::setNextFarmTypeToBuild(PlayerID playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) + return 0; + int aicIndex = aiType - 1; + + DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex++; + if (DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex >= 8) + DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex = 0; + if ((&this->aics[aicIndex].farm1)[DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex] == 0) + DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex = 0; + return (&this->aics[aicIndex].farm1)[DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex]; + } +} +} diff --git a/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp b/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp new file mode 100644 index 0000000000..56eda53175 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp @@ -0,0 +1,38 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/LandscapeState.func.hpp" +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_LandscapeState.hpp" +#include "OpenSHC/Globals/DAT_PathFindingState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CE3B0 + void AICState::setNextMoveLocationForUnits(int playerID) + { + int organismID + = (short)DAT_TileMapState::instance.OrganismLayer + [DAT_ViewportRenderState::instance + .translationMatrix[DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY] + .addXgetTile + + DAT_GameState::instance.playerDataArray[playerID].shortestDistanceX]; + if (organismID != 0) { + MACRO_CALL_MEMBER(Map::LandscapeState_Func::removeTree, DAT_LandscapeState::ptr)(organismID); + } + + MACRO_CALL_MEMBER(Map::Navigation::PathFindingState_Func::findLinkageBasedPathOrWalkRadius, + DAT_PathFindingState::ptr)(DAT_GameState::instance.playerDataArray[playerID].shortestDistanceX, + DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY, -1, -1, 4000, FALSE); + MACRO_CALL_MEMBER(Map::Navigation::PathFindingState_Func::setDestinationPairsBasedOnPreviousSearch, + DAT_PathFindingState::ptr)( + playerID - 1, DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp b/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp new file mode 100644 index 0000000000..f9d369e1e6 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp @@ -0,0 +1,106 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Navigation/DirectionAlgorithmState.func.hpp" +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/AI/AIC/AITargetChoice.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" + +#include "OpenSHC/Globals/DAT_DirectionAlgorithmState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CACB0 + void AICState::setTargetForTribeBasedOnTargetChoiceLogic(int owner, int tribe) + { + if (DAT_GameState::instance.playerDataArray[owner].aiType == 0) { + return; + } + + int aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; + + int targetPlayer = 0; + int minDistance = 10000; + int maxGold = 0; + int minPoints = 1000000; + int ownerKeepX = DAT_GameState::instance.playerDataArray[owner].campground.xEntry; + int ownerKeepY = DAT_GameState::instance.playerDataArray[owner].campground.yEntry; + for (int player = 1; player < 9; player++) { + if (DAT_GameState::instance.mapAndTime.playerTeams[player] + == DAT_GameState::instance.mapAndTime.playerTeams[owner]) { + continue; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(player) + == 0) { + continue; + } + + MACRO_CALL_MEMBER(Map::Navigation::DirectionAlgorithmState_Func::setAxisBasedDistanceResult, + DAT_DirectionAlgorithmState::ptr)(DAT_GameState::instance.playerDataArray[player].campground.xEntry, + DAT_GameState::instance.playerDataArray[player].campground.yEntry, ownerKeepX, ownerKeepY); + + if (this->aics[aicIndex].TargetChoice == AIC::AITC_PLAYER) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] != -1 + && DAT_DirectionAlgorithmState::instance.distanceHigh <= minDistance) { + minDistance = DAT_DirectionAlgorithmState::instance.distanceHigh; + targetPlayer = player; + } + } else if (this->aics[aicIndex].TargetChoice == AIC::AITC_CLOSEST) { + if (DAT_DirectionAlgorithmState::instance.distanceHigh <= minDistance) { + minDistance = DAT_DirectionAlgorithmState::instance.distanceHigh; + targetPlayer = player; + } + } else if (this->aics[aicIndex].TargetChoice == AIC::AITC_GOLD) { + if (DAT_GameState::instance.playerDataArray[player].currentResources[Game::Resources::RT_GOLD] + >= maxGold) { + maxGold + = DAT_GameState::instance.playerDataArray[player].currentResources[Game::Resources::RT_GOLD]; + targetPlayer = player; + } + } else if (this->aics[aicIndex].TargetChoice == AIC::AITC_BALANCED) { + int points = DAT_GameState::instance.playerDataArray[player].currentPopulation * 5 + + DAT_GameState::instance.playerDataArray[player].totalTroopValue + + DAT_GameState::instance.playerDataArray[player].currentResources[Game::Resources::RT_GOLD] / 100 + + DAT_DirectionAlgorithmState::instance.distanceHigh * 2; + if (points <= minPoints) { + minPoints = points; + targetPlayer = player; + } + } + } + + if (targetPlayer == 0) { + // Fallback: pick the closest enemy with a living lord + for (int player = 1; player < 9; player++) { + if (DAT_GameState::instance.mapAndTime.playerTeams[player] + == DAT_GameState::instance.mapAndTime.playerTeams[owner]) { + continue; + } + if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(player) + == 0) { + continue; + } + + MACRO_CALL_MEMBER(Map::Navigation::DirectionAlgorithmState_Func::setAxisBasedDistanceResult, + DAT_DirectionAlgorithmState::ptr)(DAT_GameState::instance.playerDataArray[player].campground.xEntry, + DAT_GameState::instance.playerDataArray[player].campground.yEntry, ownerKeepX, ownerKeepY); + if (DAT_DirectionAlgorithmState::instance.distanceHigh <= minDistance) { + minDistance = DAT_DirectionAlgorithmState::instance.distanceHigh; + targetPlayer = player; + } + } + + if (targetPlayer == 0) { + return; + } + } + + DAT_TribesState::instance.tribes[tribe].targetPlayer_outpost = (short)targetPlayer; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp new file mode 100644 index 0000000000..ceaf2f197d --- /dev/null +++ b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp @@ -0,0 +1,42 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF560 + void AICState::setTribe0x11ToAggressiveAndAttackIfConditionMet(int playerID) + { + int tribeIndex = 17; + if (DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].moat2 <= 0) { + return; + } + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + return; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3f7); + } +} +} diff --git a/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp new file mode 100644 index 0000000000..5f96df8808 --- /dev/null +++ b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp @@ -0,0 +1,38 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF400 + void AICState::setTribe0xCtoAggressiveAndAttack(int playerID) + { + int tribeIndex = 12; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + return; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3f2); + } +} +} diff --git a/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp new file mode 100644 index 0000000000..ec4cde70ec --- /dev/null +++ b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp @@ -0,0 +1,38 @@ +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF6E0 + void AICState::setTribe0xbToAggressiveAndAttack(int playerID) + { + int tribeIndex = 11; + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return; + } + + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + if (tribeID == 0) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[tribeIndex]) { + return; + } + if (DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID == 0) { + return; + } + + DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_AGGRESSIVE; + MACRO_CALL_MEMBER(Map::Units::TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( + tribeID, Map::Units::STBT_0x3f2); + } +} +} diff --git a/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp b/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp new file mode 100644 index 0000000000..94036fdeca --- /dev/null +++ b/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp @@ -0,0 +1,85 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" +#include "OpenSHC/Game/Resources/ResourceTypeShort.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::Game::Resources::ResourceTypeShort; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CBE30 + void AICState::setupWorkshopProductionType(int playerID, int buildingID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AIT_NULL) { + return; + } + + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == Map::Buildings::BT_BLACKSMITH) { + int setting = this->aics[aicIndex].blacksmithSetting; + if (setting == -999) { + int itemType = MACRO_CALL_MEMBER( + Map::Buildings::BuildingsState_Func::chooseProductionItemType, DAT_BuildingsState::ptr)( + DAT_BuildingsState::instance.buildings[buildingID].owner, Map::Buildings::BT_BLACKSMITH); + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = (ResourceTypeShort)itemType; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = (ResourceTypeShort)itemType; + return; + } + if (setting == Game::Resources::RT_SWORD) { + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_SWORD; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_SWORD; + return; + } + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_MACE; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_MACE; + return; + } + + if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == Map::Buildings::BT_POLETURNER) { + int setting = this->aics[aicIndex].poleturnerSetting; + if (setting == -999) { + int itemType = MACRO_CALL_MEMBER( + Map::Buildings::BuildingsState_Func::chooseProductionItemType, DAT_BuildingsState::ptr)( + DAT_BuildingsState::instance.buildings[buildingID].owner, Map::Buildings::BT_POLETURNER); + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = (ResourceTypeShort)itemType; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = (ResourceTypeShort)itemType; + return; + } + if (setting == Game::Resources::RT_SPEAR) { + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_SPEAR; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_SPEAR; + return; + } + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_PIKE; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_PIKE; + return; + } + + if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == Map::Buildings::BT_FLETCHER) { + int setting = this->aics[aicIndex].fletcherSetting; + if (setting == -999) { + int itemType = MACRO_CALL_MEMBER( + Map::Buildings::BuildingsState_Func::chooseProductionItemType, DAT_BuildingsState::ptr)( + DAT_BuildingsState::instance.buildings[buildingID].owner, Map::Buildings::BT_FLETCHER); + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = (ResourceTypeShort)itemType; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = (ResourceTypeShort)itemType; + return; + } + if (setting == Game::Resources::RT_BOW) { + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_BOW; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_BOW; + return; + } + DAT_BuildingsState::instance.buildings[buildingID].producedItemType = Game::Resources::RT_CROSSBOW; + DAT_BuildingsState::instance.buildings[buildingID].producedItemTypeNext = Game::Resources::RT_CROSSBOW; + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp new file mode 100644 index 0000000000..da204a2690 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp @@ -0,0 +1,77 @@ +// disable deprecation warnings for strcpy +#pragma warning(disable : 4996) + +#include "../AICState.func.hpp" + +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/Synchrony/GameSynchronyState.func.hpp" +#include "OpenSHC/Text/TextManager.func.hpp" +#include "OpenSHC/DE/SHCDE/eTextSections.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" + +namespace OpenSHC { +namespace AI { + + // FIXME: The original function never sets a return value (eax is left over from the last computation), + // so it was most likely a void function. The header declares int, which forces the "return 0"s below + // and costs an extra "xor eax, eax" in the assembly. Change the return type to void in the header. + + // FUNCTION: STRONGHOLDCRUSADER 0x004D05D0 + void AICState::shareGoldAmongTeamMembers(int playerID, int gold) + { + int candidateCount = 0; + int candidates[9]; + for (int i = 1; i < 9; i++) { + if ((DAT_GameSynchronyState::instance.currentAIArray[i] != 0 + || DAT_GameSynchronyState::instance.currentPlayerFullIDArray[i] != -1) + && i != playerID + && DAT_GameState::instance.mapAndTime.playerTeams[i] + == DAT_GameState::instance.mapAndTime.playerTeams[playerID] + && DAT_GameState::instance.playerDataArray[i].lordKilledByPlayerID == 0) { + candidates[candidateCount] = i; + candidateCount++; + } + } + + if (candidateCount == 0) { + return; + } + + int goldPerPlayer = gold / candidateCount; + if (goldPerPlayer == 0) { + return; + } + + for (int j = 0; j < candidateCount; j++) { + int targetPlayer = candidates[j]; + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[targetPlayer] != -1) { + // "Goods received from ally" + strcpy(DAT_GameSynchronyState::instance.receivedChatMessage, + MACRO_CALL_MEMBER(Text::TextManager_Func::getTextStringInGroupAtOffset, DAT_TextManagerObject::ptr)( + DE::SHCDE::TEXT_ALLIES2, 1)); + MACRO_CALL_MEMBER(Synchrony::GameSynchronyState_Func::addChatMessageToDisplayList, + DAT_GameSynchronyState::ptr)(targetPlayer, 0); + + // "Gold" + MACRO_CALL(OS_Func::_sprintf)(DAT_GameSynchronyState::instance.receivedChatMessage, "%d %s - ", + goldPerPlayer, + MACRO_CALL_MEMBER(Text::TextManager_Func::getTextStringInGroupAtOffset, DAT_TextManagerObject::ptr)( + DE::SHCDE::TEXT_GOODS, Game::Resources::RT_GOLD)); + MACRO_CALL_MEMBER(Synchrony::GameSynchronyState_Func::addChatMessageToDisplayList, + DAT_GameSynchronyState::ptr)(targetPlayer, playerID); + } + + DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] + -= goldPerPlayer; + DAT_GameState::instance.playerDataArray[targetPlayer].currentResources[Game::Resources::RT_GOLD] + += goldPerPlayer; + } + return; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp b/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp new file mode 100644 index 0000000000..ea63343e26 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp @@ -0,0 +1,52 @@ +#include "OpenSHC/AI/AIVState.func.hpp" +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" +#include "OpenSHC/Game/Resources/ResourceType.hpp" +#include "OpenSHC/Map/Buildings/BuildingType.hpp" + +#include "OpenSHC/Globals/DAT_AIVState.hpp" +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB890 + BOOLEnum AICState::shouldDestroyWoodCutterUnk(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) { + return FALSE; + } + + int buildingID; + if (DAT_AIVState::instance.mapExtraInfo.totalWoodAvailable <= 0) { + buildingID = MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::findFirstBuildingIDForPlayerAndType, + DAT_BuildingsState::ptr)(playerID, Map::Buildings::BT_WOODCUTTERSHUT); + } else { + if (DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_WOOD] <= 20) { + return FALSE; + } + if (DAT_GameState::instance.playerDataArray[playerID].noLabourerBuildingCount < 2) { + return FALSE; + } + if (DAT_GameState::instance.playerDataArray[playerID].someCount10 < 25) { + return FALSE; + } + buildingID = DAT_GameState::instance.playerDataArray[playerID].someCount11; + } + + if (buildingID != 0) { + MACRO_CALL_MEMBER(AIVState_Func::resetCountdownInHeatMap, DAT_AIVState::ptr)( + (short)DAT_BuildingsState::instance.buildings[buildingID].x, + (short)DAT_BuildingsState::instance.buildings[buildingID].y); + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::giveBackResourceForDestroyedBuilding, + DAT_BuildingsState::ptr)(buildingID, playerID, 50); + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::destroyBuilding, DAT_BuildingsState::ptr)( + buildingID); + return TRUE; + } + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp new file mode 100644 index 0000000000..51ca939344 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004ECA60 + BOOLEnum AICState::shouldNotBeBuildingArmoury(PlayerID playerID, Commands::MappersEnum commandBuildingType) + { + if (commandBuildingType != Commands::M_MAPPER_ARMOURY) { + return FALSE; + } + return DAT_GameState::instance.playerDataArray[playerID].isArmouryAlmostFilledUp == 0; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp new file mode 100644 index 0000000000..5ef58f2766 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004ECA30 + BOOLEnum AICState::shouldNotBeBuildingGranary(int playerID, Commands::MappersEnum commandBuildingType) + { + if (commandBuildingType != Commands::M_MAPPER_GRANARY) { + return FALSE; + } + return DAT_GameState::instance.playerDataArray[playerID].granaryIsAlmostFilledUp == FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp new file mode 100644 index 0000000000..b674070c31 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp @@ -0,0 +1,36 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB5B0 + BOOLEnum AICState::shouldNotBeBuildingHovel(PlayerID playerID, Commands::MappersEnum param_2) + { + if (param_2 != Commands::M_MAPPER_HOVEL) { + return FALSE; + } + + int const populationCap = DAT_GameState::instance.playerDataArray[playerID].populationCap; + if (populationCap <= 12) { + return FALSE; + } + + if (DAT_GameState::instance.playerDataArray[playerID].currentPopulation < populationCap) { + return TRUE; + } + + if (DAT_GameState::instance.playerDataArray[playerID].previousAvailablePeasants >= 5) { + return TRUE; + } + + if (DAT_GameState::instance.playerDataArray[playerID].averagePopulationGrowthUnk >= 5) { + return TRUE; + } + + return DAT_GameState::instance.playerDataArray[playerID].popularity < 5000; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp b/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp new file mode 100644 index 0000000000..d44c311ef4 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_AIVState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004ECA90 + BOOLEnum AICState::shouldNotBuildKillingPits(int playerID, Commands::MappersEnum commandBuildingType) + { + if (commandBuildingType == Commands::M_MAPPER_KILLING_PIT) { + return DAT_AIVState::instance.mapExtraInfo.playerTotalKillingPits[playerID] >= 100; + } + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp new file mode 100644 index 0000000000..8d1ab8554c --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp @@ -0,0 +1,29 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB9F0 + BOOLEnum AICState::shouldNotBuildMarketArmoryGranaryBarracksMercenarypost( + int playerID, Commands::MappersEnum param_2) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker > 0) { + // nervous: reject market/mercenarypost/barracks/armory types + if (param_2 != Commands::M_MAPPER_TRADEPOST && param_2 != Commands::M_MAPPER_BARRACKS_EURO + && param_2 != Commands::M_MAPPER_BARRACKS_ARAB && param_2 != Commands::M_MAPPER_ARMOURY) { + return param_2 != Commands::M_MAPPER_GRANARY; + } + } else { + // not nervous: only reject if destroy tracker > 0 and not marketplace + if (DAT_GameState::instance.playerDataArray[playerID].aiBuildingDestroyChoiceTracker > 0 + && param_2 != Commands::M_MAPPER_TRADEPOST) { + return param_2 != Commands::M_MAPPER_GRANARY; + } + } + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp new file mode 100644 index 0000000000..83caadc1ea --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp @@ -0,0 +1,50 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB700 + BOOLEnum AICState::shouldWaitWithBuildingAPositiveFearFactor(int playerID, Commands::MappersEnum param_2) + { + switch (param_2) { + case Commands::M_MAPPER_GARDEN1: + case Commands::M_MAPPER_GARDEN2: + case Commands::M_MAPPER_GARDEN3: + case Commands::M_MAPPER_GARDEN4: + case Commands::M_MAPPER_GARDEN5: + case Commands::M_MAPPER_GARDEN6: + case Commands::M_MAPPER_GARDEN7: + case Commands::M_MAPPER_GARDEN8: + case Commands::M_MAPPER_GARDEN9: + case Commands::M_MAPPER_GARDEN10: + case Commands::M_MAPPER_GARDEN11: + case Commands::M_MAPPER_GARDEN12: + case Commands::M_MAPPER_MAYPOLE: + case Commands::M_MAPPER_STATUE1: + case Commands::M_MAPPER_STATUE2: + case Commands::M_MAPPER_STATUE3: + case Commands::M_MAPPER_STATUE4: + case Commands::M_MAPPER_STATUE5: + case Commands::M_MAPPER_SHRINE1: + case Commands::M_MAPPER_SHRINE2: + case Commands::M_MAPPER_SHRINE3: + case Commands::M_MAPPER_SHRINE4: + case Commands::M_MAPPER_SHRINE5: + case Commands::M_MAPPER_DANCING_BEAR: + case Commands::M_MAPPER_POND1: + case Commands::M_MAPPER_POND2_SMALL: + case Commands::M_MAPPER_POND3_LARGE1: + case Commands::M_MAPPER_POND4_LARGE2: + DAT_GameState::instance.playerDataArray[playerID].aivPositiveFearFactorDelay += 1; + if (DAT_GameState::instance.playerDataArray[playerID].aivPositiveFearFactorDelay < 200) { + return TRUE; + } + DAT_GameState::instance.playerDataArray[playerID].aivPositiveFearFactorDelay = 0; + } + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp new file mode 100644 index 0000000000..768c6f8de7 --- /dev/null +++ b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp @@ -0,0 +1,39 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CB610 + BOOLEnum AICState::shouldWaitWithBuildingNegativeFearFactor(int playerID, Commands::MappersEnum mapper) + { + switch (mapper) { + case Commands::M_MAPPER_GALLOWS: + case Commands::M_MAPPER_STOCKS: + case Commands::M_MAPPER_CESS_PIT1: + case Commands::M_MAPPER_CESS_PIT2: + case Commands::M_MAPPER_CESS_PIT3: + case Commands::M_MAPPER_CESS_PIT4: + case Commands::M_MAPPER_BURNING_STAKE: + case Commands::M_MAPPER_GIBBET: + case Commands::M_MAPPER_DUNGEON: + case Commands::M_MAPPER_RACK_STRETCHING: + case Commands::M_MAPPER_RACK_FLOGGING: + case Commands::M_MAPPER_CHOPPING_BLOCK: + case Commands::M_MAPPER_DUNKING_STOOL: + if (DAT_GameState::instance.playerDataArray[playerID].popularity < 5000) { + return TRUE; + } + DAT_GameState::instance.playerDataArray[playerID].aivNegativeFearFactorDelay++; + if (DAT_GameState::instance.playerDataArray[playerID].aivNegativeFearFactorDelay < 100) { + return TRUE; + } + DAT_GameState::instance.playerDataArray[playerID].aivNegativeFearFactorDelay = 0; + return FALSE; + } + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp new file mode 100644 index 0000000000..f6194c79a7 --- /dev/null +++ b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp @@ -0,0 +1,127 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/GameCore.func.hpp" +#include "OpenSHC/Random/RNG.func.hpp" +#include "OpenSHC/Synchrony/GameSynchronyState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/Commands/GameCommandType.hpp" +#include "OpenSHC/Game/GameMode.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/SEC_RNG.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::Commands::GameCommandType; + using OpenSHC::Game::GameMode; + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D10B0 + void AICState::someChatMessageSelection() + { + int candidates[9]; + int candidateCount; + int total; + int i; + int playerID; + + if ((MACRO_CALL_MEMBER(OpenSHC::Game::GameCore_Func::getAreWeInAInGameMenu, DAT_GameCore::ptr)() != FALSE) + && (DAT_GameSynchronyState::instance.currentGameMode == OpenSHC::Game::GM_SKIRMISH_SINGLE_PLAYER)) { + + if (this->aiTauntResponseTimeWindow == 0) { + return; + } + + if (timeGetTime() - this->aiTauntResponseTimeWindow <= 2000) { + return; + } + + candidateCount = 0; + // Players 1..8, manually unrolled by 4 in the original. + for (playerID = 1; playerID < 9; playerID += 4) { + if ((DAT_GameSynchronyState::instance.currentAIArray[playerID] != 0) + && (DAT_GameState::instance.mapAndTime.playerTeams[playerID] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { + candidates[candidateCount] = playerID; + candidateCount++; + } + if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 1] != 0) + && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 1] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { + candidates[candidateCount] = playerID + 1; + candidateCount++; + } + if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 2] != 0) + && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 2] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { + candidates[candidateCount] = playerID + 2; + candidateCount++; + } + if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 3] != 0) + && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 3] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { + candidates[candidateCount] = playerID + 3; + candidateCount++; + } + } + + if (candidateCount > 0) { + total = 0; + // NOTE: 'i = total' keeps the (redundant) loop entry check of the original. + for (i = total; i < candidateCount; i++) { + total += DAT_SkirmishDefinedData::instance + .MaxBreachTribes[DAT_GameState::instance.playerDataArray[candidates[i]].aiType + + OpenSHC::AI::AIT_FREDERICK] + .tribeType; + } + + if (total != 0) { + int roll = (int)SEC_RNG::instance.currentNumber1; + MACRO_CALL_MEMBER(OpenSHC::Random::RNG_Func::nextRandomNumber1, SEC_RNG::ptr)(); + roll = roll % total; + + for (i = 0; i < candidateCount; i++) { + playerID = candidates[i]; + roll -= DAT_SkirmishDefinedData::instance + .MaxBreachTribes[DAT_GameState::instance.playerDataArray[playerID].aiType + + OpenSHC::AI::AIT_FREDERICK] + .tribeType; + if (roll < 0) { + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[1] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[2] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[3] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[4] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[5] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[6] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[7] = 1; + DAT_GameSynchronyState::instance.DAT_ChatMessageReceiverArray[8] = 1; + DAT_GameSynchronyState::instance.DAT_ChatTauntOrMessage = -2 + - DAT_SkirmishDefinedData::instance + .MaxBreachTribes[DAT_GameState::instance.playerDataArray[playerID].aiType + + OpenSHC::AI::AIT_FREDERICK] + .tribeCount; + DAT_GameSynchronyState::instance.DAT_GameCommandParam0 = playerID; + MACRO_CALL_MEMBER(OpenSHC::Synchrony::GameSynchronyState_Func::queueCommand, + DAT_GameSynchronyState::ptr)(OpenSHC::Commands::GCT_TAUNT_OR_CHAT); + break; + } + } + } + } + } + + this->aiTauntResponseTimeWindow = 0; + } + +} +} diff --git a/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp new file mode 100644 index 0000000000..480816f066 --- /dev/null +++ b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp @@ -0,0 +1,52 @@ +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004D0190 + BOOLEnum AICState::teamIsWeakRelativeToEnemy(int playerID, BOOLEnum param_2) + { + // strength of the own team in percent of the enemy strength + int _relativeStrength; + if (DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue == 0) { + _relativeStrength = 100; + } else { + _relativeStrength = DAT_GameState::instance.playerDataArray[playerID].totalTeamTroopValue * 100 + / DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; + } + DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy = _relativeStrength; + + // the team counts as weak below a threshold that is lower with an enclosed keep + // and much higher during the first 12000 ticks + if (param_2) { + if (MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID)) { + if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 70) + return FALSE; + } else if ((int)DAT_GameCore::instance.mapTimeInTicks < 12000) { + if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 300) + return FALSE; + } else if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 100) { + return FALSE; + } + } else { + // without enemy ranged troops there is no reason to become nervous + if (DAT_GameState::instance.playerDataArray[playerID].totalEnemyRangedTroopValue < 100) + return FALSE; + if (MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID)) { + if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 50) + return FALSE; + } else if ((int)DAT_GameCore::instance.mapTimeInTicks < 12000) { + if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 250) + return FALSE; + } else if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 75) { + return FALSE; + } + } + return TRUE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp new file mode 100644 index 0000000000..393f1a259e --- /dev/null +++ b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp @@ -0,0 +1,27 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Game/Skirmish/SkirmishDefinedData.hpp" + +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::Game::Skirmish::SkirmishDefinedData; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CC8D0 + BOOLEnum AICState::unitIDIsRangedOrArmored(int unitID) + { + int _unitType = DAT_UnitsState::instance.units[unitID].unitType; + + for (int i = 0; i < 7; i++) { + if (DAT_SkirmishDefinedData::instance.RangedAndArmoredUnits[i] == _unitType) { + return TRUE; + } + } + + return FALSE; + } +} +} diff --git a/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp new file mode 100644 index 0000000000..eef4ddd574 --- /dev/null +++ b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp @@ -0,0 +1,94 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/TileMapState.func.hpp" +#include "OpenSHC/AI/AIRecruitUnitChoice.hpp" +#include "OpenSHC/AI/AIType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIRecruitUnitChoice; + using OpenSHC::AI::AIType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D53E0 + void AICState::updateAIBehaviour() + { + if (DAT_GameState::instance.mapAndTime.dayTicks == 10) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::makeOutpostTribesAttack, this)(); + + // every AI gets its own tick of the day, week and month, so the work is spread out + for (int _playerID = 1; _playerID < 9; _playerID++) { + if (DAT_GameState::instance.playerDataArray[_playerID].aiType == OpenSHC::AI::AIT_NULL) + continue; + if (DAT_GameState::instance.playerDataArray[_playerID].playerDeathRelated != 0) + continue; + if (DAT_GameState::instance.playerDataArray[_playerID].lordKilledByPlayerID != 0) + continue; + int _aicIndex = DAT_GameState::instance.playerDataArray[_playerID].aiType - 1; + + if (DAT_GameState::instance.mapAndTime.dayTicks == _playerID) { + if (DAT_GameState::instance.mapAndTime.skirmishNoRushTicks == 0) { + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieRangedUnits, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieMeleeUnits, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitUnits, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::recruitHarrassingSiegeEngines, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiAssignMoatDiggers, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiCreateSiegeUnits, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineers, this)(_playerID); + } + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiBuyAndSellGoods, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiGiveRaidInstructions, this)(_playerID); + } + + if (DAT_GameState::instance.mapAndTime.weekTicks == _playerID) { + if (DAT_GameState::instance.mapAndTime.skirmishNoRushTicks == 0) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineerForOilDuty, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateTribeLocations, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIPlayerState, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiUpdateTaxesAndRations, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setFoodBuyPlan, this)(_playerID); + + // on the month tick the strength update happens below, with the nervousness handling enabled + if (DAT_GameState::instance.mapAndTime.monthTicks != _playerID) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(_playerID, 0); + + if (DAT_GameState::instance.playerDataArray[_playerID].aiRequestDelay != 0) + DAT_GameState::instance.playerDataArray[_playerID].aiRequestDelay--; + if (DAT_GameState::instance.playerDataArray[_playerID].nervousBikCountdown != 0) + DAT_GameState::instance.playerDataArray[_playerID].nervousBikCountdown--; + if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown3 != 0) + DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown3--; + if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown4 != 0) + DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown4--; + if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown5 != 0) + DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown5--; + if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown6 != 0) + DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown6--; + } + + if (DAT_GameState::instance.mapAndTime.monthTicks == _playerID) { + MACRO_CALL_MEMBER( + OpenSHC::Map::TileMapState_Func::countMoatsOwnedByEachPlayer, DAT_TileMapState::ptr)(); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::instructTribe166ToMove, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::giveMoveCommandToSortieUnits, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(_playerID, 1); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::selectAttackTarget, this)(_playerID); + + if (DAT_GameState::instance.playerDataArray[_playerID].aiRecruitUnitChoiceState + == OpenSHC::AI::AIRUC_RAIDING) { + DAT_GameState::instance.playerDataArray[_playerID].canStartSpending = 1; + } else { + // only spend on recruiting while gold is above the AIC's threshold + DAT_GameState::instance.playerDataArray[_playerID].canStartSpending + = DAT_GameState::instance.playerDataArray[_playerID].currentResources[0xf] + > this->aics[_aicIndex].recruitGoldThreshold; + } + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/updateTribeLocations.cpp b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp new file mode 100644 index 0000000000..83f75e0371 --- /dev/null +++ b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp @@ -0,0 +1,58 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" + +#include "OpenSHC/Globals/DAT_EntityState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + + // FUNCTION: STRONGHOLDCRUSADER 0x004D4940 + void AICState::updateTribeLocations(int playerID) + { + AITypeInt _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + + if (_aiType == OpenSHC::AI::AIT_NULL) { + return; + } + + DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter + = DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter + 1; + + if (DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter + >= this->aics[_aiType - 1].defWallPatrolRallyTime) { + + DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeHits + = DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeHits + 1; + + DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter = 0; + } + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::ifHasTribe0SendUnitsToKeep, this)(playerID); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendTribeAtOffset1ToCampfire, this)(playerID); + + if (DAT_GameState::instance.mapAndTime.monthTicks == playerID) { + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::digNearestMoat, this)(playerID); + } + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendRangedUnitTribesToAIVSlotsOrKeepIfNervous, this)(playerID); + + MACRO_CALL_MEMBER( + OpenSHC::AI::AICState_Func::sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed, this)(playerID); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendWallPatrolUnitTribesToAIVLocations, this)(playerID); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendOilMenForOilPickupOrToAIVLocations, this)(playerID); + + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiGiveOuterPatrolCommand, this)(playerID); + } + +} +} diff --git a/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp new file mode 100644 index 0000000000..01599292d8 --- /dev/null +++ b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp @@ -0,0 +1,105 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/TroopValueState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeInt.hpp" +#include "OpenSHC/AI/Tribes/AITribeType.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" +#include "OpenSHC/Map/Units/UnitInstructionType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::AITypeInt; + using OpenSHC::AI::Tribes::AITribeType; + using OpenSHC::Commands::MappersEnum; + using OpenSHC::Map::Units::SomeTribeBehaviorType; + using OpenSHC::Map::Units::UnitInstructionType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CEFD0 + void AICState::useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers(int playerID) + { + int _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (_aiType == OpenSHC::AI::AIT_NULL) + return; + int _aicIndex = _aiType - 1; + int _aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + if (_aiTribeID == 0) + return; + if (DAT_TribesState::instance.tribes[_aiTribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0x12]) + return; + + int _availableEngineers = DAT_TribesState::instance.tribes[_aiTribeID].size; + int _requiredEngineers; + int _totalRequiredEngineers = 0; + + for (int i = 0; i < 8; i++) { + if ((&this->aics[_aicIndex].SiegeEngine1)[i] <= 0) + break; + for (int j = 0; j < 6; j++) { + if ((&this->aics[_aicIndex].SiegeEngine1)[i] + == DAT_SkirmishDefinedData::instance.SiegeEngineUnitType[j]) { + _requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; + break; + } + } + if (_totalRequiredEngineers + _requiredEngineers > _availableEngineers) + break; + _totalRequiredEngineers += _requiredEngineers; + } + + if (_totalRequiredEngineers <= 0) + return; + + for (; DAT_TribesState::instance.tribes[_aiTribeID].size != 0; _totalRequiredEngineers--) { + if (_totalRequiredEngineers <= 0) + break; + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)( + _aiTribeID); + } + + MappersEnum _siegeEngineType; + for (int i = 0; i < 8; i++) { + if ((&this->aics[_aicIndex].SiegeEngine1)[i] <= 0) + return; + for (int j = 0; j < 6; j++) { + if ((&this->aics[_aicIndex].SiegeEngine1)[i] + == DAT_SkirmishDefinedData::instance.SiegeEngineUnitType[j]) { + _requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; + _siegeEngineType + = (MappersEnum)DAT_SkirmishDefinedData::instance.SiegeEngineCommandBuildingTypes[j]; + break; + } + } + if (_requiredEngineers > _availableEngineers) + return; + _availableEngineers -= _requiredEngineers; + + int _tribeID = MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addEngineersToSelection, this)( + playerID, _requiredEngineers); + if (_tribeID == 0) + return; + + DAT_TribesState::instance.tribes[_tribeID].tribeType = OpenSHC::AI::Tribes::AITT_ENGINEERS; + DAT_TribesState::instance.tribes[_tribeID].tribeBehaviorType + = OpenSHC::Map::Units::STBT_0x410_SIEGE_EQUIPMENT_CONSTRUCTION; + DAT_TribesState::instance.tribes[_tribeID].attackWave + = DAT_GameState::instance.playerDataArray[playerID].currentAttackWave; + + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TroopValueState_Func::placeSiegeTentOrTunnelAtSuitableLocationAndAssignEngineers, + DAT_TroopValueState::ptr)(_tribeID, _siegeEngineType, 60, (UnitInstructionType)15); + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp new file mode 100644 index 0000000000..f9a3597ee4 --- /dev/null +++ b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp @@ -0,0 +1,67 @@ +#include "../AICState.func.hpp" + +#include "OpenSHC/Map/Units/TribesState.func.hpp" +#include "OpenSHC/Map/Units/TroopValueState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/Tribes/AITribeType.hpp" +#include "OpenSHC/Commands/MappersEnum.hpp" +#include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" +#include "OpenSHC/Map/Units/UnitInstructionType.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TribesState.hpp" +#include "OpenSHC/Globals/DAT_TroopValueState.hpp" + +namespace OpenSHC { +namespace AI { + + using OpenSHC::AI::AIType; + using OpenSHC::AI::Tribes::AITribeType; + using OpenSHC::Commands::MappersEnum; + using OpenSHC::Map::Units::SomeTribeBehaviorType; + using OpenSHC::Map::Units::UnitInstructionType; + + // FUNCTION: STRONGHOLDCRUSADER 0x004CF180 + void AICState::useAITribe_0xe_toPlaceTunnels(int playerID) + { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) + return; + int _aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0xe]; + if (_aiTribeID == 0) + return; + if (DAT_TribesState::instance.tribes[_aiTribeID].uid + != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0xe]) + return; + int _countdown = DAT_TribesState::instance.tribes[_aiTribeID].size; + + while (DAT_TribesState::instance.tribes[_aiTribeID].size != 0) { + if (_countdown <= 0) + break; + + int _unitID = MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)(_aiTribeID); + // Yes this line has to be right here for the code to match. + _countdown--; + + int _tribeID = MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); + + DAT_TribesState::instance.tribes[_tribeID].attackWave + = DAT_GameState::instance.playerDataArray[playerID].currentAttackWave; + + DAT_TribesState::instance.tribes[_tribeID].tribeType = OpenSHC::AI::Tribes::AITT_TUNNELERS; + + DAT_TribesState::instance.tribes[_tribeID].tribeBehaviorType = OpenSHC::Map::Units::STBT_0x415; + + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)( + _unitID, _tribeID); + + MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TroopValueState_Func::placeSiegeTentOrTunnelAtSuitableLocationAndAssignEngineers, + DAT_TroopValueState::ptr)( + _tribeID, OpenSHC::Commands::M_MAPPER_TUNNEL_CONSTRUCTION, 50, (UnitInstructionType)21); + } + } + +} +} diff --git a/src/OpenSHC/AI/AICState/wipeAICMemory.cpp b/src/OpenSHC/AI/AICState/wipeAICMemory.cpp new file mode 100644 index 0000000000..ed4a020351 --- /dev/null +++ b/src/OpenSHC/AI/AICState/wipeAICMemory.cpp @@ -0,0 +1,18 @@ +#include "OpenSHC/IO/LowLevelMemory.func.hpp" +#include "OpenSHC/AI/AICState.hpp" + +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004C6D30 + void AICState::wipeAICMemory() + { + for (int i = 0; i < 20; i++) { + MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 676, '\0', &this->aics[i]); + } + } +} +} diff --git a/src/OpenSHC/AI/AICState/yieldCowThrow.cpp b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp new file mode 100644 index 0000000000..c381e7b3ec --- /dev/null +++ b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp @@ -0,0 +1,29 @@ +#include "OpenSHC/AI/AICState.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004CFF60 + BOOLEnum AICState::yieldCowThrow(int playerID) + { + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType != AITA_NULL) { + int aicIndex = aiType - 1; + if (DAT_GameState::instance.mapAndTime.skirmishNoCowThrowing == 0 + && this->aics[aicIndex].CowThrowInterval != 0 + && DAT_GameState::instance.playerDataArray[playerID].counter > 0) { + DAT_GameState::instance.playerDataArray[playerID].aiCowThrowCounter++; + if (DAT_GameState::instance.playerDataArray[playerID].aiCowThrowCounter + > this->aics[aicIndex].CowThrowInterval) { + DAT_GameState::instance.playerDataArray[playerID].aiCowThrowCounter = 0; + return TRUE; + } + } + } + return FALSE; + } +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 238a0fe8a6..f4b9fd3855 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -34157,73 +34157,73 @@ SHC_3BB0A8C1_0x004C6CD0 | 0.0% | Pending SHC_3BB0A8C1_0x004C6D30 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C6D60 | 0.0% | Pending +SHC_3BB0A8C1_0x004C6D60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C7120 | 0.0% | Pending +SHC_3BB0A8C1_0x004C7120 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C7520 | 0.0% | Pending +SHC_3BB0A8C1_0x004C7520 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C7910 | 0.0% | Pending +SHC_3BB0A8C1_0x004C7910 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C7D20 | 0.0% | Pending +SHC_3BB0A8C1_0x004C7D20 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C8110 | 0.0% | Pending +SHC_3BB0A8C1_0x004C8110 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C8530 | 0.0% | Pending +SHC_3BB0A8C1_0x004C8530 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C8920 | 0.0% | Pending +SHC_3BB0A8C1_0x004C8920 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C8D20 | 0.0% | Pending +SHC_3BB0A8C1_0x004C8D20 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C9120 | 0.0% | Pending +SHC_3BB0A8C1_0x004C9120 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C94F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004C94F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C9900 | 0.0% | Pending +SHC_3BB0A8C1_0x004C9900 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004C9CF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004C9CF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CA0C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CA0C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CA4D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CA4D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CA8A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CA8A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CAC70 | 0.0% | Pending +SHC_3BB0A8C1_0x004CAC70 | 95.2% | Reimplemented -SHC_3BB0A8C1_0x004CACB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CACB0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CAD10 | 0.0% | Pending SHC_3BB0A8C1_0x004CAE20 | 0.0% | Pending -SHC_3BB0A8C1_0x004CAEA0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CAEA0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB060 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB120 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB150 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB150 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB180 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB180 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB1B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB1B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB220 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB220 | 97.8% | Reimplemented -SHC_3BB0A8C1_0x004CB290 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB290 | 98.1% | Reimplemented -SHC_3BB0A8C1_0x004CB330 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB330 | 97.5% | Reimplemented -SHC_3BB0A8C1_0x004CB3A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB3A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB4D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB4D0 | 97.5% | Reimplemented -SHC_3BB0A8C1_0x004CB540 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB540 | 97.5% | Reimplemented -SHC_3BB0A8C1_0x004CB5B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB5B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB610 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB610 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB66C | 0.0% | Pending @@ -34501,7 +34501,7 @@ SHC_3BB0A8C1_0x004CB6FA | 0.0% | Pending SHC_3BB0A8C1_0x004CB6FB | 0.0% | Pending -SHC_3BB0A8C1_0x004CB700 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB700 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB754 | 0.0% | Pending @@ -34845,55 +34845,55 @@ SHC_3BB0A8C1_0x004CB803 | 0.0% | Pending SHC_3BB0A8C1_0x004CB804 | 0.0% | Pending -SHC_3BB0A8C1_0x004CB810 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB810 | 92.3% | Reimplemented -SHC_3BB0A8C1_0x004CB890 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB890 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB940 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB940 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB9F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CB9F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CBA50 | 0.0% | Pending +SHC_3BB0A8C1_0x004CBA50 | 90.7% | flag slot order differs -SHC_3BB0A8C1_0x004CBE30 | 0.0% | Pending +SHC_3BB0A8C1_0x004CBE30 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CBFA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC000 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004CC000 | 92.9% | Reimplemented -SHC_3BB0A8C1_0x004CC070 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC070 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC250 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC250 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC390 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC390 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC420 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC420 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC520 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC520 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC5A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC5A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC680 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC680 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CC6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CC720 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC720 | 95.2% | Reimplemented -SHC_3BB0A8C1_0x004CC7B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC7B0 | 95.2% | Reimplemented -SHC_3BB0A8C1_0x004CC840 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC840 | 94.3% | Reimplemented -SHC_3BB0A8C1_0x004CC8D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC8D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC910 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC910 | 97.1% | Reimplemented -SHC_3BB0A8C1_0x004CC990 | 0.0% | Pending +SHC_3BB0A8C1_0x004CC990 | 56.6% | regalloc/locals differ -SHC_3BB0A8C1_0x004CCAF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CCAF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CCBE0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CCBE0 | 99.0% | Reimplemented -SHC_3BB0A8C1_0x004CCD20 | 0.0% | Pending +SHC_3BB0A8C1_0x004CCD20 | 66.0% | frame and regalloc differ SHC_3BB0A8C1_0x004CCEDC | 0.0% | Pending @@ -35261,289 +35261,289 @@ SHC_3BB0A8C1_0x004CCFA0 | 0.0% | Pending SHC_3BB0A8C1_0x004CCFA1 | 0.0% | Pending -SHC_3BB0A8C1_0x004CCFB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CCFB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD070 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD070 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD0C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD0C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD110 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD110 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD160 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD160 | 91.7% | Register allocation differs -SHC_3BB0A8C1_0x004CD250 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD250 | 94.7% | Reimplemented -SHC_3BB0A8C1_0x004CD2A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD2A0 | 59.60% | Reimplemented functionally, code block ordering problem -SHC_3BB0A8C1_0x004CD560 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD560 | 95.2% | Reimplemented -SHC_3BB0A8C1_0x004CD690 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD690 | 94.9% | Reimplemented -SHC_3BB0A8C1_0x004CD7B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD7B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD8F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CD8F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDA50 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDA50 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDAB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDAB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDB20 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDB20 | 44.4% | regalloc/spill differs -SHC_3BB0A8C1_0x004CDBC0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDBC0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDCA0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDCA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDCF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDCF0 | 77.2% | regalloc/counters differ -SHC_3BB0A8C1_0x004CDE60 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDE60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDF10 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDF10 | 98.2% | Reimplemented -SHC_3BB0A8C1_0x004CDFD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CDFD0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE040 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE040 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE110 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE110 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE1A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE1A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE200 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE200 | 64.5% | spilled local differs SHC_3BB0A8C1_0x004CE270 | 0.0% | Pending -SHC_3BB0A8C1_0x004CE3B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE3B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE430 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE430 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE4D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE4D0 | 93.8% | Reimplemented SHC_3BB0A8C1_0x004CE530 | 0.0% | Pending -SHC_3BB0A8C1_0x004CE5F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE5F0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CE660 | 0.0% | Pending SHC_3BB0A8C1_0x004CE6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CE790 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE790 | 98.0% | Reimplemented -SHC_3BB0A8C1_0x004CE830 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE830 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CE860 | 0.0% | Pending SHC_3BB0A8C1_0x004CE890 | 0.0% | Pending -SHC_3BB0A8C1_0x004CE930 | 0.0% | Pending +SHC_3BB0A8C1_0x004CE930 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CEA50 | 0.0% | Pending +SHC_3BB0A8C1_0x004CEA50 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CEB50 | 0.0% | Pending +SHC_3BB0A8C1_0x004CEB50 | 98.8% | Reimplemented SHC_3BB0A8C1_0x004CEB80 | 0.0% | Pending -SHC_3BB0A8C1_0x004CEC80 | 0.0% | Pending +SHC_3BB0A8C1_0x004CEC80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CED90 | 0.0% | Pending +SHC_3BB0A8C1_0x004CED90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CEEA0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CEEA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CEFD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CEFD0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CF060 | 0.0% | Pending -SHC_3BB0A8C1_0x004CF180 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF180 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF270 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF270 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF2E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF2E0 | 94.7% | esi/edi regalloc differs -SHC_3BB0A8C1_0x004CF400 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF400 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF470 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF470 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF4F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF4F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF560 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF560 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF5E0 | 100.0% | Reimplemented without for-loop +SHC_3BB0A8C1_0x004CF5E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF660 | 100.0% | Reimplemented without for-loop +SHC_3BB0A8C1_0x004CF660 | 97.2% | Reimplemented -SHC_3BB0A8C1_0x004CF6E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF6E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF750 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF750 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF7C0 | 100.0% | Reimplemented, for-loop didn't work +SHC_3BB0A8C1_0x004CF7C0 | 98.2% | Reimplemented SHC_3BB0A8C1_0x004CF7F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CF870 | 100.0% | Reimplemented, for-loop didn't work +SHC_3BB0A8C1_0x004CF870 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF920 | 0.0% | Pending +SHC_3BB0A8C1_0x004CF920 | 96.9% | Reimplemented -SHC_3BB0A8C1_0x004CFA10 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFA10 | 96.9% | Reimplemented -SHC_3BB0A8C1_0x004CFB20 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFB20 | 97.8% | Reimplemented -SHC_3BB0A8C1_0x004CFBC0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFBC0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CFCD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFCD0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CFF60 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFF60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CFFD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004CFFD0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D00A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D00A0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D0110 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0190 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0190 | 100.0% | Reimplemented, compiler didn't optimize one tail -SHC_3BB0A8C1_0x004D0280 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0280 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0520 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0520 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0580 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0580 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D05D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D05D0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D0720 | 0.0% | Pending -SHC_3BB0A8C1_0x004D07C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D07C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0830 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0830 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D08B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D08B0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D0910 | 0.0% | Pending -SHC_3BB0A8C1_0x004D0A20 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0A20 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0A80 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0A80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0B10 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0B10 | 68.0% | Load scheduling differs -SHC_3BB0A8C1_0x004D0B70 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0B70 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0BB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0BB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0C00 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0C00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0C70 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0C70 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0CF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0CF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0D40 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0D40 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0DB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0DB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0E00 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0E00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0E50 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0E50 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0EA0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0EA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0EF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0EF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0F40 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0F40 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0F90 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0F90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0FC0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D0FC0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1000 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1000 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1050 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1050 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1090 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1090 | 90.0% | Reimplemented -SHC_3BB0A8C1_0x004D10B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D10B0 | 100.0% | Reimplemented, one reordered push edi SHC_3BB0A8C1_0x004D11C0 | 0.0% | Pending SHC_3BB0A8C1_0x004D12A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1320 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1320 | 72.3% | Style pass, asm differs SHC_3BB0A8C1_0x004D1700 | 0.0% | Pending SHC_3BB0A8C1_0x004D1710 | 0.0% | Pending -SHC_3BB0A8C1_0x004D18B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D18B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1950 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1950 | 98.0% | Reimplemented -SHC_3BB0A8C1_0x004D1A00 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1A00 | 58.0% | Register allocation differs -SHC_3BB0A8C1_0x004D1D60 | 0.0% | Pending +SHC_3BB0A8C1_0x004D1D60 | 62.4% | register permutation -SHC_3BB0A8C1_0x004D1F00 | 100.0% | Reimplemented, for-loop didn't work +SHC_3BB0A8C1_0x004D1F00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2000 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2000 | 41.9% | regalloc/frame differ SHC_3BB0A8C1_0x004D2080 | 0.0% | Pending SHC_3BB0A8C1_0x004D20C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D2500 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2500 | 94.6% | Reimplemented -SHC_3BB0A8C1_0x004D2660 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2660 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2730 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2730 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2790 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D2790 | 91.3% | Reimplemented -SHC_3BB0A8C1_0x004D27E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D27E0 | 92.0% | Reimplemented SHC_3BB0A8C1_0x004D2830 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2870 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2870 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D28B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D28B0 | 86.3% | select call block layout diffe -SHC_3BB0A8C1_0x004D2A70 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2A70 | 54.3% | regalloc/spills differ -SHC_3BB0A8C1_0x004D2E00 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2E00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2EC0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2EC0 | 74.1% | Call diffs, load order differs -SHC_3BB0A8C1_0x004D2F80 | 0.0% | Pending +SHC_3BB0A8C1_0x004D2F80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D30E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D30E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D3320 | 0.0% | Pending +SHC_3BB0A8C1_0x004D3320 | 97.2% | ebp/ebx regalloc differs -SHC_3BB0A8C1_0x004D3780 | 0.0% | Pending +SHC_3BB0A8C1_0x004D3780 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D3850 | 0.0% | Pending +SHC_3BB0A8C1_0x004D3850 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D38C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D38C0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D3940 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D3960 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D39B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D39B0 | 96.6% | Reimplemented SHC_3BB0A8C1_0x004D39F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D3AE0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D3AE0 | 43.4% | regalloc/spills differ -SHC_3BB0A8C1_0x004D3F20 | 0.0% | Pending +SHC_3BB0A8C1_0x004D3F20 | 97.4% | Reimplemented -SHC_3BB0A8C1_0x004D4040 | 100.0% | Reimplemented, for loop didn't work +SHC_3BB0A8C1_0x004D4040 | 97.0% | Reimplemented -SHC_3BB0A8C1_0x004D40B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D40B0 | 94.9% | Reimplemented SHC_3BB0A8C1_0x004D4130 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D4220 | 0.0% | Pending +SHC_3BB0A8C1_0x004D4220 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D4340 | 0.0% | Pending +SHC_3BB0A8C1_0x004D4340 | 54.63% | Reimplemented, different register usage SHC_3BB0A8C1_0x004D4400 | 0.0% | Pending -SHC_3BB0A8C1_0x004D44E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D44E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4530 | 0.0% | Pending @@ -35551,15 +35551,15 @@ SHC_3BB0A8C1_0x004D45E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4630 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D4680 | 0.0% | Pending +SHC_3BB0A8C1_0x004D4680 | 64.80% | Stuck, register usage SHC_3BB0A8C1_0x004D4870 | 0.0% | Pending -SHC_3BB0A8C1_0x004D48F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D48F0 | 86.7% | Register allocation differs -SHC_3BB0A8C1_0x004D4940 | 0.0% | Pending +SHC_3BB0A8C1_0x004D4940 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D49E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D49E0 | 52.84% | Register allocation differences, logic checks out SHC_3BB0A8C1_0x004D5010 | 100.0% | Reimplemented @@ -35571,7 +35571,7 @@ SHC_3BB0A8C1_0x004D5370 | 0.0% | Pending SHC_3BB0A8C1_0x004D53A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D53E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004D53E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D55D0 | 0.0% | Pending From 58bf771b6467f08ea5e6a179cc462432ca30d662 Mon Sep 17 00:00:00 2001 From: Gynt Date: Fri, 16 Oct 2026 23:29:41 +0200 Subject: [PATCH 02/10] style improvements --- .../AICState/aiCommandSiegeEngineTribes.cpp | 11 +- src/OpenSHC/AI/AICState/aiFarmChoice.cpp | 2 +- ...determineAIPlayerAttackRequestResponse.cpp | 3 +- .../getTargetableBuildingForPlayerID.cpp | 4 +- .../AI/AICState/getUnitTypeIndexForUnitID.cpp | 30 ++-- .../AI/AICState/recreateEngineersTribe.cpp | 6 +- ...andomBuildingIDFromListOfBuildingTypes.cpp | 2 +- ...gedUnitTribesToAIVSlotsOrKeepIfNervous.cpp | 5 +- .../AICState/sendTribeAtOffset1ToCampfire.cpp | 8 +- .../AI/AICState/setAICParameters_01.cpp | 110 +++++++------- .../AI/AICState/setAICParameters_02.cpp | 134 +++++++++--------- .../AI/AICState/setAICParameters_03.cpp | 104 +++++++------- .../AI/AICState/setAICParameters_04.cpp | 124 ++++++++-------- .../AI/AICState/setAICParameters_05.cpp | 126 ++++++++-------- .../AI/AICState/setAICParameters_06.cpp | 126 ++++++++-------- .../AI/AICState/setAICParameters_07.cpp | 98 ++++++------- .../AI/AICState/setAICParameters_08.cpp | 102 ++++++------- .../AI/AICState/setAICParameters_09.cpp | 122 ++++++++-------- .../AI/AICState/setAICParameters_10.cpp | 100 ++++++------- .../AI/AICState/setAICParameters_11.cpp | 112 +++++++-------- .../AI/AICState/setAICParameters_12.cpp | 114 +++++++-------- .../AI/AICState/setAICParameters_13.cpp | 110 +++++++------- .../AI/AICState/setAICParameters_14.cpp | 128 ++++++++--------- .../AI/AICState/setAICParameters_15.cpp | 98 ++++++------- .../AI/AICState/setAICParameters_16.cpp | 106 +++++++------- .../AICState/setAttackCoordinationLevel.cpp | 17 ++- .../AI/AICState/setNextFarmTypeToBuild.cpp | 2 +- .../AICState/shouldNotBeBuildingArmoury.cpp | 2 +- .../AI/AICState/shouldNotBeBuildingHovel.cpp | 4 +- ...rketArmoryGranaryBarracksMercenarypost.cpp | 12 +- ...uldWaitWithBuildingAPositiveFearFactor.cpp | 4 +- .../AI/AICState/teamIsWeakRelativeToEnemy.cpp | 12 +- .../AI/AICState/unitIDIsRangedOrArmored.cpp | 4 +- src/OpenSHC/AI/AICState/updateAIBehaviour.cpp | 90 ++++++------ .../AI/AICState/updateTribeLocations.cpp | 6 +- ...12_toPlaceSiegeTentsAndAssignEngineers.cpp | 66 +++++---- .../useAITribe_0xe_toPlaceTunnels.cpp | 30 ++-- 37 files changed, 1066 insertions(+), 1068 deletions(-) diff --git a/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp index a7da318069..ec02d29736 100644 --- a/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp @@ -55,20 +55,17 @@ namespace AI { int tribeID = DAT_UnitsState::instance.units[unitID].tribeID; if (tribeID == 0) continue; - if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.wideValuesArray + playerID * 0x177bc - 4) - != 0) + if (DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].wide3 != 0) MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( tribeID, STBT_0x414); } else if (DAT_UnitsState::instance.units[unitID].unitType == UT_S_BATTERINGRAM) { int tribeID = DAT_UnitsState::instance.units[unitID].tribeID; if (tribeID == 0) continue; - if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.gateValuesArray + playerID * 0x177bc - 4) - != 0) + if (DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].gate2 != 0) MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( tribeID, STBT_0x3f6); - else if (*(int*)((int)DAT_TroopValueState::instance.attackInfo.wideValuesArray + playerID * 0x177bc - 4) - != 0) + else if (DAT_TroopValueState::instance.attackInfo.playerInfo[playerID - 1].wide3 != 0) MACRO_CALL_MEMBER(TribesState_Func::assignAttackTargetsForTribe, DAT_TribesState::ptr)( tribeID, STBT_0x413); } else if (DAT_UnitsState::instance.units[unitID].unitType == UT_S_SHIELD) { @@ -79,7 +76,7 @@ namespace AI { continue; int targetTribeID = shieldTargetTribeIDs[shieldCount]; - DAT_TribesState::instance.tribes[tribeID].field56_0x1f2 = targetTribeID; + DAT_TribesState::instance.tribes[tribeID].supportTribeID = targetTribeID; DAT_TribesState::instance.tribes[tribeID].uid2 = DAT_TribesState::instance.tribes[targetTribeID].uid; DAT_TribesState::instance.tribes[targetTribeID].tribeID = tribeID; int targetUnitID = DAT_TribesState::instance.tribes[targetTribeID].selectionTargetUnitID; diff --git a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp index 46898001b6..9fcb0d9aaa 100644 --- a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp +++ b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp @@ -7,7 +7,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB180 - int AICState::aiFarmChoice(PlayerID playerID) + int AICState::aiFarmChoice(int playerID) { int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp index 2ec92a0c93..729f153427 100644 --- a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp +++ b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp @@ -8,7 +8,8 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D38C0 - BOOLEnum AICState::determineAIPlayerAttackRequestResponse(int playerID, undefined4 param_2, int requestedByPlayerID) + BOOLEnum AICState::determineAIPlayerAttackRequestResponse( + int playerID, undefined4 targetPlayerID, int requestedByPlayerID) { if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) return FALSE; diff --git a/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp index 83fa94d22d..63e303b6ae 100644 --- a/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp +++ b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp @@ -8,7 +8,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CDBC0 - int AICState::getTargetableBuildingForPlayerID(int playerID, int param_2) + int AICState::getTargetableBuildingForPlayerID(int playerID, int patrolGroupIndex) { if (DAT_GameState::instance.playerDataArray[playerID].aiType == 0) return 0; @@ -24,7 +24,7 @@ namespace AI { if (DAT_GameState::instance.playerDataArray[playerID].someCounter2 >= DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker) DAT_GameState::instance.playerDataArray[playerID].someCounter2 = 0; - int index = (step * param_2 + DAT_GameState::instance.playerDataArray[playerID].someCounter2) + int index = (step * patrolGroupIndex + DAT_GameState::instance.playerDataArray[playerID].someCounter2) % DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; for (int i = 0; i < DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; i++) { int buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; diff --git a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp index 1c29a67df2..1d6df9d485 100644 --- a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp +++ b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp @@ -17,39 +17,39 @@ namespace AI { using OpenSHC::Map::Units::UnitTypeShort; // FUNCTION: STRONGHOLDCRUSADER 0x004CC390 - AIVUnitType AICState::getUnitTypeIndexForUnitID(int unitID, int param_2) + AIVUnitType AICState::getUnitTypeIndexForUnitID(int unitID, int allowSlaveSlotForRanged) { - UnitTypeShort _unitType = DAT_UnitsState::instance.units[unitID].unitType; - int _playerID = DAT_UnitsState::instance.units[unitID].owner; - UnitTypeInt _unitType2; - if (_unitType == OpenSHC::Map::Units::UT_PEASANT) { - _unitType2 = DAT_UnitsState::instance.units[unitID].unitTypeToChangeInto; + UnitTypeShort unitType = DAT_UnitsState::instance.units[unitID].unitType; + int owner = DAT_UnitsState::instance.units[unitID].owner; + UnitTypeInt effectiveUnitType; + if (unitType == OpenSHC::Map::Units::UT_PEASANT) { + effectiveUnitType = DAT_UnitsState::instance.units[unitID].unitTypeToChangeInto; } else { - _unitType2 = _unitType; + effectiveUnitType = unitType; } // 6 is the Caliph's AIC index: he fields slaves rather than the ranged units listed below - if (DAT_GameState::instance.playerDataArray[_playerID].aiType - 1 != 6 && param_2 != 0 - && DAT_GameState::instance.playerDataArray[_playerID].aivUnitLocationSlotLocationCount[0xd] > 0) { - if (_unitType2 == OpenSHC::Map::Units::UT_E_ARCHER) { + if (DAT_GameState::instance.playerDataArray[owner].aiType - 1 != 6 && allowSlaveSlotForRanged != 0 + && DAT_GameState::instance.playerDataArray[owner].aivUnitLocationSlotLocationCount[0xd] > 0) { + if (effectiveUnitType == OpenSHC::Map::Units::UT_E_ARCHER) { return OpenSHC::AI::AIVUT_SLAVE; } - if (_unitType2 == OpenSHC::Map::Units::UT_E_XBOW) { + if (effectiveUnitType == OpenSHC::Map::Units::UT_E_XBOW) { return OpenSHC::AI::AIVUT_SLAVE; } - if (_unitType2 == OpenSHC::Map::Units::UT_A_ARCHER) { + if (effectiveUnitType == OpenSHC::Map::Units::UT_A_ARCHER) { return OpenSHC::AI::AIVUT_SLAVE; } - if (_unitType2 == OpenSHC::Map::Units::UT_A_SLINGER) { + if (effectiveUnitType == OpenSHC::Map::Units::UT_A_SLINGER) { return OpenSHC::AI::AIVUT_SLAVE; } - if (_unitType2 == OpenSHC::Map::Units::UT_A_FIRETHROWER) { + if (effectiveUnitType == OpenSHC::Map::Units::UT_A_FIRETHROWER) { return OpenSHC::AI::AIVUT_SLAVE; } } for (int someUnitTypeIndex = 0; someUnitTypeIndex < 0x14; someUnitTypeIndex++) { - if (DAT_SkirmishDefinedData::instance.SomeAIUnitTypeArray[someUnitTypeIndex] == _unitType2) { + if (DAT_SkirmishDefinedData::instance.SomeAIUnitTypeArray[someUnitTypeIndex] == effectiveUnitType) { return (AIVUnitType)someUnitTypeIndex; } } diff --git a/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp index ea0aff1d74..51fe48834f 100644 --- a/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp +++ b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp @@ -12,9 +12,9 @@ namespace AI { if (0 >= DAT_GameState::instance.playerDataArray[playerID].totalAttackingEngineerTroops) { return; } - int _tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; - if (_tribeID != 0) { - if (DAT_TribesState::instance.tribes[_tribeID].uid + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + if (tribeID != 0) { + if (DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0x12]) { DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12] = 0; } diff --git a/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp index c5845f0bb8..a00adfbeb7 100644 --- a/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp +++ b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp @@ -9,7 +9,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CDCA0 - int AICState::selectRandomBuildingIDFromListOfBuildingTypes(int playerID, undefined4 param_2) + int AICState::selectRandomBuildingIDFromListOfBuildingTypes(int playerID, undefined4 raidTribeIndex) { int count = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; if (count <= 0) { diff --git a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp index 0110e7fed0..3ee27482bb 100644 --- a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp +++ b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp @@ -3,6 +3,7 @@ #include "OpenSHC/AI/AIVUnitType.hpp" #include "OpenSHC/AI/AIVUnitTypeInt.hpp" #include "OpenSHC/AI/Tribes/AIVUnitTypeMaxLocationPair.hpp" +#include "OpenSHC/Map/LogicHelpers/Logic1.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp" @@ -16,6 +17,8 @@ namespace AI { using OpenSHC::AI::AIVUnitType; using OpenSHC::AI::AIVUnitTypeInt; using OpenSHC::AI::Tribes::AIVUnitTypeMaxLocationPair; + using OpenSHC::Map::LogicHelpers::L_KEEP_NON_MANOR_HOUSE; + using OpenSHC::Map::LogicHelpers::L_WALL_OR_GATEHOUSE; // FUNCTION: STRONGHOLDCRUSADER 0x004D4130 void AICState::sendRangedUnitTribesToAIVSlotsOrKeepIfNervous(int playerID) @@ -42,7 +45,7 @@ namespace AI { if ((DAT_TileMapState::instance.LogicLayer[DAT_UnitsState::instance .units[DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID] .tile] - & 0x10000100U) + & (L_KEEP_NON_MANOR_HOUSE | L_WALL_OR_GATEHOUSE)) == 0) { MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sendUnitsToKeep, this)(tribeID, playerID); } diff --git a/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp index 272c3b113d..287a244167 100644 --- a/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp +++ b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp @@ -9,13 +9,13 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2870 void AICState::sendTribeAtOffset1ToCampfire(int playerID) { - int _tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[1]; - if (_tribeID <= 0) + int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[1]; + if (tribeID <= 0) return; - if (DAT_TribesState::instance.tribes[_tribeID].uid + if (DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[1]) return; - MACRO_CALL_MEMBER(AICState_Func::sendUnitsToCampfire, this)(_tribeID, playerID); + MACRO_CALL_MEMBER(AICState_Func::sendUnitsToCampfire, this)(tribeID, playerID); } } } diff --git a/src/OpenSHC/AI/AICState/setAICParameters_01.cpp b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp index 6da83f2a3e..35c4acc91c 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_01.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp @@ -13,7 +13,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C6D60 void AICState::setAICParameters_01(int aicIndex) { - this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].flagType = 12; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -24,9 +24,9 @@ namespace AI { this->aics[aicIndex].highestPopularity = 7500; this->aics[aicIndex].taxesMin = 3; this->aics[aicIndex].taxesMax = 10; - this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].farm1 = 32; this->aics[aicIndex].populationPerFarm = 6; - this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].unknown011 = 20; this->aics[aicIndex].maxFood = 100; this->aics[aicIndex].minimumApples = 10; this->aics[aicIndex].minimumCheese = -1; @@ -35,18 +35,18 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 2; - this->aics[aicIndex].aiRequestDelay = 0x12; + this->aics[aicIndex].aiRequestDelay = 18; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; this->aics[aicIndex].doubleRationsFoodThreshold = 0; - this->aics[aicIndex].maxWood = 0x1e; - this->aics[aicIndex].maxStone = 0x28; - this->aics[aicIndex].maxResourceOther = 0x14; - this->aics[aicIndex].maxEquipment = 0x14; - this->aics[aicIndex].maxBeer = 0x14; + this->aics[aicIndex].maxWood = 30; + this->aics[aicIndex].maxStone = 40; + this->aics[aicIndex].maxResourceOther = 20; + this->aics[aicIndex].maxEquipment = 20; + this->aics[aicIndex].maxBeer = 20; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 8; - this->aics[aicIndex].populationPerQuarry = 0x12; + this->aics[aicIndex].populationPerQuarry = 18; this->aics[aicIndex].populationPerIronmine = 0; this->aics[aicIndex].populationPerPitchrig = 0; this->aics[aicIndex].maxQuarries = 1; @@ -56,92 +56,92 @@ namespace AI { this->aics[aicIndex].maxFarms = 6; this->aics[aicIndex].buildInterval = 1; this->aics[aicIndex].resourceRebuildDelay = 10; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource03 = 6; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; - this->aics[aicIndex].defWallPatrolRallyTime = 0x14; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; + this->aics[aicIndex].defWallPatrolRallyTime = 20; this->aics[aicIndex].defWallPatrolGroups = 1; this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; - this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].defSiegeEngineBuildDelay = 20; this->aics[aicIndex].unknown072 = 800; - this->aics[aicIndex].unknown073 = 0x50; - this->aics[aicIndex].recruitProbDefWeak = 0x32; + this->aics[aicIndex].unknown073 = 80; + this->aics[aicIndex].recruitProbDefWeak = 50; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; - this->aics[aicIndex].SortieUnitRanged = 0x16; - this->aics[aicIndex].SortieUnitMelee = 0x18; - this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].SortieUnitRanged = 22; + this->aics[aicIndex].SortieUnitMelee = 24; + this->aics[aicIndex].DefDiggingUnit = 24; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 10; - this->aics[aicIndex].DefUnit1 = 0x18; - this->aics[aicIndex].DefUnit2 = 0x18; - this->aics[aicIndex].DefUnit3 = 0x16; - this->aics[aicIndex].DefUnit4 = 0x16; + this->aics[aicIndex].DefUnit1 = 24; + this->aics[aicIndex].DefUnit2 = 24; + this->aics[aicIndex].DefUnit3 = 22; + this->aics[aicIndex].DefUnit4 = 22; this->aics[aicIndex].RaidUnitsBase = 10; - this->aics[aicIndex].RaidUnit1 = 0x18; - this->aics[aicIndex].RaidUnit2 = 0x18; - this->aics[aicIndex].RaidUnit3 = 0x16; + this->aics[aicIndex].RaidUnit1 = 24; + this->aics[aicIndex].RaidUnit2 = 24; + this->aics[aicIndex].RaidUnit3 = 22; this->aics[aicIndex].recruitProbDefDefault = 0; this->aics[aicIndex].recruitProbDefStrong = 0; - this->aics[aicIndex].recruitProbRaidWeak = 0x32; - this->aics[aicIndex].recruitProbRaidDefault = 0x32; + this->aics[aicIndex].recruitProbRaidWeak = 50; + this->aics[aicIndex].recruitProbRaidDefault = 50; this->aics[aicIndex].recruitProbRaidStrong = 0; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 50; this->aics[aicIndex].recruitProbAttackStrong = 100; this->aics[aicIndex].SortieUnitRangedMin = 5; this->aics[aicIndex].SortieUnitMeleeMin = 6; this->aics[aicIndex].DefDiggingUnitMax = 0; - this->aics[aicIndex].DefWalls = 0x14; - this->aics[aicIndex].DefTotal = 0x1e; + this->aics[aicIndex].DefWalls = 20; + this->aics[aicIndex].DefTotal = 30; this->aics[aicIndex].OuterPatrolGroupsMove = 0; - this->aics[aicIndex].RaidUnitsRandom = 0xf; + this->aics[aicIndex].RaidUnitsRandom = 15; this->aics[aicIndex].HarassingSiegeEnginesMax = 0; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; - this->aics[aicIndex].AttForceBase = 0x14; + this->aics[aicIndex].AttForceBase = 20; this->aics[aicIndex].AttForceRandom = 10; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0xf; - this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttForceSupportAllyThreshold = 15; + this->aics[aicIndex].AttForceRallyPercentage = 50; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; - this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x19; - this->aics[aicIndex].AttCoordinationPreference = 0x14; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 25; + this->aics[aicIndex].AttCoordinationPreference = 20; this->aics[aicIndex].SiegeEngine1 = 0; this->aics[aicIndex].CowThrowInterval = 1000; this->aics[aicIndex].AttMaxEngineers = 0; - this->aics[aicIndex].AttDiggingUnit = 0x18; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttDiggingUnit = 24; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; - this->aics[aicIndex].AttUnit2 = 0x16; + this->aics[aicIndex].AttUnit2 = 22; this->aics[aicIndex].AttUnit2Max = 0; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x16; + this->aics[aicIndex].AttUnitPatrol = 22; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x16; - this->aics[aicIndex].AttUnitBackupMax = 0x10; + this->aics[aicIndex].AttUnitBackup = 22; + this->aics[aicIndex].AttUnitBackupMax = 16; this->aics[aicIndex].AttUnitBackupGroupsCount = 0; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x18; + this->aics[aicIndex].AttUnitSiegeDef = 24; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x18; + this->aics[aicIndex].AttUnitMain1 = 24; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 1; this->aics[aicIndex].TargetChoice = AITC_PLAYER; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_02.cpp b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp index 339becf6f8..7ff3eb98f0 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_02.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp @@ -13,7 +13,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C7120 void AICState::setAICParameters_02(int aicIndex) { - this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].flagType = 12; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -23,30 +23,30 @@ namespace AI { this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xb; - this->aics[aicIndex].farm1 = 0x20; + this->aics[aicIndex].taxesMax = 11; + this->aics[aicIndex].farm1 = 32; this->aics[aicIndex].populationPerFarm = 5; - this->aics[aicIndex].unknown011 = 0xf; - this->aics[aicIndex].maxFood = 0x96; + this->aics[aicIndex].unknown011 = 15; + this->aics[aicIndex].maxFood = 150; this->aics[aicIndex].minimumApples = 10; - this->aics[aicIndex].minimumCheese = 0x14; - this->aics[aicIndex].minimumBread = 0xffffffff; - this->aics[aicIndex].minimumWheat = 0xffffffff; - this->aics[aicIndex].minimumHop = 0xffffffff; + this->aics[aicIndex].minimumCheese = 20; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; + this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 5; this->aics[aicIndex].tradeAmountEquipment = 6; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x50; - this->aics[aicIndex].maxWood = 0x30; - this->aics[aicIndex].maxStone = 0x28; - this->aics[aicIndex].maxResourceOther = 0xf; - this->aics[aicIndex].maxEquipment = 0xc; + this->aics[aicIndex].doubleRationsFoodThreshold = 80; + this->aics[aicIndex].maxWood = 48; + this->aics[aicIndex].maxStone = 40; + this->aics[aicIndex].maxResourceOther = 15; + this->aics[aicIndex].maxEquipment = 12; this->aics[aicIndex].maxBeer = 5; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 5; - this->aics[aicIndex].populationPerQuarry = 0xf; + this->aics[aicIndex].populationPerQuarry = 15; this->aics[aicIndex].populationPerIronmine = 0; this->aics[aicIndex].populationPerPitchrig = 0; this->aics[aicIndex].maxQuarries = 2; @@ -55,91 +55,91 @@ namespace AI { this->aics[aicIndex].maxPitchrigs = 1; this->aics[aicIndex].maxFarms = 10; this->aics[aicIndex].buildInterval = 2; - this->aics[aicIndex].resourceRebuildDelay = 0xc; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 12; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource03 = 6; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 4; this->aics[aicIndex].defSiegeEngineGoldThreshold = 500; - this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].defSiegeEngineBuildDelay = 20; this->aics[aicIndex].unknown072 = 400; - this->aics[aicIndex].unknown073 = 0x3c; - this->aics[aicIndex].recruitProbDefWeak = 0x46; - this->aics[aicIndex].recruitProbDefDefault = 0x1e; - this->aics[aicIndex].recruitProbDefStrong = 0x14; - this->aics[aicIndex].recruitProbRaidWeak = 0x1e; - this->aics[aicIndex].recruitProbRaidDefault = 0x28; - this->aics[aicIndex].recruitProbRaidStrong = 0x28; + this->aics[aicIndex].unknown073 = 60; + this->aics[aicIndex].recruitProbDefWeak = 70; + this->aics[aicIndex].recruitProbDefDefault = 30; + this->aics[aicIndex].recruitProbDefStrong = 20; + this->aics[aicIndex].recruitProbRaidWeak = 30; + this->aics[aicIndex].recruitProbRaidDefault = 40; + this->aics[aicIndex].recruitProbRaidStrong = 40; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x1e; - this->aics[aicIndex].recruitProbAttackStrong = 0x28; + this->aics[aicIndex].recruitProbAttackDefault = 30; + this->aics[aicIndex].recruitProbAttackStrong = 40; this->aics[aicIndex].RecruitIntervalWeak = 0; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; this->aics[aicIndex].SortieUnitRangedMin = 2; - this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitRanged = 22; this->aics[aicIndex].SortieUnitMeleeMin = 8; - this->aics[aicIndex].SortieUnitMelee = 0x18; - this->aics[aicIndex].DefDiggingUnitMax = 0x14; - this->aics[aicIndex].DefDiggingUnit = 0x18; - this->aics[aicIndex].DefWalls = 0x32; - this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].SortieUnitMelee = 24; + this->aics[aicIndex].DefDiggingUnitMax = 20; + this->aics[aicIndex].DefDiggingUnit = 24; + this->aics[aicIndex].DefWalls = 50; + this->aics[aicIndex].DefTotal = 80; this->aics[aicIndex].OuterPatrolGroupsCount = 3; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].RaidUnitsBase = 30; this->aics[aicIndex].RaidUnitsRandom = 10; - this->aics[aicIndex].RaidUnit1 = 0x47; - this->aics[aicIndex].RaidUnit2 = 0x47; - this->aics[aicIndex].RaidUnit3 = 0x47; - this->aics[aicIndex].RaidUnit4 = 0x48; + this->aics[aicIndex].RaidUnit1 = 71; + this->aics[aicIndex].RaidUnit2 = 71; + this->aics[aicIndex].RaidUnit3 = 71; + this->aics[aicIndex].RaidUnit4 = 72; this->aics[aicIndex].HarassingSiegeEnginesMax = 1; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; - this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].AttForceBase = 30; this->aics[aicIndex].AttForceRandom = 10; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; - this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttForceSupportAllyThreshold = 30; + this->aics[aicIndex].AttForceRallyPercentage = 50; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; - this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x19; - this->aics[aicIndex].AttCoordinationPreference = 0x28; - this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 25; + this->aics[aicIndex].AttCoordinationPreference = 40; + this->aics[aicIndex].SiegeEngine1 = 39; this->aics[aicIndex].CowThrowInterval = 1000; this->aics[aicIndex].AttMaxEngineers = 2; - this->aics[aicIndex].AttDiggingUnit = 0x18; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttDiggingUnit = 24; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; - this->aics[aicIndex].AttUnit2 = 0x16; - this->aics[aicIndex].AttUnit2Max = 0x14; + this->aics[aicIndex].AttUnit2 = 22; + this->aics[aicIndex].AttUnit2Max = 20; this->aics[aicIndex].AttMaxLaddermen = 10; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x48; + this->aics[aicIndex].AttUnitPatrol = 72; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x46; - this->aics[aicIndex].AttUnitBackupMax = 0x32; + this->aics[aicIndex].AttUnitBackup = 70; + this->aics[aicIndex].AttUnitBackupMax = 50; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x16; - this->aics[aicIndex].AttUnitSiegeDefMax = 0x1e; + this->aics[aicIndex].AttUnitSiegeDef = 22; + this->aics[aicIndex].AttUnitSiegeDefMax = 30; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x18; + this->aics[aicIndex].AttUnitMain1 = 24; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 1; this->aics[aicIndex].TargetChoice = AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_03.cpp b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp index d4429b581a..e6ebd69242 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_03.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp @@ -13,7 +13,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C7520 void AICState::setAICParameters_03(int aicIndex) { - this->aics[aicIndex].flagType = 0xc; + this->aics[aicIndex].flagType = 12; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -21,12 +21,12 @@ namespace AI { this->aics[aicIndex].unknown005 = 0; this->aics[aicIndex].criticalPopularity = 5000; this->aics[aicIndex].lowestPopularity = 7000; - this->aics[aicIndex].highestPopularity = 0x2134; + this->aics[aicIndex].highestPopularity = 8500; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xb; - this->aics[aicIndex].farm1 = 0x21; + this->aics[aicIndex].taxesMax = 11; + this->aics[aicIndex].farm1 = 33; this->aics[aicIndex].populationPerFarm = 4; - this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].unknown011 = 20; this->aics[aicIndex].maxFood = 400; this->aics[aicIndex].minimumApples = 10; this->aics[aicIndex].minimumCheese = 10; @@ -35,93 +35,93 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 5; this->aics[aicIndex].tradeAmountEquipment = 4; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 100; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x3c; - this->aics[aicIndex].maxWood = 0x46; - this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].doubleRationsFoodThreshold = 60; + this->aics[aicIndex].maxWood = 70; + this->aics[aicIndex].maxStone = 40; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 10; this->aics[aicIndex].maxBeer = 5; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 6; - this->aics[aicIndex].populationPerQuarry = 0x19; + this->aics[aicIndex].populationPerQuarry = 25; this->aics[aicIndex].populationPerIronmine = 10; - this->aics[aicIndex].populationPerPitchrig = 0x14; + this->aics[aicIndex].populationPerPitchrig = 20; this->aics[aicIndex].maxQuarries = 2; this->aics[aicIndex].maxIronmines = 4; this->aics[aicIndex].maxWoodcutters = 8; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].maxFarms = 12; this->aics[aicIndex].buildInterval = 3; - this->aics[aicIndex].resourceRebuildDelay = 0x32; - this->aics[aicIndex].blacksmithSetting = 0x15; - this->aics[aicIndex].fletcherSetting = 0x12; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 50; + this->aics[aicIndex].blacksmithSetting = 21; + this->aics[aicIndex].fletcherSetting = 18; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 10; this->aics[aicIndex].defWallPatrolGroups = 4; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; - this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].defSiegeEngineBuildDelay = 20; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x28; + this->aics[aicIndex].unknown073 = 40; this->aics[aicIndex].recruitProbDefWeak = 100; - this->aics[aicIndex].recruitProbDefDefault = 0x3c; - this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbDefDefault = 60; + this->aics[aicIndex].recruitProbDefStrong = 30; this->aics[aicIndex].recruitProbRaidWeak = 0; this->aics[aicIndex].recruitProbRaidDefault = 0; this->aics[aicIndex].recruitProbRaidStrong = 0; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x28; - this->aics[aicIndex].recruitProbAttackStrong = 0x46; + this->aics[aicIndex].recruitProbAttackDefault = 40; + this->aics[aicIndex].recruitProbAttackStrong = 70; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 4; - this->aics[aicIndex].SortieUnitRanged = 0x17; + this->aics[aicIndex].SortieUnitRanged = 23; this->aics[aicIndex].SortieUnitMeleeMin = 5; - this->aics[aicIndex].SortieUnitMelee = 0x1a; + this->aics[aicIndex].SortieUnitMelee = 26; this->aics[aicIndex].DefDiggingUnitMax = 0; - this->aics[aicIndex].DefDiggingUnit = 0x18; - this->aics[aicIndex].DefWalls = 0x1e; - this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].DefDiggingUnit = 24; + this->aics[aicIndex].DefWalls = 30; + this->aics[aicIndex].DefTotal = 40; this->aics[aicIndex].OuterPatrolGroupsCount = 2; this->aics[aicIndex].OuterPatrolGroupsMove = 1; - this->aics[aicIndex].OuterPatrolRallyDelay = 0x14; - this->aics[aicIndex].DefUnit1 = 0x17; - this->aics[aicIndex].DefUnit2 = 0x17; + this->aics[aicIndex].OuterPatrolRallyDelay = 20; + this->aics[aicIndex].DefUnit1 = 23; + this->aics[aicIndex].DefUnit2 = 23; this->aics[aicIndex].RaidUnitsBase = 10; this->aics[aicIndex].RaidUnitsRandom = 5; - this->aics[aicIndex].DefUnit3 = 0x17; - this->aics[aicIndex].RaidUnit1 = 0x1a; + this->aics[aicIndex].DefUnit3 = 23; + this->aics[aicIndex].RaidUnit1 = 26; this->aics[aicIndex].HarassingSiegeEnginesMax = 2; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; this->aics[aicIndex].AttForceBase = 10; this->aics[aicIndex].AttForceRandom = 10; this->aics[aicIndex].AttForceSupportAllyThreshold = 10; - this->aics[aicIndex].AttForceRallyPercentage = 0x3c; + this->aics[aicIndex].AttForceRallyPercentage = 60; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 5; - this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0xf; - this->aics[aicIndex].AttCoordinationPreference = 0x14; - this->aics[aicIndex].CowThrowInterval = 0x1e; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x27; - this->aics[aicIndex].SiegeEngine3 = 0x27; - this->aics[aicIndex].SiegeEngine4 = 0x3b; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 15; + this->aics[aicIndex].AttCoordinationPreference = 20; + this->aics[aicIndex].CowThrowInterval = 30; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 39; + this->aics[aicIndex].SiegeEngine3 = 39; + this->aics[aicIndex].SiegeEngine4 = 59; this->aics[aicIndex].AttMaxEngineers = 10; - this->aics[aicIndex].AttDiggingUnit = 0x1a; + this->aics[aicIndex].AttDiggingUnit = 26; this->aics[aicIndex].AttDiggingUnitMax = 10; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; @@ -131,15 +131,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x17; + this->aics[aicIndex].AttUnitBackup = 23; this->aics[aicIndex].AttUnitBackupMax = 5; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x1a; + this->aics[aicIndex].AttUnitSiegeDef = 26; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x1a; + this->aics[aicIndex].AttUnitMain1 = 26; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = AITC_GOLD; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_04.cpp b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp index 2bcec1b88a..98fd06c9c9 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_04.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp @@ -13,23 +13,23 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C7910 void AICState::setAICParameters_04(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; - this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].criticalPopularity = 4500; this->aics[aicIndex].lowestPopularity = 6000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xb; - this->aics[aicIndex].farm1 = 0x21; - this->aics[aicIndex].farm2 = 0x20; - this->aics[aicIndex].farm3 = 0x1f; - this->aics[aicIndex].farm4 = 0x20; + this->aics[aicIndex].taxesMax = 11; + this->aics[aicIndex].farm1 = 33; + this->aics[aicIndex].farm2 = 32; + this->aics[aicIndex].farm3 = 31; + this->aics[aicIndex].farm4 = 32; this->aics[aicIndex].populationPerFarm = 5; - this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].unknown011 = 12; this->aics[aicIndex].maxFood = 200; this->aics[aicIndex].minimumApples = 5; this->aics[aicIndex].minimumCheese = 5; @@ -38,90 +38,90 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 4; - this->aics[aicIndex].aiRequestDelay = 0x14; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x28; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x1e; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].aiRequestDelay = 20; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 40; + this->aics[aicIndex].doubleRationsFoodThreshold = 30; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 50; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 10; - this->aics[aicIndex].maxBeer = 0xf; + this->aics[aicIndex].maxBeer = 15; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 4; this->aics[aicIndex].populationPerQuarry = 9; - this->aics[aicIndex].populationPerIronmine = 0xd; - this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].populationPerIronmine = 13; + this->aics[aicIndex].populationPerPitchrig = 15; this->aics[aicIndex].maxQuarries = 6; this->aics[aicIndex].maxIronmines = 3; - this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxWoodcutters = 12; this->aics[aicIndex].maxPitchrigs = 2; this->aics[aicIndex].maxFarms = 10; this->aics[aicIndex].buildInterval = 3; - this->aics[aicIndex].resourceRebuildDelay = 0x14; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x12; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].resourceRebuildDelay = 20; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 18; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource12 = 21; this->aics[aicIndex].defWallPatrolRallyTime = 4; this->aics[aicIndex].defWallPatrolGroups = 3; - this->aics[aicIndex].defSiegeEngineGoldThreshold = 0xfa; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 250; this->aics[aicIndex].defSiegeEngineBuildDelay = 2; this->aics[aicIndex].unknown072 = 100; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x5a; - this->aics[aicIndex].recruitProbDefDefault = 0x3c; - this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 90; + this->aics[aicIndex].recruitProbDefDefault = 60; + this->aics[aicIndex].recruitProbDefStrong = 30; this->aics[aicIndex].recruitProbRaidWeak = 10; - this->aics[aicIndex].recruitProbRaidDefault = 0x1e; + this->aics[aicIndex].recruitProbRaidDefault = 30; this->aics[aicIndex].recruitProbRaidStrong = 10; this->aics[aicIndex].recruitProbAttackWeak = 0; this->aics[aicIndex].recruitProbAttackDefault = 10; - this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].recruitProbAttackStrong = 60; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 4; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 8; - this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitRanged = 70; this->aics[aicIndex].SortieUnitMeleeMin = 6; - this->aics[aicIndex].SortieUnitMelee = 0x19; + this->aics[aicIndex].SortieUnitMelee = 25; this->aics[aicIndex].DefDiggingUnitMax = 8; - this->aics[aicIndex].DefDiggingUnit = 0x19; - this->aics[aicIndex].DefWalls = 0x50; + this->aics[aicIndex].DefDiggingUnit = 25; + this->aics[aicIndex].DefWalls = 80; this->aics[aicIndex].DefTotal = 100; this->aics[aicIndex].OuterPatrolGroupsCount = 4; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 3; - this->aics[aicIndex].DefUnit1 = 0x17; - this->aics[aicIndex].DefUnit2 = 0x17; - this->aics[aicIndex].RaidUnitsRandom = 0x14; - this->aics[aicIndex].DefUnit3 = 0x16; - this->aics[aicIndex].DefUnit4 = 0x16; + this->aics[aicIndex].DefUnit1 = 23; + this->aics[aicIndex].DefUnit2 = 23; + this->aics[aicIndex].RaidUnitsRandom = 20; + this->aics[aicIndex].DefUnit3 = 22; + this->aics[aicIndex].DefUnit4 = 22; this->aics[aicIndex].RaidUnitsBase = 5; - this->aics[aicIndex].RaidUnit1 = 0x4a; - this->aics[aicIndex].RaidUnit2 = 0x4a; + this->aics[aicIndex].RaidUnit1 = 74; + this->aics[aicIndex].RaidUnit2 = 74; this->aics[aicIndex].HarassingSiegeEnginesMax = 4; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 5; - this->aics[aicIndex].AttForceBase = 0x28; - this->aics[aicIndex].AttForceRandom = 0xf; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceBase = 40; + this->aics[aicIndex].AttForceRandom = 15; + this->aics[aicIndex].AttForceSupportAllyThreshold = 30; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; - this->aics[aicIndex].AttAssaultDelay = 0xc; + this->aics[aicIndex].AttAssaultDelay = 12; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].AttCoordinationPreference = 50; this->aics[aicIndex].CowThrowInterval = 8; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x28; - this->aics[aicIndex].SiegeEngine3 = 0x4d; - this->aics[aicIndex].SiegeEngine4 = 0x28; - this->aics[aicIndex].AttMaxEngineers = 0xc; - this->aics[aicIndex].AttDiggingUnit = 0x19; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 40; + this->aics[aicIndex].SiegeEngine3 = 77; + this->aics[aicIndex].SiegeEngine4 = 40; + this->aics[aicIndex].AttMaxEngineers = 12; + this->aics[aicIndex].AttDiggingUnit = 25; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; @@ -130,17 +130,17 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x17; - this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackup = 23; + this->aics[aicIndex].AttUnitBackupMax = 30; this->aics[aicIndex].AttUnitBackupGroupsCount = 3; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x1b; + this->aics[aicIndex].AttUnitSiegeDef = 27; this->aics[aicIndex].AttUnitSiegeDefMax = 5; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; - this->aics[aicIndex].AttUnitMain1 = 0x1b; - this->aics[aicIndex].AttUnitMain2 = 0x19; - this->aics[aicIndex].AttUnitMain3 = 0x19; + this->aics[aicIndex].AttUnitMain1 = 27; + this->aics[aicIndex].AttUnitMain2 = 25; + this->aics[aicIndex].AttUnitMain3 = 25; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 3; this->aics[aicIndex].TargetChoice = AITC_CLOSEST; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_05.cpp b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp index b87465a089..377cd7b801 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_05.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp @@ -23,14 +23,14 @@ namespace AI { this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x1f; - this->aics[aicIndex].farm2 = 0x1e; - this->aics[aicIndex].farm3 = 0x1e; - this->aics[aicIndex].farm4 = 0x20; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 31; + this->aics[aicIndex].farm2 = 30; + this->aics[aicIndex].farm3 = 30; + this->aics[aicIndex].farm4 = 32; this->aics[aicIndex].populationPerFarm = 3; - this->aics[aicIndex].unknown011 = 0x14; - this->aics[aicIndex].maxFood = 0x32; + this->aics[aicIndex].unknown011 = 20; + this->aics[aicIndex].maxFood = 50; this->aics[aicIndex].minimumApples = 5; this->aics[aicIndex].minimumCheese = 5; this->aics[aicIndex].minimumBread = 5; @@ -38,11 +38,11 @@ namespace AI { this->aics[aicIndex].minimumHop = 5; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0x28; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x14; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x14; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].aiRequestDelay = 40; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 20; + this->aics[aicIndex].doubleRationsFoodThreshold = 20; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 50; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 5; this->aics[aicIndex].maxBeer = 10; @@ -50,96 +50,96 @@ namespace AI { this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 6; this->aics[aicIndex].populationPerQuarry = 10; - this->aics[aicIndex].populationPerIronmine = 0xc; - this->aics[aicIndex].populationPerPitchrig = 0x14; + this->aics[aicIndex].populationPerIronmine = 12; + this->aics[aicIndex].populationPerPitchrig = 20; this->aics[aicIndex].maxQuarries = 4; this->aics[aicIndex].maxIronmines = 4; - this->aics[aicIndex].maxWoodcutters = 0xe; + this->aics[aicIndex].maxWoodcutters = 14; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0xf; + this->aics[aicIndex].maxFarms = 15; this->aics[aicIndex].buildInterval = 2; - this->aics[aicIndex].resourceRebuildDelay = 0x28; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x12; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].resourceRebuildDelay = 40; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 18; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].defWallPatrolRallyTime = 3; - this->aics[aicIndex].defSiegeEngineGoldThreshold = 0x14; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 20; this->aics[aicIndex].defSiegeEngineBuildDelay = 8; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource14 = 23; this->aics[aicIndex].defWallPatrolGroups = 4; this->aics[aicIndex].unknown072 = 100; - this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].unknown073 = 20; this->aics[aicIndex].recruitProbDefWeak = 100; - this->aics[aicIndex].recruitProbDefDefault = 0x22; - this->aics[aicIndex].recruitProbDefStrong = 0x19; + this->aics[aicIndex].recruitProbDefDefault = 34; + this->aics[aicIndex].recruitProbDefStrong = 25; this->aics[aicIndex].recruitProbRaidWeak = 0; - this->aics[aicIndex].recruitProbRaidDefault = 0x21; - this->aics[aicIndex].recruitProbRaidStrong = 0x19; + this->aics[aicIndex].recruitProbRaidDefault = 33; + this->aics[aicIndex].recruitProbRaidStrong = 25; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x21; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 33; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; this->aics[aicIndex].SortieUnitRangedMin = 10; - this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitRanged = 70; this->aics[aicIndex].SortieUnitMeleeMin = 7; - this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].SortieUnitMelee = 75; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x47; - this->aics[aicIndex].DefWalls = 0x32; - this->aics[aicIndex].DefTotal = 0x46; + this->aics[aicIndex].DefDiggingUnit = 71; + this->aics[aicIndex].DefWalls = 50; + this->aics[aicIndex].DefTotal = 70; this->aics[aicIndex].OuterPatrolGroupsCount = 2; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 10; - this->aics[aicIndex].DefUnit1 = 0x4b; - this->aics[aicIndex].DefUnit2 = 0x46; + this->aics[aicIndex].DefUnit1 = 75; + this->aics[aicIndex].DefUnit2 = 70; this->aics[aicIndex].RaidUnitsBase = 10; this->aics[aicIndex].RaidUnitsRandom = 5; - this->aics[aicIndex].DefUnit3 = 0x46; - this->aics[aicIndex].DefUnit4 = 0x46; - this->aics[aicIndex].DefUnit5 = 0x4c; - this->aics[aicIndex].RaidUnit1 = 0x4a; + this->aics[aicIndex].DefUnit3 = 70; + this->aics[aicIndex].DefUnit4 = 70; + this->aics[aicIndex].DefUnit5 = 76; + this->aics[aicIndex].RaidUnit1 = 74; this->aics[aicIndex].HarassingSiegeEnginesMax = 5; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; - this->aics[aicIndex].AttForceBase = 0x32; + this->aics[aicIndex].AttForceBase = 50; this->aics[aicIndex].AttForceRandom = 10; this->aics[aicIndex].AttForceSupportAllyThreshold = 8; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 4; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 1; - this->aics[aicIndex].AttCoordinationPreference = 0x3c; + this->aics[aicIndex].AttCoordinationPreference = 60; this->aics[aicIndex].CowThrowInterval = 2000; - this->aics[aicIndex].SiegeEngine1 = 0x4d; - this->aics[aicIndex].SiegeEngine2 = 0x4d; - this->aics[aicIndex].SiegeEngine3 = 0x27; - this->aics[aicIndex].SiegeEngine4 = 0x27; + this->aics[aicIndex].SiegeEngine1 = 77; + this->aics[aicIndex].SiegeEngine2 = 77; + this->aics[aicIndex].SiegeEngine3 = 39; + this->aics[aicIndex].SiegeEngine4 = 39; this->aics[aicIndex].AttMaxEngineers = 10; - this->aics[aicIndex].AttDiggingUnit = 0x47; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttDiggingUnit = 71; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 5; - this->aics[aicIndex].AttUnit2 = 0x4a; - this->aics[aicIndex].AttUnit2Max = 0x14; + this->aics[aicIndex].AttUnit2 = 74; + this->aics[aicIndex].AttUnit2Max = 20; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x4a; - this->aics[aicIndex].AttUnitPatrolMax = 0x14; + this->aics[aicIndex].AttUnitPatrol = 74; + this->aics[aicIndex].AttUnitPatrolMax = 20; this->aics[aicIndex].AttUnitPatrolGroupsCount = 1; - this->aics[aicIndex].AttUnitBackup = 0x46; - this->aics[aicIndex].AttUnitBackupMax = 0x14; + this->aics[aicIndex].AttUnitBackup = 70; + this->aics[aicIndex].AttUnitBackupMax = 20; this->aics[aicIndex].AttUnitBackupGroupsCount = 3; this->aics[aicIndex].AttUnitEngageMax = 0; - this->aics[aicIndex].AttUnitEngage = 0x4c; - this->aics[aicIndex].AttUnitSiegeDef = 0x4c; + this->aics[aicIndex].AttUnitEngage = 76; + this->aics[aicIndex].AttUnitSiegeDef = 76; this->aics[aicIndex].AttUnitSiegeDefMax = 6; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; - this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttUnitMain1 = 75; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 3; this->aics[aicIndex].TargetChoice = AITC_GOLD; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_06.cpp b/src/OpenSHC/AI/AICState/setAICParameters_06.cpp index f9b06cf09f..af8feecbf1 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_06.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_06.cpp @@ -20,12 +20,12 @@ namespace AI { this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x20; - this->aics[aicIndex].farm2 = 0x1f; - this->aics[aicIndex].farm3 = 0x20; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 32; + this->aics[aicIndex].farm2 = 31; + this->aics[aicIndex].farm3 = 32; this->aics[aicIndex].populationPerFarm = 5; - this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].unknown011 = 12; this->aics[aicIndex].maxFood = 100; this->aics[aicIndex].minimumApples = 10; this->aics[aicIndex].minimumCheese = -1; @@ -34,19 +34,19 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0xc; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x32; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; - this->aics[aicIndex].maxWood = 0x32; - this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].aiRequestDelay = 12; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 50; + this->aics[aicIndex].doubleRationsFoodThreshold = 50; + this->aics[aicIndex].maxWood = 50; + this->aics[aicIndex].maxStone = 50; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 5; - this->aics[aicIndex].maxBeer = 0xf; + this->aics[aicIndex].maxBeer = 15; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 7; this->aics[aicIndex].populationPerQuarry = 10; - this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerIronmine = 12; this->aics[aicIndex].populationPerPitchrig = 7; this->aics[aicIndex].maxQuarries = 2; this->aics[aicIndex].maxIronmines = 1; @@ -54,93 +54,93 @@ namespace AI { this->aics[aicIndex].maxPitchrigs = 10; this->aics[aicIndex].maxFarms = 10; this->aics[aicIndex].buildInterval = 3; - this->aics[aicIndex].resourceRebuildDelay = 0x3c; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x12; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].resourceRebuildDelay = 60; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 18; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].defWallPatrolRallyTime = 5; this->aics[aicIndex].defWallPatrolGroups = 2; - this->aics[aicIndex].defSiegeEngineGoldThreshold = 0x78; + this->aics[aicIndex].defSiegeEngineGoldThreshold = 120; this->aics[aicIndex].defSiegeEngineBuildDelay = 8; this->aics[aicIndex].sellResource03 = 6; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].unknown072 = 100; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x50; - this->aics[aicIndex].recruitProbDefDefault = 0x28; - this->aics[aicIndex].recruitProbDefStrong = 0x28; - this->aics[aicIndex].recruitProbRaidWeak = 0x14; - this->aics[aicIndex].recruitProbRaidDefault = 0x28; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 80; + this->aics[aicIndex].recruitProbDefDefault = 40; + this->aics[aicIndex].recruitProbDefStrong = 40; + this->aics[aicIndex].recruitProbRaidWeak = 20; + this->aics[aicIndex].recruitProbRaidDefault = 40; + this->aics[aicIndex].recruitProbRaidStrong = 30; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x14; - this->aics[aicIndex].recruitProbAttackStrong = 0x1e; + this->aics[aicIndex].recruitProbAttackDefault = 20; + this->aics[aicIndex].recruitProbAttackStrong = 30; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 0; this->aics[aicIndex].RecruitIntervalStrong = 0; this->aics[aicIndex].SortieUnitRangedMin = 7; - this->aics[aicIndex].SortieUnitRanged = 0x46; + this->aics[aicIndex].SortieUnitRanged = 70; this->aics[aicIndex].SortieUnitMeleeMin = 5; - this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].SortieUnitMelee = 75; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x47; - this->aics[aicIndex].DefWalls = 0x3c; - this->aics[aicIndex].DefTotal = 0x3c; + this->aics[aicIndex].DefDiggingUnit = 71; + this->aics[aicIndex].DefWalls = 60; + this->aics[aicIndex].DefTotal = 60; this->aics[aicIndex].OuterPatrolGroupsCount = 2; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 10; - this->aics[aicIndex].DefUnit1 = 0x4c; - this->aics[aicIndex].DefUnit2 = 0x46; - this->aics[aicIndex].RaidUnitsBase = 0x1e; - this->aics[aicIndex].RaidUnitsRandom = 0x1e; - this->aics[aicIndex].DefUnit3 = 0x46; - this->aics[aicIndex].DefUnit4 = 0x46; - this->aics[aicIndex].RaidUnit1 = 0x47; + this->aics[aicIndex].DefUnit1 = 76; + this->aics[aicIndex].DefUnit2 = 70; + this->aics[aicIndex].RaidUnitsBase = 30; + this->aics[aicIndex].RaidUnitsRandom = 30; + this->aics[aicIndex].DefUnit3 = 70; + this->aics[aicIndex].DefUnit4 = 70; + this->aics[aicIndex].RaidUnit1 = 71; this->aics[aicIndex].HarassingSiegeEnginesMax = 2; - this->aics[aicIndex].HarassingSiegeEngine1 = 0x166; - this->aics[aicIndex].HarassingSiegeEngine2 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 358; + this->aics[aicIndex].HarassingSiegeEngine2 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; - this->aics[aicIndex].AttForceBase = 0xf; + this->aics[aicIndex].AttForceBase = 15; this->aics[aicIndex].AttForceRandom = 10; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x46; + this->aics[aicIndex].AttForceSupportAllyThreshold = 70; this->aics[aicIndex].AttForceRallyPercentage = 100; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 2; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 10; - this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].AttCoordinationPreference = 50; this->aics[aicIndex].CowThrowInterval = 7; - this->aics[aicIndex].SiegeEngine1 = 0x4d; - this->aics[aicIndex].SiegeEngine2 = 0x4d; - this->aics[aicIndex].SiegeEngine3 = 0x4d; + this->aics[aicIndex].SiegeEngine1 = 77; + this->aics[aicIndex].SiegeEngine2 = 77; + this->aics[aicIndex].SiegeEngine3 = 77; this->aics[aicIndex].AttMaxEngineers = 6; - this->aics[aicIndex].AttDiggingUnit = 0x47; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttDiggingUnit = 71; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; - this->aics[aicIndex].AttUnit2 = 0x4b; + this->aics[aicIndex].AttUnit2 = 75; this->aics[aicIndex].AttUnit2Max = 0; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x4a; + this->aics[aicIndex].AttUnitPatrol = 74; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x4a; - this->aics[aicIndex].AttUnitBackupMax = 0x28; + this->aics[aicIndex].AttUnitBackup = 74; + this->aics[aicIndex].AttUnitBackupMax = 40; this->aics[aicIndex].AttUnitBackupGroupsCount = 2; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x46; + this->aics[aicIndex].AttUnitSiegeDef = 70; this->aics[aicIndex].AttUnitSiegeDefMax = 10; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; - this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttUnitMain1 = 75; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 5; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_07.cpp b/src/OpenSHC/AI/AICState/setAICParameters_07.cpp index 101537122c..0f7a127fce 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_07.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_07.cpp @@ -23,23 +23,23 @@ namespace AI { this->aics[aicIndex].taxesMax = 8; this->aics[aicIndex].farm1 = 0; this->aics[aicIndex].populationPerFarm = 100; - this->aics[aicIndex].unknown011 = 0x14; + this->aics[aicIndex].unknown011 = 20; this->aics[aicIndex].maxFood = 500; - this->aics[aicIndex].minimumApples = 0x14; + this->aics[aicIndex].minimumApples = 20; this->aics[aicIndex].minimumCheese = -1; this->aics[aicIndex].minimumBread = -1; this->aics[aicIndex].minimumWheat = -1; this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0x1e; + this->aics[aicIndex].aiRequestDelay = 30; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; this->aics[aicIndex].doubleRationsFoodThreshold = 0; - this->aics[aicIndex].maxWood = 0x1e; - this->aics[aicIndex].maxStone = 0x14; + this->aics[aicIndex].maxWood = 30; + this->aics[aicIndex].maxStone = 20; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 5; - this->aics[aicIndex].maxBeer = 0x14; + this->aics[aicIndex].maxBeer = 20; this->aics[aicIndex].maxResourceVariance = 5; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 2; @@ -48,74 +48,74 @@ namespace AI { this->aics[aicIndex].populationPerPitchrig = 0; this->aics[aicIndex].maxQuarries = 2; this->aics[aicIndex].maxIronmines = 1; - this->aics[aicIndex].maxWoodcutters = 0xf; + this->aics[aicIndex].maxWoodcutters = 15; this->aics[aicIndex].maxPitchrigs = 1; this->aics[aicIndex].maxFarms = 6; this->aics[aicIndex].buildInterval = 5; - this->aics[aicIndex].resourceRebuildDelay = 0x50; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 80; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource03 = 6; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 10; this->aics[aicIndex].defWallPatrolGroups = 2; this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; - this->aics[aicIndex].defSiegeEngineBuildDelay = 0x14; + this->aics[aicIndex].defSiegeEngineBuildDelay = 20; this->aics[aicIndex].unknown072 = 800; - this->aics[aicIndex].unknown073 = 0x50; - this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].unknown073 = 80; + this->aics[aicIndex].recruitProbDefStrong = 30; this->aics[aicIndex].recruitProbRaidWeak = 10; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; - this->aics[aicIndex].recruitProbAttackDefault = 0x1e; + this->aics[aicIndex].recruitProbRaidStrong = 30; + this->aics[aicIndex].recruitProbAttackDefault = 30; this->aics[aicIndex].DefDiggingUnitMax = 2; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 10; this->aics[aicIndex].RaidUnitsRandom = 10; - this->aics[aicIndex].recruitProbDefWeak = 0x46; - this->aics[aicIndex].recruitProbDefDefault = 0x32; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbAttackWeak = 0x14; - this->aics[aicIndex].recruitProbAttackStrong = 0x28; + this->aics[aicIndex].recruitProbDefWeak = 70; + this->aics[aicIndex].recruitProbDefDefault = 50; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbAttackWeak = 20; + this->aics[aicIndex].recruitProbAttackStrong = 40; this->aics[aicIndex].RecruitIntervalWeak = 8; this->aics[aicIndex].RecruitInterval = 8; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 0; - this->aics[aicIndex].SortieUnitRanged = 0x48; + this->aics[aicIndex].SortieUnitRanged = 72; this->aics[aicIndex].SortieUnitMeleeMin = 3; - this->aics[aicIndex].SortieUnitMelee = 0x4b; - this->aics[aicIndex].DefDiggingUnit = 0x47; - this->aics[aicIndex].DefWalls = 0x28; - this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].SortieUnitMelee = 75; + this->aics[aicIndex].DefDiggingUnit = 71; + this->aics[aicIndex].DefWalls = 40; + this->aics[aicIndex].DefTotal = 50; this->aics[aicIndex].OuterPatrolGroupsMove = 0; - this->aics[aicIndex].DefUnit1 = 0x48; - this->aics[aicIndex].DefUnit2 = 0x48; - this->aics[aicIndex].DefUnit3 = 0x4b; - this->aics[aicIndex].RaidUnitsBase = 0x14; - this->aics[aicIndex].RaidUnit1 = 0x48; + this->aics[aicIndex].DefUnit1 = 72; + this->aics[aicIndex].DefUnit2 = 72; + this->aics[aicIndex].DefUnit3 = 75; + this->aics[aicIndex].RaidUnitsBase = 20; + this->aics[aicIndex].RaidUnit1 = 72; this->aics[aicIndex].HarassingSiegeEnginesMax = 0; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 3; this->aics[aicIndex].AttForceBase = 10; - this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceRandom = 20; this->aics[aicIndex].AttForceSupportAllyThreshold = 5; - this->aics[aicIndex].AttForceRallyPercentage = 0x1e; + this->aics[aicIndex].AttForceRallyPercentage = 30; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; - this->aics[aicIndex].AttUnitPatrolRecommandDelay = 0x28; - this->aics[aicIndex].AttCoordinationPreference = 0x14; + this->aics[aicIndex].AttUnitPatrolRecommandDelay = 40; + this->aics[aicIndex].AttCoordinationPreference = 20; this->aics[aicIndex].CowThrowInterval = 10000; this->aics[aicIndex].SiegeEngine1 = 0; this->aics[aicIndex].AttMaxEngineers = 0; @@ -129,15 +129,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x46; - this->aics[aicIndex].AttUnitBackupMax = 0x78; + this->aics[aicIndex].AttUnitBackup = 70; + this->aics[aicIndex].AttUnitBackupMax = 120; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttUnitMain1 = 75; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 1; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_08.cpp b/src/OpenSHC/AI/AICState/setAICParameters_08.cpp index 28cef0fd50..f040008a6b 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_08.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_08.cpp @@ -9,7 +9,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C8920 void AICState::setAICParameters_08(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -20,11 +20,11 @@ namespace AI { this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 3; this->aics[aicIndex].taxesMax = 10; - this->aics[aicIndex].farm1 = 0x21; - this->aics[aicIndex].farm2 = 0x20; - this->aics[aicIndex].farm3 = 0x20; + this->aics[aicIndex].farm1 = 33; + this->aics[aicIndex].farm2 = 32; + this->aics[aicIndex].farm3 = 32; this->aics[aicIndex].populationPerFarm = 4; - this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].unknown011 = 12; this->aics[aicIndex].maxFood = 200; this->aics[aicIndex].minimumApples = 5; this->aics[aicIndex].minimumCheese = 5; @@ -33,11 +33,11 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 5; this->aics[aicIndex].tradeAmountEquipment = 2; - this->aics[aicIndex].aiRequestDelay = 0x16; + this->aics[aicIndex].aiRequestDelay = 22; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; - this->aics[aicIndex].maxWood = 0x32; - this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].doubleRationsFoodThreshold = 40; + this->aics[aicIndex].maxWood = 50; + this->aics[aicIndex].maxStone = 60; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 10; this->aics[aicIndex].maxBeer = 10; @@ -51,75 +51,75 @@ namespace AI { this->aics[aicIndex].maxIronmines = 4; this->aics[aicIndex].maxWoodcutters = 10; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0xf; + this->aics[aicIndex].maxFarms = 15; this->aics[aicIndex].buildInterval = 4; - this->aics[aicIndex].resourceRebuildDelay = 0x14; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].resourceRebuildDelay = 20; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource14 = 23; this->aics[aicIndex].defWallPatrolRallyTime = 8; this->aics[aicIndex].defWallPatrolGroups = 4; this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; this->aics[aicIndex].defSiegeEngineBuildDelay = 2; this->aics[aicIndex].unknown072 = 100; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x5a; - this->aics[aicIndex].recruitProbDefDefault = 0x1e; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 90; + this->aics[aicIndex].recruitProbDefDefault = 30; this->aics[aicIndex].recruitProbDefStrong = 10; this->aics[aicIndex].recruitProbRaidWeak = 0; this->aics[aicIndex].recruitProbRaidDefault = 0; this->aics[aicIndex].recruitProbRaidStrong = 0; this->aics[aicIndex].recruitProbAttackWeak = 10; - this->aics[aicIndex].recruitProbAttackDefault = 0x46; - this->aics[aicIndex].recruitProbAttackStrong = 0x5a; + this->aics[aicIndex].recruitProbAttackDefault = 70; + this->aics[aicIndex].recruitProbAttackStrong = 90; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; this->aics[aicIndex].SortieUnitRangedMin = 6; - this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitRanged = 22; this->aics[aicIndex].SortieUnitMeleeMin = 6; - this->aics[aicIndex].SortieUnitMelee = 0x19; + this->aics[aicIndex].SortieUnitMelee = 25; this->aics[aicIndex].DefDiggingUnitMax = 0; - this->aics[aicIndex].DefDiggingUnit = 0x19; - this->aics[aicIndex].DefWalls = 0x14; - this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].DefDiggingUnit = 25; + this->aics[aicIndex].DefWalls = 20; + this->aics[aicIndex].DefTotal = 40; this->aics[aicIndex].OuterPatrolGroupsCount = 2; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 5; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].DefUnit2 = 22; this->aics[aicIndex].RaidUnitsBase = 10; this->aics[aicIndex].RaidUnitsRandom = 4; - this->aics[aicIndex].DefUnit3 = 0x19; - this->aics[aicIndex].RaidUnit1 = 0x16; + this->aics[aicIndex].DefUnit3 = 25; + this->aics[aicIndex].RaidUnit1 = 22; this->aics[aicIndex].HarassingSiegeEnginesMax = 2; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 5; - this->aics[aicIndex].AttForceBase = 0x14; + this->aics[aicIndex].AttForceBase = 20; this->aics[aicIndex].AttForceRandom = 5; this->aics[aicIndex].AttForceSupportAllyThreshold = 10; this->aics[aicIndex].AttForceRallyPercentage = 10; this->aics[aicIndex].AttMovingTribesThreshold = 100; - this->aics[aicIndex].AttAssaultDelay = 0x14; + this->aics[aicIndex].AttAssaultDelay = 20; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 2; this->aics[aicIndex].AttCoordinationPreference = 10; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x27; - this->aics[aicIndex].SiegeEngine3 = 0x27; - this->aics[aicIndex].SiegeEngine4 = 0x3b; - this->aics[aicIndex].SiegeEngine5 = 0x28; - this->aics[aicIndex].SiegeEngine6 = 0x28; - this->aics[aicIndex].AttMaxEngineers = 0x10; - this->aics[aicIndex].AttDiggingUnit = 0x19; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 39; + this->aics[aicIndex].SiegeEngine3 = 39; + this->aics[aicIndex].SiegeEngine4 = 59; + this->aics[aicIndex].SiegeEngine5 = 40; + this->aics[aicIndex].SiegeEngine6 = 40; + this->aics[aicIndex].AttMaxEngineers = 16; + this->aics[aicIndex].AttDiggingUnit = 25; this->aics[aicIndex].AttDiggingUnitMax = 6; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; @@ -129,17 +129,17 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x16; - this->aics[aicIndex].AttUnitBackupMax = 0x14; + this->aics[aicIndex].AttUnitBackup = 22; + this->aics[aicIndex].AttUnitBackupMax = 20; this->aics[aicIndex].AttUnitBackupGroupsCount = 2; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x1b; + this->aics[aicIndex].AttUnitSiegeDef = 27; this->aics[aicIndex].AttUnitSiegeDefMax = 4; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 2; - this->aics[aicIndex].AttUnitMain1 = 0x1b; - this->aics[aicIndex].AttUnitMain2 = 0x19; - this->aics[aicIndex].AttUnitMain3 = 0x19; + this->aics[aicIndex].AttUnitMain1 = 27; + this->aics[aicIndex].AttUnitMain2 = 25; + this->aics[aicIndex].AttUnitMain3 = 25; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 3; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_09.cpp b/src/OpenSHC/AI/AICState/setAICParameters_09.cpp index 082d66a3a3..c7c59a8994 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_09.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_09.cpp @@ -9,22 +9,22 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C8D20 void AICState::setAICParameters_09(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; this->aics[aicIndex].criticalPopularity = 4000; - this->aics[aicIndex].lowestPopularity = 0x157c; + this->aics[aicIndex].lowestPopularity = 5500; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 3; this->aics[aicIndex].taxesMax = 10; - this->aics[aicIndex].farm1 = 0x21; - this->aics[aicIndex].farm2 = 0x20; - this->aics[aicIndex].farm3 = 0x1f; + this->aics[aicIndex].farm1 = 33; + this->aics[aicIndex].farm2 = 32; + this->aics[aicIndex].farm3 = 31; this->aics[aicIndex].populationPerFarm = 4; - this->aics[aicIndex].unknown011 = 0xc; + this->aics[aicIndex].unknown011 = 12; this->aics[aicIndex].maxFood = 200; this->aics[aicIndex].minimumApples = 5; this->aics[aicIndex].minimumCheese = 5; @@ -33,110 +33,110 @@ namespace AI { this->aics[aicIndex].minimumHop = -1; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0x16; + this->aics[aicIndex].aiRequestDelay = 22; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x3c; - this->aics[aicIndex].maxResourceOther = 0xf; - this->aics[aicIndex].maxEquipment = 0x14; + this->aics[aicIndex].doubleRationsFoodThreshold = 40; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 60; + this->aics[aicIndex].maxResourceOther = 15; + this->aics[aicIndex].maxEquipment = 20; this->aics[aicIndex].maxBeer = 10; this->aics[aicIndex].maxResourceVariance = 4; this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 7; - this->aics[aicIndex].populationPerQuarry = 0xc; + this->aics[aicIndex].populationPerQuarry = 12; this->aics[aicIndex].populationPerIronmine = 10; this->aics[aicIndex].populationPerPitchrig = 0; this->aics[aicIndex].maxQuarries = 4; this->aics[aicIndex].maxIronmines = 5; - this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxWoodcutters = 12; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].maxFarms = 12; this->aics[aicIndex].buildInterval = 4; - this->aics[aicIndex].resourceRebuildDelay = 0x1e; - this->aics[aicIndex].blacksmithSetting = 0x16; + this->aics[aicIndex].resourceRebuildDelay = 30; + this->aics[aicIndex].blacksmithSetting = 22; this->aics[aicIndex].fletcherSetting = -999; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; this->aics[aicIndex].defWallPatrolRallyTime = 8; this->aics[aicIndex].defWallPatrolGroups = 2; this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; this->aics[aicIndex].defSiegeEngineBuildDelay = 2; this->aics[aicIndex].unknown072 = 100; - this->aics[aicIndex].unknown073 = 0x14; + this->aics[aicIndex].unknown073 = 20; this->aics[aicIndex].recruitProbDefWeak = 100; - this->aics[aicIndex].recruitProbDefDefault = 0x32; - this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].recruitProbDefDefault = 50; + this->aics[aicIndex].recruitProbDefStrong = 20; this->aics[aicIndex].recruitProbRaidWeak = 0; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbRaidStrong = 30; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x1e; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 30; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 4; this->aics[aicIndex].RecruitIntervalStrong = 4; - this->aics[aicIndex].SortieUnitRangedMin = 0xc; - this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitRangedMin = 12; + this->aics[aicIndex].SortieUnitRanged = 22; this->aics[aicIndex].SortieUnitMeleeMin = 4; - this->aics[aicIndex].SortieUnitMelee = 0x1b; + this->aics[aicIndex].SortieUnitMelee = 27; this->aics[aicIndex].DefDiggingUnitMax = 10; - this->aics[aicIndex].DefDiggingUnit = 0x16; - this->aics[aicIndex].DefWalls = 0x32; - this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].DefDiggingUnit = 22; + this->aics[aicIndex].DefWalls = 50; + this->aics[aicIndex].DefTotal = 80; this->aics[aicIndex].OuterPatrolGroupsCount = 2; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 10; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].DefUnit2 = 22; this->aics[aicIndex].RaidUnitsBase = 4; - this->aics[aicIndex].DefUnit3 = 0x17; + this->aics[aicIndex].DefUnit3 = 23; this->aics[aicIndex].RaidUnitsRandom = 0; - this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].RaidUnit1 = 28; this->aics[aicIndex].HarassingSiegeEnginesMax = 2; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 6; - this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].AttForceBase = 30; this->aics[aicIndex].AttForceRandom = 4; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x14; - this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttForceSupportAllyThreshold = 20; + this->aics[aicIndex].AttForceRallyPercentage = 50; this->aics[aicIndex].AttMovingTribesThreshold = 100; - this->aics[aicIndex].AttAssaultDelay = 0x14; + this->aics[aicIndex].AttAssaultDelay = 20; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].AttCoordinationPreference = 50; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x28; - this->aics[aicIndex].SiegeEngine2 = 0x28; - this->aics[aicIndex].SiegeEngine3 = 0x28; - this->aics[aicIndex].SiegeEngine4 = 0x28; - this->aics[aicIndex].SiegeEngine5 = 0x28; - this->aics[aicIndex].SiegeEngine6 = 0x28; - this->aics[aicIndex].AttMaxEngineers = 0x12; - this->aics[aicIndex].AttDiggingUnit = 0x16; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].SiegeEngine1 = 40; + this->aics[aicIndex].SiegeEngine2 = 40; + this->aics[aicIndex].SiegeEngine3 = 40; + this->aics[aicIndex].SiegeEngine4 = 40; + this->aics[aicIndex].SiegeEngine5 = 40; + this->aics[aicIndex].SiegeEngine6 = 40; + this->aics[aicIndex].AttMaxEngineers = 18; + this->aics[aicIndex].AttDiggingUnit = 22; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x17; - this->aics[aicIndex].AttUnitPatrolMax = 0x14; + this->aics[aicIndex].AttUnitPatrol = 23; + this->aics[aicIndex].AttUnitPatrolMax = 20; this->aics[aicIndex].AttUnitPatrolGroupsCount = 1; - this->aics[aicIndex].AttUnitBackup = 0x16; - this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackup = 22; + this->aics[aicIndex].AttUnitBackupMax = 30; this->aics[aicIndex].AttUnitBackupGroupsCount = 2; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x17; + this->aics[aicIndex].AttUnitSiegeDef = 23; this->aics[aicIndex].AttUnitSiegeDefMax = 10; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; - this->aics[aicIndex].AttUnitMain1 = 0x1b; - this->aics[aicIndex].AttUnitMain2 = 0x1b; + this->aics[aicIndex].AttUnitMain1 = 27; + this->aics[aicIndex].AttUnitMain2 = 27; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 4; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_GOLD; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_10.cpp b/src/OpenSHC/AI/AICState/setAICParameters_10.cpp index 99dc276f8e..bb6654eb74 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_10.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_10.cpp @@ -10,7 +10,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004C9120 void AICState::setAICParameters_10(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -21,8 +21,8 @@ namespace AI { this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 2; this->aics[aicIndex].taxesMax = 10; - this->aics[aicIndex].farm1 = 0x20; - this->aics[aicIndex].farm2 = 0x20; + this->aics[aicIndex].farm1 = 32; + this->aics[aicIndex].farm2 = 32; this->aics[aicIndex].populationPerFarm = 5; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 100; @@ -31,14 +31,14 @@ namespace AI { this->aics[aicIndex].minimumBread = 10; this->aics[aicIndex].minimumWheat = -1; this->aics[aicIndex].minimumHop = -1; - this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountFood = 20; this->aics[aicIndex].tradeAmountEquipment = 2; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x3c; - this->aics[aicIndex].maxResourceOther = 0xf; + this->aics[aicIndex].doubleRationsFoodThreshold = 50; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 60; + this->aics[aicIndex].maxResourceOther = 15; this->aics[aicIndex].maxEquipment = 6; this->aics[aicIndex].maxBeer = 10; this->aics[aicIndex].maxResourceVariance = 4; @@ -53,76 +53,76 @@ namespace AI { this->aics[aicIndex].maxPitchrigs = 1; this->aics[aicIndex].maxFarms = 8; this->aics[aicIndex].buildInterval = 4; - this->aics[aicIndex].resourceRebuildDelay = 0x3c; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 60; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource14 = 23; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x46; - this->aics[aicIndex].recruitProbDefDefault = 0x28; - this->aics[aicIndex].recruitProbDefStrong = 0x14; - this->aics[aicIndex].recruitProbRaidWeak = 0x14; - this->aics[aicIndex].recruitProbRaidDefault = 0x28; - this->aics[aicIndex].recruitProbRaidStrong = 0x14; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 70; + this->aics[aicIndex].recruitProbDefDefault = 40; + this->aics[aicIndex].recruitProbDefStrong = 20; + this->aics[aicIndex].recruitProbRaidWeak = 20; + this->aics[aicIndex].recruitProbRaidDefault = 40; + this->aics[aicIndex].recruitProbRaidStrong = 20; this->aics[aicIndex].recruitProbAttackWeak = 10; - this->aics[aicIndex].recruitProbAttackDefault = 0x14; - this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].recruitProbAttackDefault = 20; + this->aics[aicIndex].recruitProbAttackStrong = 60; this->aics[aicIndex].RecruitIntervalWeak = 4; this->aics[aicIndex].RecruitInterval = 4; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 2; - this->aics[aicIndex].SortieUnitRanged = 0x16; - this->aics[aicIndex].SortieUnitMeleeMin = 0x14; - this->aics[aicIndex].SortieUnitMelee = 0x18; + this->aics[aicIndex].SortieUnitRanged = 22; + this->aics[aicIndex].SortieUnitMeleeMin = 20; + this->aics[aicIndex].SortieUnitMelee = 24; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x18; + this->aics[aicIndex].DefDiggingUnit = 24; this->aics[aicIndex].DefWalls = 4; - this->aics[aicIndex].DefTotal = 0x14; + this->aics[aicIndex].DefTotal = 20; this->aics[aicIndex].OuterPatrolGroupsCount = 4; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x1c; - this->aics[aicIndex].DefUnit2 = 0x16; + this->aics[aicIndex].DefUnit1 = 28; + this->aics[aicIndex].DefUnit2 = 22; this->aics[aicIndex].RaidUnitsBase = 4; this->aics[aicIndex].RaidUnitsRandom = 4; - this->aics[aicIndex].DefUnit3 = 0x16; - this->aics[aicIndex].DefUnit4 = 0x16; - this->aics[aicIndex].DefUnit5 = 0x16; - this->aics[aicIndex].DefUnit6 = 0x16; - this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].DefUnit3 = 22; + this->aics[aicIndex].DefUnit4 = 22; + this->aics[aicIndex].DefUnit5 = 22; + this->aics[aicIndex].DefUnit6 = 22; + this->aics[aicIndex].RaidUnit1 = 28; this->aics[aicIndex].HarassingSiegeEnginesMax = 1; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 4; this->aics[aicIndex].AttForceBase = 10; - this->aics[aicIndex].AttForceRandom = 0x14; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x28; - this->aics[aicIndex].AttForceRallyPercentage = 0x28; + this->aics[aicIndex].AttForceRandom = 20; + this->aics[aicIndex].AttForceSupportAllyThreshold = 40; + this->aics[aicIndex].AttForceRallyPercentage = 40; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x46; + this->aics[aicIndex].AttCoordinationPreference = 70; this->aics[aicIndex].CowThrowInterval = 10000; this->aics[aicIndex].SiegeEngine1 = 0; this->aics[aicIndex].AttMaxEngineers = 0; - this->aics[aicIndex].AttDiggingUnit = 0x18; - this->aics[aicIndex].AttDiggingUnitMax = 0x3c; + this->aics[aicIndex].AttDiggingUnit = 24; + this->aics[aicIndex].AttDiggingUnitMax = 60; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; - this->aics[aicIndex].AttUnit2Max = 0x18; + this->aics[aicIndex].AttUnit2Max = 24; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; this->aics[aicIndex].AttUnitPatrol = 0; @@ -136,8 +136,8 @@ namespace AI { this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x18; - this->aics[aicIndex].AttUnitMain2 = 0x18; + this->aics[aicIndex].AttUnitMain1 = 24; + this->aics[aicIndex].AttUnitMain2 = 24; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_11.cpp b/src/OpenSHC/AI/AICState/setAICParameters_11.cpp index 57e5e6c3ba..8f4dcb309e 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_11.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_11.cpp @@ -15,12 +15,12 @@ namespace AI { this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; - this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].criticalPopularity = 4500; this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 2; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x1e; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 30; this->aics[aicIndex].populationPerFarm = 5; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 100; @@ -29,13 +29,13 @@ namespace AI { this->aics[aicIndex].minimumBread = -1; this->aics[aicIndex].minimumWheat = 2; this->aics[aicIndex].minimumHop = -1; - this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountFood = 20; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0x16; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x1e; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x32; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].aiRequestDelay = 22; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 30; + this->aics[aicIndex].doubleRationsFoodThreshold = 50; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 40; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 4; this->aics[aicIndex].maxBeer = 10; @@ -43,7 +43,7 @@ namespace AI { this->aics[aicIndex].recruitGoldThreshold = 100; this->aics[aicIndex].populationPerWoodcutter = 7; this->aics[aicIndex].populationPerQuarry = 6; - this->aics[aicIndex].populationPerIronmine = 0xc; + this->aics[aicIndex].populationPerIronmine = 12; this->aics[aicIndex].populationPerPitchrig = 6; this->aics[aicIndex].maxQuarries = 3; this->aics[aicIndex].maxIronmines = 1; @@ -51,74 +51,74 @@ namespace AI { this->aics[aicIndex].maxPitchrigs = 4; this->aics[aicIndex].maxFarms = 8; this->aics[aicIndex].buildInterval = 3; - this->aics[aicIndex].resourceRebuildDelay = 0x32; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 50; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource02 = 3; this->aics[aicIndex].sellResource03 = 6; - this->aics[aicIndex].sellResource06 = 0xe; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource06 = 14; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x46; - this->aics[aicIndex].recruitProbDefDefault = 0x1e; - this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 70; + this->aics[aicIndex].recruitProbDefDefault = 30; + this->aics[aicIndex].recruitProbDefStrong = 20; this->aics[aicIndex].recruitProbRaidWeak = 0; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbRaidStrong = 0x14; - this->aics[aicIndex].recruitProbAttackWeak = 0x1e; - this->aics[aicIndex].recruitProbAttackDefault = 0x32; - this->aics[aicIndex].recruitProbAttackStrong = 0x3c; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbRaidStrong = 20; + this->aics[aicIndex].recruitProbAttackWeak = 30; + this->aics[aicIndex].recruitProbAttackDefault = 50; + this->aics[aicIndex].recruitProbAttackStrong = 60; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; this->aics[aicIndex].SortieUnitRangedMin = 6; - this->aics[aicIndex].SortieUnitRanged = 0x4a; + this->aics[aicIndex].SortieUnitRanged = 74; this->aics[aicIndex].SortieUnitMeleeMin = 10; - this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].SortieUnitMelee = 75; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x47; - this->aics[aicIndex].DefWalls = 0x28; - this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].DefDiggingUnit = 71; + this->aics[aicIndex].DefWalls = 40; + this->aics[aicIndex].DefTotal = 40; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x46; - this->aics[aicIndex].DefUnit2 = 0x4c; - this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].DefUnit1 = 70; + this->aics[aicIndex].DefUnit2 = 76; + this->aics[aicIndex].RaidUnitsBase = 30; this->aics[aicIndex].RaidUnitsRandom = 10; - this->aics[aicIndex].RaidUnit1 = 0x4a; + this->aics[aicIndex].RaidUnit1 = 74; this->aics[aicIndex].HarassingSiegeEnginesMax = 4; - this->aics[aicIndex].HarassingSiegeEngine1 = 0x166; + this->aics[aicIndex].HarassingSiegeEngine1 = 358; this->aics[aicIndex].RaidRetargetDelay = 4; - this->aics[aicIndex].AttForceBase = 0x28; + this->aics[aicIndex].AttForceBase = 40; this->aics[aicIndex].AttForceRandom = 5; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x1e; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceSupportAllyThreshold = 30; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 4; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x5a; + this->aics[aicIndex].AttCoordinationPreference = 90; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x28; - this->aics[aicIndex].SiegeEngine2 = 0x4d; - this->aics[aicIndex].SiegeEngine3 = 0x4d; - this->aics[aicIndex].SiegeEngine4 = 0x4d; + this->aics[aicIndex].SiegeEngine1 = 40; + this->aics[aicIndex].SiegeEngine2 = 77; + this->aics[aicIndex].SiegeEngine3 = 77; + this->aics[aicIndex].SiegeEngine4 = 77; this->aics[aicIndex].AttMaxEngineers = 9; - this->aics[aicIndex].AttDiggingUnit = 0x47; - this->aics[aicIndex].AttDiggingUnitMax = 0xf; + this->aics[aicIndex].AttDiggingUnit = 71; + this->aics[aicIndex].AttDiggingUnitMax = 15; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; @@ -127,15 +127,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x4a; - this->aics[aicIndex].AttUnitBackupMax = 0x50; + this->aics[aicIndex].AttUnitBackup = 74; + this->aics[aicIndex].AttUnitBackupMax = 80; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 10; - this->aics[aicIndex].AttUnitEngage = 0x4c; + this->aics[aicIndex].AttUnitEngage = 76; this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttUnitMain1 = 75; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_12.cpp b/src/OpenSHC/AI/AICState/setAICParameters_12.cpp index 887cf7c843..8b658e7c98 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_12.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_12.cpp @@ -16,30 +16,30 @@ namespace AI { this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; - this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].criticalPopularity = 4500; this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 2; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x1e; - this->aics[aicIndex].farm2 = 0x20; - this->aics[aicIndex].farm3 = 0x1e; - this->aics[aicIndex].farm4 = 0x1f; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 30; + this->aics[aicIndex].farm2 = 32; + this->aics[aicIndex].farm3 = 30; + this->aics[aicIndex].farm4 = 31; this->aics[aicIndex].populationPerFarm = 4; this->aics[aicIndex].unknown011 = 10; - this->aics[aicIndex].maxFood = 0x50; + this->aics[aicIndex].maxFood = 80; this->aics[aicIndex].minimumApples = 10; this->aics[aicIndex].minimumCheese = -1; this->aics[aicIndex].minimumBread = -1; this->aics[aicIndex].minimumWheat = 2; this->aics[aicIndex].minimumHop = 2; - this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountFood = 20; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x3c; + this->aics[aicIndex].doubleRationsFoodThreshold = 40; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 60; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 4; this->aics[aicIndex].maxBeer = 10; @@ -53,73 +53,73 @@ namespace AI { this->aics[aicIndex].maxIronmines = 3; this->aics[aicIndex].maxWoodcutters = 10; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0x10; + this->aics[aicIndex].maxFarms = 16; this->aics[aicIndex].buildInterval = 2; - this->aics[aicIndex].resourceRebuildDelay = 0x28; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].resourceRebuildDelay = 40; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x50; - this->aics[aicIndex].recruitProbDefDefault = 0x28; - this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 80; + this->aics[aicIndex].recruitProbDefDefault = 40; + this->aics[aicIndex].recruitProbDefStrong = 20; this->aics[aicIndex].recruitProbRaidWeak = 10; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbRaidStrong = 30; this->aics[aicIndex].recruitProbAttackWeak = 10; - this->aics[aicIndex].recruitProbAttackDefault = 0x28; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 40; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 0; this->aics[aicIndex].RecruitIntervalStrong = 0; this->aics[aicIndex].SortieUnitRangedMin = 4; - this->aics[aicIndex].SortieUnitRanged = 0x46; - this->aics[aicIndex].SortieUnitMeleeMin = 0x14; - this->aics[aicIndex].SortieUnitMelee = 0x4b; + this->aics[aicIndex].SortieUnitRanged = 70; + this->aics[aicIndex].SortieUnitMeleeMin = 20; + this->aics[aicIndex].SortieUnitMelee = 75; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x16; - this->aics[aicIndex].DefWalls = 0x32; - this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].DefDiggingUnit = 22; + this->aics[aicIndex].DefWalls = 50; + this->aics[aicIndex].DefTotal = 50; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].DefUnit2 = 0x46; - this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].DefUnit2 = 70; + this->aics[aicIndex].RaidUnitsBase = 30; this->aics[aicIndex].RaidUnitsRandom = 10; - this->aics[aicIndex].RaidUnit1 = 0x4b; + this->aics[aicIndex].RaidUnit1 = 75; this->aics[aicIndex].HarassingSiegeEnginesMax = 3; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; - this->aics[aicIndex].HarassingSiegeEngine2 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; + this->aics[aicIndex].HarassingSiegeEngine2 = 190; this->aics[aicIndex].RaidRetargetDelay = 4; - this->aics[aicIndex].HarassingSiegeEngine3 = 0x166; - this->aics[aicIndex].AttForceBase = 0x1e; + this->aics[aicIndex].HarassingSiegeEngine3 = 358; + this->aics[aicIndex].AttForceBase = 30; this->aics[aicIndex].AttForceRandom = 10; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x14; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceSupportAllyThreshold = 20; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x50; + this->aics[aicIndex].AttCoordinationPreference = 80; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x27; - this->aics[aicIndex].SiegeEngine3 = 0x3d; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 39; + this->aics[aicIndex].SiegeEngine3 = 61; this->aics[aicIndex].AttMaxEngineers = 6; - this->aics[aicIndex].AttDiggingUnit = 0x16; - this->aics[aicIndex].AttDiggingUnitMax = 0xf; + this->aics[aicIndex].AttDiggingUnit = 22; + this->aics[aicIndex].AttDiggingUnitMax = 15; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; @@ -128,15 +128,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x4a; - this->aics[aicIndex].AttUnitBackupMax = 0x50; + this->aics[aicIndex].AttUnitBackup = 74; + this->aics[aicIndex].AttUnitBackupMax = 80; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x4b; + this->aics[aicIndex].AttUnitMain1 = 75; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_GOLD; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_13.cpp b/src/OpenSHC/AI/AICState/setAICParameters_13.cpp index afea2e4b06..d9b40524d9 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_13.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_13.cpp @@ -15,15 +15,15 @@ namespace AI { this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; - this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].criticalPopularity = 4500; this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 2; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x1e; - this->aics[aicIndex].farm2 = 0x1e; - this->aics[aicIndex].farm3 = 0x1e; - this->aics[aicIndex].farm4 = 0x1f; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 30; + this->aics[aicIndex].farm2 = 30; + this->aics[aicIndex].farm3 = 30; + this->aics[aicIndex].farm4 = 31; this->aics[aicIndex].populationPerFarm = 3; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 100; @@ -34,89 +34,89 @@ namespace AI { this->aics[aicIndex].minimumHop = 5; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0xc; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x1e; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x1e; - this->aics[aicIndex].maxWood = 0x32; - this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].aiRequestDelay = 12; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 30; + this->aics[aicIndex].doubleRationsFoodThreshold = 30; + this->aics[aicIndex].maxWood = 50; + this->aics[aicIndex].maxStone = 40; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 4; this->aics[aicIndex].maxBeer = 10; this->aics[aicIndex].maxResourceVariance = 4; this->aics[aicIndex].recruitGoldThreshold = 100; this->aics[aicIndex].populationPerWoodcutter = 7; - this->aics[aicIndex].populationPerQuarry = 0x14; + this->aics[aicIndex].populationPerQuarry = 20; this->aics[aicIndex].populationPerIronmine = 10; - this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].populationPerPitchrig = 15; this->aics[aicIndex].maxQuarries = 1; this->aics[aicIndex].maxIronmines = 2; - this->aics[aicIndex].maxWoodcutters = 0xc; + this->aics[aicIndex].maxWoodcutters = 12; this->aics[aicIndex].maxPitchrigs = 1; - this->aics[aicIndex].maxFarms = 0x10; + this->aics[aicIndex].maxFarms = 16; this->aics[aicIndex].buildInterval = 1; - this->aics[aicIndex].resourceRebuildDelay = 0x14; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 20; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource03 = 6; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x50; - this->aics[aicIndex].recruitProbDefDefault = 0x32; - this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 80; + this->aics[aicIndex].recruitProbDefDefault = 50; + this->aics[aicIndex].recruitProbDefStrong = 20; this->aics[aicIndex].recruitProbRaidWeak = 0; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; - this->aics[aicIndex].recruitProbAttackWeak = 0x14; - this->aics[aicIndex].recruitProbAttackDefault = 0x1e; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbRaidStrong = 30; + this->aics[aicIndex].recruitProbAttackWeak = 20; + this->aics[aicIndex].recruitProbAttackDefault = 30; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].RecruitIntervalWeak = 8; this->aics[aicIndex].RecruitInterval = 4; this->aics[aicIndex].RecruitIntervalStrong = 1; this->aics[aicIndex].SortieUnitRangedMin = 5; - this->aics[aicIndex].SortieUnitRanged = 0x46; - this->aics[aicIndex].SortieUnitMeleeMin = 0xf; - this->aics[aicIndex].SortieUnitMelee = 0x46; - this->aics[aicIndex].DefDiggingUnitMax = 0x3c; - this->aics[aicIndex].DefDiggingUnit = 0x47; - this->aics[aicIndex].DefWalls = 0x50; - this->aics[aicIndex].DefTotal = 0x50; + this->aics[aicIndex].SortieUnitRanged = 70; + this->aics[aicIndex].SortieUnitMeleeMin = 15; + this->aics[aicIndex].SortieUnitMelee = 70; + this->aics[aicIndex].DefDiggingUnitMax = 60; + this->aics[aicIndex].DefDiggingUnit = 71; + this->aics[aicIndex].DefWalls = 80; + this->aics[aicIndex].DefTotal = 80; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x46; + this->aics[aicIndex].DefUnit1 = 70; this->aics[aicIndex].RaidUnitsBase = 5; this->aics[aicIndex].RaidUnitsRandom = 5; - this->aics[aicIndex].RaidUnit1 = 0x49; + this->aics[aicIndex].RaidUnit1 = 73; this->aics[aicIndex].HarassingSiegeEnginesMax = 0; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 4; - this->aics[aicIndex].AttForceBase = 0x28; + this->aics[aicIndex].AttForceBase = 40; this->aics[aicIndex].AttForceRandom = 0; this->aics[aicIndex].AttForceSupportAllyThreshold = 10; - this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttForceRallyPercentage = 50; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].AttCoordinationPreference = 50; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x27; + this->aics[aicIndex].SiegeEngine1 = 39; this->aics[aicIndex].AttMaxEngineers = 0; - this->aics[aicIndex].AttDiggingUnit = 0x47; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; - this->aics[aicIndex].AttMaxAssassins = 0x28; + this->aics[aicIndex].AttDiggingUnit = 71; + this->aics[aicIndex].AttDiggingUnitMax = 20; + this->aics[aicIndex].AttMaxAssassins = 40; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; this->aics[aicIndex].AttMaxLaddermen = 0; @@ -124,7 +124,7 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x4a; + this->aics[aicIndex].AttUnitBackup = 74; this->aics[aicIndex].AttUnitBackupMax = 0; this->aics[aicIndex].AttUnitBackupGroupsCount = 0; this->aics[aicIndex].AttUnitEngageMax = 0; @@ -132,7 +132,7 @@ namespace AI { this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x49; + this->aics[aicIndex].AttUnitMain1 = 73; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 4; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_14.cpp b/src/OpenSHC/AI/AICState/setAICParameters_14.cpp index 64c2099b75..551c1a0f1f 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_14.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_14.cpp @@ -10,7 +10,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CA0C0 void AICState::setAICParameters_14(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -20,25 +20,25 @@ namespace AI { this->aics[aicIndex].lowestPopularity = 6000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 3; - this->aics[aicIndex].taxesMax = 0xb; - this->aics[aicIndex].farm1 = 0x20; - this->aics[aicIndex].farm2 = 0x1f; - this->aics[aicIndex].farm3 = 0x21; + this->aics[aicIndex].taxesMax = 11; + this->aics[aicIndex].farm1 = 32; + this->aics[aicIndex].farm2 = 31; + this->aics[aicIndex].farm3 = 33; this->aics[aicIndex].populationPerFarm = 4; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 300; - this->aics[aicIndex].minimumApples = 0x14; - this->aics[aicIndex].minimumCheese = 0x14; - this->aics[aicIndex].minimumBread = 0xffffffff; - this->aics[aicIndex].minimumWheat = 0xffffffff; + this->aics[aicIndex].minimumApples = 20; + this->aics[aicIndex].minimumCheese = 20; + this->aics[aicIndex].minimumBread = -1; + this->aics[aicIndex].minimumWheat = -1; this->aics[aicIndex].minimumHop = 2; this->aics[aicIndex].tradeAmountFood = 10; this->aics[aicIndex].tradeAmountEquipment = 2; - this->aics[aicIndex].aiRequestDelay = 0x28; - this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0x28; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; - this->aics[aicIndex].maxWood = 0x32; - this->aics[aicIndex].maxStone = 0x32; + this->aics[aicIndex].aiRequestDelay = 40; + this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 40; + this->aics[aicIndex].doubleRationsFoodThreshold = 40; + this->aics[aicIndex].maxWood = 50; + this->aics[aicIndex].maxStone = 50; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 10; this->aics[aicIndex].maxBeer = 10; @@ -46,8 +46,8 @@ namespace AI { this->aics[aicIndex].recruitGoldThreshold = 200; this->aics[aicIndex].populationPerWoodcutter = 7; this->aics[aicIndex].populationPerQuarry = 10; - this->aics[aicIndex].populationPerIronmine = 0xc; - this->aics[aicIndex].populationPerPitchrig = 0xf; + this->aics[aicIndex].populationPerIronmine = 12; + this->aics[aicIndex].populationPerPitchrig = 15; this->aics[aicIndex].maxQuarries = 3; this->aics[aicIndex].maxIronmines = 6; this->aics[aicIndex].maxWoodcutters = 10; @@ -55,92 +55,92 @@ namespace AI { this->aics[aicIndex].maxFarms = 10; this->aics[aicIndex].buildInterval = 3; this->aics[aicIndex].resourceRebuildDelay = 8; - this->aics[aicIndex].blacksmithSetting = 0x15; - this->aics[aicIndex].fletcherSetting = 0x12; - this->aics[aicIndex].poleturnerSetting = 0x14; + this->aics[aicIndex].blacksmithSetting = 21; + this->aics[aicIndex].fletcherSetting = 18; + this->aics[aicIndex].poleturnerSetting = 20; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource08 = 0x11; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource08 = 17; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 8; this->aics[aicIndex].defWallPatrolGroups = 2; this->aics[aicIndex].defSiegeEngineGoldThreshold = 200; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x1e; + this->aics[aicIndex].unknown073 = 30; this->aics[aicIndex].recruitProbDefWeak = 100; - this->aics[aicIndex].recruitProbDefDefault = 0x32; - this->aics[aicIndex].recruitProbDefStrong = 0x1e; + this->aics[aicIndex].recruitProbDefDefault = 50; + this->aics[aicIndex].recruitProbDefStrong = 30; this->aics[aicIndex].recruitProbRaidWeak = 0; - this->aics[aicIndex].recruitProbRaidDefault = 0x1e; - this->aics[aicIndex].recruitProbRaidStrong = 0x32; + this->aics[aicIndex].recruitProbRaidDefault = 30; + this->aics[aicIndex].recruitProbRaidStrong = 50; this->aics[aicIndex].recruitProbAttackWeak = 0; - this->aics[aicIndex].recruitProbAttackDefault = 0x14; - this->aics[aicIndex].recruitProbAttackStrong = 0x14; + this->aics[aicIndex].recruitProbAttackDefault = 20; + this->aics[aicIndex].recruitProbAttackStrong = 20; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 4; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 10; - this->aics[aicIndex].SortieUnitRanged = 0x17; + this->aics[aicIndex].SortieUnitRanged = 23; this->aics[aicIndex].SortieUnitMeleeMin = 10; - this->aics[aicIndex].SortieUnitMelee = 0x1a; + this->aics[aicIndex].SortieUnitMelee = 26; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x1a; - this->aics[aicIndex].DefWalls = 0x28; - this->aics[aicIndex].DefTotal = 0x32; + this->aics[aicIndex].DefDiggingUnit = 26; + this->aics[aicIndex].DefWalls = 40; + this->aics[aicIndex].DefTotal = 50; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 5; - this->aics[aicIndex].DefUnit1 = 0x17; - this->aics[aicIndex].DefUnit2 = 0x17; + this->aics[aicIndex].DefUnit1 = 23; + this->aics[aicIndex].DefUnit2 = 23; this->aics[aicIndex].RaidUnitsBase = 10; this->aics[aicIndex].RaidUnitsRandom = 4; - this->aics[aicIndex].DefUnit3 = 0x17; - this->aics[aicIndex].DefUnit4 = 0x4c; - this->aics[aicIndex].DefUnit5 = 0x49; - this->aics[aicIndex].RaidUnit1 = 0x1a; + this->aics[aicIndex].DefUnit3 = 23; + this->aics[aicIndex].DefUnit4 = 76; + this->aics[aicIndex].DefUnit5 = 73; + this->aics[aicIndex].RaidUnit1 = 26; this->aics[aicIndex].HarassingSiegeEnginesMax = 5; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; - this->aics[aicIndex].HarassingSiegeEngine2 = 0x166; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; + this->aics[aicIndex].HarassingSiegeEngine2 = 358; this->aics[aicIndex].RaidRetargetDelay = 4; - this->aics[aicIndex].AttForceBase = 0x32; - this->aics[aicIndex].AttForceRandom = 0x14; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x32; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceBase = 50; + this->aics[aicIndex].AttForceRandom = 20; + this->aics[aicIndex].AttForceSupportAllyThreshold = 50; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 5; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 8; - this->aics[aicIndex].AttCoordinationPreference = 0x32; + this->aics[aicIndex].AttCoordinationPreference = 50; this->aics[aicIndex].CowThrowInterval = 6; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x27; - this->aics[aicIndex].SiegeEngine3 = 0x4d; - this->aics[aicIndex].SiegeEngine4 = 0x4d; - this->aics[aicIndex].SiegeEngine5 = 0x4d; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 39; + this->aics[aicIndex].SiegeEngine3 = 77; + this->aics[aicIndex].SiegeEngine4 = 77; + this->aics[aicIndex].SiegeEngine5 = 77; this->aics[aicIndex].AttMaxEngineers = 10; - this->aics[aicIndex].AttDiggingUnit = 0x47; - this->aics[aicIndex].AttDiggingUnitMax = 0x50; + this->aics[aicIndex].AttDiggingUnit = 71; + this->aics[aicIndex].AttDiggingUnitMax = 80; this->aics[aicIndex].AttMaxAssassins = 10; - this->aics[aicIndex].AttUnit2 = 0x1a; + this->aics[aicIndex].AttUnit2 = 26; this->aics[aicIndex].AttUnit2Max = 10; this->aics[aicIndex].AttMaxLaddermen = 0; this->aics[aicIndex].AttMaxTunnelers = 0; - this->aics[aicIndex].AttUnitPatrol = 0x4c; + this->aics[aicIndex].AttUnitPatrol = 76; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x17; - this->aics[aicIndex].AttUnitBackupMax = 0x32; + this->aics[aicIndex].AttUnitBackup = 23; + this->aics[aicIndex].AttUnitBackupMax = 50; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; - this->aics[aicIndex].AttUnitSiegeDef = 0x1a; + this->aics[aicIndex].AttUnitSiegeDef = 26; this->aics[aicIndex].AttUnitSiegeDefMax = 6; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 1; - this->aics[aicIndex].AttUnitMain1 = 0x1a; - this->aics[aicIndex].AttUnitMain2 = 0x1a; + this->aics[aicIndex].AttUnitMain1 = 26; + this->aics[aicIndex].AttUnitMain2 = 26; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 3; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_CLOSEST; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_15.cpp b/src/OpenSHC/AI/AICState/setAICParameters_15.cpp index 856ba40695..b75bf7c2ee 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_15.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_15.cpp @@ -9,7 +9,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CA4D0 void AICState::setAICParameters_15(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; @@ -20,10 +20,10 @@ namespace AI { this->aics[aicIndex].highestPopularity = 8000; this->aics[aicIndex].taxesMin = 2; this->aics[aicIndex].taxesMax = 10; - this->aics[aicIndex].farm1 = 0x21; - this->aics[aicIndex].farm2 = 0x1f; - this->aics[aicIndex].farm3 = 0x21; - this->aics[aicIndex].farm4 = 0x21; + this->aics[aicIndex].farm1 = 33; + this->aics[aicIndex].farm2 = 31; + this->aics[aicIndex].farm3 = 33; + this->aics[aicIndex].farm4 = 33; this->aics[aicIndex].populationPerFarm = 5; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 100; @@ -32,14 +32,14 @@ namespace AI { this->aics[aicIndex].minimumBread = -1; this->aics[aicIndex].minimumWheat = -1; this->aics[aicIndex].minimumHop = 5; - this->aics[aicIndex].tradeAmountFood = 0x14; + this->aics[aicIndex].tradeAmountFood = 20; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 0; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x50; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x32; - this->aics[aicIndex].maxResourceOther = 0xc; + this->aics[aicIndex].doubleRationsFoodThreshold = 80; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 50; + this->aics[aicIndex].maxResourceOther = 12; this->aics[aicIndex].maxEquipment = 10; this->aics[aicIndex].maxBeer = 6; this->aics[aicIndex].maxResourceVariance = 4; @@ -54,68 +54,68 @@ namespace AI { this->aics[aicIndex].maxPitchrigs = 1; this->aics[aicIndex].maxFarms = 9; this->aics[aicIndex].buildInterval = 3; - this->aics[aicIndex].resourceRebuildDelay = 0x28; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 40; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource04 = 7; this->aics[aicIndex].sellResource05 = 9; - this->aics[aicIndex].sellResource07 = 0x10; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource14 = 0x17; + this->aics[aicIndex].sellResource07 = 16; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource14 = 23; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x32; - this->aics[aicIndex].recruitProbDefDefault = 0x1e; - this->aics[aicIndex].recruitProbDefStrong = 0x14; - this->aics[aicIndex].recruitProbRaidWeak = 0x28; - this->aics[aicIndex].recruitProbRaidDefault = 0x28; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 50; + this->aics[aicIndex].recruitProbDefDefault = 30; + this->aics[aicIndex].recruitProbDefStrong = 20; + this->aics[aicIndex].recruitProbRaidWeak = 40; + this->aics[aicIndex].recruitProbRaidDefault = 40; + this->aics[aicIndex].recruitProbRaidStrong = 30; this->aics[aicIndex].recruitProbAttackWeak = 10; - this->aics[aicIndex].recruitProbAttackDefault = 0x1e; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 30; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 4; this->aics[aicIndex].SortieUnitRangedMin = 4; - this->aics[aicIndex].SortieUnitRanged = 0x16; + this->aics[aicIndex].SortieUnitRanged = 22; this->aics[aicIndex].SortieUnitMeleeMin = 4; - this->aics[aicIndex].SortieUnitMelee = 0x1c; + this->aics[aicIndex].SortieUnitMelee = 28; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefDiggingUnit = 0x16; - this->aics[aicIndex].DefWalls = 0x1e; - this->aics[aicIndex].DefTotal = 0x28; + this->aics[aicIndex].DefDiggingUnit = 22; + this->aics[aicIndex].DefWalls = 30; + this->aics[aicIndex].DefTotal = 40; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].RaidUnitsBase = 0x10; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].RaidUnitsBase = 16; this->aics[aicIndex].RaidUnitsRandom = 4; - this->aics[aicIndex].RaidUnit1 = 0x1c; + this->aics[aicIndex].RaidUnit1 = 28; this->aics[aicIndex].HarassingSiegeEnginesMax = 1; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; this->aics[aicIndex].RaidRetargetDelay = 4; this->aics[aicIndex].AttForceBase = 10; - this->aics[aicIndex].AttForceRandom = 0x14; + this->aics[aicIndex].AttForceRandom = 20; this->aics[aicIndex].AttForceSupportAllyThreshold = 10; - this->aics[aicIndex].AttForceRallyPercentage = 0x32; + this->aics[aicIndex].AttForceRallyPercentage = 50; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x46; + this->aics[aicIndex].AttCoordinationPreference = 70; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x28; - this->aics[aicIndex].SiegeEngine2 = 0x28; + this->aics[aicIndex].SiegeEngine1 = 40; + this->aics[aicIndex].SiegeEngine2 = 40; this->aics[aicIndex].AttMaxEngineers = 6; - this->aics[aicIndex].AttDiggingUnit = 0x16; - this->aics[aicIndex].AttDiggingUnitMax = 0x14; + this->aics[aicIndex].AttDiggingUnit = 22; + this->aics[aicIndex].AttDiggingUnitMax = 20; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; this->aics[aicIndex].AttUnit2Max = 0; @@ -124,15 +124,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x16; - this->aics[aicIndex].AttUnitBackupMax = 0x1e; + this->aics[aicIndex].AttUnitBackup = 22; + this->aics[aicIndex].AttUnitBackupMax = 30; this->aics[aicIndex].AttUnitBackupGroupsCount = 3; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x1b; + this->aics[aicIndex].AttUnitMain1 = 27; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAICParameters_16.cpp b/src/OpenSHC/AI/AICState/setAICParameters_16.cpp index 2ce895b500..b6836e4e76 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_16.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_16.cpp @@ -10,20 +10,20 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CA8A0 void AICState::setAICParameters_16(int aicIndex) { - this->aics[aicIndex].flagType = 0xd; + this->aics[aicIndex].flagType = 13; this->aics[aicIndex].unknown002 = 0; this->aics[aicIndex].unknown001 = 0; this->aics[aicIndex].unknown003 = 0; this->aics[aicIndex].unknown004 = 1; this->aics[aicIndex].unknown005 = 1; - this->aics[aicIndex].criticalPopularity = 0x1194; + this->aics[aicIndex].criticalPopularity = 4500; this->aics[aicIndex].lowestPopularity = 5000; this->aics[aicIndex].highestPopularity = 9000; this->aics[aicIndex].taxesMin = 2; - this->aics[aicIndex].taxesMax = 0xc; - this->aics[aicIndex].farm1 = 0x1f; - this->aics[aicIndex].farm2 = 0x1e; - this->aics[aicIndex].farm3 = 0x1e; + this->aics[aicIndex].taxesMax = 12; + this->aics[aicIndex].farm1 = 31; + this->aics[aicIndex].farm2 = 30; + this->aics[aicIndex].farm3 = 30; this->aics[aicIndex].populationPerFarm = 4; this->aics[aicIndex].unknown011 = 10; this->aics[aicIndex].maxFood = 100; @@ -34,16 +34,16 @@ namespace AI { this->aics[aicIndex].minimumHop = 2; this->aics[aicIndex].tradeAmountFood = 5; this->aics[aicIndex].tradeAmountEquipment = 0; - this->aics[aicIndex].aiRequestDelay = 0xc; + this->aics[aicIndex].aiRequestDelay = 12; this->aics[aicIndex].minimumGoodsRequiredAfterTrade = 10; - this->aics[aicIndex].doubleRationsFoodThreshold = 0x28; - this->aics[aicIndex].maxWood = 0x3c; - this->aics[aicIndex].maxStone = 0x28; + this->aics[aicIndex].doubleRationsFoodThreshold = 40; + this->aics[aicIndex].maxWood = 60; + this->aics[aicIndex].maxStone = 40; this->aics[aicIndex].maxResourceOther = 10; this->aics[aicIndex].maxEquipment = 4; this->aics[aicIndex].maxBeer = 5; this->aics[aicIndex].maxResourceVariance = 4; - this->aics[aicIndex].recruitGoldThreshold = 0x32; + this->aics[aicIndex].recruitGoldThreshold = 50; this->aics[aicIndex].populationPerWoodcutter = 7; this->aics[aicIndex].populationPerQuarry = 6; this->aics[aicIndex].populationPerIronmine = 10; @@ -52,71 +52,71 @@ namespace AI { this->aics[aicIndex].maxIronmines = 2; this->aics[aicIndex].maxWoodcutters = 10; this->aics[aicIndex].maxPitchrigs = 0; - this->aics[aicIndex].maxFarms = 0xc; + this->aics[aicIndex].maxFarms = 12; this->aics[aicIndex].buildInterval = 2; - this->aics[aicIndex].resourceRebuildDelay = 0x28; - this->aics[aicIndex].blacksmithSetting = 0x16; - this->aics[aicIndex].fletcherSetting = 0x11; - this->aics[aicIndex].poleturnerSetting = 0x13; + this->aics[aicIndex].resourceRebuildDelay = 40; + this->aics[aicIndex].blacksmithSetting = 22; + this->aics[aicIndex].fletcherSetting = 17; + this->aics[aicIndex].poleturnerSetting = 19; this->aics[aicIndex].sellResource03 = 6; - this->aics[aicIndex].sellResource09 = 0x12; - this->aics[aicIndex].sellResource10 = 0x13; - this->aics[aicIndex].sellResource11 = 0x14; - this->aics[aicIndex].sellResource12 = 0x15; - this->aics[aicIndex].sellResource13 = 0x16; - this->aics[aicIndex].sellResource14 = 0x17; - this->aics[aicIndex].sellResource15 = 0x18; + this->aics[aicIndex].sellResource09 = 18; + this->aics[aicIndex].sellResource10 = 19; + this->aics[aicIndex].sellResource11 = 20; + this->aics[aicIndex].sellResource12 = 21; + this->aics[aicIndex].sellResource13 = 22; + this->aics[aicIndex].sellResource14 = 23; + this->aics[aicIndex].sellResource15 = 24; this->aics[aicIndex].defWallPatrolRallyTime = 2; this->aics[aicIndex].defWallPatrolGroups = 3; this->aics[aicIndex].defSiegeEngineGoldThreshold = 100; this->aics[aicIndex].defSiegeEngineBuildDelay = 4; this->aics[aicIndex].unknown072 = 200; - this->aics[aicIndex].unknown073 = 0x14; - this->aics[aicIndex].recruitProbDefWeak = 0x50; - this->aics[aicIndex].recruitProbDefDefault = 0x28; - this->aics[aicIndex].recruitProbDefStrong = 0x14; + this->aics[aicIndex].unknown073 = 20; + this->aics[aicIndex].recruitProbDefWeak = 80; + this->aics[aicIndex].recruitProbDefDefault = 40; + this->aics[aicIndex].recruitProbDefStrong = 20; this->aics[aicIndex].recruitProbRaidWeak = 10; this->aics[aicIndex].RecruitIntervalWeak = 1; this->aics[aicIndex].RecruitInterval = 1; this->aics[aicIndex].RecruitIntervalStrong = 1; - this->aics[aicIndex].SortieUnitRanged = 0x16; - this->aics[aicIndex].DefDiggingUnit = 0x16; + this->aics[aicIndex].SortieUnitRanged = 22; + this->aics[aicIndex].DefDiggingUnit = 22; this->aics[aicIndex].OuterPatrolGroupsCount = 1; this->aics[aicIndex].OuterPatrolGroupsMove = 1; this->aics[aicIndex].OuterPatrolRallyDelay = 2; - this->aics[aicIndex].DefUnit1 = 0x16; - this->aics[aicIndex].recruitProbRaidDefault = 0x14; - this->aics[aicIndex].recruitProbRaidStrong = 0x1e; + this->aics[aicIndex].DefUnit1 = 22; + this->aics[aicIndex].recruitProbRaidDefault = 20; + this->aics[aicIndex].recruitProbRaidStrong = 30; this->aics[aicIndex].recruitProbAttackWeak = 10; - this->aics[aicIndex].recruitProbAttackDefault = 0x28; - this->aics[aicIndex].recruitProbAttackStrong = 0x32; + this->aics[aicIndex].recruitProbAttackDefault = 40; + this->aics[aicIndex].recruitProbAttackStrong = 50; this->aics[aicIndex].SortieUnitRangedMin = 4; - this->aics[aicIndex].SortieUnitMeleeMin = 0x14; - this->aics[aicIndex].SortieUnitMelee = 0x25; + this->aics[aicIndex].SortieUnitMeleeMin = 20; + this->aics[aicIndex].SortieUnitMelee = 37; this->aics[aicIndex].DefDiggingUnitMax = 4; - this->aics[aicIndex].DefWalls = 0x1e; - this->aics[aicIndex].DefTotal = 0x1e; - this->aics[aicIndex].RaidUnitsBase = 0x1e; + this->aics[aicIndex].DefWalls = 30; + this->aics[aicIndex].DefTotal = 30; + this->aics[aicIndex].RaidUnitsBase = 30; this->aics[aicIndex].RaidUnitsRandom = 10; - this->aics[aicIndex].RaidUnit1 = 0x25; + this->aics[aicIndex].RaidUnit1 = 37; this->aics[aicIndex].HarassingSiegeEnginesMax = 5; this->aics[aicIndex].RaidRetargetDelay = 4; - this->aics[aicIndex].HarassingSiegeEngine1 = 0xbe; - this->aics[aicIndex].AttForceBase = 0x32; + this->aics[aicIndex].HarassingSiegeEngine1 = 190; + this->aics[aicIndex].AttForceBase = 50; this->aics[aicIndex].AttForceRandom = 10; - this->aics[aicIndex].AttForceSupportAllyThreshold = 0x28; - this->aics[aicIndex].AttForceRallyPercentage = 0x50; + this->aics[aicIndex].AttForceSupportAllyThreshold = 40; + this->aics[aicIndex].AttForceRallyPercentage = 80; this->aics[aicIndex].AttMovingTribesThreshold = 100; this->aics[aicIndex].AttAssaultDelay = 0; this->aics[aicIndex].AttUnitPatrolRecommandDelay = 5; - this->aics[aicIndex].AttCoordinationPreference = 0x50; + this->aics[aicIndex].AttCoordinationPreference = 80; this->aics[aicIndex].CowThrowInterval = 10000; - this->aics[aicIndex].SiegeEngine1 = 0x27; - this->aics[aicIndex].SiegeEngine2 = 0x27; - this->aics[aicIndex].SiegeEngine3 = 0x27; - this->aics[aicIndex].SiegeEngine4 = 0x27; + this->aics[aicIndex].SiegeEngine1 = 39; + this->aics[aicIndex].SiegeEngine2 = 39; + this->aics[aicIndex].SiegeEngine3 = 39; + this->aics[aicIndex].SiegeEngine4 = 39; this->aics[aicIndex].AttMaxEngineers = 8; - this->aics[aicIndex].AttDiggingUnit = 0x16; + this->aics[aicIndex].AttDiggingUnit = 22; this->aics[aicIndex].AttDiggingUnitMax = 10; this->aics[aicIndex].AttMaxAssassins = 0; this->aics[aicIndex].AttUnit2 = 0; @@ -126,15 +126,15 @@ namespace AI { this->aics[aicIndex].AttUnitPatrol = 0; this->aics[aicIndex].AttUnitPatrolMax = 0; this->aics[aicIndex].AttUnitPatrolGroupsCount = 0; - this->aics[aicIndex].AttUnitBackup = 0x16; - this->aics[aicIndex].AttUnitBackupMax = 0x28; + this->aics[aicIndex].AttUnitBackup = 22; + this->aics[aicIndex].AttUnitBackupMax = 40; this->aics[aicIndex].AttUnitBackupGroupsCount = 1; this->aics[aicIndex].AttUnitEngageMax = 0; this->aics[aicIndex].AttUnitEngage = 0; this->aics[aicIndex].AttUnitSiegeDef = 0; this->aics[aicIndex].AttUnitSiegeDefMax = 0; this->aics[aicIndex].AttUnitSiegeDefGroupsCount = 0; - this->aics[aicIndex].AttUnitMain1 = 0x25; + this->aics[aicIndex].AttUnitMain1 = 37; this->aics[aicIndex].AttMaxDefault = 200; this->aics[aicIndex].AttMainGroupsCount = 2; this->aics[aicIndex].TargetChoice = OpenSHC::AI::AIC::AITC_BALANCED; diff --git a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp index b6a98e4894..324a91bf07 100644 --- a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp +++ b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp @@ -11,23 +11,22 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D0110 void AICState::setAttackCoordinationLevel(int playerID) { - int const _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; - if (_aiType == AITA_NULL) { + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == AITA_NULL) { return; } - int _willingnessPercentage = this->aics[_aiType - 1].AttCoordinationPreference + int willingnessPercentage = this->aics[aiType - 1].AttCoordinationPreference + DAT_GameState::instance.playerDataArray[playerID].currentAttackWave * 4; - if (90 < _willingnessPercentage) { - _willingnessPercentage = 90; + if (90 < willingnessPercentage) { + willingnessPercentage = 90; } - int _rngMod100 = SEC_RNG::instance.currentNumber2 % 100; + int rngMod100 = SEC_RNG::instance.currentNumber2 % 100; MACRO_CALL_MEMBER(Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); - if (_rngMod100 < _willingnessPercentage / 2) { + if (rngMod100 < willingnessPercentage / 2) { DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel = 2; return; } - DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel - = _rngMod100 < _willingnessPercentage; + DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel = rngMod100 < willingnessPercentage; } } } diff --git a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp index 01b79f53fc..1abc1fb1a1 100644 --- a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp +++ b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp @@ -7,7 +7,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB1B0 - int AICState::setNextFarmTypeToBuild(PlayerID playerID) + int AICState::setNextFarmTypeToBuild(int playerID) { int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp index 51ca939344..4cf955f92a 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp @@ -7,7 +7,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004ECA60 - BOOLEnum AICState::shouldNotBeBuildingArmoury(PlayerID playerID, Commands::MappersEnum commandBuildingType) + BOOLEnum AICState::shouldNotBeBuildingArmoury(int playerID, Commands::MappersEnum commandBuildingType) { if (commandBuildingType != Commands::M_MAPPER_ARMOURY) { return FALSE; diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp index b674070c31..f552416afa 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp @@ -7,9 +7,9 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB5B0 - BOOLEnum AICState::shouldNotBeBuildingHovel(PlayerID playerID, Commands::MappersEnum param_2) + BOOLEnum AICState::shouldNotBeBuildingHovel(int playerID, Commands::MappersEnum mapper) { - if (param_2 != Commands::M_MAPPER_HOVEL) { + if (mapper != Commands::M_MAPPER_HOVEL) { return FALSE; } diff --git a/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp index 8d1ab8554c..11a96eaaf2 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp @@ -8,19 +8,19 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB9F0 BOOLEnum AICState::shouldNotBuildMarketArmoryGranaryBarracksMercenarypost( - int playerID, Commands::MappersEnum param_2) + int playerID, Commands::MappersEnum mapper) { if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker > 0) { // nervous: reject market/mercenarypost/barracks/armory types - if (param_2 != Commands::M_MAPPER_TRADEPOST && param_2 != Commands::M_MAPPER_BARRACKS_EURO - && param_2 != Commands::M_MAPPER_BARRACKS_ARAB && param_2 != Commands::M_MAPPER_ARMOURY) { - return param_2 != Commands::M_MAPPER_GRANARY; + if (mapper != Commands::M_MAPPER_TRADEPOST && mapper != Commands::M_MAPPER_BARRACKS_EURO + && mapper != Commands::M_MAPPER_BARRACKS_ARAB && mapper != Commands::M_MAPPER_ARMOURY) { + return mapper != Commands::M_MAPPER_GRANARY; } } else { // not nervous: only reject if destroy tracker > 0 and not marketplace if (DAT_GameState::instance.playerDataArray[playerID].aiBuildingDestroyChoiceTracker > 0 - && param_2 != Commands::M_MAPPER_TRADEPOST) { - return param_2 != Commands::M_MAPPER_GRANARY; + && mapper != Commands::M_MAPPER_TRADEPOST) { + return mapper != Commands::M_MAPPER_GRANARY; } } return FALSE; diff --git a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp index 83caadc1ea..118a0cf3ff 100644 --- a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp +++ b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp @@ -7,9 +7,9 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB700 - BOOLEnum AICState::shouldWaitWithBuildingAPositiveFearFactor(int playerID, Commands::MappersEnum param_2) + BOOLEnum AICState::shouldWaitWithBuildingAPositiveFearFactor(int playerID, Commands::MappersEnum mapper) { - switch (param_2) { + switch (mapper) { case Commands::M_MAPPER_GARDEN1: case Commands::M_MAPPER_GARDEN2: case Commands::M_MAPPER_GARDEN3: diff --git a/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp index 480816f066..609c5c523a 100644 --- a/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp +++ b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp @@ -8,21 +8,21 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D0190 - BOOLEnum AICState::teamIsWeakRelativeToEnemy(int playerID, BOOLEnum param_2) + BOOLEnum AICState::teamIsWeakRelativeToEnemy(int playerID, BOOLEnum alreadyNervous) { // strength of the own team in percent of the enemy strength - int _relativeStrength; + int relativeStrength; if (DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue == 0) { - _relativeStrength = 100; + relativeStrength = 100; } else { - _relativeStrength = DAT_GameState::instance.playerDataArray[playerID].totalTeamTroopValue * 100 + relativeStrength = DAT_GameState::instance.playerDataArray[playerID].totalTeamTroopValue * 100 / DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; } - DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy = _relativeStrength; + DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy = relativeStrength; // the team counts as weak below a threshold that is lower with an enclosed keep // and much higher during the first 12000 ticks - if (param_2) { + if (alreadyNervous) { if (MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID)) { if (DAT_GameState::instance.playerDataArray[playerID].relativeStrengthOfTeamComparedToEnemy >= 70) return FALSE; diff --git a/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp index 393f1a259e..ba348e523d 100644 --- a/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp +++ b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp @@ -13,10 +13,10 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC8D0 BOOLEnum AICState::unitIDIsRangedOrArmored(int unitID) { - int _unitType = DAT_UnitsState::instance.units[unitID].unitType; + int unitType = DAT_UnitsState::instance.units[unitID].unitType; for (int i = 0; i < 7; i++) { - if (DAT_SkirmishDefinedData::instance.RangedAndArmoredUnits[i] == _unitType) { + if (DAT_SkirmishDefinedData::instance.RangedAndArmoredUnits[i] == unitType) { return TRUE; } } diff --git a/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp index eef4ddd574..1d5d82924a 100644 --- a/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp +++ b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp @@ -20,71 +20,71 @@ namespace AI { MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::makeOutpostTribesAttack, this)(); // every AI gets its own tick of the day, week and month, so the work is spread out - for (int _playerID = 1; _playerID < 9; _playerID++) { - if (DAT_GameState::instance.playerDataArray[_playerID].aiType == OpenSHC::AI::AIT_NULL) + for (int playerID = 1; playerID < 9; playerID++) { + if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) continue; - if (DAT_GameState::instance.playerDataArray[_playerID].playerDeathRelated != 0) + if (DAT_GameState::instance.playerDataArray[playerID].playerDeathRelated != 0) continue; - if (DAT_GameState::instance.playerDataArray[_playerID].lordKilledByPlayerID != 0) + if (DAT_GameState::instance.playerDataArray[playerID].lordKilledByPlayerID != 0) continue; - int _aicIndex = DAT_GameState::instance.playerDataArray[_playerID].aiType - 1; + int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; - if (DAT_GameState::instance.mapAndTime.dayTicks == _playerID) { + if (DAT_GameState::instance.mapAndTime.dayTicks == playerID) { if (DAT_GameState::instance.mapAndTime.skirmishNoRushTicks == 0) { - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieRangedUnits, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieMeleeUnits, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitUnits, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::recruitHarrassingSiegeEngines, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiAssignMoatDiggers, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiCreateSiegeUnits, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineers, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieRangedUnits, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitSortieMeleeUnits, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitUnits, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::recruitHarrassingSiegeEngines, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiAssignMoatDiggers, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiCreateSiegeUnits, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineers, this)(playerID); } - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiBuyAndSellGoods, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiGiveRaidInstructions, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiBuyAndSellGoods, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiGiveRaidInstructions, this)(playerID); } - if (DAT_GameState::instance.mapAndTime.weekTicks == _playerID) { + if (DAT_GameState::instance.mapAndTime.weekTicks == playerID) { if (DAT_GameState::instance.mapAndTime.skirmishNoRushTicks == 0) - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineerForOilDuty, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateTribeLocations, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIPlayerState, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiUpdateTaxesAndRations, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setFoodBuyPlan, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiRecruitEngineerForOilDuty, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateTribeLocations, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIPlayerState, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::aiUpdateTaxesAndRations, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::setFoodBuyPlan, this)(playerID); // on the month tick the strength update happens below, with the nervousness handling enabled - if (DAT_GameState::instance.mapAndTime.monthTicks != _playerID) - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(_playerID, 0); + if (DAT_GameState::instance.mapAndTime.monthTicks != playerID) + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(playerID, 0); - if (DAT_GameState::instance.playerDataArray[_playerID].aiRequestDelay != 0) - DAT_GameState::instance.playerDataArray[_playerID].aiRequestDelay--; - if (DAT_GameState::instance.playerDataArray[_playerID].nervousBikCountdown != 0) - DAT_GameState::instance.playerDataArray[_playerID].nervousBikCountdown--; - if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown3 != 0) - DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown3--; - if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown4 != 0) - DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown4--; - if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown5 != 0) - DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown5--; - if (DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown6 != 0) - DAT_GameState::instance.playerDataArray[_playerID].someAiCountdown6--; + if (DAT_GameState::instance.playerDataArray[playerID].aiRequestDelay != 0) + DAT_GameState::instance.playerDataArray[playerID].aiRequestDelay--; + if (DAT_GameState::instance.playerDataArray[playerID].nervousBikCountdown != 0) + DAT_GameState::instance.playerDataArray[playerID].nervousBikCountdown--; + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown3 != 0) + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown3--; + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown4 != 0) + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown4--; + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown5 != 0) + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown5--; + if (DAT_GameState::instance.playerDataArray[playerID].someAiCountdown6 != 0) + DAT_GameState::instance.playerDataArray[playerID].someAiCountdown6--; } - if (DAT_GameState::instance.mapAndTime.monthTicks == _playerID) { + if (DAT_GameState::instance.mapAndTime.monthTicks == playerID) { MACRO_CALL_MEMBER( OpenSHC::Map::TileMapState_Func::countMoatsOwnedByEachPlayer, DAT_TileMapState::ptr)(); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::instructTribe166ToMove, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::giveMoveCommandToSortieUnits, this)(_playerID); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(_playerID, 1); - MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::selectAttackTarget, this)(_playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::instructTribe166ToMove, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::giveMoveCommandToSortieUnits, this)(playerID); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::updateAIStrengthState, this)(playerID, 1); + MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::selectAttackTarget, this)(playerID); - if (DAT_GameState::instance.playerDataArray[_playerID].aiRecruitUnitChoiceState + if (DAT_GameState::instance.playerDataArray[playerID].aiRecruitUnitChoiceState == OpenSHC::AI::AIRUC_RAIDING) { - DAT_GameState::instance.playerDataArray[_playerID].canStartSpending = 1; + DAT_GameState::instance.playerDataArray[playerID].canStartSpending = 1; } else { // only spend on recruiting while gold is above the AIC's threshold - DAT_GameState::instance.playerDataArray[_playerID].canStartSpending - = DAT_GameState::instance.playerDataArray[_playerID].currentResources[0xf] - > this->aics[_aicIndex].recruitGoldThreshold; + DAT_GameState::instance.playerDataArray[playerID].canStartSpending + = DAT_GameState::instance.playerDataArray[playerID].currentResources[0xf] + > this->aics[aicIndex].recruitGoldThreshold; } } } diff --git a/src/OpenSHC/AI/AICState/updateTribeLocations.cpp b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp index 83f75e0371..4364f547c3 100644 --- a/src/OpenSHC/AI/AICState/updateTribeLocations.cpp +++ b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp @@ -15,9 +15,9 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D4940 void AICState::updateTribeLocations(int playerID) { - AITypeInt _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; - if (_aiType == OpenSHC::AI::AIT_NULL) { + if (aiType == OpenSHC::AI::AIT_NULL) { return; } @@ -25,7 +25,7 @@ namespace AI { = DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter + 1; if (DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeWaitCounter - >= this->aics[_aiType - 1].defWallPatrolRallyTime) { + >= this->aics[aiType - 1].defWallPatrolRallyTime) { DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeHits = DAT_GameState::instance.playerDataArray[playerID].defWallPatrolRallyTimeHits + 1; diff --git a/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp index 01599292d8..1b78abcc77 100644 --- a/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp +++ b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp @@ -27,77 +27,75 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CEFD0 void AICState::useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers(int playerID) { - int _aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; - if (_aiType == OpenSHC::AI::AIT_NULL) + int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + if (aiType == OpenSHC::AI::AIT_NULL) return; - int _aicIndex = _aiType - 1; - int _aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; - if (_aiTribeID == 0) + int aicIndex = aiType - 1; + int aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + if (aiTribeID == 0) return; - if (DAT_TribesState::instance.tribes[_aiTribeID].uid + if (DAT_TribesState::instance.tribes[aiTribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0x12]) return; - int _availableEngineers = DAT_TribesState::instance.tribes[_aiTribeID].size; - int _requiredEngineers; - int _totalRequiredEngineers = 0; + int availableEngineers = DAT_TribesState::instance.tribes[aiTribeID].size; + int requiredEngineers; + int totalRequiredEngineers = 0; for (int i = 0; i < 8; i++) { - if ((&this->aics[_aicIndex].SiegeEngine1)[i] <= 0) + if ((&this->aics[aicIndex].SiegeEngine1)[i] <= 0) break; for (int j = 0; j < 6; j++) { - if ((&this->aics[_aicIndex].SiegeEngine1)[i] + if ((&this->aics[aicIndex].SiegeEngine1)[i] == DAT_SkirmishDefinedData::instance.SiegeEngineUnitType[j]) { - _requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; + requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; break; } } - if (_totalRequiredEngineers + _requiredEngineers > _availableEngineers) + if (totalRequiredEngineers + requiredEngineers > availableEngineers) break; - _totalRequiredEngineers += _requiredEngineers; + totalRequiredEngineers += requiredEngineers; } - if (_totalRequiredEngineers <= 0) + if (totalRequiredEngineers <= 0) return; - for (; DAT_TribesState::instance.tribes[_aiTribeID].size != 0; _totalRequiredEngineers--) { - if (_totalRequiredEngineers <= 0) + for (; DAT_TribesState::instance.tribes[aiTribeID].size != 0; totalRequiredEngineers--) { + if (totalRequiredEngineers <= 0) break; - MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)( - _aiTribeID); + MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)(aiTribeID); } - MappersEnum _siegeEngineType; + MappersEnum siegeEngineType; for (int i = 0; i < 8; i++) { - if ((&this->aics[_aicIndex].SiegeEngine1)[i] <= 0) + if ((&this->aics[aicIndex].SiegeEngine1)[i] <= 0) return; for (int j = 0; j < 6; j++) { - if ((&this->aics[_aicIndex].SiegeEngine1)[i] + if ((&this->aics[aicIndex].SiegeEngine1)[i] == DAT_SkirmishDefinedData::instance.SiegeEngineUnitType[j]) { - _requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; - _siegeEngineType - = (MappersEnum)DAT_SkirmishDefinedData::instance.SiegeEngineCommandBuildingTypes[j]; + requiredEngineers = DAT_SkirmishDefinedData::instance.SiegeEngineTypeRequiredEngineers[j]; + siegeEngineType = (MappersEnum)DAT_SkirmishDefinedData::instance.SiegeEngineCommandBuildingTypes[j]; break; } } - if (_requiredEngineers > _availableEngineers) + if (requiredEngineers > availableEngineers) return; - _availableEngineers -= _requiredEngineers; + availableEngineers -= requiredEngineers; - int _tribeID = MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addEngineersToSelection, this)( - playerID, _requiredEngineers); - if (_tribeID == 0) + int tribeID = MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addEngineersToSelection, this)( + playerID, requiredEngineers); + if (tribeID == 0) return; - DAT_TribesState::instance.tribes[_tribeID].tribeType = OpenSHC::AI::Tribes::AITT_ENGINEERS; - DAT_TribesState::instance.tribes[_tribeID].tribeBehaviorType + DAT_TribesState::instance.tribes[tribeID].tribeType = OpenSHC::AI::Tribes::AITT_ENGINEERS; + DAT_TribesState::instance.tribes[tribeID].tribeBehaviorType = OpenSHC::Map::Units::STBT_0x410_SIEGE_EQUIPMENT_CONSTRUCTION; - DAT_TribesState::instance.tribes[_tribeID].attackWave + DAT_TribesState::instance.tribes[tribeID].attackWave = DAT_GameState::instance.playerDataArray[playerID].currentAttackWave; MACRO_CALL_MEMBER( OpenSHC::Map::Units::TroopValueState_Func::placeSiegeTentOrTunnelAtSuitableLocationAndAssignEngineers, - DAT_TroopValueState::ptr)(_tribeID, _siegeEngineType, 60, (UnitInstructionType)15); + DAT_TroopValueState::ptr)(tribeID, siegeEngineType, 60, (UnitInstructionType)15); } } diff --git a/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp index f9a3597ee4..90dccdc640 100644 --- a/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp +++ b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp @@ -26,40 +26,40 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) return; - int _aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0xe]; - if (_aiTribeID == 0) + int aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0xe]; + if (aiTribeID == 0) return; - if (DAT_TribesState::instance.tribes[_aiTribeID].uid + if (DAT_TribesState::instance.tribes[aiTribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0xe]) return; - int _countdown = DAT_TribesState::instance.tribes[_aiTribeID].size; + int countdown = DAT_TribesState::instance.tribes[aiTribeID].size; - while (DAT_TribesState::instance.tribes[_aiTribeID].size != 0) { - if (_countdown <= 0) + while (DAT_TribesState::instance.tribes[aiTribeID].size != 0) { + if (countdown <= 0) break; - int _unitID = MACRO_CALL_MEMBER( - OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)(_aiTribeID); + int unitID = MACRO_CALL_MEMBER( + OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)(aiTribeID); // Yes this line has to be right here for the code to match. - _countdown--; + countdown--; - int _tribeID = MACRO_CALL_MEMBER( + int tribeID = MACRO_CALL_MEMBER( OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); - DAT_TribesState::instance.tribes[_tribeID].attackWave + DAT_TribesState::instance.tribes[tribeID].attackWave = DAT_GameState::instance.playerDataArray[playerID].currentAttackWave; - DAT_TribesState::instance.tribes[_tribeID].tribeType = OpenSHC::AI::Tribes::AITT_TUNNELERS; + DAT_TribesState::instance.tribes[tribeID].tribeType = OpenSHC::AI::Tribes::AITT_TUNNELERS; - DAT_TribesState::instance.tribes[_tribeID].tribeBehaviorType = OpenSHC::Map::Units::STBT_0x415; + DAT_TribesState::instance.tribes[tribeID].tribeBehaviorType = OpenSHC::Map::Units::STBT_0x415; MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)( - _unitID, _tribeID); + unitID, tribeID); MACRO_CALL_MEMBER( OpenSHC::Map::Units::TroopValueState_Func::placeSiegeTentOrTunnelAtSuitableLocationAndAssignEngineers, DAT_TroopValueState::ptr)( - _tribeID, OpenSHC::Commands::M_MAPPER_TUNNEL_CONSTRUCTION, 50, (UnitInstructionType)21); + tribeID, OpenSHC::Commands::M_MAPPER_TUNNEL_CONSTRUCTION, 50, (UnitInstructionType)21); } } From af3a05d548c7e5675129899faa32d23c59a016eb Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 00:11:08 +0200 Subject: [PATCH 03/10] review: BOOLEnum return and named global for the AICState review comments Two generated-header changes requested in the PR review, kept separate from the .cpp work as AGENTS.md asks: - AICState::sendUnitsToAttackBreachedCastle returns BOOLEnum instead of undefined4; the body returns TRUE/FALSE accordingly. - The 0x00EB0B18 global is named TIME_LastThanksBikPlaybackTime instead of DWORD_00eb0b18, which is what playThanksBikFromPlayerToPlayer stores into. quick_diff holds at its baseline for both functions (1.0000 and 0.9762). Co-Authored-By: Claude Opus 5 (1M context) --- .../AI/AICState/playThanksBikFromPlayerToPlayer.cpp | 9 +++++---- .../AI/AICState/sendUnitsToAttackBreachedCastle.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp index 823e435e96..d0e1541dc1 100644 --- a/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp @@ -1,12 +1,13 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" #include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" -#include "OpenSHC/Globals/DWORD_00eb0b18.hpp" +#include "OpenSHC/Globals/TIME_LastThanksBikPlaybackTime.hpp" namespace OpenSHC { namespace AI { @@ -31,11 +32,11 @@ namespace AI { } DWORD now = timeGetTime(); - if (DWORD_00eb0b18::instance != 0 && now - DWORD_00eb0b18::instance < 1200000) { + if (TIME_LastThanksBikPlaybackTime::instance != 0 && now - TIME_LastThanksBikPlaybackTime::instance < 1200000) { return; } - DWORD_00eb0b18::instance = now; + TIME_LastThanksBikPlaybackTime::instance = now; MACRO_CALL_MEMBER(Rendering::Bink::AIMessageQueue_Func::playBikVideoFromPlayer, DAT_VideoBikQueue::ptr)( playerID, aicIndex, 15); } diff --git a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp index 026d0d65f8..83a8beb308 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp @@ -25,11 +25,11 @@ namespace AI { using OpenSHC::WindowsHelper::Enums::BOOLEnum; // FUNCTION: STRONGHOLDCRUSADER 0x004D30E0 - undefined4 AICState::sendUnitsToAttackBreachedCastle(int attackingPlayerIndex) + BOOLEnum AICState::sendUnitsToAttackBreachedCastle(int attackingPlayerIndex) { int vector = 0; if (DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiType == OpenSHC::AI::AIT_NULL) { - return 1; + return TRUE; } BOOLEnum sentUnitsToAttackLord = FALSE; @@ -96,14 +96,14 @@ namespace AI { OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( tribeID, lordX, lordY, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0) == 0) { - return 0; + return FALSE; } sentUnitsToAttackLord = TRUE; } } } - return 1; + return TRUE; } } From 998050f239b712780eca6d23d6d894e3b6f4a4f9 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 00:11:37 +0200 Subject: [PATCH 04/10] review: address the AICState PR review comments Include hygiene (the reviewer's "wrong import", checked across all 137 files): every AICState .cpp now opens with the relative "../AICState.func.hpp" instead of the absolute "OpenSHC/AI/AICState.hpp", matching the files that already did. 63 files changed; the func header is a superset, so no other include moved. Magic values and style: - assignRequiredIdleEngineersToNewTribe: drop the stale (int) cast on maxUnitCount (already int in the header), and test `dying` for truthiness. - checksAndGenerateAITribesForPlayerIfNotExisting: `if (checkOnly)` instead of `if (checkOnly != FALSE)`. - playGoodsSentBikFromPlayerToPlayer: `if (!getAliveLordForPlayer(...))`. - getUnitTypeIndexForUnitID: the Caliph check now reads `aiType - 1 != AITA_CALIPH`, and the loop bound 0x14 is written as 20. - wipeAICMemory: sizeof(this->aics[i]) instead of the literal 676. - shareGoldAmongTeamMembers: drop the obsolete FIXME about the int return (the header already declares void), and use s__d__s___005a7674 from string-literals.hpp for the "%d %s - " format. Measured, not assumed: - aiRequiresExtraOxtethers: the (short) on quarryStockpileID is load-bearing (removing it drops quick_diff 1.0000 -> 0.9901), so it stays, with a comment. - someChatMessageSelection: rolling the unrolled player scan into a plain 1..8 loop drops quick_diff 0.9198 -> 0.6745, so the unroll is in the original source. Kept, with the measurement recorded in the comment. - computeNervousness: isNotNervousByEnemyTroopValue is an int field storing 0/1, which per AGENTS.md is an int and not a bool, so it is left as is. status/addresses: reverted the 56 changed lines that belong to functions outside this PR; the remaining 121 all map to a `// FUNCTION:` address in src/OpenSHC/AI/AICState. No regressions: quick_diff is unchanged from baseline on every touched function. Co-Authored-By: Claude Opus 5 (1M context) --- .../aiCommandTribe11StandGroundToGate.cpp | 3 +- .../aiCommandTribe13DefensiveWave.cpp | 3 +- src/OpenSHC/AI/AICState/aiFarmChoice.cpp | 3 +- .../AI/AICState/aiRecruitEngineers.cpp | 3 +- .../AI/AICState/aiRequiresExtraOxtethers.cpp | 1 + .../assignRequiredIdleEngineersToNewTribe.cpp | 7 +- ...GenerateAITribesForPlayerIfNotExisting.cpp | 2 +- .../AICState/destroyAnyBuildingInCategory.cpp | 3 +- .../AI/AICState/destroyBuildingIfNoWorker.cpp | 3 +- .../AI/AICState/getAIBuildInterval.cpp | 3 +- .../getCurrentDesiredAttackRaidUnitCount.cpp | 3 +- .../AI/AICState/getResourceRebuildDelay.cpp | 3 +- .../AI/AICState/getUnitTypeIndexForUnitID.cpp | 9 +- .../AICState/hasNoTroopsOrAllAreDiggers.cpp | 2 +- .../AI/AICState/hasNotEnoughSupplies.cpp | 3 +- ...qualThanMinimumGoodsRequiredAfterTrade.cpp | 3 +- ...erIsWoodCuttersHutWhileNoWoodAvailable.cpp | 3 +- .../AI/AICState/playAnger1BikFromPlayer.cpp | 3 +- .../playAnger2BikFromPlayerToPlayer.cpp | 3 +- .../playFriendlyVictoryBikFromPlayer.cpp | 3 +- .../playGoodsNotSentBikFromPlayer.cpp | 3 +- .../playGoodsRequestBikFromPlayerToPlayer.cpp | 3 +- .../playGoodsSentBikFromPlayerToPlayer.cpp | 5 +- .../AI/AICState/playJokeBikFromAIToHuman.cpp | 3 +- .../AI/AICState/playNervous1BikFromPlayer.cpp | 3 +- .../AI/AICState/playNoHelpBikFromPlayer.cpp | 3 +- ...yerKilledBiksFromKilledAndKillerPlayer.cpp | 3 +- .../AICState/playRequestHelpBikFromPlayer.cpp | 3 +- ...playTauntToAttackedPlayerBikFromPlayer.cpp | 3 +- .../AICState/playTeamWinningBikFromPlayer.cpp | 3 +- .../playVictory2BikFromPlayerToPlayer.cpp | 3 +- .../playWillAttackBikFromPlayerToPlayer.cpp | 3 +- .../playWillHelpBikFromPlayerToPlayer.cpp | 3 +- ...layWillNotAttack1BikFromPlayerToPlayer.cpp | 3 +- ...layWillNotAttack2BikFromPlayerToPlayer.cpp | 3 +- .../playWillNotHelp1BikFromPlayerToPlayer.cpp | 3 +- .../playWillNotHelp2BikFromPlayerToPlayer.cpp | 3 +- .../sendAITribe_0xf_toAttackPatrol.cpp | 3 +- src/OpenSHC/AI/AICState/sendTribeToAttack.cpp | 3 +- .../AI/AICState/sendUnitsToCampfire.cpp | 3 +- src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp | 3 +- .../AI/AICState/setAICParameters_01.cpp | 3 +- .../AI/AICState/setAICParameters_02.cpp | 3 +- .../AI/AICState/setAICParameters_03.cpp | 3 +- .../AI/AICState/setAICParameters_04.cpp | 3 +- .../AI/AICState/setAICParameters_05.cpp | 3 +- .../AICState/setAttackCoordinationLevel.cpp | 3 +- .../AI/AICState/setAttackPrimeInfo.cpp | 2 +- .../AI/AICState/setCurrentAttackStrength.cpp | 3 +- ...htTribe0xc0TribesToAggressiveAndAttack.cpp | 3 +- .../AI/AICState/setNextFarmTypeToBuild.cpp | 3 +- ...x11ToAggressiveAndAttackIfConditionMet.cpp | 3 +- .../setTribe0xCtoAggressiveAndAttack.cpp | 3 +- .../setTribe0xbToAggressiveAndAttack.cpp | 3 +- .../AI/AICState/shareGoldAmongTeamMembers.cpp | 7 +- .../AICState/shouldDestroyWoodCutterUnk.cpp | 3 +- .../AICState/shouldNotBeBuildingArmoury.cpp | 3 +- .../AICState/shouldNotBeBuildingGranary.cpp | 3 +- .../AI/AICState/shouldNotBeBuildingHovel.cpp | 3 +- .../AI/AICState/shouldNotBuildKillingPits.cpp | 3 +- ...rketArmoryGranaryBarracksMercenarypost.cpp | 3 +- ...uldWaitWithBuildingAPositiveFearFactor.cpp | 3 +- ...ouldWaitWithBuildingNegativeFearFactor.cpp | 3 +- .../AI/AICState/someChatMessageSelection.cpp | 3 +- .../AI/AICState/teamIsWeakRelativeToEnemy.cpp | 3 +- src/OpenSHC/AI/AICState/wipeAICMemory.cpp | 5 +- src/OpenSHC/AI/AICState/yieldCowThrow.cpp | 3 +- status/addresses-SHC-3BB0A8C1.txt | 112 +++++++++--------- 68 files changed, 194 insertions(+), 132 deletions(-) diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp index 265f1d75dd..d401d21346 100644 --- a/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TroopValueState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp index fe85393295..a54e50f8dd 100644 --- a/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp index 9fcb0d9aaa..f563b02049 100644 --- a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp +++ b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp index ba7ee99f22..7445e89534 100644 --- a/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp +++ b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Buildings/BuildingType.hpp" #include "OpenSHC/Map/Units/UnitType.hpp" diff --git a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp index 799e96e0c4..8a2ed19b5f 100644 --- a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp +++ b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp @@ -26,6 +26,7 @@ namespace AI { for (; quarryID != 0; quarryID = MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::findNextBuildingForPlayerAndType, DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_QUARRY, quarryID)) { + // The (short) is load-bearing: quarryStockpileID is undefined2, and the original sign-extends it. int stone = DAT_BuildingsState::instance .buildings[(short)DAT_BuildingsState::instance.buildings[quarryID].quarryStockpileID] .resources[Game::Resources::RT_STONE]; diff --git a/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp index 2418ab3e9b..0b6acabc30 100644 --- a/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp +++ b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Map/Units/States/UnitState.hpp" #include "OpenSHC/Map/Units/UnitLogicState.hpp" #include "OpenSHC/Map/Units/UnitType.hpp" @@ -15,14 +16,14 @@ namespace AI { { int tribeID = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); - for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) { + for (int unitID = 1; unitID < DAT_UnitsState::instance.maxUnitCount; unitID++) { if (count <= 0) break; if (DAT_UnitsState::instance.units[unitID].logicalState != Map::Units::ULS_NORMAL) continue; if (DAT_UnitsState::instance.units[unitID].owner != playerID) continue; - if (DAT_UnitsState::instance.units[unitID].dying != 0) + if (DAT_UnitsState::instance.units[unitID].dying) continue; if (DAT_UnitsState::instance.units[unitID].unitType != Map::Units::UT_E_ENGINEER) continue; diff --git a/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp index 00347b8466..1c7ebdc94a 100644 --- a/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp +++ b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp @@ -25,7 +25,7 @@ namespace AI { if (tribeID == 0 || DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[baseOffset + offset]) { - if (checkOnly != FALSE) { + if (checkOnly) { return 1; } int newTribeID = MACRO_CALL_MEMBER( diff --git a/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp b/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp index 4ce6d8fee6..644190c5ff 100644 --- a/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp +++ b/src/OpenSHC/AI/AICState/destroyAnyBuildingInCategory.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Map/Buildings/BuildingLogicalState.hpp" #include "OpenSHC/Map/Buildings/BuildingType.hpp" diff --git a/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp index afa234ad5a..7da727d069 100644 --- a/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp +++ b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIVState.func.hpp" #include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Game/GameMode.hpp" #include "OpenSHC/Globals/DAT_AIVState.hpp" diff --git a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp index de9383a306..749a17bcdf 100644 --- a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp +++ b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp b/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp index c4ad3be311..321504c8d4 100644 --- a/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp +++ b/src/OpenSHC/AI/AICState/getCurrentDesiredAttackRaidUnitCount.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Game/GameMode2.hpp" #include "OpenSHC/Game/TrailType.hpp" diff --git a/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp index 5ab4f3163c..8e3e49bcbb 100644 --- a/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp +++ b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp index 1d6df9d485..4030cac530 100644 --- a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp +++ b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp @@ -1,5 +1,6 @@ #include "../AICState.func.hpp" +#include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/AI/AIVUnitType.hpp" #include "OpenSHC/Map/Units/UnitType.hpp" #include "OpenSHC/Map/Units/UnitTypeInt.hpp" @@ -12,6 +13,7 @@ namespace OpenSHC { namespace AI { + using OpenSHC::AI::AITypeA; using OpenSHC::AI::AIVUnitType; using OpenSHC::Map::Units::UnitTypeInt; using OpenSHC::Map::Units::UnitTypeShort; @@ -28,8 +30,9 @@ namespace AI { effectiveUnitType = unitType; } - // 6 is the Caliph's AIC index: he fields slaves rather than the ranged units listed below - if (DAT_GameState::instance.playerDataArray[owner].aiType - 1 != 6 && allowSlaveSlotForRanged != 0 + // The Caliph fields slaves rather than the ranged units listed below + if (DAT_GameState::instance.playerDataArray[owner].aiType - 1 != OpenSHC::AI::AITA_CALIPH + && allowSlaveSlotForRanged != 0 && DAT_GameState::instance.playerDataArray[owner].aivUnitLocationSlotLocationCount[0xd] > 0) { if (effectiveUnitType == OpenSHC::Map::Units::UT_E_ARCHER) { return OpenSHC::AI::AIVUT_SLAVE; @@ -48,7 +51,7 @@ namespace AI { } } - for (int someUnitTypeIndex = 0; someUnitTypeIndex < 0x14; someUnitTypeIndex++) { + for (int someUnitTypeIndex = 0; someUnitTypeIndex < 20; someUnitTypeIndex++) { if (DAT_SkirmishDefinedData::instance.SomeAIUnitTypeArray[someUnitTypeIndex] == effectiveUnitType) { return (AIVUnitType)someUnitTypeIndex; } diff --git a/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp b/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp index b009cbc8a7..2c69186aa9 100644 --- a/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp +++ b/src/OpenSHC/AI/AICState/hasNoTroopsOrAllAreDiggers.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp b/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp index 96e8e3c36a..fd5fac651f 100644 --- a/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp +++ b/src/OpenSHC/AI/AICState/hasNotEnoughSupplies.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Buildings/BuildingType.hpp" #include "OpenSHC/Globals/DAT_BuildingsState.hpp" diff --git a/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp b/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp index d4224026c0..4df0de5fc0 100644 --- a/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp +++ b/src/OpenSHC/AI/AICState/isResourceLargerOrEqualThanMinimumGoodsRequiredAfterTrade.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Game/Resources/ResourceType.hpp" diff --git a/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp b/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp index 41ac2d5150..527d339f61 100644 --- a/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp +++ b/src/OpenSHC/AI/AICState/mapperIsWoodCuttersHutWhileNoWoodAvailable.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_AIVState.hpp" diff --git a/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp index c2f18af591..a6f214b0c8 100644 --- a/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp index df0b308ad6..17af74870c 100644 --- a/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playAnger2BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp index 64249dc9ce..0d5236677b 100644 --- a/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playFriendlyVictoryBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" diff --git a/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp index ca55ee528e..7e41253d45 100644 --- a/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playGoodsNotSentBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" diff --git a/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp index acb064856d..7bfb0fc2a3 100644 --- a/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playGoodsRequestBikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp index 7b807ddfc0..69553606b8 100644 --- a/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playGoodsSentBikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" @@ -13,7 +14,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D0BB0 void AICState::playGoodsSentBikFromPlayerToPlayer(int playerID, int targetPlayerID) { - if (MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID) == 0) { + if (!MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(playerID)) { return; } if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { diff --git a/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp b/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp index 639186e16a..887485f99b 100644 --- a/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp +++ b/src/OpenSHC/AI/AICState/playJokeBikFromAIToHuman.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" #include "OpenSHC/Globals/DAT_VideoBikQueue.hpp" diff --git a/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp index 0bdd24ea65..ed4056ca54 100644 --- a/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playNervous1BikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" diff --git a/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp index 07b38053e9..f21f64e4c4 100644 --- a/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playNoHelpBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" diff --git a/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp b/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp index a652216ca2..dfefafdbc4 100644 --- a/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playPlayerKilledBiksFromKilledAndKillerPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp index 5f1cee729f..09f8d00397 100644 --- a/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playRequestHelpBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp index f498395747..d65e97b24f 100644 --- a/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp index 4295184961..291c2e0b98 100644 --- a/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playTeamWinningBikFromPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_UnitsState.hpp" diff --git a/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp index 0d11e93d4d..def0dfcd2c 100644 --- a/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playVictory2BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp index 6898bcfdf9..39dbbc6b8d 100644 --- a/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillAttackBikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp index 1cca496c95..ce1eaf5893 100644 --- a/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillHelpBikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp index a89b2faeb8..4a76916350 100644 --- a/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillNotAttack1BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp index 7de2373fdc..77b3b681aa 100644 --- a/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillNotAttack2BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp index 5c7ab00f7f..33040b8fe1 100644 --- a/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillNotHelp1BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp index 164826d3fd..9b8ae5f288 100644 --- a/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playWillNotHelp2BikFromPlayerToPlayer.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/UnitsState.func.hpp" #include "OpenSHC/Rendering/Bink/AIMessageQueue.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" diff --git a/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp index ccea764295..dddc34439b 100644 --- a/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp +++ b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TroopValueState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" diff --git a/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp index 7ceb0cfef3..bee2c6691d 100644 --- a/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp +++ b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp b/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp index c824f5d752..a5b115838e 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToCampfire.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp index fcb585017e..f9f667f72a 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_BuildingsState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/setAICParameters_01.cpp b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp index 35c4acc91c..df3fd43ed6 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_01.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_01.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIC/AITargetChoice.hpp" -#include "OpenSHC/AI/AICState.hpp" namespace OpenSHC { namespace AI { diff --git a/src/OpenSHC/AI/AICState/setAICParameters_02.cpp b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp index 7ff3eb98f0..13e52f8625 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_02.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_02.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIC/AITargetChoice.hpp" -#include "OpenSHC/AI/AICState.hpp" namespace OpenSHC { namespace AI { diff --git a/src/OpenSHC/AI/AICState/setAICParameters_03.cpp b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp index e6ebd69242..244e6ec73b 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_03.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_03.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIC/AITargetChoice.hpp" -#include "OpenSHC/AI/AICState.hpp" namespace OpenSHC { namespace AI { diff --git a/src/OpenSHC/AI/AICState/setAICParameters_04.cpp b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp index 98fd06c9c9..a8678896ba 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_04.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_04.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIC/AITargetChoice.hpp" -#include "OpenSHC/AI/AICState.hpp" namespace OpenSHC { namespace AI { diff --git a/src/OpenSHC/AI/AICState/setAICParameters_05.cpp b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp index 377cd7b801..f96fb8e310 100644 --- a/src/OpenSHC/AI/AICState/setAICParameters_05.cpp +++ b/src/OpenSHC/AI/AICState/setAICParameters_05.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIC/AITargetChoice.hpp" -#include "OpenSHC/AI/AICState.hpp" namespace OpenSHC { namespace AI { diff --git a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp index 324a91bf07..5bedb45135 100644 --- a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp +++ b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Random/RNG.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp index db0febac56..71cc3c5850 100644 --- a/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp +++ b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_PathFindingState.hpp" diff --git a/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp index 879635162f..c55ebcb180 100644 --- a/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp +++ b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Random/RNG.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp index bf1b2a003d..16effb1af2 100644 --- a/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp index 1abc1fb1a1..e6c337edd5 100644 --- a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp +++ b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp index ceaf2f197d..18200218e4 100644 --- a/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp index 5f96df8808..d0e022dc7a 100644 --- a/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp index ec4cde70ec..9c0ae6175e 100644 --- a/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Map/Units/TribesState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp" #include "OpenSHC/Map/Units/SomeTribeBehaviorType.hpp" diff --git a/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp index da204a2690..b5816876a3 100644 --- a/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp +++ b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp @@ -8,6 +8,7 @@ #include "OpenSHC/Text/TextManager.func.hpp" #include "OpenSHC/DE/SHCDE/eTextSections.hpp" #include "OpenSHC/Game/Resources/ResourceType.hpp" +#include "OpenSHC/string-literals.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" @@ -16,10 +17,6 @@ namespace OpenSHC { namespace AI { - // FIXME: The original function never sets a return value (eax is left over from the last computation), - // so it was most likely a void function. The header declares int, which forces the "return 0"s below - // and costs an extra "xor eax, eax" in the assembly. Change the return type to void in the header. - // FUNCTION: STRONGHOLDCRUSADER 0x004D05D0 void AICState::shareGoldAmongTeamMembers(int playerID, int gold) { @@ -57,7 +54,7 @@ namespace AI { DAT_GameSynchronyState::ptr)(targetPlayer, 0); // "Gold" - MACRO_CALL(OS_Func::_sprintf)(DAT_GameSynchronyState::instance.receivedChatMessage, "%d %s - ", + MACRO_CALL(OS_Func::_sprintf)(DAT_GameSynchronyState::instance.receivedChatMessage, s__d__s___005a7674, goldPerPlayer, MACRO_CALL_MEMBER(Text::TextManager_Func::getTextStringInGroupAtOffset, DAT_TextManagerObject::ptr)( DE::SHCDE::TEXT_GOODS, Game::Resources::RT_GOLD)); diff --git a/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp b/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp index ea63343e26..8df98c6397 100644 --- a/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp +++ b/src/OpenSHC/AI/AICState/shouldDestroyWoodCutterUnk.cpp @@ -1,6 +1,7 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AIVState.func.hpp" #include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Game/Resources/ResourceType.hpp" #include "OpenSHC/Map/Buildings/BuildingType.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp index 4cf955f92a..817ca72e22 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingArmoury.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp index 5ef58f2766..4abf99ecc7 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingGranary.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp index f552416afa..1de3299a95 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBeBuildingHovel.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp b/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp index d44c311ef4..4011c4bc00 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBuildKillingPits.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_AIVState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp index 11a96eaaf2..93acb36555 100644 --- a/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp +++ b/src/OpenSHC/AI/AICState/shouldNotBuildMarketArmoryGranaryBarracksMercenarypost.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp index 118a0cf3ff..a7533fc120 100644 --- a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp +++ b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingAPositiveFearFactor.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp index 768c6f8de7..29be1ab5e0 100644 --- a/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp +++ b/src/OpenSHC/AI/AICState/shouldWaitWithBuildingNegativeFearFactor.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/Commands/MappersEnum.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp index f6194c79a7..2ca457f604 100644 --- a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp +++ b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp @@ -43,7 +43,8 @@ namespace AI { } candidateCount = 0; - // Players 1..8, manually unrolled by 4 in the original. + // Players 1..8, manually unrolled by 4 in the original. Measured: rolling this into a plain + // 1..8 loop drops quick_diff from 0.92 to 0.67, so the unroll is in the original source. for (playerID = 1; playerID < 9; playerID += 4) { if ((DAT_GameSynchronyState::instance.currentAIArray[playerID] != 0) && (DAT_GameState::instance.mapAndTime.playerTeams[playerID] diff --git a/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp index 609c5c523a..a4ccb2dbf4 100644 --- a/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp +++ b/src/OpenSHC/AI/AICState/teamIsWeakRelativeToEnemy.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/Game/GameStateStructures.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_GameCore.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/src/OpenSHC/AI/AICState/wipeAICMemory.cpp b/src/OpenSHC/AI/AICState/wipeAICMemory.cpp index ed4a020351..a63c87e1d7 100644 --- a/src/OpenSHC/AI/AICState/wipeAICMemory.cpp +++ b/src/OpenSHC/AI/AICState/wipeAICMemory.cpp @@ -1,5 +1,6 @@ +#include "../AICState.func.hpp" + #include "OpenSHC/IO/LowLevelMemory.func.hpp" -#include "OpenSHC/AI/AICState.hpp" #include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" @@ -11,7 +12,7 @@ namespace AI { { for (int i = 0; i < 20; i++) { MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( - 676, '\0', &this->aics[i]); + sizeof(this->aics[i]), '\0', &this->aics[i]); } } } diff --git a/src/OpenSHC/AI/AICState/yieldCowThrow.cpp b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp index c381e7b3ec..8c7c35fded 100644 --- a/src/OpenSHC/AI/AICState/yieldCowThrow.cpp +++ b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp @@ -1,4 +1,5 @@ -#include "OpenSHC/AI/AICState.hpp" +#include "../AICState.func.hpp" + #include "OpenSHC/AI/AITypeA.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index f4b9fd3855..612480157f 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -34189,7 +34189,7 @@ SHC_3BB0A8C1_0x004CA4D0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CA8A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CAC70 | 95.2% | Reimplemented +SHC_3BB0A8C1_0x004CAC70 | 0.0% | Pending SHC_3BB0A8C1_0x004CACB0 | 100.0% | Reimplemented @@ -34209,17 +34209,17 @@ SHC_3BB0A8C1_0x004CB180 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB1B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB220 | 97.8% | Reimplemented +SHC_3BB0A8C1_0x004CB220 | 0.0% | Pending -SHC_3BB0A8C1_0x004CB290 | 98.1% | Reimplemented +SHC_3BB0A8C1_0x004CB290 | 0.0% | Pending -SHC_3BB0A8C1_0x004CB330 | 97.5% | Reimplemented +SHC_3BB0A8C1_0x004CB330 | 0.0% | Pending SHC_3BB0A8C1_0x004CB3A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CB4D0 | 97.5% | Reimplemented +SHC_3BB0A8C1_0x004CB4D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CB540 | 97.5% | Reimplemented +SHC_3BB0A8C1_0x004CB540 | 0.0% | Pending SHC_3BB0A8C1_0x004CB5B0 | 100.0% | Reimplemented @@ -34845,7 +34845,7 @@ SHC_3BB0A8C1_0x004CB803 | 0.0% | Pending SHC_3BB0A8C1_0x004CB804 | 0.0% | Pending -SHC_3BB0A8C1_0x004CB810 | 92.3% | Reimplemented +SHC_3BB0A8C1_0x004CB810 | 0.0% | Pending SHC_3BB0A8C1_0x004CB890 | 100.0% | Reimplemented @@ -34853,7 +34853,7 @@ SHC_3BB0A8C1_0x004CB940 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CB9F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CBA50 | 90.7% | flag slot order differs +SHC_3BB0A8C1_0x004CBA50 | 0.0% | Pending SHC_3BB0A8C1_0x004CBE30 | 100.0% | Reimplemented @@ -34877,23 +34877,23 @@ SHC_3BB0A8C1_0x004CC680 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CC6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CC720 | 95.2% | Reimplemented +SHC_3BB0A8C1_0x004CC720 | 0.0% | Pending -SHC_3BB0A8C1_0x004CC7B0 | 95.2% | Reimplemented +SHC_3BB0A8C1_0x004CC7B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CC840 | 94.3% | Reimplemented +SHC_3BB0A8C1_0x004CC840 | 0.0% | Pending SHC_3BB0A8C1_0x004CC8D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC910 | 97.1% | Reimplemented +SHC_3BB0A8C1_0x004CC910 | 0.0% | Pending -SHC_3BB0A8C1_0x004CC990 | 56.6% | regalloc/locals differ +SHC_3BB0A8C1_0x004CC990 | 0.0% | Pending SHC_3BB0A8C1_0x004CCAF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CCBE0 | 99.0% | Reimplemented +SHC_3BB0A8C1_0x004CCBE0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CCD20 | 66.0% | frame and regalloc differ +SHC_3BB0A8C1_0x004CCD20 | 0.0% | Pending SHC_3BB0A8C1_0x004CCEDC | 0.0% | Pending @@ -35269,15 +35269,15 @@ SHC_3BB0A8C1_0x004CD0C0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CD110 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CD160 | 91.7% | Register allocation differs +SHC_3BB0A8C1_0x004CD160 | 0.0% | Pending -SHC_3BB0A8C1_0x004CD250 | 94.7% | Reimplemented +SHC_3BB0A8C1_0x004CD250 | 0.0% | Pending -SHC_3BB0A8C1_0x004CD2A0 | 59.60% | Reimplemented functionally, code block ordering problem +SHC_3BB0A8C1_0x004CD2A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CD560 | 95.2% | Reimplemented +SHC_3BB0A8C1_0x004CD560 | 0.0% | Pending -SHC_3BB0A8C1_0x004CD690 | 94.9% | Reimplemented +SHC_3BB0A8C1_0x004CD690 | 0.0% | Pending SHC_3BB0A8C1_0x004CD7B0 | 100.0% | Reimplemented @@ -35287,17 +35287,17 @@ SHC_3BB0A8C1_0x004CDA50 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CDAB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDB20 | 44.4% | regalloc/spill differs +SHC_3BB0A8C1_0x004CDB20 | 0.0% | Pending SHC_3BB0A8C1_0x004CDBC0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CDCA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDCF0 | 77.2% | regalloc/counters differ +SHC_3BB0A8C1_0x004CDCF0 | 0.0% | Pending SHC_3BB0A8C1_0x004CDE60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CDF10 | 98.2% | Reimplemented +SHC_3BB0A8C1_0x004CDF10 | 0.0% | Pending SHC_3BB0A8C1_0x004CDFD0 | 100.0% | Reimplemented @@ -35307,7 +35307,7 @@ SHC_3BB0A8C1_0x004CE110 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CE1A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE200 | 64.5% | spilled local differs +SHC_3BB0A8C1_0x004CE200 | 0.0% | Pending SHC_3BB0A8C1_0x004CE270 | 0.0% | Pending @@ -35315,7 +35315,7 @@ SHC_3BB0A8C1_0x004CE3B0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CE430 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CE4D0 | 93.8% | Reimplemented +SHC_3BB0A8C1_0x004CE4D0 | 0.0% | Pending SHC_3BB0A8C1_0x004CE530 | 0.0% | Pending @@ -35325,7 +35325,7 @@ SHC_3BB0A8C1_0x004CE660 | 0.0% | Pending SHC_3BB0A8C1_0x004CE6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004CE790 | 98.0% | Reimplemented +SHC_3BB0A8C1_0x004CE790 | 0.0% | Pending SHC_3BB0A8C1_0x004CE830 | 100.0% | Reimplemented @@ -35337,7 +35337,7 @@ SHC_3BB0A8C1_0x004CE930 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CEA50 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CEB50 | 98.8% | Reimplemented +SHC_3BB0A8C1_0x004CEB50 | 0.0% | Pending SHC_3BB0A8C1_0x004CEB80 | 0.0% | Pending @@ -35355,7 +35355,7 @@ SHC_3BB0A8C1_0x004CF180 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CF270 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF2E0 | 94.7% | esi/edi regalloc differs +SHC_3BB0A8C1_0x004CF2E0 | 0.0% | Pending SHC_3BB0A8C1_0x004CF400 | 100.0% | Reimplemented @@ -35367,23 +35367,23 @@ SHC_3BB0A8C1_0x004CF560 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CF5E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF660 | 97.2% | Reimplemented +SHC_3BB0A8C1_0x004CF660 | 100.0% | Reimplemented without for-loop SHC_3BB0A8C1_0x004CF6E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CF750 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF7C0 | 98.2% | Reimplemented +SHC_3BB0A8C1_0x004CF7C0 | 100.0% | Reimplemented, for-loop didn't work SHC_3BB0A8C1_0x004CF7F0 | 0.0% | Pending SHC_3BB0A8C1_0x004CF870 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CF920 | 96.9% | Reimplemented +SHC_3BB0A8C1_0x004CF920 | 0.0% | Pending -SHC_3BB0A8C1_0x004CFA10 | 96.9% | Reimplemented +SHC_3BB0A8C1_0x004CFA10 | 0.0% | Pending -SHC_3BB0A8C1_0x004CFB20 | 97.8% | Reimplemented +SHC_3BB0A8C1_0x004CFB20 | 0.0% | Pending SHC_3BB0A8C1_0x004CFBC0 | 100.0% | Reimplemented @@ -35421,7 +35421,7 @@ SHC_3BB0A8C1_0x004D0A20 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D0A80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D0B10 | 68.0% | Load scheduling differs +SHC_3BB0A8C1_0x004D0B10 | 0.0% | Pending SHC_3BB0A8C1_0x004D0B70 | 100.0% | Reimplemented @@ -35455,7 +35455,7 @@ SHC_3BB0A8C1_0x004D1000 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D1050 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1090 | 90.0% | Reimplemented +SHC_3BB0A8C1_0x004D1090 | 0.0% | Pending SHC_3BB0A8C1_0x004D10B0 | 100.0% | Reimplemented, one reordered push edi @@ -35463,7 +35463,7 @@ SHC_3BB0A8C1_0x004D11C0 | 0.0% | Pending SHC_3BB0A8C1_0x004D12A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1320 | 72.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004D1320 | 0.0% | Pending SHC_3BB0A8C1_0x004D1700 | 0.0% | Pending @@ -35471,47 +35471,47 @@ SHC_3BB0A8C1_0x004D1710 | 0.0% | Pending SHC_3BB0A8C1_0x004D18B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D1950 | 98.0% | Reimplemented +SHC_3BB0A8C1_0x004D1950 | 0.0% | Pending -SHC_3BB0A8C1_0x004D1A00 | 58.0% | Register allocation differs +SHC_3BB0A8C1_0x004D1A00 | 0.0% | Pending -SHC_3BB0A8C1_0x004D1D60 | 62.4% | register permutation +SHC_3BB0A8C1_0x004D1D60 | 0.0% | Pending SHC_3BB0A8C1_0x004D1F00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2000 | 41.9% | regalloc/frame differ +SHC_3BB0A8C1_0x004D2000 | 0.0% | Pending SHC_3BB0A8C1_0x004D2080 | 0.0% | Pending SHC_3BB0A8C1_0x004D20C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D2500 | 94.6% | Reimplemented +SHC_3BB0A8C1_0x004D2500 | 0.0% | Pending SHC_3BB0A8C1_0x004D2660 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D2730 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2790 | 91.3% | Reimplemented +SHC_3BB0A8C1_0x004D2790 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D27E0 | 92.0% | Reimplemented +SHC_3BB0A8C1_0x004D27E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D2830 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D2870 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D28B0 | 86.3% | select call block layout diffe +SHC_3BB0A8C1_0x004D28B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D2A70 | 54.3% | regalloc/spills differ +SHC_3BB0A8C1_0x004D2A70 | 0.0% | Pending SHC_3BB0A8C1_0x004D2E00 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D2EC0 | 74.1% | Call diffs, load order differs +SHC_3BB0A8C1_0x004D2EC0 | 0.0% | Pending SHC_3BB0A8C1_0x004D2F80 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D30E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D3320 | 97.2% | ebp/ebx regalloc differs +SHC_3BB0A8C1_0x004D3320 | 0.0% | Pending SHC_3BB0A8C1_0x004D3780 | 100.0% | Reimplemented @@ -35523,23 +35523,23 @@ SHC_3BB0A8C1_0x004D3940 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D3960 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D39B0 | 96.6% | Reimplemented +SHC_3BB0A8C1_0x004D39B0 | 0.0% | Pending SHC_3BB0A8C1_0x004D39F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D3AE0 | 43.4% | regalloc/spills differ +SHC_3BB0A8C1_0x004D3AE0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D3F20 | 97.4% | Reimplemented +SHC_3BB0A8C1_0x004D3F20 | 0.0% | Pending -SHC_3BB0A8C1_0x004D4040 | 97.0% | Reimplemented +SHC_3BB0A8C1_0x004D4040 | 100.0% | Reimplemented, for loop didn't work -SHC_3BB0A8C1_0x004D40B0 | 94.9% | Reimplemented +SHC_3BB0A8C1_0x004D40B0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4130 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4220 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D4340 | 54.63% | Reimplemented, different register usage +SHC_3BB0A8C1_0x004D4340 | 0.0% | Pending SHC_3BB0A8C1_0x004D4400 | 0.0% | Pending @@ -35551,15 +35551,15 @@ SHC_3BB0A8C1_0x004D45E0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4630 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D4680 | 64.80% | Stuck, register usage +SHC_3BB0A8C1_0x004D4680 | 0.0% | Pending SHC_3BB0A8C1_0x004D4870 | 0.0% | Pending -SHC_3BB0A8C1_0x004D48F0 | 86.7% | Register allocation differs +SHC_3BB0A8C1_0x004D48F0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004D4940 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004D49E0 | 52.84% | Register allocation differences, logic checks out +SHC_3BB0A8C1_0x004D49E0 | 0.0% | Pending SHC_3BB0A8C1_0x004D5010 | 100.0% | Reimplemented From 8cac0228ab075c0893f2c068226a33280486d476 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 00:28:15 +0200 Subject: [PATCH 05/10] review: roll someChatMessageSelection's unrolled player scan into a nested loop The 4 hand-written copies of the candidate test are replaced by an inner `for (offset = 0; offset < 4; offset++)` inside the existing step-by-4 outer loop. The generated instruction stream is identical to the unrolled source -- 132 instructions, same opcodes and operands, differing only in MSVC's internal label numbering -- so quick_diff stays at 0.9198 (118 vs the original's 119). This corrects the reasoning in the previous commit. The compiler does unroll here, contrary to the "MSVC1400 at /O2 never unrolls a loop" note in AGENTS.md: writing all 8 iterations out by hand compiles to byte-identical code to a plain 1..8 loop (136 instructions, 0.6745 either way). What the original's shape actually pins down is the unroll *factor* of 4, not the absence of a loop in its source, so the outer loop must step by 4 while the inner 4 can be left to the compiler. Also measured and rejected: a file-local inlined helper called 4 times in the outer loop (identical code, but emits a dead out-of-line copy of the helper), the same helper called 8 times (0.4000), unroll by 2 (0.7339), and a half/offset index split (0.8220). Co-Authored-By: Claude Opus 5 (1M context) --- .../AI/AICState/someChatMessageSelection.cpp | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp index 2ca457f604..acc57cc544 100644 --- a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp +++ b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp @@ -43,36 +43,19 @@ namespace AI { } candidateCount = 0; - // Players 1..8, manually unrolled by 4 in the original. Measured: rolling this into a plain - // 1..8 loop drops quick_diff from 0.92 to 0.67, so the unroll is in the original source. + // Players 1..8. The original unrolls this 4 at a time, so the outer loop has to step by 4; + // the compiler unrolls the inner 4 itself, producing the same instructions as writing the + // four copies out. A plain 1..8 loop does not work: MSVC then unrolls all 8 and the match + // drops from 0.92 to 0.67 (writing 8 copies out by hand compiles to exactly the same thing). for (playerID = 1; playerID < 9; playerID += 4) { - if ((DAT_GameSynchronyState::instance.currentAIArray[playerID] != 0) - && (DAT_GameState::instance.mapAndTime.playerTeams[playerID] - != DAT_GameState::instance.mapAndTime - .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { - candidates[candidateCount] = playerID; - candidateCount++; - } - if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 1] != 0) - && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 1] - != DAT_GameState::instance.mapAndTime - .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { - candidates[candidateCount] = playerID + 1; - candidateCount++; - } - if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 2] != 0) - && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 2] - != DAT_GameState::instance.mapAndTime - .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { - candidates[candidateCount] = playerID + 2; - candidateCount++; - } - if ((DAT_GameSynchronyState::instance.currentAIArray[playerID + 3] != 0) - && (DAT_GameState::instance.mapAndTime.playerTeams[playerID + 3] - != DAT_GameState::instance.mapAndTime - .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID])) { - candidates[candidateCount] = playerID + 3; - candidateCount++; + for (int offset = 0; offset < 4; offset++) { + if (DAT_GameSynchronyState::instance.currentAIArray[playerID + offset] != 0 + && DAT_GameState::instance.mapAndTime.playerTeams[playerID + offset] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + candidates[candidateCount] = playerID + offset; + candidateCount++; + } } } From 831e6797785619fed9004563f07314b22aeea658 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 14:23:59 +0200 Subject: [PATCH 06/10] review: record why a plain 1..8 loop cannot match someChatMessageSelection Tried `for (int i = 1; i < 9; i++)` and three other spellings of the same loop (reusing the function's declared `i`, a fresh name declared in the `for`, and the pre-declared `playerID`). All four produce byte-identical assembly at 0.6745 and 154 instructions, against 132 for the nested form and 119 in the original, so the loop variable's name, declaration site and reuse are all irrelevant here. The reason is visible in the diff: fully unrolling 8 iterations with a known trip count lets MSVC constant-fold every index, so each body gets its own absolute addresses and an immediate player number. The original instead keeps the index in a register and computes the stored value with `lea`, which means its source had an induction variable that survived the unroll. Stepping the outer loop by 4 is what reproduces that. Comment updated with the mechanism; no code change. Co-Authored-By: Claude Opus 5 (1M context) --- src/OpenSHC/AI/AICState/someChatMessageSelection.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp index acc57cc544..2045651c56 100644 --- a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp +++ b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp @@ -43,10 +43,12 @@ namespace AI { } candidateCount = 0; - // Players 1..8. The original unrolls this 4 at a time, so the outer loop has to step by 4; - // the compiler unrolls the inner 4 itself, producing the same instructions as writing the - // four copies out. A plain 1..8 loop does not work: MSVC then unrolls all 8 and the match - // drops from 0.92 to 0.67 (writing 8 copies out by hand compiles to exactly the same thing). + // Players 1..8, unrolled 4 at a time. The outer loop has to step by 4 and the inner 4 can be + // left to the compiler, which unrolls them into the same instructions as four written-out + // copies. A plain 1..8 loop does not work (0.92 -> 0.67, and the same for every spelling of + // it): MSVC unrolls all 8 and, with the trip count known, constant-folds every index into an + // absolute address and an immediate. The original keeps the index in a register, so its + // source had an induction variable surviving the unroll - which is what stepping by 4 gives. for (playerID = 1; playerID < 9; playerID += 4) { for (int offset = 0; offset < 4; offset++) { if (DAT_GameSynchronyState::instance.currentAIArray[playerID + offset] != 0 From a42d41296e6d8740e1305ef6fab8804bb6e99ec5 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 14:44:33 +0200 Subject: [PATCH 07/10] review: PlayerData::isNotNervousByEnemyTroopValue is a BOOLEnum Verified against the original binary with Ghidra rather than inferred. The field at PlayerData + 0x3820 has 7 writes and 5 reads in the whole image, and every write stores 0 or 1: 004d3802 computeNervousness xor eax, eax -> 0 004d383f computeNervousness ebx -> 1 004ad1c5 ProcessAllyAcceptsRequest imm -> 0 004ad295 ProcessAllyDeniesRequest2 imm -> 0 004ad315 ProcessAllyRequestAttackDefense eax after xor -> 0 004ad38e ProcessAllyRequestAttackDefense imm -> 1 004ad433 ProcessAllyRequestAttackDefense imm -> 0 All five reads are == 0 / != 0 truthiness tests, so the field is boolean. BOOLEnum is already the convention for such fields in PlayerData.hpp. This also corrects the note in the earlier commit, which argued the field had to stay an int because the original stores it with `mov dword ptr [..], 0/1`. That AGENTS.md rule distinguishes int from C++ `bool` (a one-byte store); BOOLEnum is a typedef of BOOL, hence int, so the dword store is exactly what a BOOLEnum field looks like and was never evidence against it. Being the same underlying type, the change is purely semantic: quick_diff stays at 1.0000 for computeNervousness, determineAIPlayerHelp and determineAIPlayerAttackRequestResponse, the field's only users. The two readers also lose their `!= 0` per the review's preferred if() style. Co-Authored-By: Claude Opus 5 (1M context) --- src/OpenSHC/AI/AICState/computeNervousness.cpp | 10 +++++++--- .../determineAIPlayerAttackRequestResponse.cpp | 2 +- src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/OpenSHC/AI/AICState/computeNervousness.cpp b/src/OpenSHC/AI/AICState/computeNervousness.cpp index 65e1fe7bc4..f836f9fa5d 100644 --- a/src/OpenSHC/AI/AICState/computeNervousness.cpp +++ b/src/OpenSHC/AI/AICState/computeNervousness.cpp @@ -1,5 +1,7 @@ #include "../AICState.func.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" + #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" #include "OpenSHC/Globals/DAT_TroopValueState.hpp" @@ -7,6 +9,8 @@ namespace OpenSHC { namespace AI { + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + // FUNCTION: STRONGHOLDCRUSADER 0x004D3780 void AICState::computeNervousness(int playerID) { @@ -14,7 +18,7 @@ namespace AI { = DAT_TroopValueState::instance.attackInfo.playerTotalTroopValueOfTroopsNearKeep[playerID]; int enemyTroopValue = DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; - int isNotNervous = 1; + BOOLEnum isNotNervous = TRUE; int margin; if (enemyTroopValue < 50) margin = -20; @@ -32,8 +36,8 @@ namespace AI { margin = 500; if (troopValueNearKeep > enemyTroopValue + margin) { - isNotNervous = 0; - } else if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue == 0) { + isNotNervous = FALSE; + } else if (!DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue) { if (DAT_GameState::instance.playerDataArray[playerID] .totalEnemyTroopValueByPlayerID[DAT_GameSynchronyState::instance.currentPlayerSlotID] > troopValueNearKeep) diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp index 729f153427..d906d7875a 100644 --- a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp +++ b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp @@ -15,7 +15,7 @@ namespace AI { return FALSE; int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; - if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue != 0) { + if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue) { MACRO_CALL_MEMBER(AICState_Func::playWillNotAttack1BikFromPlayerToPlayer, this)( playerID, requestedByPlayerID); return FALSE; diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp index 46df0cb275..611dccbd6a 100644 --- a/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp +++ b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp @@ -14,7 +14,7 @@ namespace AI { return FALSE; int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; - if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue != 0) { + if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue) { MACRO_CALL_MEMBER(AICState_Func::playWillNotHelp1BikFromPlayerToPlayer, this)( playerID, requestedByPlayerID); return FALSE; From c60ff36ef2be176a8e473ae3ebb601420a91393f Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 15:13:38 +0200 Subject: [PATCH 08/10] review: use `TYPE const name` for single-assignment locals in AICState 165 locals across the AICState sources gain `const` after the type, per the project's preferred `int const stackvariable` spelling. Applied only where the local is initialised once at its declaration and never afterwards assigned, incremented, decremented or address-taken; arrays, multi-declarators and uninitialised declarations are left alone. Wrong calls would not compile, and all 137 files were compiled. This also restores the `const` on getAIBuildInterval's `aiType`, which was not dropped deliberately: it was lost in a8f7dae2, where the AICState sources were re-added from the field-refactor script's output. It was the only one of the four files predating that commit to lose it. const is NOT codegen-neutral here, so it is applied by measurement rather than by rule. Seven locals of the form `int tribeIndex = ` had to keep their non-const spelling: with const, MSVC1400 folds the literal into the array index at its use site and drops 4 instructions that the original still has, costing 0.18 to 0.50 of match in aiCommandTribe11StandGroundToGate, aiCommandTribe13DefensiveWave, sendAITribe_0xf_toAttackPatrol, sendTribeToAttack, setTribe0x11ToAggressiveAndAttackIfConditionMet, setTribe0xCtoAggressiveAndAttack and setTribe0xbToAggressiveAndAttack. const on a local initialised from a memory read or a call is neutral, which is every other case here. Verified by a full before/after quick_diff sweep of all 137 functions: every one is identical to its baseline. Co-Authored-By: Claude Opus 5 (1M context) --- .../addBuildingToTargetableBuildings.cpp | 2 +- .../AI/AICState/addEngineersToSelection.cpp | 2 +- .../AICState/addUnitToSmallestPatrolTribe.cpp | 6 ++--- .../aiChoiceAttForceRallyPercentage.cpp | 10 ++++---- .../AICState/aiCommandSiegeEngineTribes.cpp | 10 ++++---- .../aiCommandTribe11StandGroundToGate.cpp | 2 +- .../aiCommandTribe13DefensiveWave.cpp | 2 +- src/OpenSHC/AI/AICState/aiFarmChoice.cpp | 2 +- .../AI/AICState/aiRecruitEngineers.cpp | 4 ++-- .../AI/AICState/aiRequiresExtraOxtethers.cpp | 17 ++++++++------ .../AI/AICState/aiUpdateTaxesAndRations.cpp | 6 ++--- .../assignRequiredIdleEngineersToNewTribe.cpp | 2 +- .../AI/AICState/assignUnitToATribe.cpp | 2 +- ...GenerateAITribesForPlayerIfNotExisting.cpp | 6 ++--- .../AI/AICState/clearOutdatedAITribes.cpp | 6 ++--- .../AI/AICState/computeNervousness.cpp | 4 ++-- .../AI/AICState/destroyBuildingIfNoWorker.cpp | 23 +++++++++++-------- ...determineAIPlayerAttackRequestResponse.cpp | 2 +- .../AI/AICState/determineAIPlayerHelp.cpp | 2 +- ...ndAttackTribePositionAndPathToDefenses.cpp | 10 ++++---- .../generateSiegeCreationInformation.cpp | 6 ++--- .../AI/AICState/getAIBuildInterval.cpp | 2 +- .../AI/AICState/getResourceRebuildDelay.cpp | 2 +- .../AI/AICState/getSmallestPatrolTribe.cpp | 2 +- .../getTargetableBuildingForPlayerID.cpp | 6 ++--- .../getUnitTypeForUnitBehaviourType.cpp | 8 +++---- .../AI/AICState/getUnitTypeIndexForUnitID.cpp | 4 ++-- .../AICState/giveMoveCommandToSortieUnits.cpp | 10 ++++---- .../AICState/ifHasTribe0SendUnitsToKeep.cpp | 2 +- .../AI/AICState/instructTribe166ToMove.cpp | 6 ++--- .../AI/AICState/makeOutpostTribesAttack.cpp | 2 +- ...eUnitsGoDefensiveAndBackToSomeLocation.cpp | 12 +++++----- .../AICState/moveAttackTribesToLocations.cpp | 6 ++--- .../moveAttackingUnitsToNextRallyPoint.cpp | 10 ++++---- ...rcentageNonMovingTribesGTEAICSpecified.cpp | 10 ++++---- .../AI/AICState/playAnger1BikFromPlayer.cpp | 2 +- ...playTauntToAttackedPlayerBikFromPlayer.cpp | 2 +- .../playThanksBikFromPlayerToPlayer.cpp | 2 +- .../processAttForceRallyPercentage.cpp | 10 ++++---- .../randomlySelectAttackUnitTypeToRecruit.cpp | 6 ++--- .../recomputeAIPathCostToAttackedKeep.cpp | 4 ++-- .../AI/AICState/recreateEngineersTribe.cpp | 2 +- ...oveOrganismsAndSetMoveDestinationPairs.cpp | 6 ++--- ...selectBuildingFromAListOfBuildingTypes.cpp | 2 +- ...andomBuildingIDFromListOfBuildingTypes.cpp | 4 ++-- .../sendAITribe_0xf_toAttackPatrol.cpp | 2 +- ...oAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp | 6 ++--- ...sendOilMenForOilPickupOrToAIVLocations.cpp | 4 ++-- ...gedUnitTribesToAIVSlotsOrKeepIfNervous.cpp | 4 ++-- .../AICState/sendTribeAtOffset1ToCampfire.cpp | 2 +- .../AICState/sendTribeToAIVLocationSlot.cpp | 6 ++--- src/OpenSHC/AI/AICState/sendTribeToAttack.cpp | 2 +- .../sendUnitsToAttackBreachedCastle.cpp | 14 +++++------ src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp | 2 +- .../sendUnitsToPlayerIDsKeepIfPossible.cpp | 12 +++++----- .../AICState/setAttackCoordinationLevel.cpp | 2 +- .../AI/AICState/setAttackPrimeInfo.cpp | 2 +- .../AI/AICState/setCurrentAttackStrength.cpp | 4 ++-- ...htTribe0xc0TribesToAggressiveAndAttack.cpp | 2 +- .../AI/AICState/setNextFarmTypeToBuild.cpp | 4 ++-- .../AICState/setNextMoveLocationForUnits.cpp | 2 +- ...TargetForTribeBasedOnTargetChoiceLogic.cpp | 8 +++---- ...x11ToAggressiveAndAttackIfConditionMet.cpp | 2 +- .../setTribe0xCtoAggressiveAndAttack.cpp | 2 +- .../setTribe0xbToAggressiveAndAttack.cpp | 2 +- .../AICState/setupWorkshopProductionType.cpp | 2 +- .../AI/AICState/shareGoldAmongTeamMembers.cpp | 4 ++-- .../AI/AICState/unitIDIsRangedOrArmored.cpp | 2 +- src/OpenSHC/AI/AICState/updateAIBehaviour.cpp | 2 +- .../AI/AICState/updateTribeLocations.cpp | 2 +- ...12_toPlaceSiegeTentsAndAssignEngineers.cpp | 8 +++---- .../useAITribe_0xe_toPlaceTunnels.cpp | 6 ++--- src/OpenSHC/AI/AICState/yieldCowThrow.cpp | 4 ++-- 73 files changed, 184 insertions(+), 178 deletions(-) diff --git a/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp b/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp index bd48cbe1c0..2cd0c7498f 100644 --- a/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp +++ b/src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp @@ -12,7 +12,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CDA50 void AICState::addBuildingToTargetableBuildings(int buildingID) { - int owner = DAT_BuildingsState::instance.buildings[buildingID].owner; + int const owner = DAT_BuildingsState::instance.buildings[buildingID].owner; if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) return; if (DAT_GameState::instance.playerDataArray[owner].top100TargetableBuildingsTracker >= 100) diff --git a/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp b/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp index ce614c0985..b84a31b9db 100644 --- a/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp +++ b/src/OpenSHC/AI/AICState/addEngineersToSelection.cpp @@ -14,7 +14,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC680 int AICState::addEngineersToSelection(int playerID, int unitCount) { - int tribeID + int const tribeID = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) { if (unitCount <= 0) diff --git a/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp b/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp index e92b28080d..5df7b00273 100644 --- a/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp +++ b/src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp @@ -13,13 +13,13 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2730 void AICState::addUnitToSmallestPatrolTribe(int unitID) { - int owner = DAT_UnitsState::instance.units[unitID].owner; + int const owner = DAT_UnitsState::instance.units[unitID].owner; if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL) return; - int aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 4; - int tribeID = MACRO_CALL_MEMBER(AICState_Func::getSmallestPatrolTribe, this)( + int const tribeID = MACRO_CALL_MEMBER(AICState_Func::getSmallestPatrolTribe, this)( owner, this->aics[aicIndex].OuterPatrolGroupsCount); MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID); } diff --git a/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp b/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp index 890450502e..8b592dd2fa 100644 --- a/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp +++ b/src/OpenSHC/AI/AICState/aiChoiceAttForceRallyPercentage.cpp @@ -12,18 +12,18 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CEC80 BOOLEnum AICState::aiChoiceAttForceRallyPercentage(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return FALSE; - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; int activeTribes = 0; int rallyingTribes = 0; for (int i = 0; i < 11; i++) { - int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp index ec02d29736..5bc2a4b90f 100644 --- a/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandSiegeEngineTribes.cpp @@ -75,18 +75,18 @@ namespace AI { if (shieldCount >= 3) continue; - int targetTribeID = shieldTargetTribeIDs[shieldCount]; + int const targetTribeID = shieldTargetTribeIDs[shieldCount]; DAT_TribesState::instance.tribes[tribeID].supportTribeID = targetTribeID; DAT_TribesState::instance.tribes[tribeID].uid2 = DAT_TribesState::instance.tribes[targetTribeID].uid; DAT_TribesState::instance.tribes[targetTribeID].tribeID = tribeID; - int targetUnitID = DAT_TribesState::instance.tribes[targetTribeID].selectionTargetUnitID; - int tile = DAT_UnitsState::instance.units[targetUnitID].tile; + int const targetUnitID = DAT_TribesState::instance.tribes[targetTribeID].selectionTargetUnitID; + int const tile = DAT_UnitsState::instance.units[targetUnitID].tile; shieldCount++; if (tile <= 0) continue; - int y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; - int x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; MACRO_CALL_MEMBER(TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( tribeID, x, y, 0, 0, Instructions::UMSE_0); MACRO_CALL_MEMBER( diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp index d401d21346..423f1b41f8 100644 --- a/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandTribe11StandGroundToGate.cpp @@ -17,7 +17,7 @@ namespace AI { int tribeIndex = 11; if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) return; - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) return; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp index a54e50f8dd..19c90fa5cf 100644 --- a/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp +++ b/src/OpenSHC/AI/AICState/aiCommandTribe13DefensiveWave.cpp @@ -17,7 +17,7 @@ namespace AI { int tribeIndex = 13; if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) return; - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) return; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp index f563b02049..93a7ec91bf 100644 --- a/src/OpenSHC/AI/AICState/aiFarmChoice.cpp +++ b/src/OpenSHC/AI/AICState/aiFarmChoice.cpp @@ -10,7 +10,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB180 int AICState::aiFarmChoice(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) return 0; return (&this->aics[aiType - 1].farm1)[DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex]; diff --git a/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp index 7445e89534..0b73e843cb 100644 --- a/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp +++ b/src/OpenSHC/AI/AICState/aiRecruitEngineers.cpp @@ -15,7 +15,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC520 void AICState::aiRecruitEngineers(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) return; if (DAT_GameState::instance.playerDataArray[playerID].isEngineerRequired == FALSE) @@ -26,7 +26,7 @@ namespace AI { + DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] < 30) return; - int guildID = DAT_GameState::instance.playerDataArray[playerID].engineersGuild.id; + int const guildID = DAT_GameState::instance.playerDataArray[playerID].engineersGuild.id; if (guildID <= 0) return; if (DAT_BuildingsState::instance.buildings[guildID].buildingType != Map::Buildings::BT_ENGINEERSGUILD) diff --git a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp index 8a2ed19b5f..15437a60ac 100644 --- a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp +++ b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp @@ -2,6 +2,7 @@ #include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" #include "OpenSHC/Map/Buildings/BuildingType.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" #include "OpenSHC/Globals/DAT_BuildingsState.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" @@ -9,8 +10,10 @@ namespace OpenSHC { namespace AI { + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + // FUNCTION: STRONGHOLDCRUSADER 0x004CB3A0 - undefined4 AICState::aiRequiresExtraOxtethers(int playerID) + BOOLEnum AICState::aiRequiresExtraOxtethers(int playerID) { int quarryID = MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::findFirstBuildingIDForPlayerAndType, @@ -20,19 +23,19 @@ namespace AI { if (MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::countBuildingsForPlayer, DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_OXTETHER, 1) >= 10) - return 0; + return FALSE; DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = 0; for (; quarryID != 0; quarryID = MACRO_CALL_MEMBER(OpenSHC::Map::Buildings::BuildingsState_Func::findNextBuildingForPlayerAndType, DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_QUARRY, quarryID)) { // The (short) is load-bearing: quarryStockpileID is undefined2, and the original sign-extends it. - int stone = DAT_BuildingsState::instance + int const stone = DAT_BuildingsState::instance .buildings[(short)DAT_BuildingsState::instance.buildings[quarryID].quarryStockpileID] .resources[Game::Resources::RT_STONE]; int tetherCount = 0; for (int i = 0; i < 3; i++) { - int tetherID = DAT_BuildingsState::instance.buildings[quarryID].quarryLinkedOxTethers[i]; + int const tetherID = DAT_BuildingsState::instance.buildings[quarryID].quarryLinkedOxTethers[i]; if (tetherID == 0) continue; if (DAT_BuildingsState::instance.buildings[tetherID].buildingType @@ -45,7 +48,7 @@ namespace AI { if (tetherCount <= 0) { DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = quarryID; - return 1; + return TRUE; } if (stone / tetherCount > highestStonePerTether) { highestQuarryID = quarryID; @@ -55,9 +58,9 @@ namespace AI { if (highestStonePerTether > 20) { DAT_GameState::instance.playerDataArray[playerID].highestLoadedQuarryUnk = highestQuarryID; - return 1; + return TRUE; } - return 0; + return FALSE; } } diff --git a/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp b/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp index cd1b580356..26024f8668 100644 --- a/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp +++ b/src/OpenSHC/AI/AICState/aiUpdateTaxesAndRations.cpp @@ -10,12 +10,12 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CAEA0 void AICState::aiUpdateTaxesAndRations(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return; - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; - int popularity = DAT_GameState::instance.playerDataArray[playerID].popularity; + int const popularity = DAT_GameState::instance.playerDataArray[playerID].popularity; if (popularity <= this->aics[aicIndex].criticalPopularity) DAT_GameState::instance.playerDataArray[playerID].aiPopularityDecisionValue = 2; else if (popularity <= this->aics[aicIndex].lowestPopularity) diff --git a/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp index 0b6acabc30..617ccfeaa9 100644 --- a/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp +++ b/src/OpenSHC/AI/AICState/assignRequiredIdleEngineersToNewTribe.cpp @@ -14,7 +14,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC5A0 int AICState::assignRequiredIdleEngineersToNewTribe(int playerID, int count) { - int tribeID + int const tribeID = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); for (int unitID = 1; unitID < DAT_UnitsState::instance.maxUnitCount; unitID++) { if (count <= 0) diff --git a/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp b/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp index 547e164cf0..252668ad7b 100644 --- a/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp +++ b/src/OpenSHC/AI/AICState/assignUnitToATribe.cpp @@ -13,7 +13,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2660 void AICState::assignUnitToATribe(int unitID) { - int owner = DAT_UnitsState::instance.units[unitID].owner; + int const owner = DAT_UnitsState::instance.units[unitID].owner; if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL) return; diff --git a/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp index 1c7ebdc94a..3d27768782 100644 --- a/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp +++ b/src/OpenSHC/AI/AICState/checksAndGenerateAITribesForPlayerIfNotExisting.cpp @@ -16,19 +16,19 @@ namespace AI { int AICState::checksAndGenerateAITribesForPlayerIfNotExisting(int playerID, int maxAmount, BOOLEnum checkOnly) { int offset = 0; - int baseOffset = DAT_SkirmishDefinedData::instance.AITribeIDOffsetForAIVUnitType[1]; + int const baseOffset = DAT_SkirmishDefinedData::instance.AITribeIDOffsetForAIVUnitType[1]; for (; offset < maxAmount; offset++) { if (offset >= 10) { return 0; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[baseOffset + offset]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[baseOffset + offset]; if (tribeID == 0 || DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[baseOffset + offset]) { if (checkOnly) { return 1; } - int newTribeID = MACRO_CALL_MEMBER( + int const newTribeID = MACRO_CALL_MEMBER( OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[baseOffset + offset] = (short)newTribeID; DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[baseOffset + offset] diff --git a/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp b/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp index 8e7e231788..9559e083f0 100644 --- a/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp +++ b/src/OpenSHC/AI/AICState/clearOutdatedAITribes.cpp @@ -19,10 +19,10 @@ namespace AI { if (i == 8) continue; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; - int tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/computeNervousness.cpp b/src/OpenSHC/AI/AICState/computeNervousness.cpp index f836f9fa5d..af63f65c96 100644 --- a/src/OpenSHC/AI/AICState/computeNervousness.cpp +++ b/src/OpenSHC/AI/AICState/computeNervousness.cpp @@ -14,9 +14,9 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D3780 void AICState::computeNervousness(int playerID) { - int troopValueNearKeep + int const troopValueNearKeep = DAT_TroopValueState::instance.attackInfo.playerTotalTroopValueOfTroopsNearKeep[playerID]; - int enemyTroopValue = DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; + int const enemyTroopValue = DAT_GameState::instance.playerDataArray[playerID].totalEnemyTroopValue; BOOLEnum isNotNervous = TRUE; int margin; diff --git a/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp index 7da727d069..9ffa6b35fb 100644 --- a/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp +++ b/src/OpenSHC/AI/AICState/destroyBuildingIfNoWorker.cpp @@ -3,6 +3,7 @@ #include "OpenSHC/AI/AIVState.func.hpp" #include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" #include "OpenSHC/Game/GameMode.hpp" +#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" #include "OpenSHC/Globals/DAT_AIVState.hpp" #include "OpenSHC/Globals/DAT_BuildingsState.hpp" @@ -12,27 +13,29 @@ namespace OpenSHC { namespace AI { + using OpenSHC::WindowsHelper::Enums::BOOLEnum; + // FUNCTION: STRONGHOLDCRUSADER 0x004CB940 - undefined4 AICState::destroyBuildingIfNoWorker(int buildingID) + BOOLEnum AICState::destroyBuildingIfNoWorker(int buildingID) { - short countdown = DAT_BuildingsState::instance.buildings[buildingID].unknownTickRelatedValue; - int owner = DAT_BuildingsState::instance.buildings[buildingID].owner; + short const countdown = DAT_BuildingsState::instance.buildings[buildingID].unknownTickRelatedValue; + int const owner = DAT_BuildingsState::instance.buildings[buildingID].owner; if (countdown <= 0) - return 0; + return FALSE; if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[owner] != -1) - return 0; + return FALSE; if (DAT_GameSynchronyState::instance.currentAIArray[owner] == 0) - return 0; + return FALSE; if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) - return 0; + return FALSE; if (DAT_BuildingsState::instance.buildings[buildingID].workers[0] != 0) { if (DAT_GameState::instance.mapAndTime.monthTicks == owner) DAT_BuildingsState::instance.buildings[buildingID].unknownTickRelatedValue = countdown - 1; - return 0; + return FALSE; } if (countdown < 20) - return 0; + return FALSE; MACRO_CALL_MEMBER(AIVState_Func::resetCountdownInHeatMap, DAT_AIVState::ptr)( (short)DAT_BuildingsState::instance.buildings[buildingID].x, @@ -40,7 +43,7 @@ namespace AI { MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::giveBackResourceForDestroyedBuilding, DAT_BuildingsState::ptr)(buildingID, owner, 50); MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::destroyBuilding, DAT_BuildingsState::ptr)(buildingID); - return 1; + return TRUE; } } } diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp index d906d7875a..1875d06074 100644 --- a/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp +++ b/src/OpenSHC/AI/AICState/determineAIPlayerAttackRequestResponse.cpp @@ -13,7 +13,7 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) return FALSE; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue) { MACRO_CALL_MEMBER(AICState_Func::playWillNotAttack1BikFromPlayerToPlayer, this)( diff --git a/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp index 611dccbd6a..e2d371895e 100644 --- a/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp +++ b/src/OpenSHC/AI/AICState/determineAIPlayerHelp.cpp @@ -12,7 +12,7 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) return FALSE; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_GameState::instance.playerDataArray[playerID].isNotNervousByEnemyTroopValue) { MACRO_CALL_MEMBER(AICState_Func::playWillNotHelp1BikFromPlayerToPlayer, this)( diff --git a/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp b/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp index 803bd3d6c1..a2a3ed5875 100644 --- a/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp +++ b/src/OpenSHC/AI/AICState/findAttackTribePositionAndPathToDefenses.cpp @@ -19,10 +19,10 @@ namespace AI { int y = 0; for (int i = 0; i < 11; i++) { int targetUnitID = 0; - int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid @@ -42,13 +42,13 @@ namespace AI { if (x == 0) return; - int tile = MACRO_CALL_MEMBER( + int const tile = MACRO_CALL_MEMBER( OpenSHC::Map::Navigation::PathFindingState_Func::tracePathToFriendlyDefensesAndReturnTileUnk, DAT_PathFindingState::ptr)(playerID, x, y); if (tile <= 0) return; - int tileY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const tileY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; DAT_GameState::instance.playerDataArray[playerID].someTile = tile; DAT_GameState::instance.playerDataArray[playerID].someY = tileY; DAT_GameState::instance.playerDataArray[playerID].someX diff --git a/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp index dbc9260e1c..399141ccd6 100644 --- a/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp +++ b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp @@ -29,10 +29,10 @@ namespace AI { else return; - int slot = DAT_SkirmishDefinedData::instance.SiegeEngineMetaInfoArray[siegeIndex].slot; - int locationCount = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[slot]; + int const slot = DAT_SkirmishDefinedData::instance.SiegeEngineMetaInfoArray[siegeIndex].slot; + int const locationCount = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[slot]; while (i < locationCount) { - int index = i; + int const index = i; i++; if (DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[slot][index] > 0 && buildingID diff --git a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp index 749a17bcdf..2cb13d26b4 100644 --- a/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp +++ b/src/OpenSHC/AI/AICState/getAIBuildInterval.cpp @@ -10,7 +10,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB120 int AICState::getAIBuildInterval(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) return 0; return this->aics[aiType - 1].buildInterval; diff --git a/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp index 8e3e49bcbb..3c04e88818 100644 --- a/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp +++ b/src/OpenSHC/AI/AICState/getResourceRebuildDelay.cpp @@ -10,7 +10,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB150 int AICState::getResourceRebuildDelay(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) return 0; return this->aics[aiType - 1].resourceRebuildDelay; diff --git a/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp b/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp index 09ce8c0d59..85dcc6f50f 100644 --- a/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp +++ b/src/OpenSHC/AI/AICState/getSmallestPatrolTribe.cpp @@ -23,7 +23,7 @@ namespace AI { break; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[170 + i]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[170 + i]; if (tribeID == 0 || DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[i + 170]) { diff --git a/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp index 63e303b6ae..e87f7a6504 100644 --- a/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp +++ b/src/OpenSHC/AI/AICState/getTargetableBuildingForPlayerID.cpp @@ -12,13 +12,13 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == 0) return 0; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (this->aics[aicIndex].OuterPatrolGroupsCount <= 0) return 0; if (DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker <= 0) return 0; - int step = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker + int const step = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker / this->aics[aicIndex].OuterPatrolGroupsCount; DAT_GameState::instance.playerDataArray[playerID].someCounter2++; if (DAT_GameState::instance.playerDataArray[playerID].someCounter2 @@ -27,7 +27,7 @@ namespace AI { int index = (step * patrolGroupIndex + DAT_GameState::instance.playerDataArray[playerID].someCounter2) % DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; for (int i = 0; i < DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; i++) { - int buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; + int const buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; index++; if (index >= DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker) index = 0; diff --git a/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp b/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp index fd1ea735fc..09528bb709 100644 --- a/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp +++ b/src/OpenSHC/AI/AICState/getUnitTypeForUnitBehaviourType.cpp @@ -12,10 +12,10 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC250 UnitType AICState::getUnitTypeForUnitBehaviourType(int playerID, AIUnitBehaviourType unitBehaviourType) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return (UnitType)0; - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; if (unitBehaviourType == OpenSHC::AI::AIUBT_ENGINEERING) return OpenSHC::Map::Units::UT_E_ENGINEER; @@ -45,8 +45,8 @@ namespace AI { if (DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex >= 4) DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex = 0; - int choice = DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex; - UnitType unitType = (UnitType)(&this->aics[aicIndex].AttUnitMain1)[choice]; + int const choice = DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex; + UnitType const unitType = (UnitType)(&this->aics[aicIndex].AttUnitMain1)[choice]; DAT_GameState::instance.playerDataArray[playerID].aiAttUnitMainChoiceIndex = choice + 1; return unitType; } diff --git a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp index 4030cac530..f1cfe9a7f1 100644 --- a/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp +++ b/src/OpenSHC/AI/AICState/getUnitTypeIndexForUnitID.cpp @@ -21,8 +21,8 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC390 AIVUnitType AICState::getUnitTypeIndexForUnitID(int unitID, int allowSlaveSlotForRanged) { - UnitTypeShort unitType = DAT_UnitsState::instance.units[unitID].unitType; - int owner = DAT_UnitsState::instance.units[unitID].owner; + UnitTypeShort const unitType = DAT_UnitsState::instance.units[unitID].unitType; + int const owner = DAT_UnitsState::instance.units[unitID].owner; UnitTypeInt effectiveUnitType; if (unitType == OpenSHC::Map::Units::UT_PEASANT) { effectiveUnitType = DAT_UnitsState::instance.units[unitID].unitTypeToChangeInto; diff --git a/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp b/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp index 5423d33399..51d41bbb25 100644 --- a/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp +++ b/src/OpenSHC/AI/AICState/giveMoveCommandToSortieUnits.cpp @@ -18,12 +18,12 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CD8F0 void AICState::giveMoveCommandToSortieUnits(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return; - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[167]; - int aicIndex = aiType - 1; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[167]; + int const aicIndex = aiType - 1; if (tribeID == 0) return; if (DAT_TribesState::instance.tribes[tribeID].uid @@ -34,13 +34,13 @@ namespace AI { < DAT_GameState::instance.playerDataArray[playerID].totalTroopsType7 - 1) MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::syncBehaviourType7UnitTribes, this)(playerID); - int targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + int const targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; bool sendToKeep = true; if (DAT_GameState::instance.playerDataArray[playerID].aiNervousActionsTracker <= 0) { if (DAT_TribesState::instance.tribes[tribeID].size < this->aics[aicIndex].SortieUnitMeleeMin) { sendToKeep = false; } else { - int unitID = DAT_GameState::instance.playerDataArray[playerID].lastEncounteredTroopUnitID; + int const unitID = DAT_GameState::instance.playerDataArray[playerID].lastEncounteredTroopUnitID; if (unitID != 0 && DAT_GameState::instance.playerDataArray[playerID].lastEncounteredTroopUnitUID == DAT_UnitsState::instance.units[unitID].uid diff --git a/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp b/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp index 95b2d1aeb0..c90f9ce3b1 100644 --- a/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp +++ b/src/OpenSHC/AI/AICState/ifHasTribe0SendUnitsToKeep.cpp @@ -9,7 +9,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2830 void AICState::ifHasTribe0SendUnitsToKeep(int playerID) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0]; if (tribeID <= 0) return; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp b/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp index f7d69ad605..428a7bc1df 100644 --- a/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp +++ b/src/OpenSHC/AI/AICState/instructTribe166ToMove.cpp @@ -16,17 +16,17 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CD7B0 void AICState::instructTribe166ToMove(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return; - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; if (DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 > 0) DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01--; if (DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 > 50) DAT_GameState::instance.playerDataArray[playerID].unknownCounter_01 = 50; - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[166]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[166]; BOOLEnum keepEnclosed = MACRO_CALL_MEMBER( OpenSHC::Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID); if (tribeID == 0) diff --git a/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp b/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp index 243d4828c6..2ae6606933 100644 --- a/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp +++ b/src/OpenSHC/AI/AICState/makeOutpostTribesAttack.cpp @@ -9,7 +9,7 @@ namespace AI { void AICState::makeOutpostTribesAttack() { for (int i = 0; i < 1000; i++) { - int tribeID = this->tribeIDArray[i]; + int const tribeID = this->tribeIDArray[i]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid != this->tribeUIDArray[i]) diff --git a/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp b/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp index d4f23d1641..01b9947429 100644 --- a/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp +++ b/src/OpenSHC/AI/AICState/makeUnitsGoDefensiveAndBackToSomeLocation.cpp @@ -21,20 +21,20 @@ namespace AI { return; for (int i = 0; i < 11; i++) { - int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[j + tribeType]) continue; - int x = DAT_GameState::instance.playerDataArray[playerID].someX; + int const x = DAT_GameState::instance.playerDataArray[playerID].someX; DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; - int y = DAT_GameState::instance.playerDataArray[playerID].someY; - uint result = MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, + int const y = DAT_GameState::instance.playerDataArray[playerID].someY; + uint const result = MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)(tribeID, x, y, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0); if (result == 0) MACRO_CALL_MEMBER(OpenSHC::Map::Units::TribesState_Func::removeAllTribeUnits, DAT_TribesState::ptr)( diff --git a/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp b/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp index ee8e3ad579..4ef01ddee0 100644 --- a/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp +++ b/src/OpenSHC/AI/AICState/moveAttackTribesToLocations.cpp @@ -20,10 +20,10 @@ namespace AI { int destIndex = 0; for (int i = 0; i < 11; i++) { - int tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeType + j]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp b/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp index 04aa9c19d7..ab8dac6e09 100644 --- a/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp +++ b/src/OpenSHC/AI/AICState/moveAttackingUnitsToNextRallyPoint.cpp @@ -22,7 +22,7 @@ namespace AI { return; for (int i = 0; i < 2; i++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[190 + i]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[190 + i]; if (tribeID == 0) continue; if (DAT_TribesState::instance.tribes[tribeID].uid @@ -38,14 +38,14 @@ namespace AI { DAT_TribesState::instance.tribes[tribeID].unknownAttackRelatedUpdateCounter = 0; MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addRallyPointForTribe, this)(tribeID); - short rallyPointCount = DAT_TribesState::instance.tribes[tribeID].rallyPointCount; + short const rallyPointCount = DAT_TribesState::instance.tribes[tribeID].rallyPointCount; int rallyPointIndex = DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex + 1; if (rallyPointIndex >= rallyPointCount) rallyPointIndex = 0; - int x = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][0]; - int y = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][1]; - int targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + int const x = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][0]; + int const y = DAT_TribesState::instance.tribes[tribeID].rallyPointArray[rallyPointIndex][1]; + int const targetUnitID = DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = rallyPointIndex; if (rallyPointCount <= 0) diff --git a/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp b/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp index a7af36538b..132e9a1be8 100644 --- a/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp +++ b/src/OpenSHC/AI/AICState/percentageNonMovingTribesGTEAICSpecified.cpp @@ -18,21 +18,21 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CED90 BOOLEnum AICState::percentageNonMovingTribesGTEAICSpecified(int playerID) { - AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + AITypeInt const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) { return FALSE; } - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; int tribeTotal = 0; int notReallyMoving = 0; for (int i = 0; i < 11; i++) { - int tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp index a6f214b0c8..35899d6991 100644 --- a/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playAnger1BikFromPlayer.cpp @@ -19,7 +19,7 @@ namespace AI { return; } - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_GameState::instance.mapAndTime.playerTeams[playerID] == DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { return; diff --git a/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp index d65e97b24f..72ac065f9e 100644 --- a/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playTauntToAttackedPlayerBikFromPlayer.cpp @@ -20,7 +20,7 @@ namespace AI { } int bik = 0; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_GameState::instance.mapAndTime.playerTeams[playerID] == DAT_GameState::instance.mapAndTime.playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { bik = 23; diff --git a/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp index d0e1541dc1..fb3e9204d5 100644 --- a/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp +++ b/src/OpenSHC/AI/AICState/playThanksBikFromPlayerToPlayer.cpp @@ -19,7 +19,7 @@ namespace AI { return; } - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; DAT_GameState::instance.playerDataArray[playerID].aiRequestDelay = this->aics[aicIndex].aiRequestDelay; if (targetPlayerID != DAT_GameSynchronyState::instance.currentPlayerSlotID) { diff --git a/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp b/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp index 302c38a63f..e5a72e902d 100644 --- a/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp +++ b/src/OpenSHC/AI/AICState/processAttForceRallyPercentage.cpp @@ -21,18 +21,18 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CEEA0 BOOLEnum AICState::processAttForceRallyPercentage(int playerID) { - AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + AITypeInt const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) { return FALSE; } - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; int tribeTotal = 0; int notReallyMoving = 0; for (int i = 0; i < 11; i++) { - int tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeIndex = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; if (tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_BASIC_07_01 || tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_10_01 || tribeIndex == OpenSHC::AI::Tribes::AITI_BREACH_BASIC_05_01) { @@ -40,7 +40,7 @@ namespace AI { } for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex + j]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp b/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp index 4b0108c3d5..b979de3d4d 100644 --- a/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp +++ b/src/OpenSHC/AI/AICState/randomlySelectAttackUnitTypeToRecruit.cpp @@ -19,13 +19,13 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC070 AIUnitBehaviourType AICState::randomlySelectAttackUnitTypeToRecruit(int playerID) { - AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + AITypeInt const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) { return OpenSHC::AI::AIUBT_ATTUNITMAIN; } - int attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; - int aicIndex = aiType - 1; + int const attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; + int const aicIndex = aiType - 1; int requiredCount = 0; // clear out flags diff --git a/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp index 5fae78c3f3..698893f57c 100644 --- a/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp +++ b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp @@ -19,8 +19,8 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CE040 void AICState::recomputeAIPathCostToAttackedKeep(int playerID, int useBorderDistance) { - int attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; - int keepArea = (short)DAT_TileMapState::instance + int const attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; + int const keepArea = (short)DAT_TileMapState::instance .PathConnectionLayer[DAT_GameState::instance.playerDataArray[playerID].campground.tileEntry]; int borderDistance; diff --git a/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp index 51fe48834f..3fd8df74e4 100644 --- a/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp +++ b/src/OpenSHC/AI/AICState/recreateEngineersTribe.cpp @@ -12,7 +12,7 @@ namespace AI { if (0 >= DAT_GameState::instance.playerDataArray[playerID].totalAttackingEngineerTroops) { return; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; if (tribeID != 0) { if (DAT_TribesState::instance.tribes[tribeID].uid != DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[0x12]) { diff --git a/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp b/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp index 8d50e0976c..99d4ce303b 100644 --- a/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp +++ b/src/OpenSHC/AI/AICState/removeOrganismsAndSetMoveDestinationPairs.cpp @@ -24,7 +24,7 @@ namespace AI { void AICState::removeOrganismsAndSetMoveDestinationPairs(int playerID) { // Clear a tree standing on the target tile - int organismID + int const organismID = (short)DAT_TileMapState::instance.OrganismLayer [DAT_ViewportRenderState::instance .translationMatrix[DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY] @@ -35,8 +35,8 @@ namespace AI { } // Hardcoded exception: the Sultan keeps a smaller distance than all other AIs - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; - int extraDistance = aicIndex == OpenSHC::AI::AIT_SULTAN - 1 ? 8 : 20; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const extraDistance = aicIndex == OpenSHC::AI::AIT_SULTAN - 1 ? 8 : 20; MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findLinkageBasedPathOrWalkRadius, DAT_PathFindingState::ptr)(DAT_GameState::instance.playerDataArray[playerID].shortestDistanceX, DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY, -1, -1, 10000, FALSE); diff --git a/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp b/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp index 11008c4533..96b4f48b33 100644 --- a/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp +++ b/src/OpenSHC/AI/AICState/selectBuildingFromAListOfBuildingTypes.cpp @@ -14,7 +14,7 @@ namespace AI { int selectedBuildingID = 0; int bestPriority = 46; for (int i = 0; i < DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; i++) { - int buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[i]; + int const buildingID = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[i]; if (buildingID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp index a00adfbeb7..22f900fec0 100644 --- a/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp +++ b/src/OpenSHC/AI/AICState/selectRandomBuildingIDFromListOfBuildingTypes.cpp @@ -11,12 +11,12 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CDCA0 int AICState::selectRandomBuildingIDFromListOfBuildingTypes(int playerID, undefined4 raidTribeIndex) { - int count = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; + int const count = DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildingsTracker; if (count <= 0) { return 0; } - int index = SEC_RNG::instance.currentNumber2 % count; + int const index = SEC_RNG::instance.currentNumber2 % count; MACRO_CALL_MEMBER(OpenSHC::Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); return DAT_GameState::instance.playerDataArray[playerID].top100TargetableBuildings[index]; } diff --git a/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp index dddc34439b..81be98e1e3 100644 --- a/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp +++ b/src/OpenSHC/AI/AICState/sendAITribe_0xf_toAttackPatrol.cpp @@ -20,7 +20,7 @@ namespace AI { } // Bug: only tribe 15 is sent, although tribe 16 can also exist if 'AIC: AttUnitPatrolGroupsCount' is 2 - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) { return; } diff --git a/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp index abe6c64a13..b8400dfc42 100644 --- a/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp +++ b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp @@ -23,14 +23,14 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D4220 void AICState::sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed(int playerID) { - BOOLEnum enclosed = MACRO_CALL_MEMBER( + BOOLEnum const enclosed = MACRO_CALL_MEMBER( OpenSHC::Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(playerID); for (int i = 0; i < 6; i++) { - int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount + int const count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount [DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].aivUnitType]; for (int j = 0; j < count; j++) { - int tribeID + int const tribeID = DAT_GameState::instance.playerDataArray[playerID] .aiTribeIDs[DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].tribeArrayOffset + j]; diff --git a/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp b/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp index 5fc7b54b3c..117a3bda2d 100644 --- a/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp +++ b/src/OpenSHC/AI/AICState/sendOilMenForOilPickupOrToAIVLocations.cpp @@ -19,7 +19,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D44E0 void AICState::sendOilMenForOilPickupOrToAIVLocations(int playerID) { - int oilSmelterID = DAT_GameState::instance.playerDataArray[playerID].oilSmelter.id; + int const oilSmelterID = DAT_GameState::instance.playerDataArray[playerID].oilSmelter.id; int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[1]; if (count < 1) { return; @@ -30,7 +30,7 @@ namespace AI { // Oil men tribes start at offset 71 in the tribe ID array for (int i = 1; i <= count; i++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[70 + i]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[70 + i]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp index 3ee27482bb..99836d1b1e 100644 --- a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp +++ b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp @@ -24,10 +24,10 @@ namespace AI { void AICState::sendRangedUnitTribesToAIVSlotsOrKeepIfNervous(int playerID) { for (int i = 0; i < 5; i++) { - int count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount + int const count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount [DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].aivUnitType]; for (int j = 0; j < count; j++) { - int tribeID + int const tribeID = DAT_GameState::instance.playerDataArray[playerID] .aiTribeIDs[DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].tribeArrayOffset + j]; diff --git a/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp index 287a244167..ef76334dae 100644 --- a/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp +++ b/src/OpenSHC/AI/AICState/sendTribeAtOffset1ToCampfire.cpp @@ -9,7 +9,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2870 void AICState::sendTribeAtOffset1ToCampfire(int playerID) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[1]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[1]; if (tribeID <= 0) return; if (DAT_TribesState::instance.tribes[tribeID].uid diff --git a/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp b/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp index a93f91fa05..16f0648222 100644 --- a/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp +++ b/src/OpenSHC/AI/AICState/sendTribeToAIVLocationSlot.cpp @@ -17,7 +17,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D2E00 void AICState::sendTribeToAIVLocationSlot(int tribeID, AIVUnitType aivUnitType, int slotIndex) { - int owner = DAT_TribesState::instance.tribes[tribeID].owner; + int const owner = DAT_TribesState::instance.tribes[tribeID].owner; // Find the slotIndex-th non-empty slot int tile = 0; @@ -32,8 +32,8 @@ namespace AI { } } - int y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; - int x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; if (MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::canNavigateUnitsFromTileToTargetTile, this)(tribeID, tile) != FALSE) { diff --git a/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp index bee2c6691d..a4defde577 100644 --- a/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp +++ b/src/OpenSHC/AI/AICState/sendTribeToAttack.cpp @@ -19,7 +19,7 @@ namespace AI { return; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) { return; } diff --git a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp index 83a8beb308..7b7799363d 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp @@ -33,18 +33,18 @@ namespace AI { } BOOLEnum sentUnitsToAttackLord = FALSE; - int defendingLordID = MACRO_CALL_MEMBER(OpenSHC::Map::Units::UnitsState_Func::getAliveLordForPlayer, + int const defendingLordID = MACRO_CALL_MEMBER(OpenSHC::Map::Units::UnitsState_Func::getAliveLordForPlayer, DAT_UnitsState::ptr)(DAT_GameState::instance.playerDataArray[attackingPlayerIndex].attackedPlayerID); for (int i = 0; i < 11; i++) { - int tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; + int const tribeType = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxBreachTribes[i].tribeCount; if (tribeType == 18 || tribeType == 14 || tribeType == 13) { continue; } for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeIDs[tribeType + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeIDs[tribeType + j]; if (tribeID == 0) { continue; } @@ -53,7 +53,7 @@ namespace AI { continue; } - int targetUnitID = (short)DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; + int const targetUnitID = (short)DAT_TribesState::instance.tribes[tribeID].selectionTargetUnitID; DAT_TribesState::instance.tribes[tribeID].unitStance = OpenSHC::Map::Units::Behavior::USE_DEFENSIVE; if (sentUnitsToAttackLord != FALSE || defendingLordID == 0 || tribeType == 186) { @@ -90,8 +90,8 @@ namespace AI { vector += 1; } else { // Send units to attack lord - int lordY = DAT_UnitsState::instance.units[defendingLordID].y; - int lordX = DAT_UnitsState::instance.units[defendingLordID].x; + int const lordY = DAT_UnitsState::instance.units[defendingLordID].y; + int const lordX = DAT_UnitsState::instance.units[defendingLordID].x; if (MACRO_CALL_MEMBER( OpenSHC::Map::Units::TribesState_Func::giveTribeMoveInstruction, DAT_TribesState::ptr)( tribeID, lordX, lordY, 0, 0, OpenSHC::Map::Units::Instructions::UMSE_0) diff --git a/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp index f9f667f72a..3582df1ebc 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToKeep.cpp @@ -12,7 +12,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CD0C0 void AICState::sendUnitsToKeep(int tribeID, int playerID) { - int keepID = DAT_GameState::instance.playerDataArray[playerID].keep.id; + int const keepID = DAT_GameState::instance.playerDataArray[playerID].keep.id; if (keepID <= 0) { return; } diff --git a/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp index be3532ffbc..81b5bf96e6 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp @@ -20,15 +20,15 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CE5F0 void AICState::sendUnitsToPlayerIDsKeepIfPossible(int playerID1, int playerID2) { - uint campfireX = DAT_GameState::instance.playerDataArray[playerID1].campground.xEntry; - uint campfireY = DAT_GameState::instance.playerDataArray[playerID1].campground.yEntry; + uint const campfireX = DAT_GameState::instance.playerDataArray[playerID1].campground.xEntry; + uint const campfireY = DAT_GameState::instance.playerDataArray[playerID1].campground.yEntry; uint gatehouseX; uint gatehouseY; if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::canNavigateFromKeepToKeep, DAT_GameState::ptr)( playerID1, playerID2) == FALSE) { - uint gatehouseTile = MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findOwnedGatehouse, + uint const gatehouseTile = MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findOwnedGatehouse, DAT_PathFindingState::ptr)(playerID2, campfireX, campfireY); if (gatehouseTile != 0) { gatehouseY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[gatehouseTile]; @@ -41,10 +41,10 @@ namespace AI { } for (int i = 0; i < 11; i++) { - int tribeTypeStart = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; - int tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; + int const tribeTypeStart = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeType; + int const tribeCount = DAT_SkirmishDefinedData::instance.MaxAttackTribes1[i].tribeCount; for (int j = 0; j < tribeCount; j++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID1].aiTribeIDs[tribeTypeStart + j]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID1].aiTribeIDs[tribeTypeStart + j]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp index 5bedb45135..8e9c2562f7 100644 --- a/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp +++ b/src/OpenSHC/AI/AICState/setAttackCoordinationLevel.cpp @@ -21,7 +21,7 @@ namespace AI { if (90 < willingnessPercentage) { willingnessPercentage = 90; } - int rngMod100 = SEC_RNG::instance.currentNumber2 % 100; + int const rngMod100 = SEC_RNG::instance.currentNumber2 % 100; MACRO_CALL_MEMBER(Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); if (rngMod100 < willingnessPercentage / 2) { DAT_GameState::instance.playerDataArray[playerID].aiAttackCoordinationLevel = 2; diff --git a/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp index 71cc3c5850..545fa5f44b 100644 --- a/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp +++ b/src/OpenSHC/AI/AICState/setAttackPrimeInfo.cpp @@ -11,7 +11,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CDFD0 void AICState::setAttackPrimeInfo(int playerID, int attackedPlayerID) { - int tile = DAT_GameState::instance.playerDataArray[playerID].shortestDistanceTile; + int const tile = DAT_GameState::instance.playerDataArray[playerID].shortestDistanceTile; DAT_TroopValueState::instance.attackInfo.startZone = (char)DAT_TileMapState::instance.AIZoneLayer[tile]; DAT_TroopValueState::instance.attackInfo.startCon = (short)DAT_TileMapState::instance.PathConnectionLayer[tile]; DAT_TroopValueState::instance.attackInfo.zoneSize diff --git a/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp index c55ebcb180..d73ebde3b5 100644 --- a/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp +++ b/src/OpenSHC/AI/AICState/setCurrentAttackStrength.cpp @@ -14,8 +14,8 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == AITA_NULL) return; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; - int randomPercent = SEC_RNG::instance.currentNumber2 % 100; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const randomPercent = SEC_RNG::instance.currentNumber2 % 100; MACRO_CALL_MEMBER(Random::RNG_Func::nextRandomNumber2, SEC_RNG::ptr)(); DAT_GameState::instance.playerDataArray[playerID].currentWaveRandomAttackingStrength diff --git a/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp index 16effb1af2..b35e4d414b 100644 --- a/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setEightTribe0xc0TribesToAggressiveAndAttack.cpp @@ -19,7 +19,7 @@ namespace AI { } for (int i = 0; i < 8; i++) { - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[i + 0xc0]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[i + 0xc0]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp index e6c337edd5..80c64fcce0 100644 --- a/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp +++ b/src/OpenSHC/AI/AICState/setNextFarmTypeToBuild.cpp @@ -10,10 +10,10 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CB1B0 int AICState::setNextFarmTypeToBuild(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == AITA_NULL) return 0; - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex++; if (DAT_GameState::instance.playerDataArray[playerID].aiFarmIndex >= 8) diff --git a/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp b/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp index 56eda53175..18a10f4d94 100644 --- a/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp +++ b/src/OpenSHC/AI/AICState/setNextMoveLocationForUnits.cpp @@ -16,7 +16,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CE3B0 void AICState::setNextMoveLocationForUnits(int playerID) { - int organismID + int const organismID = (short)DAT_TileMapState::instance.OrganismLayer [DAT_ViewportRenderState::instance .translationMatrix[DAT_GameState::instance.playerDataArray[playerID].shortestDistanceY] diff --git a/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp b/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp index f9d369e1e6..10ebf610c3 100644 --- a/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp +++ b/src/OpenSHC/AI/AICState/setTargetForTribeBasedOnTargetChoiceLogic.cpp @@ -21,14 +21,14 @@ namespace AI { return; } - int aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[owner].aiType - 1; int targetPlayer = 0; int minDistance = 10000; int maxGold = 0; int minPoints = 1000000; - int ownerKeepX = DAT_GameState::instance.playerDataArray[owner].campground.xEntry; - int ownerKeepY = DAT_GameState::instance.playerDataArray[owner].campground.yEntry; + int const ownerKeepX = DAT_GameState::instance.playerDataArray[owner].campground.xEntry; + int const ownerKeepY = DAT_GameState::instance.playerDataArray[owner].campground.yEntry; for (int player = 1; player < 9; player++) { if (DAT_GameState::instance.mapAndTime.playerTeams[player] == DAT_GameState::instance.mapAndTime.playerTeams[owner]) { @@ -62,7 +62,7 @@ namespace AI { targetPlayer = player; } } else if (this->aics[aicIndex].TargetChoice == AIC::AITC_BALANCED) { - int points = DAT_GameState::instance.playerDataArray[player].currentPopulation * 5 + int const points = DAT_GameState::instance.playerDataArray[player].currentPopulation * 5 + DAT_GameState::instance.playerDataArray[player].totalTroopValue + DAT_GameState::instance.playerDataArray[player].currentResources[Game::Resources::RT_GOLD] / 100 + DAT_DirectionAlgorithmState::instance.distanceHigh * 2; diff --git a/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp index 18200218e4..b3375206b7 100644 --- a/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0x11ToAggressiveAndAttackIfConditionMet.cpp @@ -23,7 +23,7 @@ namespace AI { return; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) { return; } diff --git a/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp index d0e022dc7a..fe31982dbb 100644 --- a/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0xCtoAggressiveAndAttack.cpp @@ -19,7 +19,7 @@ namespace AI { return; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) { return; } diff --git a/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp index 9c0ae6175e..ee402e6ece 100644 --- a/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp +++ b/src/OpenSHC/AI/AICState/setTribe0xbToAggressiveAndAttack.cpp @@ -19,7 +19,7 @@ namespace AI { return; } - int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; + int const tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[tribeIndex]; if (tribeID == 0) { return; } diff --git a/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp b/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp index 94036fdeca..04905465e9 100644 --- a/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp +++ b/src/OpenSHC/AI/AICState/setupWorkshopProductionType.cpp @@ -21,7 +21,7 @@ namespace AI { return; } - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == Map::Buildings::BT_BLACKSMITH) { int setting = this->aics[aicIndex].blacksmithSetting; if (setting == -999) { diff --git a/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp index b5816876a3..dd8fa82256 100644 --- a/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp +++ b/src/OpenSHC/AI/AICState/shareGoldAmongTeamMembers.cpp @@ -38,13 +38,13 @@ namespace AI { return; } - int goldPerPlayer = gold / candidateCount; + int const goldPerPlayer = gold / candidateCount; if (goldPerPlayer == 0) { return; } for (int j = 0; j < candidateCount; j++) { - int targetPlayer = candidates[j]; + int const targetPlayer = candidates[j]; if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[targetPlayer] != -1) { // "Goods received from ally" strcpy(DAT_GameSynchronyState::instance.receivedChatMessage, diff --git a/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp index ba348e523d..ad660c7369 100644 --- a/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp +++ b/src/OpenSHC/AI/AICState/unitIDIsRangedOrArmored.cpp @@ -13,7 +13,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CC8D0 BOOLEnum AICState::unitIDIsRangedOrArmored(int unitID) { - int unitType = DAT_UnitsState::instance.units[unitID].unitType; + int const unitType = DAT_UnitsState::instance.units[unitID].unitType; for (int i = 0; i < 7; i++) { if (DAT_SkirmishDefinedData::instance.RangedAndArmoredUnits[i] == unitType) { diff --git a/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp index 1d5d82924a..87177170bb 100644 --- a/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp +++ b/src/OpenSHC/AI/AICState/updateAIBehaviour.cpp @@ -27,7 +27,7 @@ namespace AI { continue; if (DAT_GameState::instance.playerDataArray[playerID].lordKilledByPlayerID != 0) continue; - int aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + int const aicIndex = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; if (DAT_GameState::instance.mapAndTime.dayTicks == playerID) { if (DAT_GameState::instance.mapAndTime.skirmishNoRushTicks == 0) { diff --git a/src/OpenSHC/AI/AICState/updateTribeLocations.cpp b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp index 4364f547c3..cbb774fb40 100644 --- a/src/OpenSHC/AI/AICState/updateTribeLocations.cpp +++ b/src/OpenSHC/AI/AICState/updateTribeLocations.cpp @@ -15,7 +15,7 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004D4940 void AICState::updateTribeLocations(int playerID) { - AITypeInt aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + AITypeInt const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) { return; diff --git a/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp index 1b78abcc77..7532eefcf0 100644 --- a/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp +++ b/src/OpenSHC/AI/AICState/useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers.cpp @@ -27,11 +27,11 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CEFD0 void AICState::useAITribe_0x12_toPlaceSiegeTentsAndAssignEngineers(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType == OpenSHC::AI::AIT_NULL) return; - int aicIndex = aiType - 1; - int aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; + int const aicIndex = aiType - 1; + int const aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0x12]; if (aiTribeID == 0) return; if (DAT_TribesState::instance.tribes[aiTribeID].uid @@ -82,7 +82,7 @@ namespace AI { return; availableEngineers -= requiredEngineers; - int tribeID = MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addEngineersToSelection, this)( + int const tribeID = MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::addEngineersToSelection, this)( playerID, requiredEngineers); if (tribeID == 0) return; diff --git a/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp index 90dccdc640..7cdba06e58 100644 --- a/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp +++ b/src/OpenSHC/AI/AICState/useAITribe_0xe_toPlaceTunnels.cpp @@ -26,7 +26,7 @@ namespace AI { { if (DAT_GameState::instance.playerDataArray[playerID].aiType == OpenSHC::AI::AIT_NULL) return; - int aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0xe]; + int const aiTribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[0xe]; if (aiTribeID == 0) return; if (DAT_TribesState::instance.tribes[aiTribeID].uid @@ -38,12 +38,12 @@ namespace AI { if (countdown <= 0) break; - int unitID = MACRO_CALL_MEMBER( + int const unitID = MACRO_CALL_MEMBER( OpenSHC::Map::Units::TribesState_Func::popUnitFromTribe, DAT_TribesState::ptr)(aiTribeID); // Yes this line has to be right here for the code to match. countdown--; - int tribeID = MACRO_CALL_MEMBER( + int const tribeID = MACRO_CALL_MEMBER( OpenSHC::Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID); DAT_TribesState::instance.tribes[tribeID].attackWave diff --git a/src/OpenSHC/AI/AICState/yieldCowThrow.cpp b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp index 8c7c35fded..5129c6cc1d 100644 --- a/src/OpenSHC/AI/AICState/yieldCowThrow.cpp +++ b/src/OpenSHC/AI/AICState/yieldCowThrow.cpp @@ -10,9 +10,9 @@ namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004CFF60 BOOLEnum AICState::yieldCowThrow(int playerID) { - int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType; if (aiType != AITA_NULL) { - int aicIndex = aiType - 1; + int const aicIndex = aiType - 1; if (DAT_GameState::instance.mapAndTime.skirmishNoCowThrowing == 0 && this->aics[aicIndex].CowThrowInterval != 0 && DAT_GameState::instance.playerDataArray[playerID].counter > 0) { From dd9cb473583aa273746e17cfb1b00044662446f3 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 15:42:27 +0200 Subject: [PATCH 09/10] clang-formatting --- src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp | 4 ++-- src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp | 3 ++- .../AI/AICState/recomputeAIPathCostToAttackedKeep.cpp | 5 +++-- ...tainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp | 2 +- .../sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp | 2 +- src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp | 3 ++- .../AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp | 5 +++-- src/OpenSHC/AI/AICState/someChatMessageSelection.cpp | 2 +- 8 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp index 15437a60ac..6c231cc6f8 100644 --- a/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp +++ b/src/OpenSHC/AI/AICState/aiRequiresExtraOxtethers.cpp @@ -31,8 +31,8 @@ namespace AI { DAT_BuildingsState::ptr)(playerID, OpenSHC::Map::Buildings::BT_QUARRY, quarryID)) { // The (short) is load-bearing: quarryStockpileID is undefined2, and the original sign-extends it. int const stone = DAT_BuildingsState::instance - .buildings[(short)DAT_BuildingsState::instance.buildings[quarryID].quarryStockpileID] - .resources[Game::Resources::RT_STONE]; + .buildings[(short)DAT_BuildingsState::instance.buildings[quarryID].quarryStockpileID] + .resources[Game::Resources::RT_STONE]; int tetherCount = 0; for (int i = 0; i < 3; i++) { int const tetherID = DAT_BuildingsState::instance.buildings[quarryID].quarryLinkedOxTethers[i]; diff --git a/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp index 399141ccd6..2761ea9257 100644 --- a/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp +++ b/src/OpenSHC/AI/AICState/generateSiegeCreationInformation.cpp @@ -30,7 +30,8 @@ namespace AI { return; int const slot = DAT_SkirmishDefinedData::instance.SiegeEngineMetaInfoArray[siegeIndex].slot; - int const locationCount = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[slot]; + int const locationCount + = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[slot]; while (i < locationCount) { int const index = i; i++; diff --git a/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp index 698893f57c..55d4930283 100644 --- a/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp +++ b/src/OpenSHC/AI/AICState/recomputeAIPathCostToAttackedKeep.cpp @@ -20,8 +20,9 @@ namespace AI { void AICState::recomputeAIPathCostToAttackedKeep(int playerID, int useBorderDistance) { int const attackedPlayerID = DAT_GameState::instance.playerDataArray[playerID].attackedPlayerID; - int const keepArea = (short)DAT_TileMapState::instance - .PathConnectionLayer[DAT_GameState::instance.playerDataArray[playerID].campground.tileEntry]; + int const keepArea + = (short)DAT_TileMapState::instance + .PathConnectionLayer[DAT_GameState::instance.playerDataArray[playerID].campground.tileEntry]; int borderDistance; if (DAT_GameState::instance.playerDataArray[attackedPlayerID].unknownPathBorderDistanceRelated > 120) { diff --git a/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp index b8400dfc42..2ee9c8a9ed 100644 --- a/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp +++ b/src/OpenSHC/AI/AICState/sendCertainUnitTribesToAIVSlotsOrKeepIfNervousAndNotEnclosed.cpp @@ -28,7 +28,7 @@ namespace AI { for (int i = 0; i < 6; i++) { int const count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount - [DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].aivUnitType]; + [DAT_SkirmishDefinedData::instance.MaxAIVLocationForGroundUnits[i].aivUnitType]; for (int j = 0; j < count; j++) { int const tribeID = DAT_GameState::instance.playerDataArray[playerID] diff --git a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp index 99836d1b1e..e22092e3e9 100644 --- a/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp +++ b/src/OpenSHC/AI/AICState/sendRangedUnitTribesToAIVSlotsOrKeepIfNervous.cpp @@ -25,7 +25,7 @@ namespace AI { { for (int i = 0; i < 5; i++) { int const count = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount - [DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].aivUnitType]; + [DAT_SkirmishDefinedData::instance.MaxAIVLocationForRangedUnits[i].aivUnitType]; for (int j = 0; j < count; j++) { int const tribeID = DAT_GameState::instance.playerDataArray[playerID] diff --git a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp index 7b7799363d..51d390bf36 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToAttackBreachedCastle.cpp @@ -44,7 +44,8 @@ namespace AI { } for (int j = 0; j < tribeCount; j++) { - int const tribeID = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeIDs[tribeType + j]; + int const tribeID + = DAT_GameState::instance.playerDataArray[attackingPlayerIndex].aiTribeIDs[tribeType + j]; if (tribeID == 0) { continue; } diff --git a/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp index 81b5bf96e6..06dc5d2070 100644 --- a/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp +++ b/src/OpenSHC/AI/AICState/sendUnitsToPlayerIDsKeepIfPossible.cpp @@ -28,8 +28,9 @@ namespace AI { if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::canNavigateFromKeepToKeep, DAT_GameState::ptr)( playerID1, playerID2) == FALSE) { - uint const gatehouseTile = MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findOwnedGatehouse, - DAT_PathFindingState::ptr)(playerID2, campfireX, campfireY); + uint const gatehouseTile + = MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::findOwnedGatehouse, + DAT_PathFindingState::ptr)(playerID2, campfireX, campfireY); if (gatehouseTile != 0) { gatehouseY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[gatehouseTile]; gatehouseX diff --git a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp index 2045651c56..efcd33cacd 100644 --- a/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp +++ b/src/OpenSHC/AI/AICState/someChatMessageSelection.cpp @@ -54,7 +54,7 @@ namespace AI { if (DAT_GameSynchronyState::instance.currentAIArray[playerID + offset] != 0 && DAT_GameState::instance.mapAndTime.playerTeams[playerID + offset] != DAT_GameState::instance.mapAndTime - .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID]) { candidates[candidateCount] = playerID + offset; candidateCount++; } From 21ede332f1dd8619d89632379a5b83aa9385fc2d Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 16:53:18 +0200 Subject: [PATCH 10/10] status: limit address-status changes to this branch's functions Restore status/addresses-SHC-3BB0A8C1.txt from origin/main and re-apply only the entries for addresses carrying a FUNCTION marker in the .cpp files added or changed on this branch (120 entries). Drops the unrelated 0x004CC000 percentage change for buyGoods.cpp, which this branch does not touch. Co-Authored-By: Claude Opus 5 (1M context) --- status/addresses-SHC-3BB0A8C1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 612480157f..ef3cb11e6e 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -34859,7 +34859,7 @@ SHC_3BB0A8C1_0x004CBE30 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CBFA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004CC000 | 92.9% | Reimplemented +SHC_3BB0A8C1_0x004CC000 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004CC070 | 100.0% | Reimplemented