Skip to content
4 changes: 3 additions & 1 deletion cmake/compiler-flags-gl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ src/OpenSHC/Map/Buildings/BuildingsState/applyVersionUpgradeAccessibilityRecompu
src/OpenSHC/Map/Buildings/BuildingsState/recomputeAccessibilityForAllBuildings.cpp
src/OpenSHC/Map/Buildings/BuildingsState/getResourceSpace.cpp
src/OpenSHC/Synchrony/GameSynchronyState/processSyncPacket.cpp
src/OpenSHC/Synchrony/GameSynchronyState/translateMultiplayerIDsIntoPlayerIDs.cpp
src/OpenSHC/Synchrony/GameSynchronyState/translateMultiplayerIDsIntoPlayerIDs.cpp
src/OpenSHC/Map/Buildings/BuildingsState/processResourceLoss.cpp
src/OpenSHC/Map/Buildings/BuildingsState/canUnitReachBuildingPerimeter.cpp
2 changes: 1 addition & 1 deletion src/OpenSHC/AI/AIVState/aiPlaceAIVBuilding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ namespace AI {
orientation);
int const placedID = DAT_TileMapState::instance.placedBuildingID;
if (!DAT_TileMapState::instance.buildingPlacementFail) {
DAT_BuildingsState::instance.buildings[placedID].field202_0x2c8 = 1;
DAT_BuildingsState::instance.buildings[placedID].field201_0x2c8 = 1;
MACRO_CALL_MEMBER(AICState_Func::setupWorkshopProductionType, DAT_AICState::ptr)(playerID, placedID);
}
if (!DAT_TileMapState::instance.buildingPlacementFail) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "../BuildingsState.func.hpp"

#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"
#include "OpenSHC/Map/Units/UnitsState.func.hpp"

#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
#include "OpenSHC/Globals/DAT_TileMapState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp"

#include <stdlib.h>

