Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/OpenSHC/AI/AICState/Constructor_AICState.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "OpenSHC/AI/AICState.func.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004D3940
AICState* AICState::Constructor_AICState()
{
MACRO_CALL_MEMBER(AICState_Func::setInitialAIC, this)();
this->aiTauntResponseTimeWindow = 0;
return this;
}
}
}
23 changes: 23 additions & 0 deletions src/OpenSHC/AI/AICState/abortAttackAndGoIdle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "../AICState.func.hpp"

#include "OpenSHC/Map/Buildings/BuildingsState.func.hpp"

#include "OpenSHC/Globals/DAT_BuildingsState.hpp"
#include "OpenSHC/Globals/DAT_GameState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004D45E0
void AICState::abortAttackAndGoIdle(int playerID)
{
MACRO_CALL_MEMBER(Map::Buildings::BuildingsState_Func::removeSiegeBuildings, DAT_BuildingsState::ptr)(
DAT_GameState::instance.playerDataArray[playerID].currentAttackWave, playerID);
MACRO_CALL_MEMBER(AICState_Func::disbandAIPlayerSiegeUnits, this)(playerID);
MACRO_CALL_MEMBER(AICState_Func::addEngineersToTribe, this)(playerID);
MACRO_CALL_MEMBER(AICState_Func::aiReassignTunnelersToTribe, this)(playerID);
DAT_GameState::instance.playerDataArray[playerID].aiPlayerState = 0;
}

}
}
24 changes: 24 additions & 0 deletions src/OpenSHC/AI/AICState/addBuildingToTargetableBuildings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "../AICState.func.hpp"

#include "OpenSHC/Globals/DAT_BuildingsState.hpp"
#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004CDA50
void AICState::addBuildingToTargetableBuildings(int buildingID)
{
int _player = DAT_BuildingsState::instance.buildings[buildingID].owner;
if (DAT_GameSynchronyState::instance.DAT_CurrentGameMode != Game::GM_SOLITARY) {
int* piVar1 = &DAT_GameState::instance.playerDataArray[_player].top100TargetableBuildingsTracker;
if ((*piVar1 < 100) && (DAT_BuildingsState::instance.buildings[buildingID].fireDuration == 0)) {
DAT_GameState::instance.playerDataArray[_player].top100TargetableBuildings[*piVar1] = (short)buildingID;
*piVar1 = *piVar1 + 1;
}
}
}

}
}
45 changes: 45 additions & 0 deletions src/OpenSHC/AI/AICState/addEngineersToSelection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "../AICState.func.hpp"

#include "OpenSHC/Map/Units/TribesState.func.hpp"
#include "OpenSHC/Map/Units/States/UnitState.hpp"
#include "OpenSHC/Map/Units/UnitLogicState.hpp"

#include "OpenSHC/Globals/DAT_TribesState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004CC680
int AICState::addEngineersToSelection(int playerID, int unitCount)
{
int tribeID;
uint unitID;

tribeID = MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID);
unitID = 1;
if (1 < (int)DAT_UnitsState::instance.maxUnitCount) {
/* Unit offset 150 */
Map::Units::Unit* _ptrUnit = &DAT_UnitsState::instance.units[1];
do {
if (unitCount <= 0) {
return tribeID;
}
if ((((_ptrUnit->logicalState == Map::Units::ULS_NORMAL) && (_ptrUnit->owner == playerID))
&& (_ptrUnit->dying == 0))
&& (((_ptrUnit->unitType == Map::Units::UT_E_ENGINEER) && (_ptrUnit->aiUnitBehaviourType == 10))
&& ((_ptrUnit->tribeID == 0)
&& ((_ptrUnit->state).generic != Map::Units::States::US_STAND_UPUnk)))) {
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(
unitID, tribeID);
unitCount = unitCount + -1;
}
unitID = unitID + 1;
_ptrUnit = _ptrUnit + 1;
} while ((int)unitID < (int)DAT_UnitsState::instance.maxUnitCount);
}
return tribeID;
}

}
}
32 changes: 32 additions & 0 deletions src/OpenSHC/AI/AICState/addEngineersToTribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "../AICState.func.hpp"

#include "OpenSHC/Map/Units/UnitLogicState.hpp"

#include "OpenSHC/Globals/DAT_UnitsState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004D4040
void AICState::addEngineersToTribe(int playerID)
{
int _unitID = 1;
if (1 < (int)DAT_UnitsState::instance.maxUnitCount) {
Map::Units::Unit* _pUnit = &DAT_UnitsState::instance.units[1];
do {
/* if logicalState == normal && owner == playerID && unitType == 0x1e (engineer)
&& aiUnitBehaviourType == 10 */
if ((((_pUnit->logicalState == Map::Units::ULS_NORMAL) && (_pUnit->owner == playerID))
&& (_pUnit->dying == 0))
&& (((_pUnit->unitType == Map::Units::UT_E_ENGINEER) && (_pUnit->aiUnitBehaviourType == 10))
&& (_pUnit->tribeID == 0))) {
MACRO_CALL_MEMBER(AICState_Func::addUnitToItsTribe, this)(_unitID, 10);
}
_unitID = _unitID + 1;
_pUnit = _pUnit + 1;
} while (_unitID < (int)DAT_UnitsState::instance.maxUnitCount);
}
}

}
}
101 changes: 101 additions & 0 deletions src/OpenSHC/AI/AICState/addRallyPointForTribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "OpenSHC/AI/AICState.func.hpp"
#include "OpenSHC/Game/GameStateStructures.func.hpp"
#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"
#include "OpenSHC/Map/Units/Unit.hpp"
#include "OpenSHC/Map/Units/UnitLogicState.hpp"
#include "OpenSHC/Map/Units/UnitType.hpp"
#include "OpenSHC/Map/Units/UnitTypeShort.hpp"
#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp"

