Skip to content

Commit d6aaae3

Browse files
committed
reimplement: AICState methods that are less than 100%
1 parent 4e79ec5 commit d6aaae3

57 files changed

Lines changed: 4097 additions & 3 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/Map/Units/UnitLogicState.hpp"
4+
#include "OpenSHC/Map/Units/UnitType.hpp"
5+
6+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
7+
8+
namespace OpenSHC {
9+
namespace AI {
10+
11+
// FUNCTION: STRONGHOLDCRUSADER 0x004D4040
12+
void AICState::addEngineersToTribe(int playerID)
13+
{
14+
for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) {
15+
if (DAT_UnitsState::instance.units[unitID].logicalState != Map::Units::ULS_NORMAL)
16+
continue;
17+
if (DAT_UnitsState::instance.units[unitID].owner != playerID)
18+
continue;
19+
if (DAT_UnitsState::instance.units[unitID].dying != 0)
20+
continue;
21+
if (DAT_UnitsState::instance.units[unitID].unitType != Map::Units::UT_E_ENGINEER)
22+
continue;
23+
if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType != 10)
24+
continue;
25+
if (DAT_UnitsState::instance.units[unitID].tribeID != 0)
26+
continue;
27+
28+
MACRO_CALL_MEMBER(AICState_Func::addUnitToItsTribe, this)(unitID, 10);
29+
}
30+
}
31+
32+
}
33+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/Game/GameStateStructures.func.hpp"
4+
#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp"
5+
#include "OpenSHC/Map/Units/UnitLogicState.hpp"
6+
#include "OpenSHC/Map/Units/UnitType.hpp"
7+
#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp"
8+
9+
#include "OpenSHC/Globals/DAT_GameState.hpp"
10+
#include "OpenSHC/Globals/DAT_PathFindingState.hpp"
11+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
12+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
13+
14+
namespace OpenSHC {
15+
namespace AI {
16+
17+
// FUNCTION: STRONGHOLDCRUSADER 0x004CFA10
18+
void AICState::addRallyPointForTribe(int tribeID)
19+
{
20+
DAT_TribesState::instance.tribes[tribeID].rallyPointCount = 0;
21+
for (int unitID = 1; unitID < 2500; unitID++) {
22+
if (DAT_UnitsState::instance.units[unitID].logicalState == OpenSHC::Map::Units::ULS_INVISIBLE)
23+
continue;
24+
if (MACRO_CALL_MEMBER(OpenSHC::Game::GameStateStructures_Func::getTeamsDifferent, DAT_GameState::ptr)(
25+
DAT_TribesState::instance.tribes[tribeID].owner, DAT_UnitsState::instance.units[unitID].owner)
26+
!= FALSE)
27+
continue;
28+
if (DAT_UnitsState::instance.units[unitID].unitType != OpenSHC::Map::Units::UT_S_CATAPULT
29+
&& DAT_UnitsState::instance.units[unitID].unitType != OpenSHC::Map::Units::UT_S_TREBUCHET
30+
&& DAT_UnitsState::instance.units[unitID].unitType != OpenSHC::Map::Units::UT_S_FBALLISTA)
31+
continue;
32+
if (DAT_UnitsState::instance.units[unitID].unknownSiegeTentRelated02 != 3)
33+
continue;
34+
35+
MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::computeNextRallyPointDestination,
36+
DAT_PathFindingState::ptr)(
37+
-1, DAT_UnitsState::instance.units[unitID].x, DAT_UnitsState::instance.units[unitID].y);
38+
DAT_TribesState::instance.tribes[tribeID]
39+
.rallyPointArray[DAT_TribesState::instance.tribes[tribeID].rallyPointCount][0]
40+
= DAT_PathFindingState::instance.ALG_ResultX;
41+
DAT_TribesState::instance.tribes[tribeID]
42+
.rallyPointArray[DAT_TribesState::instance.tribes[tribeID].rallyPointCount][1]
43+
= DAT_PathFindingState::instance.ALG_ResultY;
44+
DAT_TribesState::instance.tribes[tribeID].rallyPointCount++;
45+
if (DAT_TribesState::instance.tribes[tribeID].rallyPointCount >= 9)
46+
break;
47+
}
48+
49+
if (DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex < 0)
50+
DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = 0;
51+
if (DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex
52+
>= DAT_TribesState::instance.tribes[tribeID].rallyPointCount)
53+
DAT_TribesState::instance.tribes[tribeID].currentRallyPointIndex = 0;
54+
}
55+
56+
}
57+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/Map/Units/TribesState.func.hpp"
4+
#include "OpenSHC/AI/AITypeA.hpp"
5+
6+
#include "OpenSHC/Globals/DAT_GameState.hpp"
7+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
8+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
9+
10+
namespace OpenSHC {
11+
namespace AI {
12+
13+
// FUNCTION: STRONGHOLDCRUSADER 0x004D27E0
14+
void AICState::addUnitToItsTribe(int unitID, int aiUnitBehaviourType)
15+
{
16+
int owner = DAT_UnitsState::instance.units[unitID].owner;
17+
if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL)
18+
return;
19+
20+
DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = aiUnitBehaviourType;
21+
int tribeID = MACRO_CALL_MEMBER(AICState_Func::addUnitToSmallestBehaviourTypeTribe, this)(
22+
owner, unitID, aiUnitBehaviourType);
23+
if (tribeID != 0)
24+
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID);
25+
}
26+
}
27+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "OpenSHC/Map/Units/TribesState.func.hpp"
2+
#include "OpenSHC/AI/AICState.hpp"
3+
#include "OpenSHC/AI/AITypeA.hpp"
4+
5+
#include "OpenSHC/Globals/DAT_GameState.hpp"
6+
#include "OpenSHC/Globals/DAT_SkirmishDefinedData.hpp"
7+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
8+
9+
namespace OpenSHC {
10+
namespace AI {
11+
12+
// FUNCTION: STRONGHOLDCRUSADER 0x004CCD20
13+
int AICState::addUnitToSmallestBehaviourTypeTribe(
14+
undefined4 playerID, undefined4 unitID, undefined4 aiUnitBehaviourType)
15+
{
16+
int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType;
17+
if (aiType == AITA_NULL)
18+
return 0;
19+
20+
int aicIndex = aiType - 1;
21+
int groupsCount;
22+
switch (DAT_SkirmishDefinedData::instance.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10]) {
23+
case 15:
24+
groupsCount = this->aics[aicIndex].AttUnitPatrolGroupsCount;
25+
break;
26+
case 186:
27+
groupsCount = this->aics[aicIndex].AttUnitBackupGroupsCount;
28+
break;
29+
case 190:
30+
groupsCount = this->aics[aicIndex].AttUnitSiegeDefGroupsCount;
31+
break;
32+
case 192:
33+
groupsCount = this->aics[aicIndex].AttMainGroupsCount;
34+
break;
35+
default:
36+
groupsCount = 1;
37+
break;
38+
}
39+
40+
int selectedTribeID = 0;
41+
int selectedSlot = 0;
42+
if (groupsCount <= 1) {
43+
int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[DAT_SkirmishDefinedData::instance
44+
.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10]];
45+
if (tribeID != 0
46+
&& DAT_TribesState::instance.tribes[tribeID].uid
47+
== DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[DAT_SkirmishDefinedData::instance
48+
.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10]])
49+
return tribeID;
50+
selectedTribeID
51+
= MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID);
52+
selectedSlot = DAT_SkirmishDefinedData::instance.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10];
53+
} else {
54+
int smallestSize = 1000;
55+
for (int slot = DAT_SkirmishDefinedData::instance.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10]; slot
56+
< DAT_SkirmishDefinedData::instance.AIUnitBehaviourTypeMapping[aiUnitBehaviourType - 10] + groupsCount;
57+
slot++) {
58+
int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[slot];
59+
if (tribeID == 0
60+
|| DAT_TribesState::instance.tribes[tribeID].uid
61+
!= DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[slot]) {
62+
selectedTribeID = MACRO_CALL_MEMBER(
63+
Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(playerID);
64+
selectedSlot = slot;
65+
break;
66+
}
67+
if (DAT_TribesState::instance.tribes[tribeID].size < smallestSize) {
68+
smallestSize = DAT_TribesState::instance.tribes[tribeID].size;
69+
selectedTribeID = tribeID;
70+
selectedSlot = slot;
71+
}
72+
}
73+
}
74+
if (selectedTribeID <= 0)
75+
return 0;
76+
DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[selectedSlot] = selectedTribeID;
77+
DAT_GameState::instance.playerDataArray[playerID].aiTribeUIDs[selectedSlot]
78+
= DAT_TribesState::instance.tribes[selectedTribeID].uid;
79+
return selectedTribeID;
80+
}
81+
}
82+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "OpenSHC/Map/Units/TribesState.func.hpp"
2+
#include "OpenSHC/AI/AICState.hpp"
3+
#include "OpenSHC/Map/Units/UnitLogicState.hpp"
4+
5+
#include "OpenSHC/Globals/DAT_GameState.hpp"
6+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
7+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
8+
9+
namespace OpenSHC {
10+
namespace AI {
11+
12+
// FUNCTION: STRONGHOLDCRUSADER 0x004CC720
13+
void AICState::addUnitsToTribe166(int playerID)
14+
{
15+
for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) {
16+
if (DAT_UnitsState::instance.units[unitID].owner != playerID)
17+
continue;
18+
if (DAT_UnitsState::instance.units[unitID].logicalState != Map::Units::ULS_NORMAL)
19+
continue;
20+
if (DAT_UnitsState::instance.units[unitID].dying != 0)
21+
continue;
22+
if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType != 6)
23+
continue;
24+
25+
int tribeID = DAT_GameState::instance.playerDataArray[playerID].aiTribeIDs[166];
26+
if (DAT_UnitsState::instance.units[unitID].tribeID == tribeID)
27+
continue;
28+
29+
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::removeUnitFromTribe, DAT_TribesState::ptr)(
30+
unitID, DAT_UnitsState::instance.units[unitID].tribeID);
31+
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID);
32+
}
33+
}
34+
}
35+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "OpenSHC/Map/Units/TribesState.func.hpp"
2+
#include "OpenSHC/AI/AICState.hpp"
3+
#include "OpenSHC/Map/Units/Behavior/UnitStanceEnum.hpp"
4+
5+
#include "OpenSHC/Globals/DAT_GameState.hpp"
6+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
7+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
8+
9+
namespace OpenSHC {
10+
namespace AI {
11+
12+
// FUNCTION: STRONGHOLDCRUSADER 0x004CC840
13+
void AICState::aiAddUnitToMoatDiggerTribe(int unitID)
14+
{
15+
int owner = DAT_UnitsState::instance.units[unitID].owner;
16+
DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 5;
17+
int tribeID = DAT_GameState::instance.playerDataArray[owner].aiTribeIDs[10];
18+
if (tribeID == 0
19+
|| DAT_TribesState::instance.tribes[tribeID].uid
20+
!= DAT_GameState::instance.playerDataArray[owner].aiTribeUIDs[10]) {
21+
tribeID
22+
= MACRO_CALL_MEMBER(Map::Units::TribesState_Func::createTribeForPlayer, DAT_TribesState::ptr)(owner);
23+
DAT_GameState::instance.playerDataArray[owner].aiTribeIDs[10] = tribeID;
24+
DAT_GameState::instance.playerDataArray[owner].aiTribeUIDs[10]
25+
= DAT_TribesState::instance.tribes[tribeID].uid;
26+
}
27+
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID);
28+
DAT_TribesState::instance.tribes[tribeID].unitStance = Map::Units::Behavior::USE_DEFENSIVE;
29+
}
30+
}
31+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/AI/AITypeA.hpp"
4+
#include "OpenSHC/Map/Units/UnitLogicState.hpp"
5+
#include "OpenSHC/Map/Units/UnitType.hpp"
6+
7+
#include "OpenSHC/Globals/DAT_GameState.hpp"
8+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
9+
10+
namespace OpenSHC {
11+
namespace AI {
12+
13+
using namespace OpenSHC::Map::Units;
14+
15+
// FUNCTION: STRONGHOLDCRUSADER 0x004D3F20
16+
void AICState::aiAssignMoatDiggers(int playerID)
17+
{
18+
int aiType = DAT_GameState::instance.playerDataArray[playerID].aiType;
19+
if (aiType == AITA_NULL)
20+
return;
21+
int aicIndex = aiType - 1;
22+
if (DAT_GameState::instance.playerDataArray[playerID].totalTroopsType0 <= 0)
23+
return;
24+
25+
for (int unitID = 1; unitID < (int)DAT_UnitsState::instance.maxUnitCount; unitID++) {
26+
if (DAT_UnitsState::instance.units[unitID].logicalState == ULS_INVISIBLE)
27+
continue;
28+
if (DAT_UnitsState::instance.units[unitID].owner != playerID)
29+
continue;
30+
if (DAT_UnitsState::instance.units[unitID].isSelectable_OR_matchTime == 0)
31+
continue;
32+
if (DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType != 0)
33+
continue;
34+
if (DAT_UnitsState::instance.units[unitID].dying != 0)
35+
continue;
36+
37+
if (DAT_UnitsState::instance.units[unitID].unitType == UT_LORD
38+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_E_ENGINEER
39+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_TUNNELER
40+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_CATAPULT
41+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_TREBUCHET
42+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_MANGONEL
43+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_TOWER
44+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_BATTERINGRAM
45+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_SHIELD
46+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_BALLISTA
47+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_S_FBALLISTA)
48+
continue;
49+
50+
if (this->aics[aicIndex].DefDiggingUnitMax == 0
51+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_E_ARCHER
52+
|| DAT_UnitsState::instance.units[unitID].unitType == UT_E_XBOW
53+
|| DAT_UnitsState::instance.units[unitID].someUnitStat4 == 0)
54+
MACRO_CALL_MEMBER(AICState_Func::assignUnitToATribe, this)(unitID);
55+
else
56+
MACRO_CALL_MEMBER(AICState_Func::aiAddUnitToMoatDiggerTribe, this)(unitID);
57+
}
58+
}
59+
}
60+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/Map/Units/TribesState.func.hpp"
4+
#include "OpenSHC/AI/AITypeA.hpp"
5+
6+
#include "OpenSHC/Globals/DAT_GameState.hpp"
7+
#include "OpenSHC/Globals/DAT_TribesState.hpp"
8+
#include "OpenSHC/Globals/DAT_UnitsState.hpp"
9+
10+
namespace OpenSHC {
11+
namespace AI {
12+
13+
// FUNCTION: STRONGHOLDCRUSADER 0x004D2790
14+
void AICState::aiAssignUnitToDefensiveTribe(int unitID)
15+
{
16+
int owner = DAT_UnitsState::instance.units[unitID].owner;
17+
if (DAT_GameState::instance.playerDataArray[owner].aiType == AITA_NULL)
18+
return;
19+
20+
DAT_UnitsState::instance.units[unitID].aiUnitBehaviourType = 2;
21+
int tribeID = MACRO_CALL_MEMBER(AICState_Func::getDefensiveTribeForUnit, this)(owner, unitID);
22+
if (tribeID != 0)
23+
MACRO_CALL_MEMBER(Map::Units::TribesState_Func::addUnitToTribe, DAT_TribesState::ptr)(unitID, tribeID);
24+
}
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "../AICState.func.hpp"
2+
3+
#include "OpenSHC/Globals/DAT_GameState.hpp"
4+
5+
namespace OpenSHC {
6+
namespace AI {
7+
8+
// FUNCTION: STRONGHOLDCRUSADER 0x004D48F0
9+
void AICState::aiBuyAndSellGoods(int playerID)
10+
{
11+
int marketID = DAT_GameState::instance.playerDataArray[playerID].marketplace.id;
12+
DAT_GameState::instance.playerDataArray[playerID].hasMarketUnk = 0;
13+
if (marketID != 0)
14+
DAT_GameState::instance.playerDataArray[playerID].hasMarketUnk = 1;
15+
if (DAT_GameState::instance.playerDataArray[playerID].hasMarketUnk == 0)
16+
return;
17+
18+
DAT_GameState::instance.playerDataArray[playerID].willBuy
19+
= DAT_GameState::instance.playerDataArray[playerID].willBuy ^ TRUE;
20+
if (DAT_GameState::instance.playerDataArray[playerID].willBuy == FALSE) {
21+
MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::sellExcessGoods, this)(playerID);
22+
return;
23+
}
24+
MACRO_CALL_MEMBER(OpenSHC::AI::AICState_Func::buyRequiredGoods, this)(playerID);
25+
}
26+
27+
}
28+
}

0 commit comments

Comments
 (0)