namespace OpenSHC {
namespace Map {
namespace Buildings {

// FUNCTION: STRONGHOLDCRUSADER 0x004105F0
BOOLEnum BuildingsState::canUnitReachAdjacentTile(int param_1, int param_2)
{
int const row = DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[param_1];
int const unitArea
= (short)DAT_TileMapState::instance.PathConnectionLayer[DAT_UnitsState::instance.units[param_2].tile];
int const height = DAT_TileMapState::instance.HeightLayer[param_1];
if (MACRO_CALL_MEMBER(Units::UnitsState_Func::selectionContainsOnlyArabAssassins, DAT_UnitsState::ptr)()
!= FALSE) {
return FALSE;
}
for (int direction = 0; direction < 8; ++direction) {
int const area
= (short)DAT_TileMapState::instance
.PathConnectionLayer[DAT_TileMapState::instance.directionTranslationMatrix[row][direction]
+ param_1];
// The original compares the height of param_1 with itself, not with the neighbouring tile.
if (abs(height - DAT_TileMapState::instance.HeightLayer[param_1]) < 16 && area != 0
&& MACRO_CALL_MEMBER(
Navigation::PathFindingState_Func::calculateCanPlayerUnitsNavigateToAreaFromArea,
DAT_PathFindingState::ptr)(DAT_UnitsState::instance.units[param_2].owner, unitArea, area,
MACRO_CALL_MEMBER(Units::UnitsState_Func::canAUnitClimb, DAT_UnitsState::ptr)())
!= 0) {
return TRUE;
}
}
return FALSE;
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "../BuildingsState.func.hpp"

#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"
#include "OpenSHC/Map/Units/UnitsState.func.hpp"

#include "OpenSHC/Globals/DAT_BuildingDefinedData.hpp"
#include "OpenSHC/Globals/DAT_BuildingsState.hpp"
#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
#include "OpenSHC/Globals/DAT_TileMapState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp"

#include <stdlib.h>

namespace OpenSHC {
namespace Map {
namespace Buildings {

// FUNCTION: STRONGHOLDCRUSADER 0x00410440
BOOLEnum BuildingsState::canUnitReachBuildingPerimeter(int buildingID, int unitID)
{
if (buildingID == 0 || buildingID >= 2000) {
return FALSE;
}
int const unitArea
= (short)DAT_TileMapState::instance.PathConnectionLayer[DAT_UnitsState::instance.units[unitID].tile];
int const size = this->buildings[buildingID].widthOrHeight;
int const buildingHeight
= DAT_TileMapState::instance.DefaultHeightLayer[DAT_BuildingsState::instance.buildings[buildingID]
.currentTilePositionAdjusted];
int const tileCount = DAT_BuildingDefinedData::instance.BuildingAccessibleTilesCount[size];
int onlyAssassins = 0;
if (MACRO_CALL_MEMBER(Units::UnitsState_Func::selectionContainsOnlyArabAssassins, DAT_UnitsState::ptr)()
!= FALSE) {
onlyAssassins = 1;
}
for (int i = 0; i < tileCount; ++i) {
MACRO_CALL_MEMBER(BuildingsState_Func::setupNextCandidateLocationComputeOffsets2, this)(size, 1, i, 0);
int const tile = DAT_ViewportRenderState::instance
.translationMatrix[this->buildings[buildingID].y + this->DAT_TempYOffset]
.addXgetTile
+ this->buildings[buildingID].x + this->DAT_TempXOffset;
int const area = (short)DAT_TileMapState::instance.PathConnectionLayer[tile];
int tileHeight = DAT_TileMapState::instance.HeightLayer[tile];
if (DAT_TileMapState::instance.BuildingLayer[tile] != 0) {
tileHeight += MACRO_CALL_MEMBER(BuildingsState_Func::getBuildingHeightForBuildingID,
DAT_BuildingsState::ptr)(DAT_TileMapState::instance.BuildingLayer[tile]);
}
if (abs(buildingHeight - tileHeight) >= 16 || area == 0) {
continue;
}
int reachable;
if (onlyAssassins == 1) {
reachable
= MACRO_CALL_MEMBER(Navigation::PathFindingState_Func::calculateCanReachUsingCachedAreaLogic,
DAT_PathFindingState::ptr)(DAT_UnitsState::instance.units[unitID].tile, tile);
} else {
reachable = MACRO_CALL_MEMBER(
Navigation::PathFindingState_Func::calculateCanPlayerUnitsNavigateToAreaFromArea,
DAT_PathFindingState::ptr)(DAT_UnitsState::instance.units[unitID].owner, unitArea, area,
MACRO_CALL_MEMBER(Units::UnitsState_Func::canAUnitClimb, DAT_UnitsState::ptr)());
}
if (reachable != 0) {
return TRUE;
}
}
return FALSE;
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Map {
if (this->buildings[buildingID].logicalState == BLS_NORMAL
&& this->buildings[buildingID].owner == playerID
&& this->buildings[buildingID].buildingType == buildingType
&& (includeBool == 0 || this->buildings[buildingID].field202_0x2c8 == 0)) {
&& (includeBool == 0 || this->buildings[buildingID].field201_0x2c8 == 0)) {
++count;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/OpenSHC/Map/Buildings/BuildingsState/countFarms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Map {
&& (this->buildings[buildingID].buildingType == BT_WHEATFARM
|| this->buildings[buildingID].buildingType == BT_APPLEFARM
|| this->buildings[buildingID].buildingType == BT_DAIRYFARM)
&& (param_2 == 0 || this->buildings[buildingID].field202_0x2c8 == 0)) {
&& (param_2 == 0 || this->buildings[buildingID].field201_0x2c8 == 0)) {
++count;
}
}
Expand Down
57 changes: 57 additions & 0 deletions src/OpenSHC/Map/Buildings/BuildingsState/countPlayerResources.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp"
#include "OpenSHC/Map/Buildings/BuildingLogicalState.hpp"
#include "OpenSHC/Map/Buildings/BuildingType.hpp"

#include "OpenSHC/Globals/DAT_GameState.hpp"

namespace OpenSHC {
namespace Map {
namespace Buildings {

using OpenSHC::Map::Buildings::BuildingLogicalState;
using OpenSHC::Map::Buildings::BuildingType;

// FUNCTION: STRONGHOLDCRUSADER 0x0040C300
void BuildingsState::countPlayerResources(int playerID)
{
int gold
= DAT_GameState::instance.playerDataArray[playerID].currentResources[OpenSHC::Game::Resources::RT_GOLD];

// Reset the stored resources and recount them from the storage buildings, gold is kept
for (int i = 0; i < 25; ++i) {
if (i != OpenSHC::Game::Resources::RT_GOLD) {
DAT_GameState::instance.playerDataArray[playerID].currentResources[i] = 0;
}
}
for (int i = 1; i < this->maxBuildingsCount; ++i) {
if (this->buildings[i].logicalState != BLS_NORMAL || this->buildings[i].owner != playerID) {
continue;
}
if (this->buildings[i].buildingType != BT_STOCKPILE && this->buildings[i].buildingType != BT_GRANARY
&& this->buildings[i].buildingType != BT_ARMORY) {
continue;
}
if (this->buildings[i].buildingType == BT_STOCKPILE) {
for (int r = OpenSHC::Game::Resources::RT_WOOD; r <= OpenSHC::Game::Resources::RT_FLOUR; ++r) {
DAT_GameState::instance.playerDataArray[playerID].currentResources[r]
+= this->buildings[i].resources[r];
}
} else if (this->buildings[i].buildingType == BT_GRANARY) {
for (int r = OpenSHC::Game::Resources::RT_BREAD; r <= OpenSHC::Game::Resources::RT_APPLE; ++r) {
DAT_GameState::instance.playerDataArray[playerID].currentResources[r]
+= this->buildings[i].resources[r];
}
} else if (this->buildings[i].buildingType == BT_ARMORY) {
for (int r = OpenSHC::Game::Resources::RT_BOW; r < 25; ++r) {
DAT_GameState::instance.playerDataArray[playerID].currentResources[r]
+= this->buildings[i].resources[r];
}
}
}
DAT_GameState::instance.playerDataArray[playerID].currentResources[OpenSHC::Game::Resources::RT_GOLD]
= gold;
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "../BuildingsState.func.hpp"

#include "OpenSHC/Map/Entities/EntityState.func.hpp"
#include "OpenSHC/Map/TileMapState.func.hpp"
#include "OpenSHC/Map/Buildings/BuildingType.hpp"

#include "OpenSHC/Globals/DAT_BuildingDefinedData.hpp"
#include "OpenSHC/Globals/DAT_BuildingsState.hpp"
#include "OpenSHC/Globals/DAT_EntityState.hpp"
#include "OpenSHC/Globals/DAT_TileMapState.hpp"
#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp"

namespace OpenSHC {
namespace Map {
namespace Buildings {

// FUNCTION: STRONGHOLDCRUSADER 0x004109F0
void BuildingsState::extinguishBuildingFire(int buildingID)
{
if (this->buildings[buildingID].fireDuration == 0) {
return;
}
int const x = this->buildings[buildingID].x;
int const y = this->buildings[buildingID].y;
int size = this->buildings[buildingID].widthOrHeight;
this->buildings[buildingID].fireDuration = 0;
this->buildings[buildingID].cooldownTimer = 2000;
if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_WHEATFARM) {
size = 9;
} else if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_HOPFARM) {
size = 9;
} else if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_DAIRYFARM) {
size = 10;
} else if (DAT_BuildingsState::instance.buildings[buildingID].buildingType == BT_APPLEFARM) {
size = 11;
}
int tile = 0;
do {
MACRO_CALL_MEMBER(TileMapState_Func::getBuildingSizeIndexMappingData, DAT_TileMapState::ptr)(
tile, size);
MACRO_CALL_MEMBER(Entities::EntityState_Func::updateAllFireEntitiesAtTile, DAT_EntityState::ptr)(
DAT_ViewportRenderState::instance.translationMatrix[y + DAT_TileMapState::instance.buildingY]
.addXgetTile
+ DAT_TileMapState::instance.buildingX + x);
++tile;
} while (tile < DAT_TileMapState::instance.constructionTileCount);
int const tileCount = DAT_BuildingDefinedData::instance.BuildingAccessibleTilesCount[size];
for (int try_ = 0; try_ < tileCount; ++try_) {
MACRO_CALL_MEMBER(BuildingsState_Func::setupBuildingEntrancesOffset, this)(size, 1, try_, 0);
int const rowTile
= DAT_ViewportRenderState::instance.translationMatrix[this->DAT_TempYOffset + y].addXgetTile + x;
MACRO_CALL_MEMBER(Entities::EntityState_Func::updateAllFireEntitiesAtTile, DAT_EntityState::ptr)(
rowTile + this->DAT_TempXOffset);
}
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "../BuildingsState.func.hpp"

#include "OpenSHC/Map/Navigation/DirectionAlgorithmState.func.hpp"
#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"
#include "OpenSHC/Map/Buildings/BuildingLogicalState.hpp"

#include "OpenSHC/Globals/DAT_DirectionAlgorithmState.hpp"
#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
#include "OpenSHC/Globals/DAT_TileMapState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp"

namespace OpenSHC {
namespace Map {
namespace Buildings {

// FUNCTION: STRONGHOLDCRUSADER 0x00410B10
int BuildingsState::findClosestReachableAlliedBuilding(int unitID)
{
int closestBuildingID = 0;
int closestDistance = 1000;
int const fromArea
= (short)DAT_TileMapState::instance.PathConnectionLayer[DAT_UnitsState::instance.units[unitID].tile];
for (int buildingID = 1; buildingID < this->maxBuildingsCount; ++buildingID) {
if (this->buildings[buildingID].logicalState == 0
|| this->buildings[buildingID].logicalState == BLS_REMOVE) {
continue;
}
if (DAT_GameState::instance.mapAndTime.playerTeams[this->buildings[buildingID].owner]
!= DAT_GameState::instance.mapAndTime.playerTeams[DAT_UnitsState::instance.units[unitID].owner]) {
continue;
}
if (this->buildings[buildingID].fireDuration == 0) {
continue;
}
MACRO_CALL_MEMBER(Navigation::DirectionAlgorithmState_Func::setAxisBasedDistanceResult,
DAT_DirectionAlgorithmState::ptr)(DAT_UnitsState::instance.units[unitID].x,
DAT_UnitsState::instance.units[unitID].y, this->buildings[buildingID].buildingEntryX,
this->buildings[buildingID].buildingEntryY);
if (DAT_DirectionAlgorithmState::instance.distanceHigh >= closestDistance) {
continue;
}
int const tile
= DAT_ViewportRenderState::instance.translationMatrix[this->buildings[buildingID].buildingEntryY]
.addXgetTile
+ this->buildings[buildingID].buildingEntryX;
if (MACRO_CALL_MEMBER(Navigation::PathFindingState_Func::calculateCanPlayerUnitsNavigateToAreaFromArea,
DAT_PathFindingState::ptr)(DAT_UnitsState::instance.units[unitID].owner, fromArea,
(short)DAT_TileMapState::instance.PathConnectionLayer[tile], 0)
!= 0) {
closestDistance = DAT_DirectionAlgorithmState::instance.distanceHigh;
closestBuildingID = buildingID;
}
}
if (closestBuildingID != 0) {
return closestBuildingID;
}
return 0;
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "../BuildingsState.func.hpp"

#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"

#include "OpenSHC/Globals/DAT_BuildingDefinedData.hpp"
#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
#include "OpenSHC/Globals/DAT_TileMapState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp"

namespace OpenSHC {
namespace Map {
namespace Buildings {

// FUNCTION: STRONGHOLDCRUSADER 0x0040E610
BOOLEnum BuildingsState::findFreeCathedralAssemblyTile(int playerID, int unitID)
{
if (DAT_GameState::instance.playerDataArray[playerID].specialBuildingAssemblyPoints[3].x != 0) {
int const assemblyX
= DAT_GameState::instance.playerDataArray[playerID].specialBuildingAssemblyPoints[3].x;
int const assemblyY
= DAT_GameState::instance.playerDataArray[playerID].specialBuildingAssemblyPoints[3].y;
for (int i = (short)DAT_GameState::instance.playerDataArray[playerID].someCount30; i < 49; ++i) {
// The original reads the fixed offset [3] on every iteration instead of offset [i].
int const x = DAT_BuildingDefinedData::instance.SearchRelatedXYOffsets_1[3].x + assemblyX;
int const y = DAT_BuildingDefinedData::instance.SearchRelatedXYOffsets_1[3].y + assemblyY;
int const tile = DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile + x;
int const occupantID = DAT_TileMapState::instance.UnitLayer[tile];
if (occupantID != 0 && occupantID != unitID
&& DAT_UnitsState::instance.units[unitID].movementRelated == 8) {
continue;
}
if (MACRO_CALL_MEMBER(
Navigation::PathFindingState_Func::calculateCanPlayerUnitsNavigateToAreaFromArea,
DAT_PathFindingState::ptr)(playerID,
(short)DAT_TileMapState::instance
.PathConnectionLayer[DAT_UnitsState::instance.units[unitID].tile],
(short)DAT_TileMapState::instance.PathConnectionLayer[tile], 0)
!= 0) {
this->DAT_TempXOffset = x;
this->DAT_TempYOffset = y;
if (x == DAT_UnitsState::instance.units[unitID].x
&& y == DAT_UnitsState::instance.units[unitID].y) {
return FALSE;
}
return TRUE;
}
}
return FALSE;
}
return FALSE;
}

}
}
}
Loading
Loading