From a830a0fbfb41e6662282a9bc2235dde62f50644e Mon Sep 17 00:00:00 2001 From: Gynt Date: Wed, 14 Oct 2026 14:01:47 +0200 Subject: [PATCH 01/15] reimplement: AIVState methods that are less than 100% --- .../AI/AIVState/aiDecideOnNewBuildings.cpp | 115 +++ src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp | 54 ++ .../AI/AIVState/aiPlaceWoodcuttershut.cpp | 43 + src/OpenSHC/AI/AIVState/applyAIV.cpp | 186 ++++ .../AIVState/computeLargestSeparateArea.cpp | 36 + .../AI/AIVState/executeDefaultCastleAIV.cpp | 643 +++++++++++++ ...findAppropriateGridLocationForBuilding.cpp | 91 ++ .../hostChecksLobbyAIVAvailability.cpp | 123 +++ src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp | 186 ++++ src/OpenSHC/AI/AIVState/rotateAIV.cpp | 46 + ...dingsStateAndUpdateAIBuildingDecisions.cpp | 105 ++ status/addresses-SHC-3BB0A8C1.txt | 898 +++++++++--------- 12 files changed, 2085 insertions(+), 441 deletions(-) create mode 100644 src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp create mode 100644 src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp create mode 100644 src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp create mode 100644 src/OpenSHC/AI/AIVState/applyAIV.cpp create mode 100644 src/OpenSHC/AI/AIVState/computeLargestSeparateArea.cpp create mode 100644 src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp create mode 100644 src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp create mode 100644 src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp create mode 100644 src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp create mode 100644 src/OpenSHC/AI/AIVState/rotateAIV.cpp create mode 100644 src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp diff --git a/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp b/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp new file mode 100644 index 000000000..a0c2c6e69 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp @@ -0,0 +1,115 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/AI/AICState.func.hpp" + +#include "OpenSHC/Globals/DAT_AICState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004F15C0 + void AIVState::aiDecideOnNewBuildings(PlayerID playerID) + { + int const aivID = DAT_GameState::instance.playerDataArray[playerID].aivID; + + if (aivID <= 0) { + return; + } + + int isPausing = 0; + int stepIncrement = 1; + + if (DAT_GameState::instance.playerDataArray[playerID].resourceRebuildDelay != 0) { + ++DAT_GameState::instance.playerDataArray[playerID].resourceRebuildDelay; + if (DAT_GameState::instance.playerDataArray[playerID].resourceRebuildDelay + < MACRO_CALL_MEMBER(AICState_Func::getResourceRebuildDelay, DAT_AICState::ptr)(playerID)) { + return; + } + DAT_GameState::instance.playerDataArray[playerID].resourceRebuildDelay = 0; + } + + if (DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] > 16000) { + // rich + stepIncrement = 2; + } else if (DAT_GameState::instance.playerDataArray[playerID].currentResources[Game::Resources::RT_GOLD] + > 5000) { + stepIncrement = 1; + } else { + // poor + ++this->aivs[aivID].aivPoorCounter; + if (this->aivs[aivID].aivPoorCounter < this->aivs[aivID].aivPoorLimit_OR_AIC_buildInterval) { + return; + } + } + this->aivs[aivID].aivPoorCounter = 0; + + ++DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator; + if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator >= 5) { + DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator = 0; + } + if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator == 0) { + if (!MACRO_CALL_MEMBER(AICState_Func::shouldDestroyWoodCutterUnk, DAT_AICState::ptr)(playerID) + && MACRO_CALL_MEMBER(AICState_Func::aiShouldBuildWoodcutter, DAT_AICState::ptr)(playerID)) { + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceWoodcuttershut, this)(playerID); + } + } else if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator == 1) { + if (MACRO_CALL_MEMBER(AICState_Func::aiShouldBuildFarm, DAT_AICState::ptr)(playerID) + && MACRO_CALL_MEMBER(AIVState_Func::aiPlaceFarm, this)(playerID, + (MappersEnum)MACRO_CALL_MEMBER(AICState_Func::aiFarmChoice, DAT_AICState::ptr)(playerID))) { + MACRO_CALL_MEMBER(AICState_Func::setNextFarmTypeToBuild, DAT_AICState::ptr)(playerID); + } + } else if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator == 2) { + if (MACRO_CALL_MEMBER(AICState_Func::aiShouldBuildQuarry, DAT_AICState::ptr)(playerID)) { + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceQuarryAndOxtether, this)(playerID); + } + if (MACRO_CALL_MEMBER(AICState_Func::aiRequiresExtraOxtethers, DAT_AICState::ptr)(playerID)) { + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceAdditionalOxtether, this)(playerID); + } + } else if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator == 3) { + if (MACRO_CALL_MEMBER(AICState_Func::aiShouldBuildIronMine, DAT_AICState::ptr)(playerID)) { + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceIronMine, this)(playerID); + } + } else if (DAT_GameState::instance.playerDataArray[playerID].aiResourceBuildingFocusIndicator == 4) { + if (MACRO_CALL_MEMBER(AICState_Func::aiShouldBuildPitchrig, DAT_AICState::ptr)(playerID)) { + MACRO_CALL_MEMBER(AIVState_Func::aiPlacePitchrig, this)(playerID); + } + } + + if (DAT_GameState::instance.playerDataArray[playerID].aivCurrentPause != 0) { + if (stepIncrement > 1) { + DAT_GameState::instance.playerDataArray[playerID].aivCurrentPause = 0; + } else { + --DAT_GameState::instance.playerDataArray[playerID].aivCurrentPause; + } + isPausing = 1; + } else { + int const pauseStep + = DAT_GameState::instance.playerDataArray[playerID] + .aivPauses[DAT_GameState::instance.playerDataArray[playerID].aivCurrentPauseIndex]; + if (pauseStep > 0 && this->aivs[aivID].currentStepGoal >= pauseStep) { + DAT_GameState::instance.playerDataArray[playerID].aivCurrentPause + = DAT_GameState::instance.playerDataArray[playerID].aivPauseDelay; + ++DAT_GameState::instance.playerDataArray[playerID].aivCurrentPauseIndex; + return; + } + // the step goal can advance by 2 when the player is rich + this->aivs[aivID].currentStepGoal += stepIncrement; + } + + if (this->aivs[aivID].aivSubType == 0) { + MACRO_CALL_MEMBER(AIVState_Func::executeDefaultCastleAIV, this)(playerID, isPausing); + } else if (!MACRO_CALL_MEMBER(AICState_Func::destroyHouse, DAT_AICState::ptr)(playerID)) { + for (int step = 1; step <= this->aivs[aivID].totalSteps && step <= this->aivs[aivID].currentStepGoal; + ++step) { + if (MACRO_CALL_MEMBER(AIVState_Func::aiPlaceAIVBuilding, this)(playerID, step, isPausing)) { + break; + } + } + } + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceFlag, this)(playerID); + MACRO_CALL_MEMBER(AIVState_Func::aiPlaceBrazier, this)(playerID); + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp b/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp new file mode 100644 index 000000000..1dc63dacd --- /dev/null +++ b/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp @@ -0,0 +1,54 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/Map/Entities/EntityState.func.hpp" +#include "OpenSHC/Map/TileMapState.func.hpp" +#include "OpenSHC/AI/AIVUnitType.hpp" + +#include "OpenSHC/Globals/DAT_AICState.hpp" +#include "OpenSHC/Globals/DAT_EntityState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004ED240 + void AIVState::aiPlaceFlag(PlayerID playerID) + { + Map::Entities::EntityType const flagType + = (Map::Entities::EntityType)DAT_AICState::instance + .aics[DAT_GameState::instance.playerDataArray[playerID].aiType - 1] + .flagType; + if (DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[AIVUT_FLAG] <= 0) { + return; + } + for (int i = 0; i < 10; ++i) { + int const tile = DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[AIVUT_FLAG][i]; + if (tile <= 0) { + continue; + } + int const entityID = DAT_TileMapState::instance.EntityLayer[tile]; + if (entityID != 0 && DAT_EntityState::instance.entityArray[entityID].entityType == flagType) { + continue; + } + int const height + = MACRO_CALL_MEMBER(Map::TileMapState_Func::getTotalHeightAt, DAT_TileMapState::ptr)(tile, playerID); + if (height <= 0) { + continue; + } + MACRO_CALL_MEMBER(Map::Entities::EntityState_Func::spawnProjectileEntity, DAT_EntityState::ptr)(0, playerID, + playerID, + (tile + - DAT_ViewportRenderState::instance + .translationMatrix[DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]] + .addXgetTile) + * 8 + + 4, + DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile] * 8 + 4, height, 0, 0, 0, + flagType, 0); + } + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp b/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp new file mode 100644 index 000000000..b115a429c --- /dev/null +++ b/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp @@ -0,0 +1,43 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/Map/TileMapState.func.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004EFAB0 + void AIVState::aiPlaceWoodcuttershut(int playerID) + { + if (!MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkRequiredResourcesForBuildingOrPlanToBuy, + DAT_GameState::ptr)(Commands::M_MAPPER_WOODSMAN, playerID, FALSE) + || DAT_BuildingsState::instance.unknownCountdown01 < 20) { + return; + } + MACRO_CALL_MEMBER(AIVState_Func::findAppropriateWoodCutterGridLocation, this)(playerID); + if (this->buildingApproriateGridXPosition == -1) { + return; + } + this->heatMaps[this->buildingApproriateGridXPosition][this->buildingAppropriateGridYPosition] + .woodRelatedCountdownTo0 = 4; + // search around the result of the woodcutter search + MACRO_CALL_MEMBER(AIVState_Func::findSuitableGridLocationFittingCriteria, this)( + this->buildingApproriateGridXPosition, this->buildingAppropriateGridYPosition); + if (this->buildingApproriateGridXPosition == -1) { + return; + } + ++this->heatMaps[this->buildingApproriateGridXPosition][this->buildingAppropriateGridYPosition].structureCount; + MACRO_CALL_MEMBER(Map::TileMapState_Func::placeBuilding, DAT_TileMapState::ptr)(playerID, + this->buildingApproriateGridXPosition * 5, this->buildingAppropriateGridYPosition * 5, + Commands::M_MAPPER_WOODSMAN, + MACRO_CALL_MEMBER(Map::TileMapState_Func::getBuildingSizeForCommandBuildingType, DAT_TileMapState::ptr)( + Commands::M_MAPPER_WOODSMAN), + 15); + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp new file mode 100644 index 000000000..b4e1b2a48 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -0,0 +1,186 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/IO/FilePackager.func.hpp" +#include "OpenSHC/Rendering/ViewportRenderState.func.hpp" +#include "OpenSHC/AI/AIVUnitType.hpp" + +#include "OpenSHC/Globals/DAT_AIVDefinedData.hpp" +#include "OpenSHC/Globals/DAT_AIVState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" +#include "OpenSHC/Globals/FilePackagerObj.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004EF0D0 + void AIVState::applyAIV(int aivID, int playerID) + { + BOOLEnum keepDefined = FALSE; + MACRO_CALL_MEMBER(IO::FilePackager_Func::unpackAIVFile, FilePackagerObj::ptr)( + DAT_AIVDefinedData::instance.AIVSectionAddressArray, + DAT_AIVDefinedData::instance.AIVFileNames[this->aivs[aivID].aiType - 2][this->aivs[aivID].castleID]); + MACRO_CALL_MEMBER(AIVState_Func::rotateAIV, this)(this->aivs[aivID].keepOrientation); + + // single buildings and the keep, steps is accessed as a flat 100 * 100 array + int x; + int y; + int index = 0; + for (y = 0; y < 100; ++y) { + for (x = 0; x < 100; ++x, ++index) { + if (this->isHandled[index]) { + continue; + } + int const type = this->constructions[index]; + if (type == 0) { + this->isHandled[index] = 1; + } else if (type == 2) { + this->isHandled[index] = 1; + } else if (type == AIV::AIVBT_KEEP2) { + if (!keepDefined) { + this->keepX = this->aivs[aivID].keepXOffset + x; + this->keepY = this->aivs[aivID].keepYOffset + y; + keepDefined = TRUE; + } + this->isHandled[index] = 1; + } else { + MappersEnum const mapper = MACRO_CALL_MEMBER( + AIVState_Func::convertAIVBuildingTypeToCommandBuildingType, this)((AIV::AIVBuildingType2)type); + int const step = this->steps[0][index]; + // walls, moats and pitch ditches are collected below + if (mapper == Commands::M_MAPPER_WALL || mapper == Commands::M_MAPPER_WOODWALL + || mapper == Commands::M_MAPPER_CRENAL || mapper == Commands::M_MAPPER_CRENAL2 + || mapper == Commands::M_MAPPER_MOAT || mapper == Commands::M_MAPPER_PITCH_DITCH) { + continue; + } + this->isHandled[index] = 1; + if (this->aivs[aivID].aivBuildingSteps[step].quantity > 0) { + continue; + } + int const realY = this->aivs[aivID].keepYOffset + y; + if (!MACRO_CALL_MEMBER(Rendering::ViewportRenderState_Func::xyAreValid, + DAT_ViewportRenderState::ptr)(this->aivs[aivID].keepXOffset + x, realY)) { + continue; + } + this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; + this->aivs[aivID].aivBuildingSteps[step].quantity = 1; + this->aivs[aivID].aivBuildingSteps[step].location.tile.tile + = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile + + this->aivs[aivID].keepXOffset + x; + if (step > this->aivs[aivID].totalSteps) { + this->aivs[aivID].totalSteps = step; + } + } + } + } + + // collect the tiles of each wall, moat and pitch ditch step, one step per pass + int startY = 0; + BOOLEnum selected; + do { + selected = FALSE; + index = startY * 100; + if (startY >= 100) { + break; + } + int step; + MappersEnum mapper; + for (y = startY; y < 100; ++y) { + for (x = 0; x < 100; ++x, ++index) { + if (this->isHandled[index]) { + continue; + } + if (!selected) { + mapper = MACRO_CALL_MEMBER(AIVState_Func::convertAIVBuildingTypeToCommandBuildingType, this)( + (AIV::AIVBuildingType2)this->constructions[index]); + step = this->steps[0][index]; + this->aivs[aivID].aivBuildingSteps[step].location.tile.tile + = this->aivs[aivID].wallLocationsArrayIndex; + selected = TRUE; + if (y > startY) { + startY = y; + } + } else if (this->steps[0][index] != step) { + continue; + } + uint const realX = this->aivs[aivID].keepXOffset + x; + uint const realY = this->aivs[aivID].keepYOffset + y; + if (realX <= 399 && realY <= 399 + && DAT_ViewportRenderState::instance.DAT_BinaryTileMap400x400[realY * 400 + realX]) { + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; + this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; + ++this->aivs[aivID].aivBuildingSteps[step].quantity; + this->aivs[aivID].locationsArray[this->aivs[aivID].wallLocationsArrayIndex] + = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile + + this->aivs[aivID].keepXOffset + x; + ++this->aivs[aivID].wallLocationsArrayIndex; + if (step > this->aivs[aivID].totalSteps) { + this->aivs[aivID].totalSteps = step; + } + this->isHandled[index] = 1; + } else { + this->isHandled[index] = 1; + } + } + } + } while (selected); + + // rotate the unit locations and copy them to the player + for (int unitType = 0; unitType < 22; ++unitType) { + DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[unitType] = 0; + if (unitType == AIVUT_PIKEMAN || unitType == AIVUT_SWORDSMAN || unitType == AIVUT_ARABIAN_SWORDSMAN) { + continue; + } + for (int i = 0; i < 10; ++i) { + int const location = DAT_AIVState::instance.unitLocations[unitType][i]; + if (location <= 0) { + continue; + } + int const relativeY = location / 100; + int const relativeX = location % 100; + if (this->aivs[aivID].keepOrientation == 0) { + x = relativeX; + y = relativeY; + } else if (this->aivs[aivID].keepOrientation == 4) { + x = 99 - relativeX; + y = 99 - relativeY; + } else if (this->aivs[aivID].keepOrientation == 6) { + x = 99 - relativeY; + y = relativeX; + } else if (this->aivs[aivID].keepOrientation == 2) { + y = 99 - relativeX; + x = relativeY; + } + int const tile + = DAT_ViewportRenderState::instance.translationMatrix[this->aivs[aivID].keepYOffset + y].addXgetTile + + this->aivs[aivID].keepXOffset + x; + DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[unitType][i] = tile; + if (tile > 0) { + ++DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[unitType]; + } + } + } + + for (int i = 0; i < 20; ++i) { + DAT_GameState::instance.playerDataArray[playerID].aivPauses[i] = (short)DAT_AIVState::instance.pauses[i]; + } + DAT_GameState::instance.playerDataArray[playerID].aivCurrentPauseIndex = 1; + if (DAT_AIVState::instance.pauseDelay <= 0) { + DAT_AIVState::instance.pauseDelay = 100; + } + DAT_GameState::instance.playerDataArray[playerID].aivPauseDelay = DAT_AIVState::instance.pauseDelay; + + // steps that can not be built + for (int step = 1; step <= this->aivs[aivID].totalSteps; ++step) { + int const buildingType = this->aivs[aivID].aivBuildingSteps[step].buildingType; + if (buildingType == Commands::M_MAPPER_NULL || buildingType == Commands::M_MAPPER_KEEP3 + || buildingType == Commands::M_MAPPER_POND1 || buildingType == Commands::M_MAPPER_POND2_SMALL + || buildingType == Commands::M_MAPPER_POND3_LARGE1 || buildingType == Commands::M_MAPPER_POND4_LARGE2) { + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_disabled; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/computeLargestSeparateArea.cpp b/src/OpenSHC/AI/AIVState/computeLargestSeparateArea.cpp new file mode 100644 index 000000000..04d2df38a --- /dev/null +++ b/src/OpenSHC/AI/AIVState/computeLargestSeparateArea.cpp @@ -0,0 +1,36 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" + +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004EDD00 + int AIVState::computeLargestSeparateArea() + { + int areaSizes[10000]; + MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + sizeof(areaSizes), 0, areaSizes); + for (int tile = 0; tile < 80400; ++tile) { + int const areaID = (short)DAT_TileMapState::instance.PathConnectionLayer[tile]; + if (areaID > 0) { + ++areaSizes[areaID]; + } + } + + int highestSize = 0; + int largestAreaID = 0; + for (int areaID = 0; areaID < 10000; ++areaID) { + if (areaSizes[areaID] > highestSize) { + highestSize = areaSizes[areaID]; + largestAreaID = areaID; + } + } + return largestAreaID; + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp new file mode 100644 index 000000000..cb4e3aa55 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp @@ -0,0 +1,643 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/AI/AICState.func.hpp" +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/Map/TileMapState.func.hpp" +#include "OpenSHC/AI/AIType.hpp" +#include "OpenSHC/AI/AITypeA.hpp" + +#include "OpenSHC/Globals/DAT_AICState.hpp" +#include "OpenSHC/Globals/DAT_AIVState.hpp" +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TerrainDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + // builds a generic castle for AIs without an AIV, the number of each building depends on the AI character + // FUNCTION: STRONGHOLDCRUSADER 0x004F0060 + BOOLEnum AIVState::executeDefaultCastleAIV(PlayerID playerID, int isPausing) + { + int const aivID = DAT_GameState::instance.playerDataArray[playerID].aivID; + int stockpiles = 0; + int hovels = 0; + int granaries = 1; + int marketplaces = 1; + int armories = 0; + int barracks = 0; + int mercenaryPosts = 0; + int cathedrals = 0; + int chapels = 0; + int inns = 0; + int breweries = 0; + int bakeries = 0; + int mills = 0; + int poleturners = 0; + int fletchers = 0; + int tanners = 0; + int blacksmiths = 0; + int armourers = 0; + int engineersGuilds = 0; + int tunnelersGuilds = 0; + int stables = 0; + int const aiType = DAT_GameState::instance.playerDataArray[playerID].aiType - 1; + if (aiType == AITA_RAT) { + stockpiles = 0; + hovels = 3; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 1; + fletchers = 1; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 0; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_SNAKE) { + stockpiles = 2; + hovels = 4; + armories = 1; + barracks = 1; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 2; + fletchers = 2; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_PIG) { + stockpiles = 2; + hovels = 4; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 2; + tanners = 2; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_WOLF) { + stockpiles = 3; + hovels = 5; + armories = 1; + barracks = 1; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 2; + inns = 2; + breweries = 3; + bakeries = 0; + mills = 0; + poleturners = 2; + fletchers = 2; + tanners = 1; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 1; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_SALADIN) { + stockpiles = 3; + hovels = 8; + armories = 0; + barracks = 0; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 4; + mills = 2; + poleturners = 0; + fletchers = 0; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_CALIPH) { + stockpiles = 2; + hovels = 6; + armories = 0; + barracks = 0; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 2; + breweries = 5; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 0; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_SULTAN) { + stockpiles = 0; + hovels = 3; + armories = 0; + barracks = 0; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 0; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_RICHARD) { + stockpiles = 2; + hovels = 6; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 0; + chapels = 2; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 2; + fletchers = 2; + tanners = 0; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 2; + stables = 0; + tunnelersGuilds = 1; + } else if (aiType == AITA_FREDERICK) { + stockpiles = 3; + hovels = 7; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 1; + chapels = 0; + inns = 2; + breweries = 2; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 2; + tanners = 2; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 2; + stables = 2; + tunnelersGuilds = 0; + } else if (aiType == AITA_PHILIPP) { + stockpiles = 2; + hovels = 5; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 0; + chapels = 2; + inns = 0; + breweries = 0; + bakeries = 0; + mills = 0; + poleturners = 3; + fletchers = 2; + tanners = 0; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 2; + stables = 5; + tunnelersGuilds = 0; + } else if (aiType == AITA_WAZIR) { + stockpiles = 2; + hovels = 6; + armories = 0; + barracks = 0; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 0; + breweries = 0; + bakeries = 3; + mills = 1; + poleturners = 0; + fletchers = 0; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_EMIR) { + stockpiles = 3; + hovels = 7; + armories = 1; + barracks = 1; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 1; + breweries = 2; + bakeries = 2; + mills = 1; + poleturners = 0; + fletchers = 1; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_NIZAR) { + stockpiles = 2; + hovels = 8; + armories = 0; + barracks = 0; + mercenaryPosts = 1; + cathedrals = 0; + chapels = 0; + inns = 1; + breweries = 3; + bakeries = 4; + mills = 1; + poleturners = 0; + fletchers = 0; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_SHERIFF) { + stockpiles = 3; + hovels = 6; + armories = 1; + barracks = 1; + mercenaryPosts = 1; + cathedrals = 1; + chapels = 2; + inns = 2; + breweries = 2; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 2; + tanners = 2; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } else if (aiType == AITA_MARSHAL) { + stockpiles = 2; + hovels = 5; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 0; + chapels = 0; + inns = 2; + breweries = 3; + bakeries = 0; + mills = 0; + poleturners = 0; + fletchers = 2; + tanners = 0; + blacksmiths = 2; + engineersGuilds = 1; + armourers = 2; + stables = 4; + tunnelersGuilds = 0; + } else if (aiType == AITA_ABBOT) { + stockpiles = 2; + hovels = 6; + armories = 1; + barracks = 1; + mercenaryPosts = 0; + cathedrals = 1; + chapels = 5; + inns = 3; + breweries = 6; + bakeries = 4; + mills = 2; + poleturners = 0; + fletchers = 3; + tanners = 0; + blacksmiths = 0; + engineersGuilds = 1; + armourers = 0; + stables = 0; + tunnelersGuilds = 0; + } + + for (int step = 0; step < 50; ++step) { + if (step > this->aivs[aivID].currentStepGoal) { + return FALSE; + } + if (this->aivs[aivID].aivBuildingSteps[step].buildStatus == AIVBSS_disabled) { + // use the step for the next building that is still missing + if (stockpiles > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_STORES; + } else if (hovels > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_HOVEL; + } else if (granaries > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_GRANARY; + } else if (marketplaces > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_TRADEPOST; + } else if (barracks > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_BARRACKS_ARAB; + } else if (mercenaryPosts > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_BARRACKS_EURO; + } else if (armories > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_ARMOURY; + } else if (breweries > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_BREWER; + } else if (bakeries > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_BAKER; + } else if (mills > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_MILL; + } else if (poleturners > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_POLETURNER; + } else if (fletchers > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_FLETCHER; + } else if (tanners > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_TANNER; + } else if (blacksmiths > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_BLACKSMITH; + } else if (armourers > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_ARMOURER; + } else if (chapels > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_CHURCH1; + } else if (inns > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_INN; + } else if (engineersGuilds > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_ENGINEERS_GUILD; + } else if (tunnelersGuilds > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_TUNNELERS_GUILD; + } else if (stables > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_STABLES; + } else if (cathedrals > 0) { + this->aivs[aivID].aivBuildingSteps[step].buildingType = Commands::M_MAPPER_CHURCH3; + } else { + continue; + } + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; + } + + AIVBuildingStepStatusByte const status = this->aivs[aivID].aivBuildingSteps[step].buildStatus; + if (status != AIVBSS_disabled) { + if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_HOVEL) { + --hovels; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_STORES) { + --stockpiles; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_GRANARY) { + --granaries; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_TRADEPOST) { + --marketplaces; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_BARRACKS_ARAB) { + --barracks; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_BARRACKS_EURO) { + --mercenaryPosts; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_ARMOURY) { + --armories; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_BREWER) { + --breweries; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_BAKER) { + --bakeries; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_MILL) { + --mills; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_POLETURNER) { + --poleturners; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_FLETCHER) { + --fletchers; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_TANNER) { + --tanners; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_BLACKSMITH) { + --blacksmiths; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_ARMOURER) { + --armourers; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_CHURCH1) { + --chapels; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_INN) { + --inns; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType + == Commands::M_MAPPER_ENGINEERS_GUILD) { + --engineersGuilds; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType + == Commands::M_MAPPER_TUNNELERS_GUILD) { + --tunnelersGuilds; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_STABLES) { + --stables; + } else if (this->aivs[aivID].aivBuildingSteps[step].buildingType == Commands::M_MAPPER_CHURCH3) { + --cathedrals; + } + } + + MappersEnum const mapper = (MappersEnum)this->aivs[aivID].aivBuildingSteps[step].buildingType; + if (isPausing && mapper != Commands::M_MAPPER_HOVEL) { + continue; + } + if (status == AIVBSS_built) { + // only rebuild buildings that were destroyed + int const buildingID = (short)DAT_TileMapState::instance + .BuildingLayer[this->aivs[aivID].aivBuildingSteps[step].location.tile.tile]; + if (buildingID != 0 + && (short)DAT_BuildingsState::instance.buildings[buildingID].buildingType + == MACRO_CALL_MEMBER( + Map::Buildings::BuildingsState_Func::convertCommandBuildingTypeToBuildingType, + DAT_BuildingsState::ptr)(mapper)) { + continue; + } + } + if (DAT_GameState::instance.playerDataArray[playerID].closestEnemyDistanceToTheLord < 120) { + continue; + } + if (!MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkRequiredResourcesForBuildingOrPlanToBuy, + DAT_GameState::ptr)(mapper, playerID, FALSE) + || DAT_BuildingsState::instance.unknownCountdown01 < 20) { + continue; + } + if (mapper == Commands::M_MAPPER_WOODSMAN) { + if (DAT_AIVState::instance.mapExtraInfo.totalWoodAvailable <= 0) { + continue; + } + } else if (mapper == Commands::M_MAPPER_GRANARY + && !DAT_GameState::instance.playerDataArray[playerID].granaryIsAlmostFilledUp) { + continue; + } + if (MACRO_CALL_MEMBER(AICState_Func::shouldNotBeBuildingArmoury, DAT_AICState::ptr)(playerID, mapper) + || MACRO_CALL_MEMBER(AICState_Func::shouldNotBeBuildingHovel, DAT_AICState::ptr)(playerID, mapper) + || MACRO_CALL_MEMBER(AICState_Func::shouldNotBuildMarketArmoryGranaryBarracksMercenarypost, + DAT_AICState::ptr)(playerID, mapper)) { + continue; + } + + int orientation = 15; + if (mapper == Commands::M_MAPPER_BARRACKS_ARAB || mapper == Commands::M_MAPPER_BARRACKS_EURO + || mapper == Commands::M_MAPPER_ENGINEERS_GUILD || mapper == Commands::M_MAPPER_TUNNELERS_GUILD + || mapper == Commands::M_MAPPER_OIL_SMELTER) { + orientation = this->aivs[aivID].keepOrientation; + } else if (mapper == Commands::M_MAPPER_POLETURNER || mapper == Commands::M_MAPPER_BLACKSMITH + || mapper == Commands::M_MAPPER_ARMOURER || mapper == Commands::M_MAPPER_TANNER + || mapper == Commands::M_MAPPER_FLETCHER || mapper == Commands::M_MAPPER_BAKER + || mapper == Commands::M_MAPPER_BREWER) { + orientation = 8; + } + if (MACRO_CALL_MEMBER(AICState_Func::shouldWaitWithBuildingAPositiveFearFactor, DAT_AICState::ptr)( + playerID, mapper) + || MACRO_CALL_MEMBER(AICState_Func::shouldWaitWithBuildingNegativeFearFactor, DAT_AICState::ptr)( + playerID, mapper)) { + continue; + } + if (orientation == 15) { + DAT_TileMapState::instance.DAT_TempBuildingRotation = 0; + } else { + DAT_TileMapState::instance.DAT_TempBuildingRotation = orientation / 2; + } + uint const buildingSize = MACRO_CALL_MEMBER( + Map::TileMapState_Func::getBuildingSizeForCommandBuildingType, DAT_TileMapState::ptr)(mapper); + + uint x; + uint y; + if (mapper == Commands::M_MAPPER_STORES) { + // stockpiles are placed next to each other at the campground + if (stockpiles == 0) { + y = DAT_GameState::instance.playerDataArray[playerID].campground.yEntry - 11; + x = DAT_GameState::instance.playerDataArray[playerID].campground.xEntry + 9; + } else if (stockpiles == 1) { + y = DAT_GameState::instance.playerDataArray[playerID].campground.yEntry - 11; + x = DAT_GameState::instance.playerDataArray[playerID].campground.xEntry + 4; + } else if (stockpiles == 2) { + y = DAT_GameState::instance.playerDataArray[playerID].campground.yEntry - 6; + x = DAT_GameState::instance.playerDataArray[playerID].campground.xEntry + 9; + } + } else { + if (mapper == Commands::M_MAPPER_BARRACKS_ARAB || mapper == Commands::M_MAPPER_BARRACKS_EURO + || mapper == Commands::M_MAPPER_ENGINEERS_GUILD || mapper == Commands::M_MAPPER_TUNNELERS_GUILD + || mapper == Commands::M_MAPPER_CHURCH3) { + MACRO_CALL_MEMBER(AIVState_Func::findAppropriateGridLocationForBuilding, this)( + DAT_GameState::instance.playerDataArray[playerID].campground.xEntry / 5, + DAT_GameState::instance.playerDataArray[playerID].campground.yEntry / 5); + if (this->buildingApproriateGridXPosition == -1) { + continue; + } + } else { + MACRO_CALL_MEMBER(AIVState_Func::findSuitableGridLocationFittingCriteria, this)( + DAT_GameState::instance.playerDataArray[playerID].campground.xEntry / 5, + DAT_GameState::instance.playerDataArray[playerID].campground.yEntry / 5); + if (this->buildingApproriateGridXPosition == -1) { + continue; + } + } + if (this->buildingAppropriateGridYPosition == -1) { + continue; + } + x = this->buildingApproriateGridXPosition * 5; + y = this->buildingAppropriateGridYPosition * 5; + } + + int const tile = DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile + x; + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, x, y, mapper, buildingSize); + // keep orientation is 0, 2, 4 or 6, halving it gives the index of the part offsets + if (mapper == Commands::M_MAPPER_BARRACKS_EURO || mapper == Commands::M_MAPPER_BARRACKS_ARAB) { + // the three fields in front of the barracks + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][0].x + + x, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][0].y + + y, + mapper, buildingSize); + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][1].x + + x, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][1].y + + y, + mapper, buildingSize); + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][2].x + + x, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][2].y + + y, + mapper, buildingSize); + } else if (mapper == Commands::M_MAPPER_ENGINEERS_GUILD || mapper == Commands::M_MAPPER_TUNNELERS_GUILD) { + // the guild field + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][1].x + + x, + DAT_TerrainDefinedData::instance.BuildingPartsOffsets[this->aivs[aivID].keepOrientation / 2][1].y + + y, + mapper, buildingSize); + } else if (mapper == Commands::M_MAPPER_OIL_SMELTER) { + MACRO_CALL_MEMBER(Map::TileMapState_Func::prepareAreaForBuildingPlacement, DAT_TileMapState::ptr)( + playerID, + DAT_TerrainDefinedData::instance.field63_0x19c[this->aivs[aivID].keepOrientation / 2].x + x, + DAT_TerrainDefinedData::instance.field63_0x19c[this->aivs[aivID].keepOrientation / 2].y + y, mapper, + buildingSize); + } + + MACRO_CALL_MEMBER(Map::TileMapState_Func::placeBuilding, DAT_TileMapState::ptr)(playerID, x, y, mapper, + MACRO_CALL_MEMBER(Map::TileMapState_Func::getBuildingSizeForCommandBuildingType, DAT_TileMapState::ptr)( + mapper), + orientation); + int const placedID = DAT_TileMapState::instance.placedBuildingID; + if (!DAT_TileMapState::instance.buildingPlacementFail) { + DAT_BuildingsState::instance.buildings[placedID].field242_0x2c8 = 1; + MACRO_CALL_MEMBER(AICState_Func::setupWorkshopProductionType, DAT_AICState::ptr)(playerID, placedID); + this->aivs[aivID].aivBuildingSteps[step].location.tile.tile = tile; + if (!DAT_TileMapState::instance.buildingPlacementFail) { + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_built; + } + } + this->aivs[aivID].aivBuildingSteps[step].wait + = this->aivs[aivID].aivBuildingSteps[step].buildStatus == AIVBSS_built ? 10 : 16; + if (!DAT_TileMapState::instance.buildingPlacementFail) { + return TRUE; + } + } + return FALSE; + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp b/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp new file mode 100644 index 000000000..21e6ae516 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp @@ -0,0 +1,91 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/Globals/DAT_TerrainDefinedData.hpp" + +namespace OpenSHC { +namespace AI { + + // breadth first search for a grid cell whose eight neighbours are all free + // FUNCTION: STRONGHOLDCRUSADER 0x004EEE10 + void AIVState::findAppropriateGridLocationForBuilding(uint gridX, uint gridY) + { + this->visitCount = 1; + this->algAIndex = 0; + this->algBIndex = 1; + this->heatMapXArray[0] = gridX; + this->heatMapYArray[0] = gridY; + this->buildingApproriateGridXPosition = -1; + this->buildingAppropriateGridYPosition = -1; + if (gridX > 79 || gridY > 79 || this->heatMaps[gridX][gridY].isNotNearEdgeUnk) { + return; + } + ++this->mapExtraInfo.algorithmIterationNumber; + this->heatMaps[gridX][gridY].algorithmIterationNumber = this->mapExtraInfo.algorithmIterationNumber; + this->heatMaps[gridX][gridY].algorithmVisitCountUnk = this->visitCount; + + if (this->algAIndex == this->algBIndex) { + return; + } + uint candidateX; + uint candidateY; + for (;;) { + int freeCount = 0; + int const x = this->heatMapXArray[this->algAIndex]; + int const y = this->heatMapYArray[this->algAIndex]; + if (!this->heatMaps[x][y].tilesNotPartOfLargestAreaCount) { + freeCount = 1; + } + this->visitCount = (char)this->heatMaps[x][y].algorithmVisitCountUnk; + for (int direction = 0; direction < 8; ++direction) { + candidateX + = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[direction].int_.xOffset + x; + candidateY + = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[direction].int_.yOffset + y; + if (this->heatMaps[x][y].isNotNearEdgeUnk && (candidateX > 79 || candidateY > 79)) { + continue; + } + int const notInLargestArea + = (char)this->heatMaps[candidateX][candidateY].tilesNotPartOfLargestAreaCount; + if (!this->heatMaps[candidateX][candidateY].terrainDiffHigherThan12 + && !this->heatMaps[candidateX][candidateY].structureCount + && !this->heatMaps[candidateX][candidateY].isNotNearEdgeUnk + && !this->heatMaps[candidateX][candidateY].destructionBasedPlacementCooldown + && !this->heatMaps[candidateX][candidateY].treeCount + && (char)this->heatMaps[candidateX][candidateY].bouldersCount <= 0 && !notInLargestArea) { + ++freeCount; + } + if (this->heatMaps[candidateX][candidateY].algorithmIterationNumber + == this->mapExtraInfo.algorithmIterationNumber) { + continue; + } + this->heatMaps[candidateX][candidateY].algorithmIterationNumber + = this->mapExtraInfo.algorithmIterationNumber; + if (notInLargestArea >= 15) { + continue; + } + this->heatMaps[candidateX][candidateY].algorithmVisitCountUnk = this->visitCount + 1; + this->heatMapXArray[this->algBIndex] = candidateX; + this->heatMapYArray[this->algBIndex] = candidateY; + ++this->algBIndex; + if ((int)this->algBIndex >= 6400) { + this->algBIndex = 0; + } + } + if (freeCount == 9) { + break; + } + ++this->algAIndex; + if ((int)this->algAIndex >= 6400) { + this->algAIndex = 0; + } + if (this->algAIndex == this->algBIndex) { + return; + } + } + // the result is the last visited neighbour + this->buildingAppropriateGridYPosition = candidateY; + this->buildingApproriateGridXPosition = candidateX; + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp b/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp new file mode 100644 index 000000000..b8deb1d27 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp @@ -0,0 +1,123 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/Synchrony/Actions.func.hpp" +#include "OpenSHC/Synchrony/GameSynchronyState.func.hpp" +#include "OpenSHC/UI/Helpers.func.hpp" +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_WindowAndDirectDraw.hpp" + +namespace OpenSHC { +namespace AI { + + // lists the AIs with an AIV that every player has, and removes other AIs from the lobby + // FUNCTION: STRONGHOLDCRUSADER 0x004ECBC0 + void AIVState::hostChecksLobbyAIVAvailability() + { + if (DAT_GameSynchronyState::instance.currentGameMode != Game::GM_SOLITARY + && DAT_GameSynchronyState::instance.currentGameMode != Game::GM_SKIRMISH_SINGLE_PLAYER) { + if (!DAT_GameSynchronyState::instance.isHost) { + return; + } + int const localPlayer = DAT_GameSynchronyState::instance.currentPlayerSlotID; + DAT_GameCore::instance.numOfAIsWithCastleUnk = 0; + for (int aiIndex = 0; aiIndex < 16; ++aiIndex) { + BOOLEnum available = TRUE; + for (int player = 1; player < 9; ++player) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1) { + continue; + } + if (DAT_GameSynchronyState::instance.DAT_ReceivedAIVFileAvailabilityPerAIArray[player][0] == -1) { + // nothing received yet + if (player != localPlayer) { + continue; + } + if (this->aivFileAvailabilityPerAIArray[aiIndex] == 0) { + available = FALSE; + break; + } + } else if (player == localPlayer) { + if (this->aivFileAvailabilityPerAIArray[aiIndex] == 0) { + available = FALSE; + break; + } + } else if (DAT_GameSynchronyState::instance + .DAT_ReceivedAIVFileAvailabilityPerAIArray[player][aiIndex] + == 0) { + available = FALSE; + break; + } + } + if (available) { + DAT_GameCore::instance.arrayOfLordIdsWithAIVsUnk[DAT_GameCore::instance.numOfAIsWithCastleUnk] + = aiIndex + 1; + ++DAT_GameCore::instance.numOfAIsWithCastleUnk; + } + } + + BOOLEnum removedPlayer = FALSE; + for (int player = 1; player < 9; ++player) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] != -1 + || DAT_GameSynchronyState::instance.currentAIArray[player] == 0) { + continue; + } + BOOLEnum hasAIV = FALSE; + for (int i = 0; i < DAT_GameCore::instance.numOfAIsWithCastleUnk; ++i) { + if (DAT_GameSynchronyState::instance.currentAIArray[player] + == DAT_GameCore::instance.arrayOfLordIdsWithAIVsUnk[i]) { + hasAIV = TRUE; + break; + } + } + if (hasAIV) { + continue; + } + DAT_GameSynchronyState::instance.currentAIArray[player] = 0; + MACRO_CALL(Synchrony::Actions_Func::RemovePositionOfPlayer)(player); + removedPlayer = TRUE; + DAT_GameSynchronyState::instance.DAT_GameCommandParam0 = player; + MACRO_CALL_MEMBER(Synchrony::GameSynchronyState_Func::queueCommand, DAT_GameSynchronyState::ptr)( + Commands::GCT_HOST_REMOVE_PLAYER_BY_SLOT); + } + if (removedPlayer) { + MACRO_CALL_MEMBER( + Synchrony::GameSynchronyState_Func::reorderTeamsAndPositions, DAT_GameSynchronyState::ptr)(); + DAT_GameSynchronyState::instance.reparseMaps = TRUE; + } + + // switch between the small and the extended AI selection + if (DAT_MenuModalComposition1::instance.activeModalDialogID == UI::Enums::MMT_BASIC_AI_LORD_SELECT) { + if (DAT_GameCore::instance.numOfAIsWithCastleUnk > 8) { + MACRO_CALL(UI::Helpers_Func::ClearLobbyHoveredAI)(); + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::setExtraActiveModalDialog, + DAT_MenuModalComposition1::ptr)(UI::Enums::MMT_EXTENDED_AI_LORD_SELECT, + DAT_WindowAndDirectDraw::instance.mainMenuBorderWidth + 4, + DAT_WindowAndDirectDraw::instance.mainMenuBorderHeight + 205); + } + } else if (DAT_MenuModalComposition1::instance.activeModalDialogID == UI::Enums::MMT_EXTENDED_AI_LORD_SELECT + && DAT_GameCore::instance.numOfAIsWithCastleUnk <= 8) { + MACRO_CALL(UI::Helpers_Func::ClearLobbyHoveredAI)(); + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::setExtraActiveModalDialog, + DAT_MenuModalComposition1::ptr)(UI::Enums::MMT_BASIC_AI_LORD_SELECT, + DAT_WindowAndDirectDraw::instance.mainMenuBorderWidth + 4, + DAT_WindowAndDirectDraw::instance.mainMenuBorderHeight + 205); + } + return; + } + + // single player + DAT_GameCore::instance.numOfAIsWithCastleUnk = this->numberOfAIsWithAIV; + int count = 0; + for (int aiIndex = 0; aiIndex < 16; ++aiIndex) { + if (this->aivFileAvailabilityPerAIArray[aiIndex] != 0) { + DAT_GameCore::instance.arrayOfLordIdsWithAIVsUnk[count] = aiIndex + 1; + ++count; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp new file mode 100644 index 000000000..930ebd328 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp @@ -0,0 +1,186 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/Map/LandscapeState.func.hpp" +#include "OpenSHC/Map/LogicHelpers/Logic1.hpp" +#include "OpenSHC/Map/LogicHelpers/Logic2.hpp" + +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_LandscapeState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace AI { + + using namespace Map::LogicHelpers; + + // recomputes the 5x5 tile heat map cells the AI uses to place buildings + // FUNCTION: STRONGHOLDCRUSADER 0x004F0E80 + void AIVState::recomputeHeatmaps(int initialize) + { + if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) { + return; + } + + if (initialize) { + // full reset + MACRO_CALL_MEMBER(AIVState_Func::clearTheHeatmaps, this)(); + for (int y = 0; y < 80; ++y) { + for (int x = 0; x < 80; ++x) { + this->heatMaps[x][y].lowestTerrainHeight = 250; + this->heatMaps[x][y].isNotNearEdgeUnk = 1; + } + } + this->mapExtraInfo.largestSeparateArea + = MACRO_CALL_MEMBER(AIVState_Func::computeLargestSeparateArea, this)(); + } else { + for (int y = 0; y < 80; ++y) { + for (int x = 0; x < 80; ++x) { + this->heatMaps[x][y].treeCount = 0; + this->heatMaps[x][y].impassableCount = 0; + this->heatMaps[x][y].structureCount = 0; + this->heatMaps[x][y].tileOwnership = 0; + if ((char)this->heatMaps[x][y].woodRelatedCountdownTo0 > 0) { + --this->heatMaps[x][y].woodRelatedCountdownTo0; + } + if ((char)this->heatMaps[x][y].destructionBasedPlacementCooldown > 0) { + --this->heatMaps[x][y].destructionBasedPlacementCooldown; + } + } + } + } + + this->mapExtraInfo.totalWoodAvailable = 0; + if (this->mapExtraInfo.largestSeparateArea <= 0) { + return; + } + + if (initialize) { + for (int tile = 0; tile < 80400; ++tile) { + int const gridY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile] / 5; + int const gridX = (tile + - DAT_ViewportRenderState::instance + .translationMatrix[DAT_ViewportRenderState::instance + .tileTranslationMatrix_YComponent[tile]] + .addXgetTile) + / 5; + if (gridX >= 1 && gridX <= 78 && gridY >= 1 && gridY <= 78) { + this->heatMaps[gridX][gridY].isNotNearEdgeUnk = 0; + } + if ((short)DAT_TileMapState::instance.PathConnectionLayer[tile] + != this->mapExtraInfo.largestSeparateArea) { + ++this->heatMaps[gridX][gridY].tilesNotPartOfLargestAreaCount; + } + if (DAT_TileMapState::instance.LogicLayer[tile] + & (L_SEA | L_BORDER | L_BORDER_EDGE | L_RIVER | L_FORD)) { + continue; + } + + int const height = DAT_TileMapState::instance.DefaultHeightLayer[tile]; + if (height < this->heatMaps[gridX][gridY].lowestTerrainHeight) { + this->heatMaps[gridX][gridY].lowestTerrainHeight = (byte)height; + } + if (height > this->heatMaps[gridX][gridY].highestTerrainHeight) { + this->heatMaps[gridX][gridY].highestTerrainHeight = (byte)height; + } + if ((int)this->heatMaps[gridX][gridY].highestTerrainHeight + > (int)this->heatMaps[gridX][gridY].lowestTerrainHeight + 12) { + this->heatMaps[gridX][gridY].terrainDiffHigherThan12 = 1; + } + + int const logic = DAT_TileMapState::instance.LogicLayer[tile]; + if (logic & L_TREE) { + int const treeID = (short)DAT_TileMapState::instance.OrganismLayer[tile]; + // tree types 1 to 4 give wood + if (treeID != 0 + && (DAT_LandscapeState::instance.trees[treeID].treeType == 1 + || DAT_LandscapeState::instance.trees[treeID].treeType == 2 + || DAT_LandscapeState::instance.trees[treeID].treeType == 3 + || DAT_LandscapeState::instance.trees[treeID].treeType == 4) + && DAT_LandscapeState::instance.trees[treeID].stage < 4 + && DAT_LandscapeState::instance.trees[treeID].state == 2 + && MACRO_CALL_MEMBER(Map::LandscapeState_Func::isTreeAdult, DAT_LandscapeState::ptr)( + treeID, DAT_LandscapeState::instance.trees[treeID].uid)) { + this->heatMaps[gridX][gridY].treeCount += 3; + this->mapExtraInfo.totalWoodAvailable += 3; + } + continue; + } + if (logic & L_BOULDERS) { + ++this->heatMaps[gridX][gridY].bouldersCount; + } else if (logic & L_IRON) { + ++this->heatMaps[gridX][gridY].ironCount; + } else if (logic & L_OIL) { + ++this->heatMaps[gridX][gridY].oilCount; + } else if (logic & L_MARSH) { + ++this->heatMaps[gridX][gridY].marshCount; + } else if (logic & (L_BUILDING | L_KEEP_NON_MANOR_HOUSE)) { + ++this->heatMaps[gridX][gridY].structureCount; + } else if (logic & L_WALL_OR_GATEHOUSE) { + ++this->heatMaps[gridX][gridY].structureCount; + } else if (logic & L_ROCKY) { + ++this->heatMaps[gridX][gridY].impassableCount; + } + if (!(DAT_TileMapState::instance.LogicLayer[tile] & L_RIVER)) { + if (DAT_TileMapState::instance.Logic2Layer[tile] & (L2_SCRUB | L2_OASIS_GRASS | L2_THICK_SCRUB)) { + ++this->heatMaps[gridX][gridY].oasisScrubCount; + } + if (DAT_TileMapState::instance.Logic2Layer[tile] & (L2_OASIS_GRASS | L2_THICK_SCRUB)) { + ++this->heatMaps[gridX][gridY].oasisThickScrubCount; + } + } + } + return; + } + + // only update what can change during the game + for (int tile = 0; tile < 80400; ++tile) { + if (!(DAT_TileMapState::instance.LogicLayer[tile] + & (L_ROCKY | L_WALL_OR_GATEHOUSE | L_BUILDING | L_TREE | L_KEEP_NON_MANOR_HOUSE))) { + continue; + } + if (DAT_TileMapState::instance.LogicLayer[tile] & L_ROCKY) { + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const gridX = (tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile) / 5; + ++this->heatMaps[gridX][y / 5].impassableCount; + } + if (DAT_TileMapState::instance.LogicLayer[tile] & L_TREE) { + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const gridX = (tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile) / 5; + int const gridY = y / 5; + int const treeID = (short)DAT_TileMapState::instance.OrganismLayer[tile]; + // tree types 1 to 4 give wood + if (treeID != 0 + && (DAT_LandscapeState::instance.trees[treeID].treeType == 1 + || DAT_LandscapeState::instance.trees[treeID].treeType == 2 + || DAT_LandscapeState::instance.trees[treeID].treeType == 3 + || DAT_LandscapeState::instance.trees[treeID].treeType == 4) + && DAT_LandscapeState::instance.trees[treeID].stage < 4 + && DAT_LandscapeState::instance.trees[treeID].state == 2 + && MACRO_CALL_MEMBER(Map::LandscapeState_Func::isTreeAdult, DAT_LandscapeState::ptr)( + treeID, DAT_LandscapeState::instance.trees[treeID].uid)) { + this->heatMaps[gridX][gridY].treeCount += 3; + this->mapExtraInfo.totalWoodAvailable += 3; + } + } else if (DAT_TileMapState::instance.BuildingLayer[tile] != 0) { + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const gridX = (tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile) / 5; + int const gridY = y / 5; + ++this->heatMaps[gridX][gridY].structureCount; + this->heatMaps[gridX][gridY].tileOwnership + = (byte)DAT_BuildingsState::instance + .buildings[(short)DAT_TileMapState::instance.BuildingLayer[tile]] + .owner; + } else if (DAT_TileMapState::instance.LogicLayer[tile] & L_WALL_OR_GATEHOUSE) { + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const gridX = (tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile) / 5; + int const gridY = y / 5; + ++this->heatMaps[gridX][gridY].structureCount; + this->heatMaps[gridX][gridY].tileOwnership = (DAT_TileMapState::instance.WallOwnerLayer[tile] & 7) + 1; + } + } + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/rotateAIV.cpp b/src/OpenSHC/AI/AIVState/rotateAIV.cpp new file mode 100644 index 000000000..61c3d3256 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/rotateAIV.cpp @@ -0,0 +1,46 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" + +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" + +namespace OpenSHC { +namespace AI { + + // rotates the loaded AIV grid to the keep orientation + // FUNCTION: STRONGHOLDCRUSADER 0x004ED0B0 + void AIVState::rotateAIV(int orientation) + { + if (orientation == 0) { + return; + } + if (orientation == 6) { + for (int y = 0; y < 100; ++y) { + for (int x = 0; x < 100; ++x) { + this->rotatedConstructions[x][99 - y] = this->constructions[y * 100 + x]; + this->rotatedSteps[x][99 - y] = this->steps[y][x]; + } + } + } else if (orientation == 4) { + for (int y = 0; y < 100; ++y) { + for (int x = 0; x < 100; ++x) { + this->rotatedConstructions[99 - y][99 - x] = this->constructions[y * 100 + x]; + this->rotatedSteps[99 - y][99 - x] = this->steps[y][x]; + } + } + } else if (orientation == 2) { + for (int y = 0; y < 100; ++y) { + for (int x = 0; x < 100; ++x) { + this->rotatedConstructions[99 - x][y] = this->constructions[y * 100 + x]; + this->rotatedSteps[99 - x][y] = this->steps[y][x]; + } + } + } + MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::copyData, DAT_LowLevelMemory::ptr)( + sizeof(this->rotatedConstructions), this->rotatedConstructions, this->constructions); + MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::copyData, DAT_LowLevelMemory::ptr)( + sizeof(this->rotatedSteps), this->rotatedSteps, this->steps); + } + +} +} diff --git a/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp new file mode 100644 index 000000000..0c208ec57 --- /dev/null +++ b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp @@ -0,0 +1,105 @@ +#include "../AIVState.func.hpp" + +#include "OpenSHC/AI/AICState.func.hpp" +#include "OpenSHC/Audio/SFX/SFXState.func.hpp" +#include "OpenSHC/Game/GameStateStructures.func.hpp" +#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp" +#include "OpenSHC/Map/Units/UnitsState.func.hpp" +#include "OpenSHC/string-literals.hpp" + +#include "OpenSHC/Globals/DAT_AICState.hpp" +#include "OpenSHC/Globals/DAT_BuildingsState.hpp" +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp" +#include "OpenSHC/Globals/DAT_SFXState.hpp" +#include "OpenSHC/Globals/DAT_UnitsState.hpp" + +namespace OpenSHC { +namespace AI { + + // FUNCTION: STRONGHOLDCRUSADER 0x004F1860 + void AIVState::updateBuildingsStateAndUpdateAIBuildingDecisions() + { + if (DAT_GameSynchronyState::instance.currentGameMode == Game::GM_SOLITARY) { + return; + } + + if (DAT_GameState::instance.mapAndTime.startOfDay) { + this->counter = 0; + ++this->mapExtraInfo.algBuildingPlacementNudge; + if (this->mapExtraInfo.algBuildingPlacementNudge >= 31) { + this->mapExtraInfo.algBuildingPlacementNudge = 0; + } + for (int player = 1; player < 9; ++player) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1 + && DAT_GameSynchronyState::instance.currentAIArray[player] == 0) { + continue; + } + if (MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(player)) { + DAT_GameState::instance.playerDataArray[player].keepEnclosementRelatedCountdown = 5; + continue; + } + // warn the local player when he broke into an enemy castle + if (DAT_GameState::instance.playerDataArray[player].keepEnclosementRelatedCountdown > 0 + && --DAT_GameState::instance.playerDataArray[player].keepEnclosementRelatedCountdown == 0 + && DAT_GameState::instance.playerDataArray[player].defensesDamagedByPlayer + == DAT_GameSynchronyState::instance.currentPlayerSlotID + && DAT_GameState::instance.mapAndTime.playerTeams[player] + != DAT_GameState::instance.mapAndTime + .playerTeams[DAT_GameSynchronyState::instance.currentPlayerSlotID] + && DAT_GameCore::instance.genieVoiceActive) { + // "Once more unto the breach" + MACRO_CALL_MEMBER(Audio::SFX::SFXState_Func::playWAVSFX, DAT_SFXState::ptr)( + s_Genie_35_wav_005ab8b8); + } + } + } + + if (DAT_GameState::instance.mapAndTime.monthChanged) { + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::recomputePlayerDataStocksBasedOnStorageBuildings, + DAT_BuildingsState::ptr)(); + } + MACRO_CALL_MEMBER(AICState_Func::updateAIBehaviour, DAT_AICState::ptr)(); + if (DAT_GameState::instance.mapAndTime.weekChanged) { + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::updatePathLinkageTileMap, DAT_BuildingsState::ptr)( + 2); + for (int player = 1; player < 9; ++player) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1 + && DAT_GameSynchronyState::instance.currentAIArray[player] != 0 + && DAT_GameState::instance.playerDataArray[player].playerDeathRelated == 0 + && DAT_GameState::instance.playerDataArray[player].lordKilledByPlayerID == 0 + && DAT_GameState::instance.playerDataArray[player].someCount31 == 0) { + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::updateHeatmapBasedOnBuildingAccessibility, + DAT_BuildingsState::ptr)(player); + MACRO_CALL_MEMBER(Map::Units::UnitsState_Func::makeUnitsDisappearThatCannotReachTheKeep, + DAT_UnitsState::ptr)(player); + } + } + MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::updatePathLinkageTileMap, DAT_BuildingsState::ptr)( + 0); + } + + // each AI player decides on its own tick of the day + for (int player = 1; player < 9; ++player) { + if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1 + && DAT_GameSynchronyState::instance.currentAIArray[player] != 0 + && DAT_GameState::instance.playerDataArray[player].playerDeathRelated == 0 + && DAT_GameState::instance.playerDataArray[player].lordKilledByPlayerID == 0 + && DAT_GameState::instance.mapAndTime.dayTicks == player) { + MACRO_CALL_MEMBER(AIVState_Func::aiDecideOnNewBuildings, this)(player); + MACRO_CALL_MEMBER(AICState_Func::planToBuyWhenLowOnResourceAndSnoozeBuildings, DAT_AICState::ptr)( + player); + } + } + if (DAT_GameState::instance.mapAndTime.dayTicks == 8) { + MACRO_CALL_MEMBER( + Map::Buildings::BuildingsState_Func::applySnoozedStateBasedOnPlayerData, DAT_BuildingsState::ptr)(); + } + if (DAT_GameState::instance.mapAndTime.monthTicks == 10) { + MACRO_CALL_MEMBER(AIVState_Func::recomputeHeatmaps, this)(0); + } + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index f6e47278b..59be8904c 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -381,15 +381,15 @@ SHC_3BB0A8C1_0x00400260 | 0.0% | Pending SHC_3BB0A8C1_0x00400288 | 0.0% | Pending -SHC_3BB0A8C1_0x00401000 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401000 | 0.0% | Pending -SHC_3BB0A8C1_0x00401040 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401040 | 0.0% | Pending -SHC_3BB0A8C1_0x00401060 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401060 | 0.0% | Pending -SHC_3BB0A8C1_0x00401090 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401090 | 0.0% | Pending -SHC_3BB0A8C1_0x004010B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004010B0 | 0.0% | Pending SHC_3BB0A8C1_0x004010E0 | 0.0% | Pending @@ -415,13 +415,13 @@ SHC_3BB0A8C1_0x004012F0 | 0.0% | Pending SHC_3BB0A8C1_0x00401380 | 0.0% | Pending -SHC_3BB0A8C1_0x00401400 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401400 | 0.0% | Pending -SHC_3BB0A8C1_0x00401430 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401430 | 0.0% | Pending SHC_3BB0A8C1_0x00401460 | 0.0% | Pending -SHC_3BB0A8C1_0x00401540 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401540 | 0.0% | Pending SHC_3BB0A8C1_0x00401570 | 0.0% | Pending @@ -445,11 +445,11 @@ SHC_3BB0A8C1_0x004019D0 | 0.0% | Pending SHC_3BB0A8C1_0x00401A50 | 0.0% | Pending -SHC_3BB0A8C1_0x00401AE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401AE0 | 0.0% | Pending SHC_3BB0A8C1_0x00401B20 | 0.0% | Pending -SHC_3BB0A8C1_0x00401B60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00401B60 | 0.0% | Pending SHC_3BB0A8C1_0x00401BA0 | 0.0% | Pending @@ -503,7 +503,7 @@ SHC_3BB0A8C1_0x00402A18 | 0.0% | Pending SHC_3BB0A8C1_0x00402A20 | 0.0% | Pending -SHC_3BB0A8C1_0x00402AB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00402AB0 | 0.0% | Pending SHC_3BB0A8C1_0x00402AE0 | 0.0% | Pending @@ -531,7 +531,7 @@ SHC_3BB0A8C1_0x004036F0 | 0.0% | Pending SHC_3BB0A8C1_0x00403790 | 0.0% | Pending -SHC_3BB0A8C1_0x004038A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004038A0 | 0.0% | Pending SHC_3BB0A8C1_0x004038B0 | 0.0% | Pending @@ -539,9 +539,9 @@ SHC_3BB0A8C1_0x00403900 | 0.0% | Pending SHC_3BB0A8C1_0x00403980 | 0.0% | Pending -SHC_3BB0A8C1_0x004039B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004039B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004039F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004039F0 | 0.0% | Pending SHC_3BB0A8C1_0x00403A20 | 0.0% | Pending @@ -2347,9 +2347,9 @@ SHC_3BB0A8C1_0x00406900 | 0.0% | Pending SHC_3BB0A8C1_0x00406FD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00407130 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00407130 | 0.0% | Pending -SHC_3BB0A8C1_0x00407160 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00407160 | 0.0% | Pending SHC_3BB0A8C1_0x00407190 | 0.0% | Pending @@ -2597,11 +2597,11 @@ SHC_3BB0A8C1_0x00409200 | 0.0% | Pending SHC_3BB0A8C1_0x004092B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004092C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004092C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004092E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004092E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00409300 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00409300 | 0.0% | Pending SHC_3BB0A8C1_0x00409330 | 0.0% | Pending @@ -5543,15 +5543,15 @@ SHC_3BB0A8C1_0x00417B90 | 0.0% | Pending SHC_3BB0A8C1_0x00417FD0 | 0.0% | Pending -SHC_3BB0A8C1_0x004180E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004180E0 | 0.0% | Pending SHC_3BB0A8C1_0x00418100 | 0.0% | Pending -SHC_3BB0A8C1_0x004184A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004184A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004184D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004184D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00418500 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00418500 | 0.0% | Pending SHC_3BB0A8C1_0x00418530 | 0.0% | Pending @@ -5559,9 +5559,9 @@ SHC_3BB0A8C1_0x00418640 | 0.0% | Pending SHC_3BB0A8C1_0x00418740 | 0.0% | Pending -SHC_3BB0A8C1_0x00418880 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00418880 | 0.0% | Pending -SHC_3BB0A8C1_0x004188C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004188C0 | 0.0% | Pending SHC_3BB0A8C1_0x00418900 | 0.0% | Pending @@ -5575,7 +5575,7 @@ SHC_3BB0A8C1_0x00418C80 | 0.0% | Pending SHC_3BB0A8C1_0x00418EC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00418F70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00418F70 | 0.0% | Pending SHC_3BB0A8C1_0x00418F90 | 0.0% | Pending @@ -5585,7 +5585,7 @@ SHC_3BB0A8C1_0x00419190 | 0.0% | Pending SHC_3BB0A8C1_0x00419290 | 0.0% | Pending -SHC_3BB0A8C1_0x00419340 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00419340 | 0.0% | Pending SHC_3BB0A8C1_0x00419370 | 0.0% | Pending @@ -5817,13 +5817,13 @@ SHC_3BB0A8C1_0x00419EB0 | 0.0% | Pending SHC_3BB0A8C1_0x00419FA0 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A060 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A060 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A0A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A0A0 | 0.0% | Pending SHC_3BB0A8C1_0x0041A0B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A0D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A0D0 | 0.0% | Pending SHC_3BB0A8C1_0x0041A100 | 0.0% | Pending @@ -6043,17 +6043,17 @@ SHC_3BB0A8C1_0x0041A2AE | 0.0% | Pending SHC_3BB0A8C1_0x0041A2AF | 0.0% | Pending -SHC_3BB0A8C1_0x0041A2B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A2B0 | 0.0% | Pending SHC_3BB0A8C1_0x0041A2E0 | 0.0% | Pending SHC_3BB0A8C1_0x0041A340 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A390 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A390 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A3C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A3C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A3F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A3F0 | 0.0% | Pending SHC_3BB0A8C1_0x0041A420 | 0.0% | Pending @@ -6061,17 +6061,17 @@ SHC_3BB0A8C1_0x0041A460 | 0.0% | Pending SHC_3BB0A8C1_0x0041A520 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A5C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A5C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A5F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A5F0 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A620 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A620 | 0.0% | Pending SHC_3BB0A8C1_0x0041A650 | 0.0% | Pending SHC_3BB0A8C1_0x0041A680 | 0.0% | Pending -SHC_3BB0A8C1_0x0041A710 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0041A710 | 0.0% | Pending SHC_3BB0A8C1_0x0041A740 | 100.0% | Reimplemented @@ -6657,13 +6657,13 @@ SHC_3BB0A8C1_0x00424680 | 0.0% | Pending SHC_3BB0A8C1_0x004246B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004246E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004246E0 | 0.0% | Pending SHC_3BB0A8C1_0x00424700 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00424720 | 0.0% | Pending -SHC_3BB0A8C1_0x00424770 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00424770 | 0.0% | Pending SHC_3BB0A8C1_0x004247A0 | 0.0% | Pending @@ -6675,7 +6675,7 @@ SHC_3BB0A8C1_0x00424AD0 | 0.0% | Pending SHC_3BB0A8C1_0x00424B10 | 0.0% | Pending -SHC_3BB0A8C1_0x00424BD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00424BD0 | 0.0% | Pending SHC_3BB0A8C1_0x00424BE0 | 0.0% | Pending @@ -6769,7 +6769,7 @@ SHC_3BB0A8C1_0x00426570 | 0.0% | Pending SHC_3BB0A8C1_0x00426600 | 0.0% | Pending -SHC_3BB0A8C1_0x004266A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004266A0 | 0.0% | Pending SHC_3BB0A8C1_0x004266E0 | 0.0% | Pending @@ -6793,7 +6793,7 @@ SHC_3BB0A8C1_0x00426D30 | 0.0% | Pending SHC_3BB0A8C1_0x00426ED0 | 0.0% | Pending -SHC_3BB0A8C1_0x00426F80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00426F80 | 0.0% | Pending SHC_3BB0A8C1_0x00426FB0 | 0.0% | Pending @@ -6803,9 +6803,9 @@ SHC_3BB0A8C1_0x00427110 | 0.0% | Pending SHC_3BB0A8C1_0x00427180 | 0.0% | Pending -SHC_3BB0A8C1_0x004271E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004271E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00427210 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00427210 | 0.0% | Pending SHC_3BB0A8C1_0x00427240 | 0.0% | Pending @@ -6867,7 +6867,7 @@ SHC_3BB0A8C1_0x00428480 | 0.0% | Pending SHC_3BB0A8C1_0x00428590 | 0.0% | Pending -SHC_3BB0A8C1_0x004285C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004285C0 | 0.0% | Pending SHC_3BB0A8C1_0x004285F0 | 0.0% | Pending @@ -6891,7 +6891,7 @@ SHC_3BB0A8C1_0x00428A60 | 0.0% | Pending SHC_3BB0A8C1_0x00428AC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00429630 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00429630 | 0.0% | Pending SHC_3BB0A8C1_0x00429650 | 0.0% | Pending @@ -6973,9 +6973,9 @@ SHC_3BB0A8C1_0x0042AC34 | 0.0% | Pending SHC_3BB0A8C1_0x0042AC38 | 0.0% | Pending -SHC_3BB0A8C1_0x0042AC40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042AC40 | 0.0% | Pending -SHC_3BB0A8C1_0x0042AC60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042AC60 | 0.0% | Pending SHC_3BB0A8C1_0x0042AC70 | 0.0% | Pending @@ -7443,7 +7443,7 @@ SHC_3BB0A8C1_0x0042B960 | 0.0% | Pending SHC_3BB0A8C1_0x0042BA50 | 0.0% | Pending -SHC_3BB0A8C1_0x0042BB70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042BB70 | 0.0% | Pending SHC_3BB0A8C1_0x0042BB90 | 0.0% | Pending @@ -7453,7 +7453,7 @@ SHC_3BB0A8C1_0x0042BF00 | 0.0% | Pending SHC_3BB0A8C1_0x0042BFC0 | 0.0% | Pending -SHC_3BB0A8C1_0x0042C060 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042C060 | 0.0% | Pending SHC_3BB0A8C1_0x0042C090 | 0.0% | Pending @@ -8719,7 +8719,7 @@ SHC_3BB0A8C1_0x0042EF78 | 0.0% | Pending SHC_3BB0A8C1_0x0042EF80 | 0.0% | Pending -SHC_3BB0A8C1_0x0042EFE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042EFE0 | 0.0% | Pending SHC_3BB0A8C1_0x0042F010 | 0.0% | Pending @@ -8741,7 +8741,7 @@ SHC_3BB0A8C1_0x0042F3BC | 0.0% | Pending SHC_3BB0A8C1_0x0042F3C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0042F3D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042F3D0 | 0.0% | Pending SHC_3BB0A8C1_0x0042F3F0 | 0.0% | Pending @@ -9163,7 +9163,7 @@ SHC_3BB0A8C1_0x0042F940 | 0.0% | Pending SHC_3BB0A8C1_0x0042FA10 | 0.0% | Pending -SHC_3BB0A8C1_0x0042FAA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0042FAA0 | 0.0% | Pending SHC_3BB0A8C1_0x0042FAC0 | 0.0% | Pending @@ -10535,7 +10535,7 @@ SHC_3BB0A8C1_0x00430BF0 | 0.0% | Pending SHC_3BB0A8C1_0x00430CB8 | 0.0% | Pending -SHC_3BB0A8C1_0x00430CC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00430CC0 | 0.0% | Pending SHC_3BB0A8C1_0x00430CE0 | 0.0% | Pending @@ -11083,9 +11083,9 @@ SHC_3BB0A8C1_0x00431B60 | 0.0% | Pending SHC_3BB0A8C1_0x00433030 | 0.0% | Pending -SHC_3BB0A8C1_0x00433200 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00433200 | 0.0% | Pending -SHC_3BB0A8C1_0x00433230 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00433230 | 0.0% | Pending SHC_3BB0A8C1_0x00433260 | 0.0% | Pending @@ -11099,7 +11099,7 @@ SHC_3BB0A8C1_0x00433558 | 0.0% | Pending SHC_3BB0A8C1_0x0043355C | 0.0% | Pending -SHC_3BB0A8C1_0x00433560 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00433560 | 0.0% | Pending SHC_3BB0A8C1_0x004335A0 | 0.0% | Pending @@ -11135,9 +11135,9 @@ SHC_3BB0A8C1_0x00434224 | 0.0% | Pending SHC_3BB0A8C1_0x00434228 | 0.0% | Pending -SHC_3BB0A8C1_0x00434230 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00434230 | 0.0% | Pending -SHC_3BB0A8C1_0x00434260 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00434260 | 0.0% | Pending SHC_3BB0A8C1_0x00434270 | 0.0% | Pending @@ -13357,7 +13357,7 @@ SHC_3BB0A8C1_0x0043937C | 0.0% | Pending SHC_3BB0A8C1_0x00439380 | 0.0% | Pending -SHC_3BB0A8C1_0x00439390 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00439390 | 0.0% | Pending SHC_3BB0A8C1_0x004393C0 | 0.0% | Pending @@ -13389,19 +13389,19 @@ SHC_3BB0A8C1_0x00439724 | 0.0% | Pending SHC_3BB0A8C1_0x00439730 | 0.0% | Pending -SHC_3BB0A8C1_0x00439890 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00439890 | 0.0% | Pending SHC_3BB0A8C1_0x004398B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0043A850 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043A850 | 0.0% | Pending -SHC_3BB0A8C1_0x0043A860 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043A860 | 0.0% | Pending -SHC_3BB0A8C1_0x0043A880 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043A880 | 0.0% | Pending -SHC_3BB0A8C1_0x0043A8C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043A8C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0043A8D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043A8D0 | 0.0% | Pending SHC_3BB0A8C1_0x0043A8E0 | 0.0% | Pending @@ -13595,9 +13595,9 @@ SHC_3BB0A8C1_0x0043E5F0 | 0.0% | Pending SHC_3BB0A8C1_0x0043E6C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0043F2B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043F2B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0043F2C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043F2C0 | 0.0% | Pending SHC_3BB0A8C1_0x0043F2F0 | 0.0% | Pending @@ -13611,9 +13611,9 @@ SHC_3BB0A8C1_0x0043FBB0 | 0.0% | Pending SHC_3BB0A8C1_0x0043FBF0 | 0.0% | Pending -SHC_3BB0A8C1_0x0043FC80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043FC80 | 0.0% | Pending -SHC_3BB0A8C1_0x0043FCA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0043FCA0 | 0.0% | Pending SHC_3BB0A8C1_0x0043FCB0 | 0.0% | Pending @@ -13631,13 +13631,13 @@ SHC_3BB0A8C1_0x00440280 | 0.0% | Pending SHC_3BB0A8C1_0x00440360 | 0.0% | Pending -SHC_3BB0A8C1_0x004403D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004403D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00440400 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00440400 | 0.0% | Pending -SHC_3BB0A8C1_0x00440410 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00440410 | 0.0% | Pending -SHC_3BB0A8C1_0x00440420 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00440420 | 0.0% | Pending SHC_3BB0A8C1_0x00440430 | 0.0% | Pending @@ -16649,11 +16649,11 @@ SHC_3BB0A8C1_0x0044A720 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0044A830 | 0.0% | Pending -SHC_3BB0A8C1_0x0044AA70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044AA70 | 0.0% | Pending -SHC_3BB0A8C1_0x0044AA80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044AA80 | 0.0% | Pending -SHC_3BB0A8C1_0x0044AAA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044AAA0 | 0.0% | Pending SHC_3BB0A8C1_0x0044AAB0 | 100.0% | Reimplemented @@ -16867,7 +16867,7 @@ SHC_3BB0A8C1_0x0044B680 | 0.0% | Pending SHC_3BB0A8C1_0x0044B760 | 0.0% | Pending -SHC_3BB0A8C1_0x0044B7D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044B7D0 | 0.0% | Pending SHC_3BB0A8C1_0x0044B800 | 0.0% | Pending @@ -16915,17 +16915,17 @@ SHC_3BB0A8C1_0x0044CBE0 | 0.0% | Pending SHC_3BB0A8C1_0x0044CC30 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CCA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CCA0 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CCC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CCC0 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CCD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CCD0 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CCF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CCF0 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CD10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CD10 | 0.0% | Pending -SHC_3BB0A8C1_0x0044CD30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0044CD30 | 0.0% | Pending SHC_3BB0A8C1_0x0044CD40 | 0.0% | Pending @@ -16979,15 +16979,15 @@ SHC_3BB0A8C1_0x00454700 | 0.0% | Pending SHC_3BB0A8C1_0x004547C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004548D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004548D0 | 0.0% | Pending SHC_3BB0A8C1_0x00454900 | 0.0% | Pending -SHC_3BB0A8C1_0x00454960 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00454960 | 0.0% | Pending -SHC_3BB0A8C1_0x00454990 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00454990 | 0.0% | Pending -SHC_3BB0A8C1_0x004549C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004549C0 | 0.0% | Pending SHC_3BB0A8C1_0x004549F0 | 0.0% | Pending @@ -16999,21 +16999,21 @@ SHC_3BB0A8C1_0x00454CE0 | 0.0% | Pending SHC_3BB0A8C1_0x00454D20 | 0.0% | Pending -SHC_3BB0A8C1_0x00454EE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00454EE0 | 0.0% | Pending -SHC_3BB0A8C1_0x00454EF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00454EF0 | 0.0% | Pending SHC_3BB0A8C1_0x00454F00 | 0.0% | Pending SHC_3BB0A8C1_0x00455050 | 0.0% | Pending -SHC_3BB0A8C1_0x00455250 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00455250 | 0.0% | Pending -SHC_3BB0A8C1_0x00455270 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00455270 | 0.0% | Pending SHC_3BB0A8C1_0x00455290 | 0.0% | Pending -SHC_3BB0A8C1_0x004552E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004552E0 | 0.0% | Pending SHC_3BB0A8C1_0x00455300 | 0.0% | Pending @@ -17045,7 +17045,7 @@ SHC_3BB0A8C1_0x00455E40 | 0.0% | Pending SHC_3BB0A8C1_0x004560F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004563B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004563B0 | 0.0% | Pending SHC_3BB0A8C1_0x004563D0 | 0.0% | Pending @@ -17669,7 +17669,7 @@ SHC_3BB0A8C1_0x00457A70 | 0.0% | Pending SHC_3BB0A8C1_0x00457AD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00457B40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00457B40 | 0.0% | Pending SHC_3BB0A8C1_0x00457B80 | 0.0% | Pending @@ -17693,15 +17693,15 @@ SHC_3BB0A8C1_0x004585B0 | 0.0% | Pending SHC_3BB0A8C1_0x004585F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004586D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004586D0 | 0.0% | Pending SHC_3BB0A8C1_0x004586F0 | 0.0% | Pending -SHC_3BB0A8C1_0x00458700 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00458700 | 0.0% | Pending SHC_3BB0A8C1_0x00458720 | 0.0% | Pending -SHC_3BB0A8C1_0x00458740 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00458740 | 0.0% | Pending SHC_3BB0A8C1_0x00458760 | 0.0% | Pending @@ -17713,13 +17713,13 @@ SHC_3BB0A8C1_0x00458820 | 0.0% | Pending SHC_3BB0A8C1_0x00458840 | 0.0% | Pending -SHC_3BB0A8C1_0x00458890 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00458890 | 0.0% | Pending SHC_3BB0A8C1_0x004588A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004588D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004588D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004588F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004588F0 | 0.0% | Pending SHC_3BB0A8C1_0x00458910 | 100.0% | Reimplemented @@ -17757,11 +17757,11 @@ SHC_3BB0A8C1_0x00458F70 | 0.0% | Pending SHC_3BB0A8C1_0x00459080 | 0.0% | Pending -SHC_3BB0A8C1_0x00459140 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00459140 | 0.0% | Pending -SHC_3BB0A8C1_0x00459170 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00459170 | 0.0% | Pending -SHC_3BB0A8C1_0x004591B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004591B0 | 0.0% | Pending SHC_3BB0A8C1_0x004591F0 | 0.0% | Pending @@ -17889,7 +17889,7 @@ SHC_3BB0A8C1_0x004595D0 | 0.0% | Pending SHC_3BB0A8C1_0x00459640 | 0.0% | Pending -SHC_3BB0A8C1_0x004596D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004596D0 | 0.0% | Pending SHC_3BB0A8C1_0x00459700 | 0.0% | Pending @@ -17907,9 +17907,9 @@ SHC_3BB0A8C1_0x00459A40 | 0.0% | Pending SHC_3BB0A8C1_0x00459B50 | 0.0% | Pending -SHC_3BB0A8C1_0x00459BB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00459BB0 | 0.0% | Pending -SHC_3BB0A8C1_0x00459BE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00459BE0 | 0.0% | Pending SHC_3BB0A8C1_0x00459BF0 | 0.0% | Pending @@ -18025,7 +18025,7 @@ SHC_3BB0A8C1_0x0045AE70 | 0.0% | Pending SHC_3BB0A8C1_0x0045AEB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0045AF00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045AF00 | 0.0% | Pending SHC_3BB0A8C1_0x0045AF30 | 0.0% | Pending @@ -18035,13 +18035,13 @@ SHC_3BB0A8C1_0x0045B3A0 | 0.0% | Pending SHC_3BB0A8C1_0x0045B3E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0045B460 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045B460 | 0.0% | Pending SHC_3BB0A8C1_0x0045B4A0 | 0.0% | Pending SHC_3BB0A8C1_0x0045B6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0045B7F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045B7F0 | 0.0% | Pending SHC_3BB0A8C1_0x0045B830 | 0.0% | Pending @@ -18145,11 +18145,11 @@ SHC_3BB0A8C1_0x0045CA20 | 0.0% | Pending SHC_3BB0A8C1_0x0045CD10 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D060 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045D060 | 0.0% | Pending SHC_3BB0A8C1_0x0045D080 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D0B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045D0B0 | 0.0% | Pending SHC_3BB0A8C1_0x0045D0C0 | 0.0% | Pending @@ -18747,7 +18747,7 @@ SHC_3BB0A8C1_0x0045F0CD | 0.0% | Pending SHC_3BB0A8C1_0x0045F0D0 | 0.0% | Pending -SHC_3BB0A8C1_0x0045F120 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0045F120 | 0.0% | Pending SHC_3BB0A8C1_0x0045F130 | 0.0% | Pending @@ -19153,7 +19153,7 @@ SHC_3BB0A8C1_0x00462FE0 | 0.0% | Pending SHC_3BB0A8C1_0x00462FF0 | 0.0% | Pending -SHC_3BB0A8C1_0x004630B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004630B0 | 0.0% | Pending SHC_3BB0A8C1_0x004630D0 | 0.0% | Pending @@ -19843,11 +19843,11 @@ SHC_3BB0A8C1_0x00464856 | 0.0% | Pending SHC_3BB0A8C1_0x00464860 | 0.0% | Pending -SHC_3BB0A8C1_0x004649C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004649C0 | 0.0% | Pending SHC_3BB0A8C1_0x004649D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00464D90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00464D90 | 0.0% | Pending SHC_3BB0A8C1_0x00464DA0 | 0.0% | Pending @@ -19857,19 +19857,19 @@ SHC_3BB0A8C1_0x00464EF0 | 0.0% | Pending SHC_3BB0A8C1_0x00465040 | 0.0% | Pending -SHC_3BB0A8C1_0x00465080 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00465080 | 0.0% | Pending -SHC_3BB0A8C1_0x004650A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004650A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004650C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004650C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004650F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004650F0 | 0.0% | Pending SHC_3BB0A8C1_0x00465110 | 0.0% | Pending SHC_3BB0A8C1_0x00465200 | 0.0% | Pending -SHC_3BB0A8C1_0x004652A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004652A0 | 0.0% | Pending SHC_3BB0A8C1_0x004652D0 | 0.0% | Pending @@ -19905,15 +19905,15 @@ SHC_3BB0A8C1_0x00465700 | 0.0% | Pending SHC_3BB0A8C1_0x004657B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00465800 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00465800 | 0.0% | Pending SHC_3BB0A8C1_0x00465820 | 0.0% | Pending -SHC_3BB0A8C1_0x00465890 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00465890 | 0.0% | Pending SHC_3BB0A8C1_0x004658B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00465920 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00465920 | 0.0% | Pending SHC_3BB0A8C1_0x00465950 | 0.0% | Pending @@ -19929,7 +19929,7 @@ SHC_3BB0A8C1_0x00465F20 | 0.0% | Pending SHC_3BB0A8C1_0x00465F90 | 0.0% | Pending -SHC_3BB0A8C1_0x004660B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004660B0 | 0.0% | Pending SHC_3BB0A8C1_0x004660F0 | 0.0% | Pending @@ -19945,7 +19945,7 @@ SHC_3BB0A8C1_0x00466480 | 0.0% | Pending SHC_3BB0A8C1_0x00466620 | 0.0% | Pending -SHC_3BB0A8C1_0x00466710 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00466710 | 0.0% | Pending SHC_3BB0A8C1_0x00466730 | 0.0% | Pending @@ -19975,9 +19975,9 @@ SHC_3BB0A8C1_0x004668E0 | 0.0% | Pending SHC_3BB0A8C1_0x004668E4 | 0.0% | Pending -SHC_3BB0A8C1_0x004668F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004668F0 | 0.0% | Pending -SHC_3BB0A8C1_0x00466920 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00466920 | 0.0% | Pending SHC_3BB0A8C1_0x00466950 | 0.0% | Pending @@ -19987,9 +19987,9 @@ SHC_3BB0A8C1_0x00466C20 | 0.0% | Pending SHC_3BB0A8C1_0x00466D10 | 0.0% | Pending -SHC_3BB0A8C1_0x00466E00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00466E00 | 0.0% | Pending -SHC_3BB0A8C1_0x00466E10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00466E10 | 0.0% | Pending SHC_3BB0A8C1_0x00466E20 | 0.0% | Pending @@ -20051,7 +20051,7 @@ SHC_3BB0A8C1_0x00467E04 | 0.0% | Pending SHC_3BB0A8C1_0x00467E26 | 0.0% | Pending -SHC_3BB0A8C1_0x00467E40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00467E40 | 0.0% | Pending SHC_3BB0A8C1_0x00467E50 | 0.0% | Pending @@ -20059,31 +20059,31 @@ SHC_3BB0A8C1_0x00467EC0 | 0.0% | Pending SHC_3BB0A8C1_0x00467F50 | 0.0% | Pending -SHC_3BB0A8C1_0x00467F60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00467F60 | 0.0% | Pending -SHC_3BB0A8C1_0x00467F80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00467F80 | 0.0% | Pending -SHC_3BB0A8C1_0x00468030 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468030 | 0.0% | Pending -SHC_3BB0A8C1_0x004680B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004680B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004680C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004680C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00468100 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468100 | 0.0% | Pending -SHC_3BB0A8C1_0x00468370 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468370 | 0.0% | Pending -SHC_3BB0A8C1_0x00468420 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468420 | 0.0% | Pending -SHC_3BB0A8C1_0x004684D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004684D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00468590 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468590 | 0.0% | Pending -SHC_3BB0A8C1_0x004685C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004685C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004687F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004687F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004689D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004689D0 | 0.0% | Pending SHC_3BB0A8C1_0x00468A10 | 100.0% | Reimplemented @@ -20097,7 +20097,7 @@ SHC_3BB0A8C1_0x00468C30 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00468C40 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00468C50 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00468C50 | 0.0% | Pending SHC_3BB0A8C1_0x00468C80 | 0.0% | Pending @@ -20149,19 +20149,19 @@ SHC_3BB0A8C1_0x00469980 | 0.0% | Pending SHC_3BB0A8C1_0x004699E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469A30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00469A30 | 0.0% | Pending -SHC_3BB0A8C1_0x00469A70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00469A70 | 0.0% | Pending SHC_3BB0A8C1_0x00469AD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469B90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00469B90 | 0.0% | Pending SHC_3BB0A8C1_0x00469BE0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469C40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00469C40 | 0.0% | Pending -SHC_3BB0A8C1_0x00469E10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00469E10 | 0.0% | Pending SHC_3BB0A8C1_0x00469E70 | 0.0% | Pending @@ -20729,25 +20729,25 @@ SHC_3BB0A8C1_0x0046AE80 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0046AEC0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0046B080 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B080 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B0D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B0D0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B110 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B110 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B140 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B140 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B170 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B170 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B1B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B1B0 | 0.0% | Pending SHC_3BB0A8C1_0x0046B1F0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B2F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B2F0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B300 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B300 | 0.0% | Pending -SHC_3BB0A8C1_0x0046B320 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046B320 | 0.0% | Pending SHC_3BB0A8C1_0x0046B340 | 0.0% | Pending @@ -20893,7 +20893,7 @@ SHC_3BB0A8C1_0x0046BBD0 | 0.0% | Pending SHC_3BB0A8C1_0x0046BC90 | 0.0% | Pending -SHC_3BB0A8C1_0x0046BD20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046BD20 | 0.0% | Pending SHC_3BB0A8C1_0x0046BD50 | 0.0% | Pending @@ -20945,7 +20945,7 @@ SHC_3BB0A8C1_0x0046CAA0 | 0.0% | Pending SHC_3BB0A8C1_0x0046CC80 | 0.0% | Pending -SHC_3BB0A8C1_0x0046CCD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046CCD0 | 0.0% | Pending SHC_3BB0A8C1_0x0046CD30 | 100.0% | Reimplemented @@ -20967,11 +20967,11 @@ SHC_3BB0A8C1_0x0046CEAC | 0.0% | Pending SHC_3BB0A8C1_0x0046CEB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046CEC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046CEC0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046CED0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046CED0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046CEF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046CEF0 | 0.0% | Pending SHC_3BB0A8C1_0x0046CF10 | 0.0% | Pending @@ -21201,7 +21201,7 @@ SHC_3BB0A8C1_0x0046F690 | 0.0% | Pending SHC_3BB0A8C1_0x0046F6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0046F730 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0046F730 | 0.0% | Pending SHC_3BB0A8C1_0x0046F750 | 0.0% | Pending @@ -21257,13 +21257,13 @@ SHC_3BB0A8C1_0x004707F0 | 0.0% | Pending SHC_3BB0A8C1_0x004708F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004709B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004709B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00470A00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00470A00 | 0.0% | Pending -SHC_3BB0A8C1_0x00470B30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00470B30 | 0.0% | Pending -SHC_3BB0A8C1_0x00470BC0 | 100.0% | Reimplemented, requires SHC_3BB0A8C1_0x0046CCD0 to be active +SHC_3BB0A8C1_0x00470BC0 | 0.0% | Pending SHC_3BB0A8C1_0x00470E90 | 0.0% | Pending @@ -21293,9 +21293,9 @@ SHC_3BB0A8C1_0x00471570 | 0.0% | Pending SHC_3BB0A8C1_0x004715A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00471610 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00471610 | 0.0% | Pending -SHC_3BB0A8C1_0x00471670 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00471670 | 0.0% | Pending SHC_3BB0A8C1_0x00471690 | 0.0% | Pending @@ -21327,11 +21327,11 @@ SHC_3BB0A8C1_0x004718C0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004718F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004719E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004719E0 | 0.0% | Pending SHC_3BB0A8C1_0x00471A00 | 0.0% | Pending -SHC_3BB0A8C1_0x00471A80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00471A80 | 0.0% | Pending SHC_3BB0A8C1_0x00471AA0 | 0.0% | Pending @@ -21415,7 +21415,7 @@ SHC_3BB0A8C1_0x00472950 | 0.0% | Pending SHC_3BB0A8C1_0x004729B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00472A90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00472A90 | 0.0% | Pending SHC_3BB0A8C1_0x00472B20 | 0.0% | Pending @@ -21429,21 +21429,21 @@ SHC_3BB0A8C1_0x00472CB0 | 0.0% | Pending SHC_3BB0A8C1_0x00472D00 | 0.0% | Pending -SHC_3BB0A8C1_0x00472D60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00472D60 | 0.0% | Pending SHC_3BB0A8C1_0x00472DD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00472EF0 | 55.0% | Severe Register Issues, seem functional, but can not be considered done +SHC_3BB0A8C1_0x00472EF0 | 0.0% | Pending -SHC_3BB0A8C1_0x00473300 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00473300 | 0.0% | Pending -SHC_3BB0A8C1_0x004733A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004733A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00473640 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00473640 | 0.0% | Pending -SHC_3BB0A8C1_0x004737B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004737B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00473830 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00473830 | 0.0% | Pending SHC_3BB0A8C1_0x00473870 | 0.0% | Pending @@ -22307,7 +22307,7 @@ SHC_3BB0A8C1_0x0047D0D8 | 0.0% | Pending SHC_3BB0A8C1_0x0047D0DC | 0.0% | Pending -SHC_3BB0A8C1_0x0047D0E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047D0E0 | 0.0% | Pending SHC_3BB0A8C1_0x0047D100 | 0.0% | Pending @@ -22327,7 +22327,7 @@ SHC_3BB0A8C1_0x0047D3DC | 0.0% | Pending SHC_3BB0A8C1_0x0047D3E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0047D3F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047D3F0 | 0.0% | Pending SHC_3BB0A8C1_0x0047D410 | 0.0% | Pending @@ -22373,9 +22373,9 @@ SHC_3BB0A8C1_0x0047E5B0 | 0.0% | Pending SHC_3BB0A8C1_0x0047E5D0 | 0.0% | Pending -SHC_3BB0A8C1_0x0047E7E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047E7E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0047E800 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047E800 | 0.0% | Pending SHC_3BB0A8C1_0x0047E830 | 0.0% | Pending @@ -22393,7 +22393,7 @@ SHC_3BB0A8C1_0x0047EC10 | 0.0% | Pending SHC_3BB0A8C1_0x0047EDE0 | 0.0% | Pending -SHC_3BB0A8C1_0x0047EEB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047EEB0 | 0.0% | Pending SHC_3BB0A8C1_0x0047EED0 | 0.0% | Pending @@ -22411,13 +22411,13 @@ SHC_3BB0A8C1_0x0047FD50 | 0.0% | Pending SHC_3BB0A8C1_0x0047FEA0 | 0.0% | Pending -SHC_3BB0A8C1_0x0047FFA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0047FFA0 | 0.0% | Pending SHC_3BB0A8C1_0x0047FFE0 | 0.0% | Pending SHC_3BB0A8C1_0x00480050 | 0.0% | Pending -SHC_3BB0A8C1_0x004800B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004800B0 | 0.0% | Pending SHC_3BB0A8C1_0x004800E0 | 0.0% | Pending @@ -22425,7 +22425,7 @@ SHC_3BB0A8C1_0x00480210 | 0.0% | Pending SHC_3BB0A8C1_0x00480440 | 0.0% | Pending -SHC_3BB0A8C1_0x00480570 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00480570 | 0.0% | Pending SHC_3BB0A8C1_0x00480580 | 0.0% | Pending @@ -22547,7 +22547,7 @@ SHC_3BB0A8C1_0x004821D5 | 0.0% | Pending SHC_3BB0A8C1_0x004821E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00482280 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00482280 | 0.0% | Pending SHC_3BB0A8C1_0x00482290 | 0.0% | Pending @@ -23167,7 +23167,7 @@ SHC_3BB0A8C1_0x0048BD40 | 0.0% | Pending SHC_3BB0A8C1_0x0048BD80 | 0.0% | Pending -SHC_3BB0A8C1_0x0048BF70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0048BF70 | 0.0% | Pending SHC_3BB0A8C1_0x0048BF80 | 0.0% | Pending @@ -23357,7 +23357,7 @@ SHC_3BB0A8C1_0x0048F841 | 0.0% | Pending SHC_3BB0A8C1_0x0048F842 | 0.0% | Pending -SHC_3BB0A8C1_0x0048F850 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0048F850 | 0.0% | Pending SHC_3BB0A8C1_0x0048F870 | 0.0% | Pending @@ -23373,7 +23373,7 @@ SHC_3BB0A8C1_0x00490060 | 0.0% | Pending SHC_3BB0A8C1_0x00490080 | 0.0% | Pending -SHC_3BB0A8C1_0x00490340 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00490340 | 0.0% | Pending SHC_3BB0A8C1_0x00490380 | 0.0% | Pending @@ -23407,13 +23407,13 @@ SHC_3BB0A8C1_0x00491680 | 0.0% | Pending SHC_3BB0A8C1_0x004916C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00491730 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00491730 | 0.0% | Pending SHC_3BB0A8C1_0x00491750 | 0.0% | Pending SHC_3BB0A8C1_0x004917C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00491810 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00491810 | 0.0% | Pending SHC_3BB0A8C1_0x00491840 | 0.0% | Pending @@ -23421,9 +23421,9 @@ SHC_3BB0A8C1_0x00491A30 | 0.0% | Pending SHC_3BB0A8C1_0x00491AC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00491BF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00491BF0 | 0.0% | Pending -SHC_3BB0A8C1_0x00491C20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00491C20 | 0.0% | Pending SHC_3BB0A8C1_0x00491C50 | 0.0% | Pending @@ -23431,7 +23431,7 @@ SHC_3BB0A8C1_0x00491CE0 | 0.0% | Pending SHC_3BB0A8C1_0x00491D70 | 0.0% | Pending -SHC_3BB0A8C1_0x00491E80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00491E80 | 0.0% | Pending SHC_3BB0A8C1_0x00491EB0 | 0.0% | Pending @@ -23485,7 +23485,7 @@ SHC_3BB0A8C1_0x00492654 | 0.0% | Pending SHC_3BB0A8C1_0x00492658 | 0.0% | Pending -SHC_3BB0A8C1_0x00492660 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00492660 | 0.0% | Pending SHC_3BB0A8C1_0x00492690 | 0.0% | Pending @@ -23501,7 +23501,7 @@ SHC_3BB0A8C1_0x004929BC | 0.0% | Pending SHC_3BB0A8C1_0x004929C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00492A60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00492A60 | 0.0% | Pending SHC_3BB0A8C1_0x00492A90 | 0.0% | Pending @@ -23521,7 +23521,7 @@ SHC_3BB0A8C1_0x00492C58 | 0.0% | Pending SHC_3BB0A8C1_0x00492C5C | 0.0% | Pending -SHC_3BB0A8C1_0x00492C60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00492C60 | 0.0% | Pending SHC_3BB0A8C1_0x00492C90 | 0.0% | Pending @@ -23629,7 +23629,7 @@ SHC_3BB0A8C1_0x00493690 | 0.0% | Pending SHC_3BB0A8C1_0x004937A4 | 0.0% | Pending -SHC_3BB0A8C1_0x004937B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004937B0 | 0.0% | Pending SHC_3BB0A8C1_0x004937E0 | 0.0% | Pending @@ -24041,7 +24041,7 @@ SHC_3BB0A8C1_0x004941E7 | 0.0% | Pending SHC_3BB0A8C1_0x004941E8 | 0.0% | Pending -SHC_3BB0A8C1_0x004941F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004941F0 | 0.0% | Pending SHC_3BB0A8C1_0x00494210 | 0.0% | Pending @@ -24111,7 +24111,7 @@ SHC_3BB0A8C1_0x004948BF | 0.0% | Pending SHC_3BB0A8C1_0x004948C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00494920 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00494920 | 0.0% | Pending SHC_3BB0A8C1_0x00494950 | 0.0% | Pending @@ -24213,9 +24213,9 @@ SHC_3BB0A8C1_0x00495230 | 0.0% | Pending SHC_3BB0A8C1_0x004954A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00495800 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00495800 | 0.0% | Pending -SHC_3BB0A8C1_0x00495840 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00495840 | 0.0% | Pending SHC_3BB0A8C1_0x00495860 | 0.0% | Pending @@ -24343,13 +24343,13 @@ SHC_3BB0A8C1_0x00496E19 | 0.0% | Pending SHC_3BB0A8C1_0x00496E1A | 0.0% | Pending -SHC_3BB0A8C1_0x00496E20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00496E20 | 0.0% | Pending -SHC_3BB0A8C1_0x00496E30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00496E30 | 0.0% | Pending SHC_3BB0A8C1_0x00496E40 | 0.0% | Pending -SHC_3BB0A8C1_0x00496EA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00496EA0 | 0.0% | Pending SHC_3BB0A8C1_0x00496EC0 | 0.0% | Pending @@ -24417,7 +24417,7 @@ SHC_3BB0A8C1_0x0049AF50 | 0.0% | Pending SHC_3BB0A8C1_0x0049B000 | 0.0% | Pending -SHC_3BB0A8C1_0x0049B1C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0049B1C0 | 0.0% | Pending SHC_3BB0A8C1_0x0049B1D0 | 0.0% | Pending @@ -25233,7 +25233,7 @@ SHC_3BB0A8C1_0x004A4930 | 0.0% | Pending SHC_3BB0A8C1_0x004A4B30 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4B80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A4B80 | 0.0% | Pending SHC_3BB0A8C1_0x004A4BB0 | 0.0% | Pending @@ -25267,7 +25267,7 @@ SHC_3BB0A8C1_0x004A5B00 | 0.0% | Pending SHC_3BB0A8C1_0x004A5DA0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A5F60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A5F60 | 0.0% | Pending SHC_3BB0A8C1_0x004A5F90 | 0.0% | Pending @@ -25455,7 +25455,7 @@ SHC_3BB0A8C1_0x004A91F7 | 0.0% | Pending SHC_3BB0A8C1_0x004A9200 | 0.0% | Pending -SHC_3BB0A8C1_0x004A94E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A94E0 | 0.0% | Pending SHC_3BB0A8C1_0x004A9510 | 0.0% | Pending @@ -25471,17 +25471,17 @@ SHC_3BB0A8C1_0x004A98C0 | 0.0% | Pending SHC_3BB0A8C1_0x004A9B20 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9DD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A9DD0 | 0.0% | Pending SHC_3BB0A8C1_0x004A9E00 | 0.0% | Pending SHC_3BB0A8C1_0x004A9E60 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9E80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A9E80 | 0.0% | Pending SHC_3BB0A8C1_0x004A9E90 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9EB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004A9EB0 | 0.0% | Pending SHC_3BB0A8C1_0x004A9ED0 | 0.0% | Pending @@ -25519,37 +25519,37 @@ SHC_3BB0A8C1_0x004AA930 | 0.0% | Pending SHC_3BB0A8C1_0x004AA970 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAA40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAA40 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAA60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAA60 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAA80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAA80 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAAA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAAA0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAAC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAAC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAAE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAAE0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAB00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAB00 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAB20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAB20 | 0.0% | Pending -SHC_3BB0A8C1_0x004AAB40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AAB40 | 0.0% | Pending SHC_3BB0A8C1_0x004AAB50 | 0.0% | Pending -SHC_3BB0A8C1_0x004AB440 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AB440 | 0.0% | Pending SHC_3BB0A8C1_0x004AB460 | 0.0% | Pending -SHC_3BB0A8C1_0x004AB4B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AB4B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AB4E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AB4E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AB510 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AB510 | 0.0% | Pending -SHC_3BB0A8C1_0x004AB540 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AB540 | 0.0% | Pending SHC_3BB0A8C1_0x004AB570 | 0.0% | Pending @@ -25619,17 +25619,17 @@ SHC_3BB0A8C1_0x004ABB91 | 0.0% | Pending SHC_3BB0A8C1_0x004ABBA0 | 0.0% | Pending -SHC_3BB0A8C1_0x004ABCB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004ABCB0 | 0.0% | Pending -SHC_3BB0A8C1_0x004ABCE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004ABCE0 | 0.0% | Pending -SHC_3BB0A8C1_0x004ABD10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004ABD10 | 0.0% | Pending SHC_3BB0A8C1_0x004ABD20 | 0.0% | Pending -SHC_3BB0A8C1_0x004ABE50 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004ABE50 | 0.0% | Pending -SHC_3BB0A8C1_0x004ABE80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004ABE80 | 0.0% | Pending SHC_3BB0A8C1_0x004ABEB0 | 0.0% | Pending @@ -25779,7 +25779,7 @@ SHC_3BB0A8C1_0x004AC24E | 0.0% | Pending SHC_3BB0A8C1_0x004AC24F | 0.0% | Pending -SHC_3BB0A8C1_0x004AC250 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AC250 | 0.0% | Pending SHC_3BB0A8C1_0x004AC280 | 0.0% | Pending @@ -25903,31 +25903,31 @@ SHC_3BB0A8C1_0x004AF4C0 | 0.0% | Pending SHC_3BB0A8C1_0x004AF5E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF630 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF630 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF650 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF650 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF680 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF680 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF6B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF6B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF6E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF6E0 | 0.0% | Pending SHC_3BB0A8C1_0x004AF700 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF800 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF800 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF820 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF820 | 0.0% | Pending -SHC_3BB0A8C1_0x004AF840 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AF840 | 0.0% | Pending SHC_3BB0A8C1_0x004AF860 | 0.0% | Pending -SHC_3BB0A8C1_0x004AFA50 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AFA50 | 0.0% | Pending SHC_3BB0A8C1_0x004AFA80 | 0.0% | Pending -SHC_3BB0A8C1_0x004AFB00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004AFB00 | 0.0% | Pending SHC_3BB0A8C1_0x004AFB30 | 0.0% | Pending @@ -25967,7 +25967,7 @@ SHC_3BB0A8C1_0x004B0F70 | 0.0% | Pending SHC_3BB0A8C1_0x004B1000 | 0.0% | Pending -SHC_3BB0A8C1_0x004B1090 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B1090 | 0.0% | Pending SHC_3BB0A8C1_0x004B10D0 | 0.0% | Pending @@ -26001,7 +26001,7 @@ SHC_3BB0A8C1_0x004B1E60 | 0.0% | Pending SHC_3BB0A8C1_0x004B1EB0 | 0.0% | Pending -SHC_3BB0A8C1_0x004B20B0 | 82.4% | shared arm fold direction +SHC_3BB0A8C1_0x004B20B0 | 0.0% | Pending SHC_3BB0A8C1_0x004B2280 | 0.0% | Pending @@ -26881,7 +26881,7 @@ SHC_3BB0A8C1_0x004B51A0 | 0.0% | Pending SHC_3BB0A8C1_0x004B5280 | 0.0% | Pending -SHC_3BB0A8C1_0x004B5300 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B5300 | 0.0% | Pending SHC_3BB0A8C1_0x004B5330 | 0.0% | Pending @@ -26905,7 +26905,7 @@ SHC_3BB0A8C1_0x004B6480 | 0.0% | Pending SHC_3BB0A8C1_0x004B64D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004B6500 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B6500 | 0.0% | Pending SHC_3BB0A8C1_0x004B6530 | 0.0% | Pending @@ -26915,9 +26915,9 @@ SHC_3BB0A8C1_0x004B65A0 | 0.0% | Pending SHC_3BB0A8C1_0x004B65F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004B6640 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B6640 | 0.0% | Pending -SHC_3BB0A8C1_0x004B6680 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B6680 | 0.0% | Pending SHC_3BB0A8C1_0x004B66C0 | 0.0% | Pending @@ -27071,17 +27071,17 @@ SHC_3BB0A8C1_0x004B7530 | 0.0% | Pending SHC_3BB0A8C1_0x004B7600 | 0.0% | Pending -SHC_3BB0A8C1_0x004B7700 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B7700 | 0.0% | Pending SHC_3BB0A8C1_0x004B7730 | 0.0% | Pending SHC_3BB0A8C1_0x004B77A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004B77E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B77E0 | 0.0% | Pending SHC_3BB0A8C1_0x004B7800 | 0.0% | Pending -SHC_3BB0A8C1_0x004B7890 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B7890 | 0.0% | Pending SHC_3BB0A8C1_0x004B78D0 | 0.0% | Pending @@ -27097,19 +27097,19 @@ SHC_3BB0A8C1_0x004B7AF0 | 0.0% | Pending SHC_3BB0A8C1_0x004B7C90 | 0.0% | Pending -SHC_3BB0A8C1_0x004B7F60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B7F60 | 0.0% | Pending SHC_3BB0A8C1_0x004B7FA0 | 0.0% | Pending SHC_3BB0A8C1_0x004B8000 | 0.0% | Pending -SHC_3BB0A8C1_0x004B8050 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B8050 | 0.0% | Pending SHC_3BB0A8C1_0x004B8080 | 0.0% | Pending -SHC_3BB0A8C1_0x004B8200 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B8200 | 0.0% | Pending -SHC_3BB0A8C1_0x004B8210 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B8210 | 0.0% | Pending SHC_3BB0A8C1_0x004B8220 | 0.0% | Pending @@ -27639,7 +27639,7 @@ SHC_3BB0A8C1_0x004B9528 | 0.0% | Pending SHC_3BB0A8C1_0x004B9530 | 0.0% | Pending -SHC_3BB0A8C1_0x004B9610 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004B9610 | 0.0% | Pending SHC_3BB0A8C1_0x004B9620 | 0.0% | Pending @@ -29119,7 +29119,7 @@ SHC_3BB0A8C1_0x004BAEC0 | 0.0% | Pending SHC_3BB0A8C1_0x004BB010 | 0.0% | Pending -SHC_3BB0A8C1_0x004BB0B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BB0B0 | 0.0% | Pending SHC_3BB0A8C1_0x004BB0D0 | 0.0% | Pending @@ -29287,11 +29287,11 @@ SHC_3BB0A8C1_0x004BB52C | 0.0% | Pending SHC_3BB0A8C1_0x004BB530 | 0.0% | Pending -SHC_3BB0A8C1_0x004BB540 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BB540 | 0.0% | Pending SHC_3BB0A8C1_0x004BB570 | 0.0% | Pending -SHC_3BB0A8C1_0x004BB650 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BB650 | 0.0% | Pending SHC_3BB0A8C1_0x004BB680 | 0.0% | Pending @@ -29315,9 +29315,9 @@ SHC_3BB0A8C1_0x004BB900 | 0.0% | Pending SHC_3BB0A8C1_0x004BB990 | 0.0% | Pending -SHC_3BB0A8C1_0x004BB9F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BB9F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004BBA20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BBA20 | 0.0% | Pending SHC_3BB0A8C1_0x004BBA30 | 0.0% | Pending @@ -30085,17 +30085,17 @@ SHC_3BB0A8C1_0x004BC5B0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004BC5F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004BC620 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BC620 | 0.0% | Pending SHC_3BB0A8C1_0x004BC630 | 0.0% | Pending -SHC_3BB0A8C1_0x004BC690 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BC690 | 0.0% | Pending SHC_3BB0A8C1_0x004BC6C0 | 0.0% | Pending SHC_3BB0A8C1_0x004BC6F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004BC770 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BC770 | 0.0% | Pending SHC_3BB0A8C1_0x004BC790 | 0.0% | Pending @@ -30491,7 +30491,7 @@ SHC_3BB0A8C1_0x004BEA90 | 0.0% | Pending SHC_3BB0A8C1_0x004BEB20 | 0.0% | Pending -SHC_3BB0A8C1_0x004BEC10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004BEC10 | 0.0% | Pending SHC_3BB0A8C1_0x004BEC40 | 0.0% | Pending @@ -35833,7 +35833,7 @@ SHC_3BB0A8C1_0x004D6D14 | 0.0% | Pending SHC_3BB0A8C1_0x004D6D20 | 0.0% | Pending -SHC_3BB0A8C1_0x004D6EF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D6EF0 | 0.0% | Pending SHC_3BB0A8C1_0x004D6F20 | 0.0% | Pending @@ -35999,7 +35999,7 @@ SHC_3BB0A8C1_0x004D8A18 | 0.0% | Pending SHC_3BB0A8C1_0x004D8A20 | 0.0% | Pending -SHC_3BB0A8C1_0x004D8AB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D8AB0 | 0.0% | Pending SHC_3BB0A8C1_0x004D8AE0 | 0.0% | Pending @@ -36019,7 +36019,7 @@ SHC_3BB0A8C1_0x004D91D0 | 0.0% | Pending SHC_3BB0A8C1_0x004D9230 | 0.0% | Pending -SHC_3BB0A8C1_0x004D9270 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D9270 | 0.0% | Pending SHC_3BB0A8C1_0x004D9290 | 0.0% | Pending @@ -36027,7 +36027,7 @@ SHC_3BB0A8C1_0x004D9400 | 0.0% | Pending SHC_3BB0A8C1_0x004D9520 | 0.0% | Pending -SHC_3BB0A8C1_0x004D9700 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D9700 | 0.0% | Pending SHC_3BB0A8C1_0x004D9730 | 0.0% | Pending @@ -36053,9 +36053,9 @@ SHC_3BB0A8C1_0x004D9C10 | 0.0% | Pending SHC_3BB0A8C1_0x004D9CC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004D9D60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D9D60 | 0.0% | Pending -SHC_3BB0A8C1_0x004D9D90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004D9D90 | 0.0% | Pending SHC_3BB0A8C1_0x004D9DB0 | 0.0% | Pending @@ -36135,7 +36135,7 @@ SHC_3BB0A8C1_0x004DA360 | 0.0% | Pending SHC_3BB0A8C1_0x004DA570 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA640 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA640 | 0.0% | Pending SHC_3BB0A8C1_0x004DA670 | 0.0% | Pending @@ -36145,15 +36145,15 @@ SHC_3BB0A8C1_0x004DA750 | 0.0% | Pending SHC_3BB0A8C1_0x004DA7A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA7E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA7E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA810 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA810 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA840 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA840 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA870 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA870 | 0.0% | Pending -SHC_3BB0A8C1_0x004DA8A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DA8A0 | 0.0% | Pending SHC_3BB0A8C1_0x004DA8D0 | 0.0% | Pending @@ -36171,7 +36171,7 @@ SHC_3BB0A8C1_0x004DAB80 | 0.0% | Pending SHC_3BB0A8C1_0x004DABB0 | 0.0% | Pending -SHC_3BB0A8C1_0x004DABF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DABF0 | 0.0% | Pending SHC_3BB0A8C1_0x004DAC30 | 0.0% | Pending @@ -36257,7 +36257,7 @@ SHC_3BB0A8C1_0x004DC500 | 0.0% | Pending SHC_3BB0A8C1_0x004DC9E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004DCC70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004DCC70 | 0.0% | Pending SHC_3BB0A8C1_0x004DCC90 | 0.0% | Pending @@ -36375,7 +36375,7 @@ SHC_3BB0A8C1_0x004E12C0 | 0.0% | Pending SHC_3BB0A8C1_0x004E1810 | 0.0% | Pending -SHC_3BB0A8C1_0x004E1A20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E1A20 | 0.0% | Pending SHC_3BB0A8C1_0x004E1A50 | 0.0% | Pending @@ -36399,7 +36399,7 @@ SHC_3BB0A8C1_0x004E2460 | 0.0% | Pending SHC_3BB0A8C1_0x004E25A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004E2600 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E2600 | 0.0% | Pending SHC_3BB0A8C1_0x004E2630 | 0.0% | Pending @@ -36985,7 +36985,7 @@ SHC_3BB0A8C1_0x004E66F0 | 0.0% | Pending SHC_3BB0A8C1_0x004E7770 | 0.0% | Pending -SHC_3BB0A8C1_0x004E7800 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E7800 | 0.0% | Pending SHC_3BB0A8C1_0x004E7810 | 0.0% | Pending @@ -37335,11 +37335,11 @@ SHC_3BB0A8C1_0x004E8C4C | 0.0% | Pending SHC_3BB0A8C1_0x004E8C50 | 0.0% | Pending -SHC_3BB0A8C1_0x004E8C90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E8C90 | 0.0% | Pending -SHC_3BB0A8C1_0x004E8CA0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E8CA0 | 0.0% | Pending -SHC_3BB0A8C1_0x004E8CC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004E8CC0 | 0.0% | Pending SHC_3BB0A8C1_0x004E8CF0 | 0.0% | Pending @@ -37871,27 +37871,27 @@ SHC_3BB0A8C1_0x004ECA90 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ECAB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ECAD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECAD0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ECBC0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECBC0 | 68.6% | orig branch shape; registers differ SHC_3BB0A8C1_0x004ECCA0 | 0.0% | Pending SHC_3BB0A8C1_0x004ECD90 | 0.0% | Pending -SHC_3BB0A8C1_0x004ECDB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECDB0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ECDE0 | 0.0% | Pending SHC_3BB0A8C1_0x004ECDF0 | 0.0% | Pending -SHC_3BB0A8C1_0x004ECE60 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECE60 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ECEF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ECF70 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECF70 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ECFE0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ECFE0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ED070 | 0.0% | Pending @@ -37923,47 +37923,47 @@ SHC_3BB0A8C1_0x004ED0A4 | 0.0% | Pending SHC_3BB0A8C1_0x004ED0A8 | 0.0% | Pending -SHC_3BB0A8C1_0x004ED0B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ED0B0 | 97.2% | Reimplemented -SHC_3BB0A8C1_0x004ED240 | 0.0% | Pending +SHC_3BB0A8C1_0x004ED240 | 98.2% | Reimplemented -SHC_3BB0A8C1_0x004ED300 | 0.0% | Pending +SHC_3BB0A8C1_0x004ED300 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ED3B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004ED3B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ED410 | 0.0% | Pending +SHC_3BB0A8C1_0x004ED410 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EDC90 | 0.0% | Pending +SHC_3BB0A8C1_0x004EDC90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EDCB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EDCB0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EDD00 | 0.0% | Pending +SHC_3BB0A8C1_0x004EDD00 | 98.8% | Reimplemented -SHC_3BB0A8C1_0x004EDDF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EDDF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EE140 | 0.0% | Pending +SHC_3BB0A8C1_0x004EE140 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EE230 | 0.0% | Pending -SHC_3BB0A8C1_0x004EE430 | 0.0% | Pending +SHC_3BB0A8C1_0x004EE430 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EE830 | 0.0% | Pending +SHC_3BB0A8C1_0x004EE830 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EE920 | 0.0% | Pending -SHC_3BB0A8C1_0x004EEBD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EEBD0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EECC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004EEE10 | 0.0% | Pending +SHC_3BB0A8C1_0x004EEE10 | 88.2% | loop rotation; orig rematerial SHC_3BB0A8C1_0x004EEEC0 | 0.0% | Pending SHC_3BB0A8C1_0x004EEF20 | 0.0% | Pending -SHC_3BB0A8C1_0x004EF090 | 0.0% | Pending +SHC_3BB0A8C1_0x004EF090 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EF0D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EF0D0 | 67.2% | orig spills y in loop 1 SHC_3BB0A8C1_0x004EF130 | 0.0% | Pending @@ -37971,43 +37971,43 @@ SHC_3BB0A8C1_0x004EF150 | 0.0% | Pending SHC_3BB0A8C1_0x004EF450 | 0.0% | Pending -SHC_3BB0A8C1_0x004EF8C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EF8C0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EF900 | 0.0% | Pending SHC_3BB0A8C1_0x004EF920 | 0.0% | Pending -SHC_3BB0A8C1_0x004EFA60 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFA60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFAB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFAB0 | 91.4% | Register reuse after search -SHC_3BB0A8C1_0x004EFB90 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFB90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFC30 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFC30 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFD90 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFD90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFE30 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFE30 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFED0 | 0.0% | Pending +SHC_3BB0A8C1_0x004EFED0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004F0060 | 0.0% | Pending +SHC_3BB0A8C1_0x004F0060 | 53.6% | step < 50 fix; registers differ SHC_3BB0A8C1_0x004F0690 | 0.0% | Pending -SHC_3BB0A8C1_0x004F0E80 | 0.0% | Pending +SHC_3BB0A8C1_0x004F0E80 | 88.9% | rest is scheduling + a hoisted SHC_3BB0A8C1_0x004F1190 | 0.0% | Pending -SHC_3BB0A8C1_0x004F13E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004F13E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004F13F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004F13F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004F14F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004F14F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004F15C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004F15C0 | 98.5% | init stores sit after the aivID branch -SHC_3BB0A8C1_0x004F1860 | 0.0% | Pending +SHC_3BB0A8C1_0x004F1860 | 90.8% | orig has a redundant cmp eax,eax SHC_3BB0A8C1_0x004F1A60 | 0.0% | Pending @@ -38463,7 +38463,7 @@ SHC_3BB0A8C1_0x004F28E4 | 0.0% | Pending SHC_3BB0A8C1_0x004F28E8 | 0.0% | Pending -SHC_3BB0A8C1_0x004F28F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F28F0 | 0.0% | Pending SHC_3BB0A8C1_0x004F2920 | 0.0% | Pending @@ -38561,9 +38561,9 @@ SHC_3BB0A8C1_0x004F2E00 | 0.0% | Pending SHC_3BB0A8C1_0x004F2E90 | 0.0% | Pending -SHC_3BB0A8C1_0x004F2FB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F2FB0 | 0.0% | Pending -SHC_3BB0A8C1_0x004F2FE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F2FE0 | 0.0% | Pending SHC_3BB0A8C1_0x004F3010 | 0.0% | Pending @@ -38579,7 +38579,7 @@ SHC_3BB0A8C1_0x004F3560 | 0.0% | Pending SHC_3BB0A8C1_0x004F3610 | 0.0% | Pending -SHC_3BB0A8C1_0x004F3700 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F3700 | 0.0% | Pending SHC_3BB0A8C1_0x004F3730 | 0.0% | Pending @@ -38589,9 +38589,9 @@ SHC_3BB0A8C1_0x004F3840 | 0.0% | Pending SHC_3BB0A8C1_0x004F38A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004F3900 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F3900 | 0.0% | Pending -SHC_3BB0A8C1_0x004F3930 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F3930 | 0.0% | Pending SHC_3BB0A8C1_0x004F3960 | 0.0% | Pending @@ -38599,7 +38599,7 @@ SHC_3BB0A8C1_0x004F3B90 | 0.0% | Pending SHC_3BB0A8C1_0x004F3C50 | 0.0% | Pending -SHC_3BB0A8C1_0x004F3D30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F3D30 | 0.0% | Pending SHC_3BB0A8C1_0x004F3D60 | 0.0% | Pending @@ -38633,9 +38633,9 @@ SHC_3BB0A8C1_0x004F4290 | 0.0% | Pending SHC_3BB0A8C1_0x004F49D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004F4C30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F4C30 | 0.0% | Pending -SHC_3BB0A8C1_0x004F4C60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F4C60 | 0.0% | Pending SHC_3BB0A8C1_0x004F4C80 | 0.0% | Pending @@ -38697,7 +38697,7 @@ SHC_3BB0A8C1_0x004F6460 | 0.0% | Pending SHC_3BB0A8C1_0x004F6464 | 0.0% | Pending -SHC_3BB0A8C1_0x004F6470 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F6470 | 0.0% | Pending SHC_3BB0A8C1_0x004F64A0 | 0.0% | Pending @@ -38733,9 +38733,9 @@ SHC_3BB0A8C1_0x004F69D0 | 0.0% | Pending SHC_3BB0A8C1_0x004F6A20 | 0.0% | Pending -SHC_3BB0A8C1_0x004F6A60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F6A60 | 0.0% | Pending -SHC_3BB0A8C1_0x004F6A70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F6A70 | 0.0% | Pending SHC_3BB0A8C1_0x004F6A80 | 0.0% | Pending @@ -38755,11 +38755,11 @@ SHC_3BB0A8C1_0x004F6F90 | 0.0% | Pending SHC_3BB0A8C1_0x004F6FD0 | 0.0% | Pending -SHC_3BB0A8C1_0x004F70B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F70B0 | 0.0% | Pending SHC_3BB0A8C1_0x004F70D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004F70E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x004F70E0 | 0.0% | Pending SHC_3BB0A8C1_0x004F70F0 | 0.0% | Pending @@ -41419,19 +41419,19 @@ SHC_3BB0A8C1_0x00500090 | 0.0% | Pending SHC_3BB0A8C1_0x00500091 | 0.0% | Pending -SHC_3BB0A8C1_0x005000A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005000A0 | 0.0% | Pending SHC_3BB0A8C1_0x005000E0 | 0.0% | Pending SHC_3BB0A8C1_0x00500180 | 0.0% | Pending -SHC_3BB0A8C1_0x00500210 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500210 | 0.0% | Pending SHC_3BB0A8C1_0x00500250 | 0.0% | Pending SHC_3BB0A8C1_0x00500290 | 0.0% | Pending -SHC_3BB0A8C1_0x005002D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005002D0 | 0.0% | Pending SHC_3BB0A8C1_0x00500310 | 0.0% | Pending @@ -41443,19 +41443,19 @@ SHC_3BB0A8C1_0x00500500 | 0.0% | Pending SHC_3BB0A8C1_0x005005F0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500640 | 46.2% | register allocation differs +SHC_3BB0A8C1_0x00500640 | 0.0% | Pending -SHC_3BB0A8C1_0x00500680 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500680 | 0.0% | Pending SHC_3BB0A8C1_0x005006C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500720 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500720 | 0.0% | Pending -SHC_3BB0A8C1_0x00500750 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500750 | 0.0% | Pending SHC_3BB0A8C1_0x00500790 | 0.0% | Pending -SHC_3BB0A8C1_0x005007D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005007D0 | 0.0% | Pending SHC_3BB0A8C1_0x00500800 | 0.0% | Pending @@ -41471,25 +41471,25 @@ SHC_3BB0A8C1_0x00500B50 | 0.0% | Pending SHC_3BB0A8C1_0x00500BB0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500C20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500C20 | 0.0% | Pending -SHC_3BB0A8C1_0x00500C80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500C80 | 0.0% | Pending -SHC_3BB0A8C1_0x00500CB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500CB0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500CF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500CF0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500D30 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500D30 | 0.0% | Pending -SHC_3BB0A8C1_0x00500D60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500D60 | 0.0% | Pending -SHC_3BB0A8C1_0x00500DD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500DD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500E20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500E20 | 0.0% | Pending -SHC_3BB0A8C1_0x00500EE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500EE0 | 0.0% | Pending -SHC_3BB0A8C1_0x00500F40 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00500F40 | 0.0% | Pending SHC_3BB0A8C1_0x00501070 | 0.0% | Pending @@ -41503,19 +41503,19 @@ SHC_3BB0A8C1_0x005010B8 | 0.0% | Pending SHC_3BB0A8C1_0x005010BC | 0.0% | Pending -SHC_3BB0A8C1_0x005010C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005010C0 | 0.0% | Pending SHC_3BB0A8C1_0x005010D0 | 0.0% | Pending -SHC_3BB0A8C1_0x005010E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005010E0 | 0.0% | Pending SHC_3BB0A8C1_0x00501110 | 0.0% | Pending -SHC_3BB0A8C1_0x00501180 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00501180 | 0.0% | Pending -SHC_3BB0A8C1_0x005011A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005011A0 | 0.0% | Pending -SHC_3BB0A8C1_0x005011C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005011C0 | 0.0% | Pending SHC_3BB0A8C1_0x005011F0 | 0.0% | Pending @@ -41535,11 +41535,11 @@ SHC_3BB0A8C1_0x005016D0 | 0.0% | Pending SHC_3BB0A8C1_0x005016E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00501730 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00501730 | 0.0% | Pending SHC_3BB0A8C1_0x00501760 | 0.0% | Pending -SHC_3BB0A8C1_0x005017A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005017A0 | 0.0% | Pending SHC_3BB0A8C1_0x005017C0 | 0.0% | Pending @@ -42067,7 +42067,7 @@ SHC_3BB0A8C1_0x00504ED0 | 0.0% | Pending SHC_3BB0A8C1_0x00504ED1 | 0.0% | Pending -SHC_3BB0A8C1_0x00504EE0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00504EE0 | 0.0% | Pending SHC_3BB0A8C1_0x00504F10 | 0.0% | Pending @@ -44191,7 +44191,7 @@ SHC_3BB0A8C1_0x005116E0 | 0.0% | Pending SHC_3BB0A8C1_0x00511850 | 0.0% | Pending -SHC_3BB0A8C1_0x005118C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005118C0 | 0.0% | Pending SHC_3BB0A8C1_0x005119A4 | 0.0% | Pending @@ -44739,7 +44739,7 @@ SHC_3BB0A8C1_0x005127B0 | 0.0% | Pending SHC_3BB0A8C1_0x005127D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00512920 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00512920 | 0.0% | Pending SHC_3BB0A8C1_0x00512940 | 0.0% | Pending @@ -45743,7 +45743,7 @@ SHC_3BB0A8C1_0x00518180 | 0.0% | Pending SHC_3BB0A8C1_0x005182A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00518350 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00518350 | 0.0% | Pending SHC_3BB0A8C1_0x00518380 | 0.0% | Pending @@ -45773,7 +45773,7 @@ SHC_3BB0A8C1_0x00519850 | 0.0% | Pending SHC_3BB0A8C1_0x005198C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00519960 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00519960 | 0.0% | Pending SHC_3BB0A8C1_0x00519990 | 0.0% | Pending @@ -45839,9 +45839,9 @@ SHC_3BB0A8C1_0x0051AB60 | 0.0% | Pending SHC_3BB0A8C1_0x0051ABB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0051AC80 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0051AC80 | 0.0% | Pending -SHC_3BB0A8C1_0x0051ACB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0051ACB0 | 0.0% | Pending SHC_3BB0A8C1_0x0051ACE0 | 0.0% | Pending @@ -45879,7 +45879,7 @@ SHC_3BB0A8C1_0x0051B420 | 0.0% | Pending SHC_3BB0A8C1_0x0051B570 | 0.0% | Pending -SHC_3BB0A8C1_0x0051B680 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0051B680 | 0.0% | Pending SHC_3BB0A8C1_0x0051B690 | 0.0% | Pending @@ -46161,7 +46161,7 @@ SHC_3BB0A8C1_0x0051D5D0 | 0.0% | Pending SHC_3BB0A8C1_0x0051D5E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0051D680 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0051D680 | 0.0% | Pending SHC_3BB0A8C1_0x0051D690 | 0.0% | Pending @@ -46379,11 +46379,11 @@ SHC_3BB0A8C1_0x00520CD0 | 0.0% | Pending SHC_3BB0A8C1_0x00520F70 | 0.0% | Pending -SHC_3BB0A8C1_0x00521180 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00521180 | 0.0% | Pending SHC_3BB0A8C1_0x005211B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00521210 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00521210 | 0.0% | Pending SHC_3BB0A8C1_0x00521240 | 0.0% | Pending @@ -46633,7 +46633,7 @@ SHC_3BB0A8C1_0x00521EA5 | 0.0% | Pending SHC_3BB0A8C1_0x00521EA6 | 0.0% | Pending -SHC_3BB0A8C1_0x00521EB0 | 76.5% | pop esi scheduling +SHC_3BB0A8C1_0x00521EB0 | 0.0% | Pending SHC_3BB0A8C1_0x00521EF0 | 0.0% | Pending @@ -46765,11 +46765,11 @@ SHC_3BB0A8C1_0x00522083 | 0.0% | Pending SHC_3BB0A8C1_0x00522090 | 0.0% | Pending -SHC_3BB0A8C1_0x00522110 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522110 | 0.0% | Pending -SHC_3BB0A8C1_0x00522150 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522150 | 0.0% | Pending -SHC_3BB0A8C1_0x00522160 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522160 | 0.0% | Pending SHC_3BB0A8C1_0x005221A0 | 0.0% | Pending @@ -46779,15 +46779,15 @@ SHC_3BB0A8C1_0x00522210 | 0.0% | Pending SHC_3BB0A8C1_0x005222B0 | 0.0% | Pending -SHC_3BB0A8C1_0x00522360 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522360 | 0.0% | Pending SHC_3BB0A8C1_0x00522390 | 0.0% | Pending SHC_3BB0A8C1_0x00522410 | 0.0% | Pending -SHC_3BB0A8C1_0x005224E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005224E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00522520 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522520 | 0.0% | Pending SHC_3BB0A8C1_0x00522550 | 0.0% | Pending @@ -46807,11 +46807,11 @@ SHC_3BB0A8C1_0x005229C0 | 0.0% | Pending SHC_3BB0A8C1_0x00522B00 | 0.0% | Pending -SHC_3BB0A8C1_0x00522BC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522BC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00522BF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522BF0 | 0.0% | Pending -SHC_3BB0A8C1_0x00522C20 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00522C20 | 0.0% | Pending SHC_3BB0A8C1_0x00522C50 | 0.0% | Pending @@ -46833,13 +46833,13 @@ SHC_3BB0A8C1_0x005232E0 | 0.0% | Pending SHC_3BB0A8C1_0x005232F0 | 0.0% | Pending -SHC_3BB0A8C1_0x00523340 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00523340 | 0.0% | Pending -SHC_3BB0A8C1_0x00523370 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00523370 | 0.0% | Pending SHC_3BB0A8C1_0x005233A0 | 0.0% | Pending -SHC_3BB0A8C1_0x005233E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005233E0 | 0.0% | Pending SHC_3BB0A8C1_0x00523410 | 0.0% | Pending @@ -46851,7 +46851,7 @@ SHC_3BB0A8C1_0x00523630 | 0.0% | Pending SHC_3BB0A8C1_0x005236A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00523730 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00523730 | 0.0% | Pending SHC_3BB0A8C1_0x00523750 | 0.0% | Pending @@ -46865,11 +46865,11 @@ SHC_3BB0A8C1_0x00523A30 | 0.0% | Pending SHC_3BB0A8C1_0x00523B00 | 0.0% | Pending -SHC_3BB0A8C1_0x00523E00 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00523E00 | 0.0% | Pending SHC_3BB0A8C1_0x00523E30 | 0.0% | Pending -SHC_3BB0A8C1_0x00523EB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00523EB0 | 0.0% | Pending SHC_3BB0A8C1_0x00523EF0 | 0.0% | Pending @@ -46917,7 +46917,7 @@ SHC_3BB0A8C1_0x00524EF0 | 0.0% | Pending SHC_3BB0A8C1_0x00525060 | 0.0% | Pending -SHC_3BB0A8C1_0x00525090 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00525090 | 0.0% | Pending SHC_3BB0A8C1_0x005250B0 | 0.0% | Pending @@ -46947,7 +46947,7 @@ SHC_3BB0A8C1_0x00525970 | 0.0% | Pending SHC_3BB0A8C1_0x00525A70 | 0.0% | Pending -SHC_3BB0A8C1_0x00525B70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00525B70 | 0.0% | Pending SHC_3BB0A8C1_0x00525BA0 | 0.0% | Pending @@ -46959,7 +46959,7 @@ SHC_3BB0A8C1_0x005261B0 | 0.0% | Pending SHC_3BB0A8C1_0x005262A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00526370 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00526370 | 0.0% | Pending SHC_3BB0A8C1_0x005263A0 | 0.0% | Pending @@ -49233,7 +49233,7 @@ SHC_3BB0A8C1_0x0052B9E4 | 0.0% | Pending SHC_3BB0A8C1_0x0052B9E8 | 0.0% | Pending -SHC_3BB0A8C1_0x0052B9F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0052B9F0 | 0.0% | Pending SHC_3BB0A8C1_0x0052BA10 | 0.0% | Pending @@ -49317,9 +49317,9 @@ SHC_3BB0A8C1_0x0052EED0 | 0.0% | Pending SHC_3BB0A8C1_0x0052F010 | 0.0% | Pending -SHC_3BB0A8C1_0x0052F070 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0052F070 | 0.0% | Pending -SHC_3BB0A8C1_0x0052F0A0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0052F0A0 | 0.0% | Pending SHC_3BB0A8C1_0x0052F0D0 | 0.0% | Pending @@ -49345,9 +49345,9 @@ SHC_3BB0A8C1_0x0052F730 | 0.0% | Pending SHC_3BB0A8C1_0x0052F7E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0052FBB0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0052FBB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0052FBF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0052FBF0 | 0.0% | Pending SHC_3BB0A8C1_0x0052FC30 | 0.0% | Pending @@ -49361,7 +49361,7 @@ SHC_3BB0A8C1_0x0052FE90 | 0.0% | Pending SHC_3BB0A8C1_0x0052FF80 | 0.0% | Pending -SHC_3BB0A8C1_0x00530080 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00530080 | 0.0% | Pending SHC_3BB0A8C1_0x005300B0 | 0.0% | Pending @@ -49649,7 +49649,7 @@ SHC_3BB0A8C1_0x00530C40 | 0.0% | Pending SHC_3BB0A8C1_0x00530CF0 | 0.0% | Pending -SHC_3BB0A8C1_0x00530D50 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00530D50 | 0.0% | Pending SHC_3BB0A8C1_0x00530D70 | 0.0% | Pending @@ -49659,11 +49659,11 @@ SHC_3BB0A8C1_0x00530EB0 | 0.0% | Pending SHC_3BB0A8C1_0x00530F20 | 0.0% | Pending -SHC_3BB0A8C1_0x00530FD0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00530FD0 | 0.0% | Pending SHC_3BB0A8C1_0x00531000 | 0.0% | Pending -SHC_3BB0A8C1_0x005311F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005311F0 | 0.0% | Pending SHC_3BB0A8C1_0x00531220 | 0.0% | Pending @@ -50643,7 +50643,7 @@ SHC_3BB0A8C1_0x00532F5D | 0.0% | Pending SHC_3BB0A8C1_0x00532F5E | 0.0% | Pending -SHC_3BB0A8C1_0x00532F60 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00532F60 | 0.0% | Pending SHC_3BB0A8C1_0x00532F80 | 0.0% | Pending @@ -50677,19 +50677,19 @@ SHC_3BB0A8C1_0x00533630 | 0.0% | Pending SHC_3BB0A8C1_0x00533810 | 0.0% | Pending -SHC_3BB0A8C1_0x00533920 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00533920 | 0.0% | Pending SHC_3BB0A8C1_0x00533960 | 0.0% | Pending SHC_3BB0A8C1_0x005339A0 | 0.0% | Pending -SHC_3BB0A8C1_0x005339F0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005339F0 | 0.0% | Pending SHC_3BB0A8C1_0x00533A10 | 0.0% | Pending SHC_3BB0A8C1_0x00533B30 | 0.0% | Pending -SHC_3BB0A8C1_0x00533C70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00533C70 | 0.0% | Pending SHC_3BB0A8C1_0x00533CA0 | 0.0% | Pending @@ -50777,7 +50777,7 @@ SHC_3BB0A8C1_0x00533F84 | 0.0% | Pending SHC_3BB0A8C1_0x00533F85 | 0.0% | Pending -SHC_3BB0A8C1_0x00533F90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00533F90 | 0.0% | Pending SHC_3BB0A8C1_0x00533FC0 | 0.0% | Pending @@ -50809,7 +50809,7 @@ SHC_3BB0A8C1_0x005343C0 | 0.0% | Pending SHC_3BB0A8C1_0x005343F0 | 0.0% | Pending -SHC_3BB0A8C1_0x00534460 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00534460 | 0.0% | Pending SHC_3BB0A8C1_0x00534490 | 0.0% | Pending @@ -50857,7 +50857,7 @@ SHC_3BB0A8C1_0x005350B0 | 0.0% | Pending SHC_3BB0A8C1_0x00535150 | 0.0% | Pending -SHC_3BB0A8C1_0x00535190 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535190 | 0.0% | Pending SHC_3BB0A8C1_0x005351C0 | 0.0% | Pending @@ -51065,11 +51065,11 @@ SHC_3BB0A8C1_0x00535513 | 0.0% | Pending SHC_3BB0A8C1_0x00535514 | 0.0% | Pending -SHC_3BB0A8C1_0x00535520 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535520 | 0.0% | Pending -SHC_3BB0A8C1_0x00535550 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535550 | 0.0% | Pending -SHC_3BB0A8C1_0x00535560 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535560 | 0.0% | Pending SHC_3BB0A8C1_0x00535580 | 0.0% | Pending @@ -51077,15 +51077,15 @@ SHC_3BB0A8C1_0x005355E0 | 0.0% | Pending SHC_3BB0A8C1_0x00535680 | 0.0% | Pending -SHC_3BB0A8C1_0x00535700 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535700 | 0.0% | Pending SHC_3BB0A8C1_0x00535730 | 0.0% | Pending SHC_3BB0A8C1_0x005357E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00535810 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535810 | 0.0% | Pending -SHC_3BB0A8C1_0x00535840 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535840 | 0.0% | Pending SHC_3BB0A8C1_0x00535870 | 0.0% | Pending @@ -51103,7 +51103,7 @@ SHC_3BB0A8C1_0x00535B00 | 0.0% | Pending SHC_3BB0A8C1_0x00535BC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00535DF0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00535DF0 | 0.0% | Pending SHC_3BB0A8C1_0x00535E20 | 0.0% | Pending @@ -51205,9 +51205,9 @@ SHC_3BB0A8C1_0x00536A60 | 0.0% | Pending SHC_3BB0A8C1_0x00536C70 | 0.0% | Pending -SHC_3BB0A8C1_0x00536C90 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00536C90 | 0.0% | Pending -SHC_3BB0A8C1_0x00536CC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00536CC0 | 0.0% | Pending SHC_3BB0A8C1_0x00536CF0 | 0.0% | Pending @@ -51221,17 +51221,17 @@ SHC_3BB0A8C1_0x00536E30 | 0.0% | Pending SHC_3BB0A8C1_0x00537070 | 0.0% | Pending -SHC_3BB0A8C1_0x005370C0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005370C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00537100 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00537100 | 0.0% | Pending -SHC_3BB0A8C1_0x00537130 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00537130 | 0.0% | Pending -SHC_3BB0A8C1_0x00537160 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x00537160 | 0.0% | Pending SHC_3BB0A8C1_0x005371A0 | 0.0% | Pending -SHC_3BB0A8C1_0x005371E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x005371E0 | 0.0% | Pending SHC_3BB0A8C1_0x005371F0 | 0.0% | Pending @@ -59625,9 +59625,9 @@ SHC_3BB0A8C1_0x0053B210 | 0.0% | Pending SHC_3BB0A8C1_0x0053B260 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B310 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053B310 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B340 | 90.91% | jne vs jl due to loop unroll prevention via != +SHC_3BB0A8C1_0x0053B340 | 0.0% | Pending SHC_3BB0A8C1_0x0053B380 | 0.0% | Pending @@ -59637,25 +59637,25 @@ SHC_3BB0A8C1_0x0053B3E0 | 0.0% | Pending SHC_3BB0A8C1_0x0053B4F0 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B530 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053B530 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B570 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053B570 | 0.0% | Pending SHC_3BB0A8C1_0x0053B5A0 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B5E0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053B5E0 | 0.0% | Pending SHC_3BB0A8C1_0x0053B610 | 0.0% | Pending SHC_3BB0A8C1_0x0053B800 | 0.0% | Pending -SHC_3BB0A8C1_0x0053B8B0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053B8B0 | 0.0% | Pending SHC_3BB0A8C1_0x0053B8E0 | 0.0% | Pending SHC_3BB0A8C1_0x0053BB10 | 0.0% | Pending -SHC_3BB0A8C1_0x0053BB70 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053BB70 | 0.0% | Pending SHC_3BB0A8C1_0x0053BB90 | 0.0% | Pending @@ -59669,7 +59669,7 @@ SHC_3BB0A8C1_0x0053C400 | 0.0% | Pending SHC_3BB0A8C1_0x0053C590 | 0.0% | Pending -SHC_3BB0A8C1_0x0053CAC0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053CAC0 | 0.0% | Pending SHC_3BB0A8C1_0x0053CAE0 | 0.0% | Pending @@ -60095,7 +60095,7 @@ SHC_3BB0A8C1_0x0053E820 | 0.0% | Pending SHC_3BB0A8C1_0x0053E870 | 0.0% | Pending -SHC_3BB0A8C1_0x0053E8D0 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0053E8D0 | 0.0% | Pending SHC_3BB0A8C1_0x0053E900 | 0.0% | Pending @@ -60107,12 +60107,8 @@ SHC_3BB0A8C1_0x0053F07C | 0.0% | Pending SHC_3BB0A8C1_0x0053F084 | 0.0% | Pending -SHC_3BB0A8C1_0x0053F088 | 0.0% | Pending - SHC_3BB0A8C1_0x0053F08F | 0.0% | Pending -SHC_3BB0A8C1_0x0053F09C | 0.0% | Pending - SHC_3BB0A8C1_0x0053F0AA | 0.0% | Pending SHC_3BB0A8C1_0x0053F0BA | 0.0% | Pending @@ -67547,7 +67543,7 @@ SHC_3BB0A8C1_0x0057B9BE | 0.0% | Pending SHC_3BB0A8C1_0x0057B9C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0057BE10 | 100.0% | Reimplemented +SHC_3BB0A8C1_0x0057BE10 | 0.0% | Pending SHC_3BB0A8C1_0x0057C815 | 0.0% | Pending @@ -68325,7 +68321,7 @@ SHC_3BB0A8C1_0x00584001 | 0.0% | Pending SHC_3BB0A8C1_0x0058401B | 0.0% | Pending -SHC_3BB0A8C1_0x00584026 | 0.0% | instruction selection differs +SHC_3BB0A8C1_0x00584026 | 0.0% | Pending SHC_3BB0A8C1_0x00584030 | 0.0% | Pending @@ -86289,14 +86285,34 @@ SHC_3BB0A8C1_0x00EE2350 | 0.0% | Pending SHC_3BB0A8C1_0x00EE2354 | 0.0% | Pending +SHC_3BB0A8C1_0x00EE2358 | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE235C | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE2360 | 0.0% | Pending + SHC_3BB0A8C1_0x00EE2364 | 0.0% | Pending SHC_3BB0A8C1_0x00EE2368 | 0.0% | Pending +SHC_3BB0A8C1_0x00EE236C | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE2370 | 0.0% | Pending + SHC_3BB0A8C1_0x00EE2374 | 0.0% | Pending +SHC_3BB0A8C1_0x00EE2378 | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE237C | 0.0% | Pending + SHC_3BB0A8C1_0x00EE2380 | 0.0% | Pending +SHC_3BB0A8C1_0x00EE2384 | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE2388 | 0.0% | Pending + +SHC_3BB0A8C1_0x00EE238C | 0.0% | Pending + SHC_3BB0A8C1_0x00EE2390 | 0.0% | Pending SHC_3BB0A8C1_0x00EE2394 | 0.0% | Pending From 488ce507e00304d3a5a30b69db9799d9b70a7cc1 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 00:56:50 +0200 Subject: [PATCH 02/15] reimplement: SHC_3BB0A8C1_0x004EEE10 99.31% loop-head align jmp Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- ...findAppropriateGridLocationForBuilding.cpp | 26 ++++++++----------- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp b/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp index 21e6ae516..132b3cd48 100644 --- a/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp +++ b/src/OpenSHC/AI/AIVState/findAppropriateGridLocationForBuilding.cpp @@ -23,12 +23,7 @@ namespace AI { this->heatMaps[gridX][gridY].algorithmIterationNumber = this->mapExtraInfo.algorithmIterationNumber; this->heatMaps[gridX][gridY].algorithmVisitCountUnk = this->visitCount; - if (this->algAIndex == this->algBIndex) { - return; - } - uint candidateX; - uint candidateY; - for (;;) { + while (this->algAIndex != this->algBIndex) { int freeCount = 0; int const x = this->heatMapXArray[this->algAIndex]; int const y = this->heatMapYArray[this->algAIndex]; @@ -37,9 +32,9 @@ namespace AI { } this->visitCount = (char)this->heatMaps[x][y].algorithmVisitCountUnk; for (int direction = 0; direction < 8; ++direction) { - candidateX + uint const candidateX = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[direction].int_.xOffset + x; - candidateY + uint const candidateY = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[direction].int_.yOffset + y; if (this->heatMaps[x][y].isNotNearEdgeUnk && (candidateX > 79 || candidateY > 79)) { continue; @@ -72,19 +67,20 @@ namespace AI { } } if (freeCount == 9) { - break; + // the result is the last visited neighbour + uint const resultY + = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[7].int_.yOffset + y; + uint const resultX + = DAT_TerrainDefinedData::instance.clockwiseCardinalTranslationMatrix[7].int_.xOffset + x; + this->buildingApproriateGridXPosition = resultX; + this->buildingAppropriateGridYPosition = resultY; + return; } ++this->algAIndex; if ((int)this->algAIndex >= 6400) { this->algAIndex = 0; } - if (this->algAIndex == this->algBIndex) { - return; - } } - // the result is the last visited neighbour - this->buildingAppropriateGridYPosition = candidateY; - this->buildingApproriateGridXPosition = candidateX; } } diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 59be8904c..aa22e1138 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37955,7 +37955,7 @@ SHC_3BB0A8C1_0x004EEBD0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EECC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004EEE10 | 88.2% | loop rotation; orig rematerial +SHC_3BB0A8C1_0x004EEE10 | 99.3% | loop-head align jmp SHC_3BB0A8C1_0x004EEEC0 | 0.0% | Pending From 97ddba36ee81402dc9509cb6d73b5b14062d949f Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 00:56:50 +0200 Subject: [PATCH 03/15] reimplement: SHC_3BB0A8C1_0x004F1860 91.29% orig re-reads slot ID Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- .../updateBuildingsStateAndUpdateAIBuildingDecisions.cpp | 3 ++- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp index 0c208ec57..6e09124f9 100644 --- a/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp +++ b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp @@ -8,6 +8,7 @@ #include "OpenSHC/string-literals.hpp" #include "OpenSHC/Globals/DAT_AICState.hpp" +#include "OpenSHC/Globals/DAT_AIVState.hpp" #include "OpenSHC/Globals/DAT_BuildingsState.hpp" #include "OpenSHC/Globals/DAT_GameCore.hpp" #include "OpenSHC/Globals/DAT_GameState.hpp" @@ -97,7 +98,7 @@ namespace AI { Map::Buildings::BuildingsState_Func::applySnoozedStateBasedOnPlayerData, DAT_BuildingsState::ptr)(); } if (DAT_GameState::instance.mapAndTime.monthTicks == 10) { - MACRO_CALL_MEMBER(AIVState_Func::recomputeHeatmaps, this)(0); + MACRO_CALL_MEMBER(AIVState_Func::recomputeHeatmaps, DAT_AIVState::ptr)(0); } } diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index aa22e1138..1f6c40e93 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -38007,7 +38007,7 @@ SHC_3BB0A8C1_0x004F14F0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004F15C0 | 98.5% | init stores sit after the aivID branch -SHC_3BB0A8C1_0x004F1860 | 90.8% | orig has a redundant cmp eax,eax +SHC_3BB0A8C1_0x004F1860 | 91.3% | orig re-reads slot ID SHC_3BB0A8C1_0x004F1A60 | 0.0% | Pending From 77cdc54c908cc5f297c7dabc223e52845ade89cd Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 01:06:27 +0200 Subject: [PATCH 04/15] reimplement: SHC_3BB0A8C1_0x004EF0D0 68.1% orig spills y in loop 1 Assign x before y in the keepOrientation == 2 arm, like the other three arms, which is the order the original emits. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/applyAIV.cpp | 2 +- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp index b4e1b2a48..c74f2d7d9 100644 --- a/src/OpenSHC/AI/AIVState/applyAIV.cpp +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -149,8 +149,8 @@ namespace AI { x = 99 - relativeY; y = relativeX; } else if (this->aivs[aivID].keepOrientation == 2) { - y = 99 - relativeX; x = relativeY; + y = 99 - relativeX; } int const tile = DAT_ViewportRenderState::instance.translationMatrix[this->aivs[aivID].keepYOffset + y].addXgetTile diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 1f6c40e93..f3c12647d 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37963,7 +37963,7 @@ SHC_3BB0A8C1_0x004EEF20 | 0.0% | Pending SHC_3BB0A8C1_0x004EF090 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EF0D0 | 67.2% | orig spills y in loop 1 +SHC_3BB0A8C1_0x004EF0D0 | 68.1% | orig spills y in loop 1 SHC_3BB0A8C1_0x004EF130 | 0.0% | Pending From 173a1779b9a1c4dc97837368b01a7671e1e24d3a Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 12:00:10 +0200 Subject: [PATCH 05/15] reimplement: SHC_3BB0A8C1_0x004EF0D0 78.3% orig spills y in loop 1 Store the rotated unit location straight into the player's slot and test the slot for the count, instead of going through a tile local: the original reads the slot back. Measured 67.2% -> 78.3%. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/applyAIV.cpp | 5 ++--- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp index c74f2d7d9..a4e50d312 100644 --- a/src/OpenSHC/AI/AIVState/applyAIV.cpp +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -152,11 +152,10 @@ namespace AI { x = relativeY; y = 99 - relativeX; } - int const tile + DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[unitType][i] = DAT_ViewportRenderState::instance.translationMatrix[this->aivs[aivID].keepYOffset + y].addXgetTile + this->aivs[aivID].keepXOffset + x; - DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[unitType][i] = tile; - if (tile > 0) { + if (DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlots[unitType][i] > 0) { ++DAT_GameState::instance.playerDataArray[playerID].aivUnitLocationSlotLocationCount[unitType]; } } diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index f3c12647d..d4d15ccf3 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37963,7 +37963,7 @@ SHC_3BB0A8C1_0x004EEF20 | 0.0% | Pending SHC_3BB0A8C1_0x004EF090 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EF0D0 | 68.1% | orig spills y in loop 1 +SHC_3BB0A8C1_0x004EF0D0 | 78.3% | orig spills y in loop 1 SHC_3BB0A8C1_0x004EF130 | 0.0% | Pending From 6d7f9596d8bbf0e5118562faf46bf825c3f27dc1 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 12:00:10 +0200 Subject: [PATCH 06/15] reimplement: SHC_3BB0A8C1_0x004F0E80 94.0% loop 1 schedules the x diff first Give the L_ROCKY arm of the update loop its own gridY local like the other three arms. Measured 88.9% -> 94.0%. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp | 3 ++- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp index 930ebd328..7b5837892 100644 --- a/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp +++ b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp @@ -143,7 +143,8 @@ namespace AI { if (DAT_TileMapState::instance.LogicLayer[tile] & L_ROCKY) { int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; int const gridX = (tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile) / 5; - ++this->heatMaps[gridX][y / 5].impassableCount; + int const gridY = y / 5; + ++this->heatMaps[gridX][gridY].impassableCount; } if (DAT_TileMapState::instance.LogicLayer[tile] & L_TREE) { int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index d4d15ccf3..a997e10ba 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37995,7 +37995,7 @@ SHC_3BB0A8C1_0x004F0060 | 53.6% | step < 50 fix; registers differ SHC_3BB0A8C1_0x004F0690 | 0.0% | Pending -SHC_3BB0A8C1_0x004F0E80 | 88.9% | rest is scheduling + a hoisted +SHC_3BB0A8C1_0x004F0E80 | 94.0% | rest is scheduling + a hoisted SHC_3BB0A8C1_0x004F1190 | 0.0% | Pending From 4d9c2204a4982a529a445b423d6a91b977b0e146 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 12:21:04 +0200 Subject: [PATCH 07/15] reimplement: SHC_3BB0A8C1_0x004EFAB0 100.0% Reimplemented Index the heat map with the grid position cast to uint. The original compares the position against -1 from memory and then reloads it for the index, so the two reads are different expressions; the cast stops them being merged. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp | 5 +++-- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp b/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp index b115a429c..801074065 100644 --- a/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp +++ b/src/OpenSHC/AI/AIVState/aiPlaceWoodcuttershut.cpp @@ -22,7 +22,7 @@ namespace AI { if (this->buildingApproriateGridXPosition == -1) { return; } - this->heatMaps[this->buildingApproriateGridXPosition][this->buildingAppropriateGridYPosition] + this->heatMaps[(uint)this->buildingApproriateGridXPosition][(uint)this->buildingAppropriateGridYPosition] .woodRelatedCountdownTo0 = 4; // search around the result of the woodcutter search MACRO_CALL_MEMBER(AIVState_Func::findSuitableGridLocationFittingCriteria, this)( @@ -30,7 +30,8 @@ namespace AI { if (this->buildingApproriateGridXPosition == -1) { return; } - ++this->heatMaps[this->buildingApproriateGridXPosition][this->buildingAppropriateGridYPosition].structureCount; + ++this->heatMaps[(uint)this->buildingApproriateGridXPosition][(uint)this->buildingAppropriateGridYPosition] + .structureCount; MACRO_CALL_MEMBER(Map::TileMapState_Func::placeBuilding, DAT_TileMapState::ptr)(playerID, this->buildingApproriateGridXPosition * 5, this->buildingAppropriateGridYPosition * 5, Commands::M_MAPPER_WOODSMAN, diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index a997e10ba..f183a952e 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37979,7 +37979,7 @@ SHC_3BB0A8C1_0x004EF920 | 0.0% | Pending SHC_3BB0A8C1_0x004EFA60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EFAB0 | 91.4% | Register reuse after search +SHC_3BB0A8C1_0x004EFAB0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004EFB90 | 100.0% | Reimplemented From 433e2b0dd92644d1f04270b048c64f7bcd4e89fd Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 12:21:04 +0200 Subject: [PATCH 08/15] reimplement: SHC_3BB0A8C1_0x004F15C0 99.0% stepIncrement init after aivID test Initialise isPausing before the aivID test like the original; hoisting stepIncrement as well inverts the ebx/edi allocation and loses 17 points. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp | 4 ++-- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp b/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp index a0c2c6e69..912593888 100644 --- a/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp +++ b/src/OpenSHC/AI/AIVState/aiDecideOnNewBuildings.cpp @@ -9,15 +9,15 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004F15C0 - void AIVState::aiDecideOnNewBuildings(PlayerID playerID) + void AIVState::aiDecideOnNewBuildings(int playerID) { int const aivID = DAT_GameState::instance.playerDataArray[playerID].aivID; + int isPausing = 0; if (aivID <= 0) { return; } - int isPausing = 0; int stepIncrement = 1; if (DAT_GameState::instance.playerDataArray[playerID].resourceRebuildDelay != 0) { diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index f183a952e..aa2670240 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -38005,7 +38005,7 @@ SHC_3BB0A8C1_0x004F13F0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004F14F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004F15C0 | 98.5% | init stores sit after the aivID branch +SHC_3BB0A8C1_0x004F15C0 | 99.0% | init stores sit after the aivID branch SHC_3BB0A8C1_0x004F1860 | 91.3% | orig re-reads slot ID From fe4dbace59f8dff2cf4146284defec79d40e8f7a Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 15:46:54 +0200 Subject: [PATCH 09/15] reimplement: SHC_3BB0A8C1_0x004ECBC0 100.0% Reimplemented Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- .../AI/AIVState/hostChecksLobbyAIVAvailability.cpp | 12 ++++++++---- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp b/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp index b8deb1d27..8171ac18c 100644 --- a/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp +++ b/src/OpenSHC/AI/AIVState/hostChecksLobbyAIVAvailability.cpp @@ -25,6 +25,8 @@ namespace AI { int const localPlayer = DAT_GameSynchronyState::instance.currentPlayerSlotID; DAT_GameCore::instance.numOfAIsWithCastleUnk = 0; for (int aiIndex = 0; aiIndex < 16; ++aiIndex) { + // the original walks this entry with its own pointer next to the received array + int const* const availability = &this->aivFileAvailabilityPerAIArray[aiIndex]; BOOLEnum available = TRUE; for (int player = 1; player < 9; ++player) { if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1) { @@ -35,12 +37,12 @@ namespace AI { if (player != localPlayer) { continue; } - if (this->aivFileAvailabilityPerAIArray[aiIndex] == 0) { + if (*availability == 0) { available = FALSE; break; } } else if (player == localPlayer) { - if (this->aivFileAvailabilityPerAIArray[aiIndex] == 0) { + if (*availability == 0) { available = FALSE; break; } @@ -64,10 +66,12 @@ namespace AI { || DAT_GameSynchronyState::instance.currentAIArray[player] == 0) { continue; } + // read through an alias: the original loads the AI ID again after the test above + int const& ai = DAT_GameSynchronyState::instance.currentAIArray[player]; + int const aiID = ai; BOOLEnum hasAIV = FALSE; for (int i = 0; i < DAT_GameCore::instance.numOfAIsWithCastleUnk; ++i) { - if (DAT_GameSynchronyState::instance.currentAIArray[player] - == DAT_GameCore::instance.arrayOfLordIdsWithAIVsUnk[i]) { + if (aiID == DAT_GameCore::instance.arrayOfLordIdsWithAIVsUnk[i]) { hasAIV = TRUE; break; } diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index aa2670240..1030f863a 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37873,7 +37873,7 @@ SHC_3BB0A8C1_0x004ECAB0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ECAD0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004ECBC0 | 68.6% | orig branch shape; registers differ +SHC_3BB0A8C1_0x004ECBC0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004ECCA0 | 0.0% | Pending From c2a3dcca776f67ef1e67f05d06fccd59e7f27f71 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 15:46:54 +0200 Subject: [PATCH 10/15] reimplement: SHC_3BB0A8C1_0x004F1860 100.0% Reimplemented Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- .../updateBuildingsStateAndUpdateAIBuildingDecisions.cpp | 5 ++++- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp index 6e09124f9..4c77c23e1 100644 --- a/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp +++ b/src/OpenSHC/AI/AIVState/updateBuildingsStateAndUpdateAIBuildingDecisions.cpp @@ -33,8 +33,11 @@ namespace AI { this->mapExtraInfo.algBuildingPlacementNudge = 0; } for (int player = 1; player < 9; ++player) { + // the original tests the slot ID a third time through an alias of the same element + int const& fullID = DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player]; if (DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == -1 - && DAT_GameSynchronyState::instance.currentAIArray[player] == 0) { + && DAT_GameSynchronyState::instance.currentAIArray[player] == 0 + && DAT_GameSynchronyState::instance.currentPlayerFullIDArray[player] == fullID) { continue; } if (MACRO_CALL_MEMBER(Game::GameStateStructures_Func::checkKeepEnclosed, DAT_GameState::ptr)(player)) { diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 1030f863a..d8da36541 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -38007,7 +38007,7 @@ SHC_3BB0A8C1_0x004F14F0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004F15C0 | 99.0% | init stores sit after the aivID branch -SHC_3BB0A8C1_0x004F1860 | 91.3% | orig re-reads slot ID +SHC_3BB0A8C1_0x004F1860 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004F1A60 | 0.0% | Pending From 8ee7603fcd439e7b7602acc2dcd29d0a4a8af7b1 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 18:02:44 +0200 Subject: [PATCH 11/15] reimplement: SHC_3BB0A8C1_0x004EF0D0 84.1% loop 2 step/realY allocation Drop the hand-written `if (startY >= 100) break;` (it left a path where y was read unassigned, merging the per-loop y webs), compute the tile before the step stores in loops 1 and 2, and write loop 2's reject branch as a continue. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/applyAIV.cpp | 37 +++++++++++++--------------- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp index a4e50d312..839ac820b 100644 --- a/src/OpenSHC/AI/AIVState/applyAIV.cpp +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -62,12 +62,12 @@ namespace AI { DAT_ViewportRenderState::ptr)(this->aivs[aivID].keepXOffset + x, realY)) { continue; } + int const tile = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile + + this->aivs[aivID].keepXOffset + x; this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; this->aivs[aivID].aivBuildingSteps[step].quantity = 1; - this->aivs[aivID].aivBuildingSteps[step].location.tile.tile - = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile - + this->aivs[aivID].keepXOffset + x; + this->aivs[aivID].aivBuildingSteps[step].location.tile.tile = tile; if (step > this->aivs[aivID].totalSteps) { this->aivs[aivID].totalSteps = step; } @@ -81,9 +81,6 @@ namespace AI { do { selected = FALSE; index = startY * 100; - if (startY >= 100) { - break; - } int step; MappersEnum mapper; for (y = startY; y < 100; ++y) { @@ -106,22 +103,22 @@ namespace AI { } uint const realX = this->aivs[aivID].keepXOffset + x; uint const realY = this->aivs[aivID].keepYOffset + y; - if (realX <= 399 && realY <= 399 - && DAT_ViewportRenderState::instance.DAT_BinaryTileMap400x400[realY * 400 + realX]) { - this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; - this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; - ++this->aivs[aivID].aivBuildingSteps[step].quantity; - this->aivs[aivID].locationsArray[this->aivs[aivID].wallLocationsArrayIndex] - = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile - + this->aivs[aivID].keepXOffset + x; - ++this->aivs[aivID].wallLocationsArrayIndex; - if (step > this->aivs[aivID].totalSteps) { - this->aivs[aivID].totalSteps = step; - } - this->isHandled[index] = 1; - } else { + if (realX > 399 || realY > 399 + || !DAT_ViewportRenderState::instance.DAT_BinaryTileMap400x400[realY * 400 + realX]) { this->isHandled[index] = 1; + continue; } + int const tile = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile + + this->aivs[aivID].keepXOffset + x; + this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; + this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; + ++this->aivs[aivID].aivBuildingSteps[step].quantity; + this->aivs[aivID].locationsArray[this->aivs[aivID].wallLocationsArrayIndex] = tile; + ++this->aivs[aivID].wallLocationsArrayIndex; + if (step > this->aivs[aivID].totalSteps) { + this->aivs[aivID].totalSteps = step; + } + this->isHandled[index] = 1; } } } while (selected); diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index d8da36541..334d211e1 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37963,7 +37963,7 @@ SHC_3BB0A8C1_0x004EEF20 | 0.0% | Pending SHC_3BB0A8C1_0x004EF090 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EF0D0 | 78.3% | orig spills y in loop 1 +SHC_3BB0A8C1_0x004EF0D0 | 84.1% | loop 2 step/realY allocation SHC_3BB0A8C1_0x004EF130 | 0.0% | Pending From 508772c877c4cbb6b9c7a9f81e86e1c83396c297 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 18:16:07 +0200 Subject: [PATCH 12/15] reimplement: SHC_3BB0A8C1_0x004EF0D0 89.8% loop 2 reject-branch layout Loop 2 indexes the translation matrix by keepYOffset + y written out (the original consumes realY in the multiply and reloads nothing), y is initialised at its declaration, and loop 1 passes keepYOffset + y to xyAreValid with a realX local beside realY. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/applyAIV.cpp | 11 +++++++---- status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp index 839ac820b..7a4f53181 100644 --- a/src/OpenSHC/AI/AIVState/applyAIV.cpp +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -24,9 +24,9 @@ namespace AI { // single buildings and the keep, steps is accessed as a flat 100 * 100 array int x; - int y; + int y = 0; int index = 0; - for (y = 0; y < 100; ++y) { + for (; y < 100; ++y) { for (x = 0; x < 100; ++x, ++index) { if (this->isHandled[index]) { continue; @@ -58,8 +58,9 @@ namespace AI { continue; } int const realY = this->aivs[aivID].keepYOffset + y; + int const realX = this->aivs[aivID].keepXOffset + x; if (!MACRO_CALL_MEMBER(Rendering::ViewportRenderState_Func::xyAreValid, - DAT_ViewportRenderState::ptr)(this->aivs[aivID].keepXOffset + x, realY)) { + DAT_ViewportRenderState::ptr)(realX, this->aivs[aivID].keepYOffset + y)) { continue; } int const tile = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile @@ -108,7 +109,9 @@ namespace AI { this->isHandled[index] = 1; continue; } - int const tile = DAT_ViewportRenderState::instance.translationMatrix[realY].addXgetTile + int const tile + = DAT_ViewportRenderState::instance.translationMatrix[this->aivs[aivID].keepYOffset + y] + .addXgetTile + this->aivs[aivID].keepXOffset + x; this->aivs[aivID].aivBuildingSteps[step].buildStatus = AIVBSS_unbuilt; this->aivs[aivID].aivBuildingSteps[step].buildingType = mapper; diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 334d211e1..c5efd9954 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -37963,7 +37963,7 @@ SHC_3BB0A8C1_0x004EEF20 | 0.0% | Pending SHC_3BB0A8C1_0x004EF090 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004EF0D0 | 84.1% | loop 2 step/realY allocation +SHC_3BB0A8C1_0x004EF0D0 | 89.8% | loop 2 reject-branch layout SHC_3BB0A8C1_0x004EF130 | 0.0% | Pending From b52a0212d71d280a06cb2cb9f945e9e6144596d4 Mon Sep 17 00:00:00 2001 From: Gynt Date: Thu, 15 Oct 2026 23:15:12 +0200 Subject: [PATCH 13/15] reimplement: SHC_3BB0A8C1_0x004EF0D0 93.0% loop 2 range tests as signed pairs Loop 2 rejects a tile with three separate ifs, the range checks written as realX < 0 || realX > 399 (int locals, realY declared first). MSVC folds each pair into the original's single unsigned compare, keeps the map test's reject block inline and merges the realY reject into it, which also restores the original's loop 3 prologue store order. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0179pNuXVNcvqm3mQfQaRDMs --- src/OpenSHC/AI/AIVState/applyAIV.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/applyAIV.cpp b/src/OpenSHC/AI/AIVState/applyAIV.cpp index 7a4f53181..03cb7b5a4 100644 --- a/src/OpenSHC/AI/AIVState/applyAIV.cpp +++ b/src/OpenSHC/AI/AIVState/applyAIV.cpp @@ -102,10 +102,17 @@ namespace AI { } else if (this->steps[0][index] != step) { continue; } - uint const realX = this->aivs[aivID].keepXOffset + x; - uint const realY = this->aivs[aivID].keepYOffset + y; - if (realX > 399 || realY > 399 - || !DAT_ViewportRenderState::instance.DAT_BinaryTileMap400x400[realY * 400 + realX]) { + int const realY = this->aivs[aivID].keepYOffset + y; + int const realX = this->aivs[aivID].keepXOffset + x; + if (realX < 0 || realX > 399) { + this->isHandled[index] = 1; + continue; + } + if (realY < 0 || realY > 399) { + this->isHandled[index] = 1; + continue; + } + if (!DAT_ViewportRenderState::instance.DAT_BinaryTileMap400x400[realY * 400 + realX]) { this->isHandled[index] = 1; continue; } From 76e9d689f6c82cc8334e550b0a81bde4a53b5443 Mon Sep 17 00:00:00 2001 From: Gynt Date: Fri, 16 Oct 2026 21:35:12 +0200 Subject: [PATCH 14/15] improvements --- src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp | 2 +- src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp b/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp index 1dc63dacd..29d096362 100644 --- a/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp +++ b/src/OpenSHC/AI/AIVState/aiPlaceFlag.cpp @@ -14,7 +14,7 @@ namespace OpenSHC { namespace AI { // FUNCTION: STRONGHOLDCRUSADER 0x004ED240 - void AIVState::aiPlaceFlag(PlayerID playerID) + void AIVState::aiPlaceFlag(int playerID) { Map::Entities::EntityType const flagType = (Map::Entities::EntityType)DAT_AICState::instance diff --git a/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp index cb4e3aa55..8a903714e 100644 --- a/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp +++ b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp @@ -20,7 +20,7 @@ namespace AI { // builds a generic castle for AIs without an AIV, the number of each building depends on the AI character // FUNCTION: STRONGHOLDCRUSADER 0x004F0060 - BOOLEnum AIVState::executeDefaultCastleAIV(PlayerID playerID, int isPausing) + BOOLEnum AIVState::executeDefaultCastleAIV(int playerID, int isPausing) { int const aivID = DAT_GameState::instance.playerDataArray[playerID].aivID; int stockpiles = 0; @@ -623,7 +623,7 @@ namespace AI { orientation); int const placedID = DAT_TileMapState::instance.placedBuildingID; if (!DAT_TileMapState::instance.buildingPlacementFail) { - DAT_BuildingsState::instance.buildings[placedID].field242_0x2c8 = 1; + DAT_BuildingsState::instance.buildings[placedID].field240_0x2c8 = 1; MACRO_CALL_MEMBER(AICState_Func::setupWorkshopProductionType, DAT_AICState::ptr)(playerID, placedID); this->aivs[aivID].aivBuildingSteps[step].location.tile.tile = tile; if (!DAT_TileMapState::instance.buildingPlacementFail) { From 3ba52871487e59e519c7f46829514258ba082ec4 Mon Sep 17 00:00:00 2001 From: Gynt Date: Fri, 23 Oct 2026 01:16:52 +0200 Subject: [PATCH 15/15] fix(AIVState): build against current main headers; drop a decompiler artefact Merging main brought the regenerated Building.hpp, where the field at offset 0x2C8 is now `field202_0x2c8`. Two AIVState sources still used the old `field240_0x2c8` and no longer compiled; main does not notice because its cmake/openshc-sources.txt is empty, so nothing under src/OpenSHC is built there. Same offset, same type, so the rename is the whole fix. recomputeHeatmaps also loses a duplicated subexpression: the Y component was looked up twice, once for gridY and again as the translationMatrix index. It is now hoisted into `y`, with `x` beside it and the two divisions after, which is also the order the original computes them in. Measured neutral. reccmp, reimplemented data and all 38 AIVState resolvers enabled: avg 98.24 over 38, unchanged, with nothing regressed. Not fixed, recorded for the next pass. The loss is concentrated in executeDefaultCastleAIV (53.6%/51.9%, 299 of the 326 lost instructions). Its whole frame is shifted: the original keeps the constant 1 in ebp for the function and derives 8 as `lea edx, [ebp + 7]`, computes playerID * 0x39f4 before the register pushes, and lays its 21 counter locals out in a different stack order, so the declaration order differs from ours. quick_reorder.py -s over that declaration block is the right lever but each trial recompiles a 643-line file into a 20MB /FA listing, so a single pass runs for hours and blocks every other build; the moves it found inside one partial pass measured neutral on reccmp and were reverted. applyAIV (93.0/85.7) is a uniform 4-byte stack-slot shift, so the original has one more 4-byte local than we do. Swapping the keepY/keepX store order (0.9402 -> 0.9297) and giving the second pass its own loop variables (0.9402 -> 0.5170) both measured worse; moving keepDefined past the two opening calls (0.9376) likewise. The remaining five are one instruction each: scheduling across a branch, or a `_chkstk` call target in computeLargestSeparateArea whose normalized score is already 100. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_013Fzi11pcBU1Y7Y4oanrZQL --- src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp | 2 +- src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp | 2 +- src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp | 11 ++++------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp b/src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp index a4f565788..5e947a8bf 100644 --- a/src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp +++ b/src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp @@ -297,7 +297,7 @@ namespace AI { orientation); int const placedID = DAT_TileMapState::instance.placedBuildingID; if (!DAT_TileMapState::instance.buildingPlacementFail) { - DAT_BuildingsState::instance.buildings[placedID].field240_0x2c8 = 1; + DAT_BuildingsState::instance.buildings[placedID].field202_0x2c8 = 1; MACRO_CALL_MEMBER(AICState_Func::setupWorkshopProductionType, DAT_AICState::ptr)(playerID, placedID); } if (!DAT_TileMapState::instance.buildingPlacementFail) { diff --git a/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp index 8a903714e..91c249303 100644 --- a/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp +++ b/src/OpenSHC/AI/AIVState/executeDefaultCastleAIV.cpp @@ -623,7 +623,7 @@ namespace AI { orientation); int const placedID = DAT_TileMapState::instance.placedBuildingID; if (!DAT_TileMapState::instance.buildingPlacementFail) { - DAT_BuildingsState::instance.buildings[placedID].field240_0x2c8 = 1; + DAT_BuildingsState::instance.buildings[placedID].field202_0x2c8 = 1; MACRO_CALL_MEMBER(AICState_Func::setupWorkshopProductionType, DAT_AICState::ptr)(playerID, placedID); this->aivs[aivID].aivBuildingSteps[step].location.tile.tile = tile; if (!DAT_TileMapState::instance.buildingPlacementFail) { diff --git a/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp index 7b5837892..073c7366c 100644 --- a/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp +++ b/src/OpenSHC/AI/AIVState/recomputeHeatmaps.cpp @@ -58,13 +58,10 @@ namespace AI { if (initialize) { for (int tile = 0; tile < 80400; ++tile) { - int const gridY = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile] / 5; - int const gridX = (tile - - DAT_ViewportRenderState::instance - .translationMatrix[DAT_ViewportRenderState::instance - .tileTranslationMatrix_YComponent[tile]] - .addXgetTile) - / 5; + int const y = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tile]; + int const x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + int const gridY = y / 5; + int const gridX = x / 5; if (gridX >= 1 && gridX <= 78 && gridY >= 1 && gridY <= 78) { this->heatMaps[gridX][gridY].isNotNearEdgeUnk = 0; }