#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
#include "OpenSHC/Globals/DAT_TribesState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"

namespace OpenSHC {
namespace AI {

using OpenSHC::Map::Units::Unit;
using OpenSHC::Map::Units::UnitLogicState;
using OpenSHC::Map::Units::UnitType;
using OpenSHC::Map::Units::UnitTypeShort;
using OpenSHC::WindowsHelper::Enums::BOOLEnum;

/*
decompilerscript: committed: 2025-01-30 21:57:43.216000 */

// FUNCTION: STRONGHOLDCRUSADER 0x004CFA10
void AICState ::addRallyPointForTribe(int tribeID)

{

short* psVar1;

BOOLEnum _areInDifferentTeamsUnk;

Unit* _ptrUnit;

UnitTypeShort _unitType;

DAT_TribesState::instance.tribes[tribeID].rallyPointCount = 0;

_ptrUnit = &DAT_UnitsState::instance.units[1];

do {

if (_ptrUnit->logicalState != OpenSHC::Map::Units::ULS_INVISIBLE) {

_areInDifferentTeamsUnk = MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::getTeamsDifferent,
DAT_GameState::ptr)(DAT_TribesState::instance.tribes[tribeID].owner, (int)((int)(_ptrUnit->owner)));

if (_areInDifferentTeamsUnk == FALSE) {

_unitType = _ptrUnit->unitType;

if ((((_unitType == OpenSHC::Map::Units::UT_S_CATAPULT)
|| (_unitType == OpenSHC::Map::Units::UT_S_TREBUCHET))
|| (_unitType == OpenSHC::Map::Units::UT_S_FBALLISTA))
&& (_ptrUnit->unknownSiegeTentRelated02 == 3)) {

MACRO_CALL_MEMBER(
OpenSHC::Map::Navigation::PathFindingState_Func::computeNextRallyPointDestination,
DAT_PathFindingState::ptr)(-1, (int)((int)(_ptrUnit->x)), (int)((int)(_ptrUnit->y)));

DAT_TribesState::instance.tribes[tribeID]
.rallyPointArray[DAT_TribesState::instance.tribes[tribeID].rallyPointCount][0]
= (short)DAT_PathFindingState::instance.ALG_ResultX;

DAT_TribesState::instance.tribes[tribeID]
.rallyPointArray[DAT_TribesState::instance.tribes[tribeID].rallyPointCount][1]
= (short)DAT_PathFindingState::instance.ALG_ResultY;

psVar1 = &DAT_TribesState::instance.tribes[tribeID].rallyPointCount;

*psVar1 = *psVar1 + 1;

if (8 < DAT_TribesState::instance.tribes[tribeID].rallyPointCount)
break;
}
}
}

_ptrUnit = _ptrUnit + 0x248;

} while ((int)_ptrUnit < 0x165141a);

if (DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex < 0) {

DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = 0;
}

if (DAT_TribesState::instance.tribes[tribeID].rallyPointCount
<= DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex) {

DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = 0;
}

return;
}

}
}
26 changes: 26 additions & 0 deletions src/OpenSHC/AI/AICState/addUnitToItsTribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "OpenSHC/AI/AICState.func.hpp"
#include "OpenSHC/Map/Units/TribesState.func.hpp"
#include "OpenSHC/AI/AITypeA.hpp"

#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_TribesState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004D27E0
void AICState::addUnitToItsTribe(int unitID, int aiUnitBehaviourType)
{
int iVar1 = (int)DAT_UnitsState::instance.units[unitID].owner;
if (DAT_GameState::instance.playerDataArray[iVar1].aiType != AITA_NULL) {
DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = (short)aiUnitBehaviourType;
iVar1 = MACRO_CALL_MEMBER(AICState_Func::addUnitToSmallestBehaviourTypeTribe, this)(
iVar1, unitID, aiUnitBehaviourType);
if (iVar1 != 0) {
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, iVar1);
}
}
}
}
}
91 changes: 91 additions & 0 deletions src/OpenSHC/AI/AICState/addUnitToSmallestBehaviourTypeTribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "OpenSHC/Map/Units/TribesState.func.hpp"
#include "OpenSHC/AI/AICState.hpp"
#include "OpenSHC/AI/AITypeA.hpp"

#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp"
#include "OpenSHC/Globals/DAT_TribesState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004CCD20
int AICState::addUnitToSmallestBehaviourTypeTribe(
undefined4 playerID, undefined4 param_2, undefined4 aiUnitBehaviourType)
{
int _playerID = (int)playerID;
int AVar1 = DAT_GameState::instance.playerDataArray[_playerID].aiType;
if (AVar1 == AITA_NULL) {
return 0;
}
int _tribeTypeOffset
= DAT_SkirmishDefinedData::instance.AIUnitBehaviourTypeMapping[(int)aiUnitBehaviourType + -10];
int _smallestTribe = 0;
int _smallestTribeOffset = 0;
short _smallestTribeSize = 1000;
dword _groupsCount;

if (_tribeTypeOffset == 0xf) {
_groupsCount = this->aics[AVar1 - 1].AttUnitPatrolGroupsCount;
} else if (_tribeTypeOffset == 0xba) {
_groupsCount = this->aics[AVar1 - 1].AttUnitBackupGroupsCount;
} else if (_tribeTypeOffset == 0xbe) {
_groupsCount = this->aics[AVar1 - 1].AttUnitSiegeDefGroupsCount;
} else if (_tribeTypeOffset == 0xc0) {
_groupsCount = this->aics[AVar1 - 1].AttMainGroupsCount;
} else {
_groupsCount = 1;
}

int _selectedTribe;
int _selectedSlot;
if ((int)_groupsCount < 1 || _groupsCount == 1) {
int _tribeID_groupsCount1
= (int)DAT_GameState::instance.playerDataArray[_playerID].aiTribeIDs[_tribeTypeOffset];
if ((_tribeID_groupsCount1 != 0)
&& (DAT_TribesState::instance.tribes[_tribeID_groupsCount1].uid
== DAT_GameState::instance.playerDataArray[_playerID].aiTribeUIDs[_tribeTypeOffset])) {
return _tribeID_groupsCount1;
}
_selectedTribe = MACRO_CALL_MEMBER(
Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(_playerID);
_selectedSlot = _tribeTypeOffset;
} else {
int _maxOffset = _groupsCount + _tribeTypeOffset;
_selectedTribe = 0;
_selectedSlot = 0;
short* _pTribeIDs = DAT_GameState::instance.playerDataArray[_playerID].aiTribeIDs + _tribeTypeOffset;
if (_tribeTypeOffset < _maxOffset) {
do {
int _tribeID_2 = (int)*_pTribeIDs;
if ((_tribeID_2 == 0)
|| (DAT_TribesState::instance.tribes[_tribeID_2].uid
!= DAT_GameState::instance.playerDataArray[_playerID].aiTribeUIDs[_tribeTypeOffset])) {
_selectedTribe = MACRO_CALL_MEMBER(
Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(_playerID);
_selectedSlot = _tribeTypeOffset;
break;
}
short _tribeSize = DAT_TribesState::instance.tribes[_tribeID_2].size;
if (_tribeSize < _smallestTribeSize) {
_smallestTribeOffset = _tribeTypeOffset;
_smallestTribe = _tribeID_2;
_smallestTribeSize = _tribeSize;
}
_pTribeIDs = _pTribeIDs + 1;
_tribeTypeOffset = _tribeTypeOffset + 1;
_selectedTribe = _smallestTribe;
_selectedSlot = _smallestTribeOffset;
} while (_tribeTypeOffset < _maxOffset);
}
}
if (0 < _selectedTribe) {
DAT_GameState::instance.playerDataArray[_playerID].aiTribeIDs[_selectedSlot] = (short)_selectedTribe;
DAT_GameState::instance.playerDataArray[_playerID].aiTribeUIDs[_selectedSlot]
= DAT_TribesState::instance.tribes[_selectedTribe].uid;
return _selectedTribe;
}
return 0;
}
}
}
27 changes: 27 additions & 0 deletions src/OpenSHC/AI/AICState/addUnitToSmallestPatrolTribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "OpenSHC/AI/AICState.func.hpp"
#include "OpenSHC/Map/Units/TribesState.func.hpp"
#include "OpenSHC/AI/AICState.hpp"
#include "OpenSHC/AI/AITypeA.hpp"

#include "OpenSHC/Globals/DAT_AICState.hpp"
#include "OpenSHC/Globals/DAT_GameState.hpp"
#include "OpenSHC/Globals/DAT_TribesState.hpp"
#include "OpenSHC/Globals/DAT_UnitsState.hpp"

namespace OpenSHC {
namespace AI {

// FUNCTION: STRONGHOLDCRUSADER 0x004D2730
void AICState::addUnitToSmallestPatrolTribe(int unitID)
{
int iVar1 = (int)DAT_UnitsState::instance.units[unitID].owner;
int _aiType = DAT_GameState::instance.playerDataArray[iVar1].aiType;
if (_aiType != AITA_NULL) {
DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 4;
iVar1 = MACRO_CALL_MEMBER(AI::AICState_Func::getSmallestPatrolTribe, DAT_AICState::ptr)(
iVar1, (int)this->aics[_aiType - 1].OuterPatrolGroupsCount);
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, iVar1);
}
}
}
}
Loading