From 8f1cb96e964ec3cbcb6615bc23046dc50393abad Mon Sep 17 00:00:00 2001 From: FynnTW Date: Sun, 8 Oct 2023 01:05:41 +0300 Subject: [PATCH] expansion of unit and campaign structs --- M2TWEOP-luaPlugin/luaPlugin/basicEvents.cpp | 4 + M2TWEOP-luaPlugin/luaPlugin/basicEvents.h | 11 +- M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.cpp | 14 + M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.h | 1 + .../luaPlugin/factionHelpers.cpp | 39 ++ M2TWEOP-luaPlugin/luaPlugin/factionHelpers.h | 5 +- M2TWEOP-luaPlugin/luaPlugin/gameHelpers.cpp | 43 ++ M2TWEOP-luaPlugin/luaPlugin/gameHelpers.h | 6 +- M2TWEOP-luaPlugin/luaPlugin/luaP.cpp | 233 +++++++- M2TWEOP-luaPlugin/luaPlugin/luaP2.cpp | 147 ++++- .../luaPlugin/m2tweopHelpers.cpp | 60 +- M2TWEOP-luaPlugin/luaPlugin/realGameTypes.h | 525 ++++++++++++++++-- .../luaPlugin/stackStructHelpers.cpp | 2 +- M2TWEOP-luaPlugin/luaPlugin/unitHelpers.cpp | 109 +++- M2TWEOP-luaPlugin/luaPlugin/unitHelpers.h | 24 +- 15 files changed, 1124 insertions(+), 99 deletions(-) diff --git a/M2TWEOP-luaPlugin/luaPlugin/basicEvents.cpp b/M2TWEOP-luaPlugin/luaPlugin/basicEvents.cpp index 22e4dd1c..a9801163 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/basicEvents.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/basicEvents.cpp @@ -15,6 +15,10 @@ void onEventWrapper(const DWORD eventAddr, DWORD** vTab, DWORD arg2) void initReligionNames() { const auto* religionDb = *reinterpret_cast (0x016A0B90); + if (m2tweopHelpers::getGameVersion() == 1) + { + religionDb = *reinterpret_cast (0x016E9DC0); + } for (int i = 0; i < religionDb->religionCount; i++) { religionNames[i] = gameHelpers::getReligionName(i); diff --git a/M2TWEOP-luaPlugin/luaPlugin/basicEvents.h b/M2TWEOP-luaPlugin/luaPlugin/basicEvents.h index 3e114ee2..f2cfe270 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/basicEvents.h +++ b/M2TWEOP-luaPlugin/luaPlugin/basicEvents.h @@ -7,6 +7,8 @@ using namespace std; extern "C" PLUGINM2TWEOP_API void onReadGameDbsAtStart(); extern "C" PLUGINM2TWEOP_API void onEndSiege(int x, int y); extern "C" PLUGINM2TWEOP_API void onStartSiege(int x, int y); +std::unordered_map religionNames = { +}; extern "C" PLUGINM2TWEOP_API void onClickAtTile(int x, int y); @@ -59,15 +61,6 @@ std::unordered_map missionSuccessLvl = { {2,"partly_successful"}, {3,"highly_successful"} }; -std::unordered_map religionNames = { -}; - -struct crusade -{ -public: - char pad_0x0000[60]; //0x0000 - settlementStruct* targetSettlement; //0x003C -}; void checkLuaFunc(sol::function** lRef); void initReligionNames(); diff --git a/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.cpp index adc38518..a575cded 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.cpp @@ -91,6 +91,20 @@ void eopEduHelpers::haveAttributeLegioSet(eduEntry* eduEn, bool isHaveLegio) } } +bool eopEduHelpers::hasAttribute(unit* unit, const char* attributeName) +{ + const auto entry = unit->eduEntry; + const int attributesNum = (reinterpret_cast(entry->EndOfAttributes) - reinterpret_cast(entry->Attributes)) / 8; + for (int i = 0; i < attributesNum; i+= 2) + { + if (strcmp(reinterpret_cast(entry->Attributes[i]), attributeName) == 0) + { + return true; + } + } + return false; +} + int eopEduHelpers::getArmourUpgradeLevelsNum(int idx) { eduEntry* eduEn = eopEduHelpers::getEduEntry(idx); diff --git a/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.h b/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.h index 09f02f23..24632273 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.h +++ b/M2TWEOP-luaPlugin/luaPlugin/eopEduHelpers.h @@ -65,6 +65,7 @@ namespace eopEduHelpers int getEntryStat(int idx, UnitEnums::eduStat stat, int sec); void addUnitToRQ(int idx, settlementStruct* sett); int multiplexor(int n1, int n2, int sel); + bool hasAttribute(unit* unit, const char* attributeName); void setEntryLocalizedName(int index, const char* newLocName); void setEntryLocalizedDescr(int index, const char* newLocDescr); diff --git a/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.cpp index e5232df8..7cc3f190 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.cpp @@ -2,6 +2,8 @@ #include "plugData.h" #include +#include "gameDataAllHelper.h" + std::string factionHelpers::getFactionName(const factionStruct* fac) { return std::string(fac->factSmDescr->facName); @@ -47,6 +49,43 @@ void factionHelpers::deleteFort(const factionStruct* fac, fortStruct* fort) (*(*plugData::data.funcs.deleteFort))(fac, fort); } +bool factionHelpers::hasMilitaryAccess(const factionStruct* fac1, const factionStruct* fac2) +{ + const auto gameData = gameDataAllHelper::get(); + const auto campaign = gameData->campaignData; + const auto agreements = campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade; + return agreements & static_cast(0x2); +} + +void factionHelpers::setMilitaryAccess(const factionStruct* fac1, const factionStruct* fac2, bool set) +{ + const auto gameData = gameDataAllHelper::get(); + const auto campaign = gameData->campaignData; + const auto agreements = campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade; + if (set) + { + campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade = agreements | static_cast(0x2); + } + else + { + campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade = agreements & static_cast(~0x2); + } +} + +float factionHelpers::getFactionStanding(const factionStruct* fac1, const factionStruct* fac2) +{ + const auto gameData = gameDataAllHelper::get(); + const auto campaign = gameData->campaignData; + return campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].factionStanding; +} + +void factionHelpers::setFactionStanding(const factionStruct* fac1, const factionStruct* fac2, float standing) +{ + const auto gameData = gameDataAllHelper::get(); + const auto campaign = gameData->campaignData; + campaign->diplomaticStandings[fac1->dipNum][fac2->dipNum].factionStanding = standing; +} + void factionHelpers::createFortXY(const factionStruct* fac, int x, int y) { (*(*plugData::data.funcs.createFortXY))(fac, x, y); diff --git a/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.h b/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.h index bab2b385..461ffc17 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.h +++ b/M2TWEOP-luaPlugin/luaPlugin/factionHelpers.h @@ -19,7 +19,10 @@ namespace factionHelpers void createFortXY(const factionStruct* fac, int x, int y); void createFort(const general* gen); void changeFactionName(factionStruct* fac, const char* newName); - + bool hasMilitaryAccess(const factionStruct* fac1, const factionStruct* fac2); + float getFactionStanding(const factionStruct* fac1, const factionStruct* fac2); + void setFactionStanding(const factionStruct* fac1, const factionStruct* fac2, float standing); + void setMilitaryAccess(const factionStruct* fac1, const factionStruct* fac2, bool set); std::string getLocalizedFactionName(factionStruct* fac); //faction diff --git a/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.cpp index 248fe606..03c45e38 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.cpp @@ -336,10 +336,53 @@ namespace gameHelpers (*(*plugData::data.funcs.historicEvent))(name, title, description); } + general* gameHelpers::getCardinal(const collegeOfCardinals* college, const int index) + { + return college->cardinalsArray[index].trackedCharacter->character; + } + + fortStruct* gameHelpers::getFortAll(const campaign* campaign, const int index) + { + return campaign->fortsArray[index]; + } + + portBuildingStruct* gameHelpers::getPortAll(const campaign* campaign, const int index) + { + return campaign->portsBuildings[index]; + } + + watchTowerStruct* gameHelpers::getWatchTowerAll(const campaign* campaign, const int index) + { + return campaign->watchtowers[index]; + } + + settlementStruct* getSettlementByName(campaign* campaign, const char* name) + { + settlementList* settlementList = &campaign->settlementList; + int settNum = 0; + while (settlementList != nullptr) + { + settNum = settlementList->settlementsNum; + for (int i = 0; i < settNum; i++) + { + if (strcmp(settlementList->settlements[i]->name, name) == 0) + { + return settlementList->settlements[i]; + } + } + settlementList = settlementList->nextSettlements; + } + return nullptr; + } const char* getReligionName(const int index) { + const auto* religionDb = *reinterpret_cast (0x016A0B90); + if (m2tweopHelpers::getGameVersion() == 1) + { + religionDb = *reinterpret_cast (0x016E9DC0); + } const wchar_t* name = religionDb->religionNames[index]->string; // Determine the size of the required buffer const int size = WideCharToMultiByte(CP_UTF8, 0, name, -1, nullptr, 0, nullptr, nullptr); diff --git a/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.h b/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.h index 438327db..df3af8fe 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.h +++ b/M2TWEOP-luaPlugin/luaPlugin/gameHelpers.h @@ -31,7 +31,11 @@ namespace gameHelpers void changeRegionName(regionStruct* region, const char* newName); std::string getRegionName(regionStruct* region); void changeRebelsName(regionStruct* region, const char* newName); - + general* getCardinal(const collegeOfCardinals* college, const int index); + fortStruct* getFortAll(const campaign* campaign, const int index); + portBuildingStruct* getPortAll(const campaign* campaign, const int index); + watchTowerStruct* getWatchTowerAll(const campaign* campaign, const int index); + settlementStruct* getSettlementByName(campaign* campaign, const char* name); std::string getRebelsName(regionStruct* region); int getMercUnitNum(mercPool* mercPool); diff --git a/M2TWEOP-luaPlugin/luaPlugin/luaP.cpp b/M2TWEOP-luaPlugin/luaPlugin/luaP.cpp index 35f16890..743c566e 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/luaP.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/luaP.cpp @@ -121,6 +121,7 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) sol::usertypesiege; sol::usertypebuildingLevel; sol::usertypebattleCameraStruct; + sol::usertypeunitPositionData; }types; luaState = {}; luaPath = modPath + "\\youneuoy_Data\\plugins\\lua"; @@ -165,6 +166,12 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) return nullptr; } + luaState.new_enum( + "unitBattleProperties", + "guardMode", unitHelpers::guardMode, + "fireAtWill", unitHelpers::fireAtWill, + "skirmish", unitHelpers::skirmish + ); //luaState.new_enum( // "buildingCap", @@ -251,6 +258,7 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) @tfield getTileVisibility getTileVisibility @tfield getRegionOwner getRegionOwner @tfield setEDUUnitsSize setEDUUnitsSize + @tfield getReligionName getReligionName @table M2TWEOP */ @@ -485,6 +493,15 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) local ownerFac=M2TWEOP.getRegionOwner(regionID); */ tables.M2TWEOPTable.set_function("getRegionOwner", &m2tweopHelpers::getRegionOwner); + /*** + Get religion name by index. + @function M2TWEOP.getReligionName + @tparam int index + @treturn string name + @usage + local religionName =M2TWEOP.getReligionName(1); + */ + tables.M2TWEOPTable.set_function("getReligionName", &gameHelpers::getReligionName); @@ -895,31 +912,58 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) @tfield eduEntry eduEntry @tfield float movePoints + @tfield int aiActiveSet 0 means inactive, 1 means active, 2 means labelled unit (for Battle) @tfield int soldierCountStratMap soldiers count. You can change it on stratmap and soldiers updated. Use @{setParams} if you need change several parameters at once. @tfield int exp soldiers expierence. You can change it on stratmap and soldiers updated. Use @{setParams} if you need change several parameters at once. @tfield int armourLVL soldiers armour. You can change it on stratmap and soldiers updated. Use @{setParams} if you need change several parameters at once. @tfield int weaponLVL soldiers weapon. You can change it on stratmap and soldiers updated. Use @{setParams} if you need change several parameters at once. @tfield int soldierCountStratMapMax Read only @tfield int soldierCountBattleMap Read only + @tfield int moraleLevel (6 means routing) + @tfield int isCloseFormation + @tfield int fatigue (battle) + @tfield int maxAmmo (battle) + @tfield int currentAmmo (battle) + @tfield float battlePosX 2d position on battlemap useful for getting distance etc (battle) + @tfield float battlePosY 2d position on battlemap useful for getting distance etc (battle) @tfield character character @tfield stackStruct army + @tfield siegeEngineNum siegeEngineNum @tfield kill kill @tfield setParams setParams change soldierCountStratMap, exp, armourLVL, weaponLVL at one time. + @tfield hasAttribute hasAttribute Check if unit has edu attribute. @tfield string alias + @tfield hasBattleProperty hasBattleProperty + @tfield setBattleProperty setBattleProperty + @tfield getActionStatus getActionStatus + @tfield isMovingFastSet isMovingFastSet + @tfield setMovingFastSet setMovingFastSet + @tfield isOnWalls isOnWalls + @tfield isEngaged isEngaged + @tfield isUnderFire isUnderFire @table unit */ types.unit = luaState.new_usertype("unit"); types.unit.set("eduEntry", &unit::eduEntry); + types.unit.set("aiActiveSet", &unit::aiActiveSet); types.unit.set("movePoints", sol::property(&unitHelpers::getMovepoints, &unitHelpers::setMovepoints)); types.unit.set("soldierCountStratMap", sol::property(&unitHelpers::getsoldierCountStratMap, &unitHelpers::setSoldiersCount)); types.unit.set("exp", sol::property(&unitHelpers::getExp, &unitHelpers::setExp)); types.unit.set("armourLVL", sol::property(&unitHelpers::getarmourLVL, &unitHelpers::setarmourLVL)); types.unit.set("weaponLVL", sol::property(&unitHelpers::getweaponLVL, &unitHelpers::setweaponLVL)); types.unit.set("soldierCountStratMapMax", sol::property(&unitHelpers::getMaxSoldiersCount)); - types.unit.set("soldierCountBattleMap", &unit::numberTact); + types.unit.set("soldierCountBattleMap", &unit::SoldierCountBattlemap); types.unit.set("character", &unit::general); + types.unit.set("isCloseFormation", &unit::isCloseFormation); + types.unit.set("moraleLevel", &unit::moraleLevel); + types.unit.set("battlePosX", &unit::positionX); + types.unit.set("battlePosY", &unit::positionY); + types.unit.set("fatigue", &unit::fatigue); + types.unit.set("maxAmmo", &unit::maxAmmo); + types.unit.set("currentAmmo", &unit::currentAmmo); + types.unit.set("siegeEngineNum", &unit::siegeEnNum); types.unit.set("army", &unit::army); /*** Kill this unit @@ -939,6 +983,149 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) */ types.unit.set_function("setParams", &unitHelpers::setUnitParams); types.unit.set("alias", sol::property(&technicalHelpers::unitUniStringToStr, &technicalHelpers::setUnitUniStr)); + /*** + Check if unit has edu attribute. + @function unit:hasAttribute + @usage + local hasAttr = unit:hasAttribute("sea_faring"); + */ + types.unit.set_function("hasAttribute", &eopEduHelpers::hasAttribute); + /*** + Check if unit has guard mode, skirmish or fire at will on. + @function unit:hasBattleProperty + @tparam int property use enum: unitBattleProperties.guardMode, unitBattleProperties.skirmish, unitBattleProperties.fireAtWill + @treturn bool hasProperty + @usage + local hasProp = unit:hasBattleProperty(unitBattleProperties.guardMode); + */ + types.unit.set_function("hasBattleProperty", &unitHelpers::hasBattleProperty); + /*** + Set a unit battle property (guard mode, skirmish or fire at will). + @function unit:setBattleProperty + @tparam int property use enum: unitBattleProperties.guardMode, unitBattleProperties.skirmish, unitBattleProperties.fireAtWill + @tparam bool value + @usage + unit:setBattleProperty(unitBattleProperties.skirmish); + */ + types.unit.set_function("setBattleProperty", &unitHelpers::setBattleProperty); + /*** + Get unit action status in battle ( idling, hiding, ready, reforming, moving, withdrawing, missiles_firing, missiles_reloading, charging, fighting, pursuing, routing, fighting_backs_to_the_walls, running_amok, rallying, dead, leaving_battle, entering_battle, left_battle, go_berserk, taunting, bracing, infighting). + @function unit:getActionStatus + @treturn string actionStatus + @usage + local status = unit:getActionStatus(); + */ + types.unit.set_function("getActionStatus", &unitHelpers::getActionStatus); + /*** + Is unit set to run? + @function unit:isMovingFastSet + @treturn bool movingFastSet + @usage + local isRunning = unit:isMovingFastSet(); + */ + types.unit.set_function("isMovingFastSet", &unitHelpers::isMovingFastSet); + /*** + Toggle unit running. + @function unit:setMovingFastSet + @tparam bool movingFastSet + @usage + unit:setMovingFastSet(true); + */ + types.unit.set_function("setMovingFastSet", &unitHelpers::setMovingFastSet); + /*** + Is unit on walls? + @function unit:isOnWalls + @treturn bool isOnWalls + @usage + local isOnWalls = unit:isOnWalls(); + */ + types.unit.set_function("isOnWalls", &unitHelpers::isOnWalls); + /*** + Is unit engaged in melee? + @function unit:isEngaged + @treturn bool isEngaged + @usage + local isEngaged = unit:isEngaged(); + */ + types.unit.set_function("isEngaged", &unitHelpers::isEngaged); + /*** + Is unit under fire? + @function unit:isUnderFire + @treturn bool isUnderFire + @usage + local isUnderFire = unit:isUnderFire(); + */ + types.unit.set_function("isUnderFire", &unitHelpers::isUnderFire); + + ///Unit Position Data + //@section unitPositionData + + /*** + + @tfield int engagedUnitsNum + @tfield unit unit + @tfield int isOnWallsCount (amount of walls + @tfield int isInTowerCount (amount of towers) + @tfield int isInGateHouseCount (amount of gatehouses) + @tfield int targetsDone dont set + @tfield int additionalTargetsOverOne dont set + @tfield int targetsToGo dont set + @tfield int hasTargets dont set + @tfield int isHalted + @tfield float lastTargetCoord1 dont set + @tfield float lastTargetCoord2 dont set + @tfield int towersUnderFireFromCount + @tfield int unitsUnderFireFromCount + @tfield getUnitUnderFireFrom getUnitUnderFireFrom + @tfield getEngagedUnit getEngagedUnit + @tfield getTargetUnit getTargetUnit + + @table unitPositionData + */ + types.unitPositionData = luaState.new_usertype("unitPositionData"); + types.unitPositionData.set("engagedUnitsNum", &unitPositionData::engagedUnitsNum); + types.unitPositionData.set("unit", &unitPositionData::unit); + types.unitPositionData.set("isOnWallsCount", &unitPositionData::isOnWallsCount); + types.unitPositionData.set("isInTowerCount", &unitPositionData::isInTowerCount); + types.unitPositionData.set("isInGateHouseCount", &unitPositionData::isInGateHouseCount); + types.unitPositionData.set("targetsDone", &unitPositionData::targetsDone); + types.unitPositionData.set("additionalTargetsOverOne", &unitPositionData::additionalTargetsOverOne); + types.unitPositionData.set("targetsToGo", &unitPositionData::targetsToGo); + types.unitPositionData.set("hasTargets", &unitPositionData::hasTargets); + types.unitPositionData.set("isHalted", &unitPositionData::isHalted); + types.unitPositionData.set("lastTargetCoord1", &unitPositionData::lastTargetCoord1); + types.unitPositionData.set("lastTargetCoord2", &unitPositionData::lastTargetCoord2); + types.unitPositionData.set("towersUnderFireFromCount", &unitPositionData::towersUnderFireFromCount); + types.unitPositionData.set("unitsUnderFireFromCount", &unitPositionData::unitsUnderFireFromCount); + + /*** + Get unit that is firing at this unit. + @function unitPositionData:getUnitUnderFireFrom + @tparam int index + @treturn unit unit + @usage + local enemyUnit = unit.unitPositionData:getUnitUnderFireFrom(0); + */ + types.unitPositionData.set_function("getUnitUnderFireFrom", &unitHelpers::getUnitUnderFireFrom); + + /*** + Get unit that is fighting this unit in melee. + @function unitPositionData:getEngagedUnit + @tparam int index + @treturn unit unit + @usage + local enemyUnit = unit.unitPositionData:getEngagedUnit(0); + */ + types.unitPositionData.set_function("getEngagedUnit", &unitHelpers::getEngagedUnit); + + /*** + Get the unit this unit is currently targeting. + @function unitPositionData:getTargetUnit + @treturn unit unit + @usage + local enemyUnit = unit.unitPositionData:getTargetUnit(); + */ + types.unitPositionData.set_function("getTargetUnit", &unitHelpers::getTargetUnit); ///EduEntry @@ -1578,6 +1765,10 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) @tfield getWatchtower getWatchtower @tfield deleteFort deleteFort @tfield createFortXY createFortXY + @tfield hasMilitaryAccess hasMilitaryAccess + @tfield setMilitaryAccess setMilitaryAccess + @tfield getFactionStanding getFactionStanding + @tfield setFactionStanding setFactionStanding @table factionStruct */ @@ -1746,6 +1937,46 @@ sol::state* luaP::init(std::string& luaFilePath, std::string& modPath) */ types.factionStruct.set_function("createFortXY", &factionHelpers::createFortXY); + /*** + Check if a faction has military access to another faction. + @function factionStruct:hasMilitaryAccess + @tparam factionStruct targetFaction + @treturn bool hasMilitaryAccess + @usage + local hasAccess = fac:hasMilitaryAccess(targetFac) + */ + types.factionStruct.set_function("hasMilitaryAccess", &factionHelpers::hasMilitaryAccess); + + /*** + Set if a faction has military access to another faction. + @function factionStruct:setMilitaryAccess + @tparam factionStruct targetFaction + @tparam bool hasMilitaryAccess + @usage + fac:setMilitaryAccess(targetFac, true) + */ + types.factionStruct.set_function("setMilitaryAccess", &factionHelpers::setMilitaryAccess); + + /*** + Get the faction standing between 2 factions (a faction with itself returns global standing). + @function factionStruct:getFactionStanding + @tparam factionStruct targetFaction + @treturn float factionStanding + @usage + local standing = fac:getFactionStanding(targetFac) + */ + types.factionStruct.set_function("getFactionStanding", &factionHelpers::getFactionStanding); + /*** + Set the faction standing between 2 factions (a faction with itself sets global standing). + @function factionStruct:setFactionStanding + @tparam factionStruct targetFaction + @tparam float factionStanding + @usage + fac:setFactionStanding(targetFac, 0.5) + */ + types.factionStruct.set_function("setFactionStanding", &factionHelpers::setFactionStanding); + + ///FactionStratMapStruct //@section factionStratMapStructTable diff --git a/M2TWEOP-luaPlugin/luaPlugin/luaP2.cpp b/M2TWEOP-luaPlugin/luaPlugin/luaP2.cpp index b5c81ddf..7d1a94de 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/luaP2.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/luaP2.cpp @@ -21,6 +21,9 @@ void luaP::initCampaign() sol::usertype region; sol::usertype mercPool; sol::usertype mercPoolUnit; + sol::usertype collegeOfCardinals; + sol::usertype crusadeStruct; + sol::usertype jihadStruct; }typeAll; using namespace campaignEnums; @@ -59,16 +62,29 @@ void luaP::initCampaign() /*** Basic campaign table. + @tfield int playerFactionId + @tfield int[31] campaignDifficultyFaction Indexing starts at 1, so add 1 to faction ID. + @tfield int[31] battleDifficultyFaction Indexing starts at 1, so add 1 to faction ID. @tfield factionStruct[31] factionsSortedByDescrStrat Table of factionStruct[31], indexing starts at 1. + @tfield factionStruct[31] factionsSortedByID Table of factionStruct[31], indexing starts at 1, so add 1 to faction ID. @tfield int numberOfFactions @tfield int numberHumanFactions Number of player-controlled factions. @tfield factionStruct currentFaction Faction whose turn it is at the moment, can be set. + @tfield collegeOfCardinals collegeOfCardinals + @tfield factionStruct papalFaction + @tfield int tickCount + @tfield int millisecondCount + @tfield float secondCount @tfield int passedTurnsNum @tfield float timescale Factor for number of turns per year, see descr\_strat.txt @tfield settlementStruct romeSettlement @tfield settlementStruct constantinopleSettlement + @tfield crusadeStruct crusade + @tfield jihadStruct jihad @tfield float BrigandSpawnValue Lower values increase spawn rate. @tfield float PirateSpawnValue Lower values increase spawn rate. + @tfield bool restrictAutoResolve + @tfield bool saveEnabled @tfield int FreeUpkeepForts Number of units who get free upkeep in forts. @tfield float currentDate @tfield int currentseason season (0=summer, 1=winter) @@ -78,19 +94,36 @@ void luaP::initCampaign() @tfield int endSeason season (0=summer, 1=winter) @tfield int daysInBattle @tfield float currentTimeInBattle 24 max, so calculate as daysInBattle*24+currentTimeInBattle. + @tfield int fortsNum + @tfield int portsBuildingsNum + @tfield int watchTowerNum @tfield checkDipStance checkDipStance @tfield setDipStance setDipStance @tfield GetUnitSize GetUnitSize + @tfield getFort getFort + @tfield getPort getPort + @tfield getWatchTower getWatchTower + @tfield getSettlementByName getSettlementByName @table gameDataAll.campaignStruct */ typeAll.campaignTable = luaState.new_usertype("campaignStruct"); + typeAll.campaignTable.set("playerFactionId", &campaign::playerFactionId); + typeAll.campaignTable.set("campaignDifficultyFaction", sol::property([](campaign& self) { return std::ref(self.campaignDifficultyFaction); })); + typeAll.campaignTable.set("battleDifficultyFaction", sol::property([](campaign& self) { return std::ref(self.battleDifficultyFaction); })); typeAll.campaignTable.set("factionsSortedByDescrStrat", sol::property([](campaign& self) { return std::ref(self.factionsSortedByDescrStrat); })); + typeAll.campaignTable.set("factionsSortedByID", sol::property([](campaign& self) { return std::ref(self.factionsSortedByID); })); typeAll.campaignTable.set("numberOfFactions", &campaign::numberOfFactionsWithSlave); + typeAll.campaignTable.set("papalFaction", &campaign::papalFaction); typeAll.campaignTable.set("numberHumanFactions", &campaign::humanPlayers); + typeAll.campaignTable.set("collegeOfCardinals", &campaign::collegeOfCardinals); typeAll.campaignTable.set("currentFaction", &campaign::currentFactionTurn); - + typeAll.campaignTable.set("tickCount", &campaign::tickCount); + typeAll.campaignTable.set("millisecondCount", &campaign::millisecondCount); + typeAll.campaignTable.set("secondCount", &campaign::secondCount); typeAll.campaignTable.set("passedTurnsNum", &campaign::TurnNumber); + typeAll.campaignTable.set("crusade", &campaign::crusade); + typeAll.campaignTable.set("jihad", &campaign::jihad); typeAll.campaignTable.set("timescale", &campaign::TimeScale); typeAll.campaignTable.set("romeSettlement", &campaign::rome); @@ -98,6 +131,8 @@ void luaP::initCampaign() typeAll.campaignTable.set("BrigandSpawnValue", &campaign::BrigandSpawnValue); typeAll.campaignTable.set("BrigandSpawnValue", &campaign::PirateSpawnValue); + typeAll.campaignTable.set("restrictAutoResolve", &campaign::restrictAutoResolve); + typeAll.campaignTable.set("saveEnabled", &campaign::saveEnabled); typeAll.campaignTable.set("FreeUpkeepForts", &campaign::FreeUpkeepForts); typeAll.campaignTable.set("currentDate", &campaign::currentDate); @@ -111,6 +146,9 @@ void luaP::initCampaign() typeAll.campaignTable.set("daysInBattle", &campaign::daysInBattle); typeAll.campaignTable.set("currentTimeInBattle", &campaign::currentTimeInBattle); + typeAll.campaignTable.set("fortsNum", &campaign::fortsNum); + typeAll.campaignTable.set("portsBuildingsNum", &campaign::portsBuildingsNum); + typeAll.campaignTable.set("watchtowersNum", &campaign::watchtowersNum); /*** Check if a diplomatic relation between two factions. @function campaignStruct:checkDipStance @@ -147,6 +185,113 @@ void luaP::initCampaign() local unitSize=campaign:GetUnitSize(); */ typeAll.campaignTable.set_function("GetUnitSize", &m2tweopHelpers::GetUnitSize); + /*** + Get fort by index. + @function campaignStruct:getFort + @tparam int index + @treturn fortStruct fort + @usage + local campaign=gameDataAll.get().campaignStruct; + local fort=campaign:getFort(0); + */ + typeAll.campaignTable.set_function("getFort", &gameHelpers::getFortAll); + /*** + Get port by index. + @function campaignStruct:getPort + @tparam int index + @treturn portBuildingStruct port + @usage + local campaign=gameDataAll.get().campaignStruct; + local port=campaign:getPort(0); + */ + typeAll.campaignTable.set_function("getPort", &gameHelpers::getPortAll); + /*** + Get watchtower by index. + @function campaignStruct:getWatchTower + @tparam int index + @treturn watchTowerStruct watchtower + @usage + local campaign=gameDataAll.get().campaignStruct; + local watchtower=campaign:getWatchTower(0); + */ + typeAll.campaignTable.set_function("getWatchTower", &gameHelpers::getWatchTowerAll); + /*** + Get settlement by internal name. + @function campaignStruct:getSettlementByName + @tparam string name + @treturn settlementStruct settlement + @usage + local campaign=gameDataAll.get().campaignStruct; + local sett=campaign:getSettlementByName("London"); + */ + typeAll.campaignTable.set_function("getSettlementByName", &gameHelpers::getSettlementByName); + + /// College of Cardinals + //@section collegeOfCardinals + /*** + Basic College of Cardinals table. + @tfield namedCharacter pope + @tfield int cardinalNum + @tfield getCardinal getCardinal + + @table collegeOfCardinals + */ + typeAll.collegeOfCardinals = luaState.new_usertype("collegeOfCardinals"); + typeAll.collegeOfCardinals.set("pope", &collegeOfCardinals::pope); + typeAll.collegeOfCardinals.set("cardinalNum", &collegeOfCardinals::cardinalNum); + + /*** + Get a specific cardinal by index. + @function collegeOfCardinals:getCardinal + @tparam int index + @treturn character cardinal + @usage + local college = campaign.collegeOfCardinals; + local cardinal = college:getCardinal(2); + */ + typeAll.collegeOfCardinals.set_function("getCardinal", &gameHelpers::getCardinal); + + /// Crusade + //@section crusade + + /*** + Basic crusade table. + + @tfield int startTurn + @tfield int endTurn + @tfield settlementStruct targetSettlement + @tfield int length + @tfield int outcome + + @table crusadeStruct + */ + typeAll.crusadeStruct = luaState.new_usertype("crusadeStruct"); + typeAll.crusadeStruct.set("startTurn", &crusade::startTurn); + typeAll.crusadeStruct.set("endTurn", &crusade::endTurn); + typeAll.crusadeStruct.set("targetSettlement", &crusade::targetSettlement); + typeAll.crusadeStruct.set("length", &crusade::length); + typeAll.crusadeStruct.set("outcome", &crusade::outcome); + + /// Jihad + //@section jihad + + /*** + Basic jihad table. + + @tfield int startTurn + @tfield int endTurn + @tfield settlementStruct targetSettlement + @tfield int length + @tfield int outcome + + @table jihadStruct + */ + typeAll.jihadStruct = luaState.new_usertype("jihadStruct"); + typeAll.jihadStruct.set("startTurn", &jihad::startTurn); + typeAll.jihadStruct.set("endTurn", &jihad::endTurn); + typeAll.jihadStruct.set("targetSettlement", &jihad::targetSettlement); + typeAll.jihadStruct.set("length", &jihad::length); + typeAll.jihadStruct.set("outcome", &jihad::outcome); /// Strat Map //@section stratMap diff --git a/M2TWEOP-luaPlugin/luaPlugin/m2tweopHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/m2tweopHelpers.cpp index 81baa7d9..4ddcae50 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/m2tweopHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/m2tweopHelpers.cpp @@ -47,25 +47,25 @@ namespace m2tweopHelpers using namespace campaignEnums; if (dipType == dipRelEnum::war) { - return (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::warState); + return (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::warState); } else if (dipType == dipRelEnum::peace) { - return (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::peaceState); + return (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::peaceState); } else if (dipType == dipRelEnum::alliance) { - return (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::allianceState); + return (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::allianceState); } else if (dipType == dipRelEnum::suzerain) { - return (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::allianceState - && campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].protectorate == protectorateState + return (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state == dipStateInternalEnum::allianceState + && campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].protectorate == protectorateState ); } else if (dipType == dipRelEnum::trade) { - return (campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].trade == 1); + return (campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].trade == 1); } return false; } @@ -73,16 +73,16 @@ namespace m2tweopHelpers { using namespace campaignEnums; - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::peaceState; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::peaceState; - if (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].protectorate == protectorateState) + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::peaceState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::peaceState; + if (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].protectorate == protectorateState) { - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].protectorate = nonProtectorateeState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].protectorate = nonProtectorateeState; } - if (campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].protectorate == protectorateState) + if (campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].protectorate == protectorateState) { - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].protectorate = nonProtectorateeState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].protectorate = nonProtectorateeState; } } @@ -93,48 +93,48 @@ namespace m2tweopHelpers { disableVassalage(campaignStruct, fac1, fac2); - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].trade = 0; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].trade = 0; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade = 0; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].trade = 0; - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::warState; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::warState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::warState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::warState; } else if (dipType == dipRelEnum::peace) { disableVassalage(campaignStruct, fac1, fac2); - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::peaceState; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::peaceState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::peaceState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::peaceState; } else if (dipType == dipRelEnum::alliance) { disableVassalage(campaignStruct, fac1, fac2); - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::allianceState; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::allianceState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::allianceState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::allianceState; } else if (dipType == dipRelEnum::suzerain) { disableVassalage(campaignStruct, fac1, fac2); - if (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].protectorate == protectorateState) + if (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].protectorate == protectorateState) { - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].protectorate = nonProtectorateeState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].protectorate = nonProtectorateeState; } - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].protectorate = protectorateState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].protectorate = protectorateState; - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::allianceState; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::allianceState; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state = dipStateInternalEnum::allianceState; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].state = dipStateInternalEnum::allianceState; - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].trade = 1; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].trade = 1; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade = 1; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].trade = 1; } else if (dipType == dipRelEnum::trade) { - if (campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].state != dipStateInternalEnum::warState) + if (campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].state != dipStateInternalEnum::warState) { - campaignStruct->dipArray[fac1->dipNum][fac2->dipNum].trade = 1; - campaignStruct->dipArray[fac2->dipNum][fac1->dipNum].trade = 1; + campaignStruct->diplomaticStandings[fac1->dipNum][fac2->dipNum].trade = 1; + campaignStruct->diplomaticStandings[fac2->dipNum][fac1->dipNum].trade = 1; } } diff --git a/M2TWEOP-luaPlugin/luaPlugin/realGameTypes.h b/M2TWEOP-luaPlugin/luaPlugin/realGameTypes.h index cf501983..cb7b156d 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/realGameTypes.h +++ b/M2TWEOP-luaPlugin/luaPlugin/realGameTypes.h @@ -16,6 +16,8 @@ typedef unsigned short ushort; #pragma pack(push,1) typedef struct stackStruct stackStruct, * PstackStruct; typedef struct settlementStruct settlementStruct, * PsettlementStruct; + + struct UNICODE_STRING { USHORT something;//idk USHORT Length;//idk @@ -252,15 +254,6 @@ struct siegeS { struct stackStruct* army; }; -//diplomacy data of faction to another faction -struct factionDiplomacy { - undefined field_0x0[16]; - int state; /* diplomatic state(war, alliance, peace)(600/0/200) */ - int trade; /* trade rights(0 or 1) */ - int protectorate; /* protectorate or not(15 or 6) */ - undefined field_0x1c[108]; -}; - struct factionStratMapDescrS { /* see descr_sm_factions.txt */ int id; char* facName; @@ -315,6 +308,91 @@ struct worldRecord { undefined field_0x38[40]; }; +struct crusade +{ +public: + char pad_0000[20]; //0x0000 + void* N0000121D; //0x0014 + char pad_0018[28]; //0x0018 + int32_t startTurn; //0x0034 + int32_t endTurn; //0x0038 + struct settlementStruct* targetSettlement; //0x003C + int32_t length; //0x0040 + int32_t outcome; //0x0044 + char pad_0048[252]; //0x0048 + void* N00001269; //0x0144 + char pad_0148[44]; //0x0148 +}; //Size: 0x0174 + + + +struct jihad +{ +public: + char pad_0000[52]; //0x0000 + int32_t startTurn; //0x0034 + int32_t endTurn; //0x0038 + struct settlementStruct* targetSettlement; //0x003C + int32_t length; //0x0040 + int32_t outcome; //0x0044 + char pad_0048[292]; //0x0048 +}; //Size: 0x016C + +struct settlementList +{ + struct settlementStruct** settlements; //0x0000 + struct settlementList* nextSettlements; //0x0004 + struct settlementList* previousSettlements; //0x0008 + int32_t settlementsSize; //0x000C + int32_t settlementsNum; //0x0010 +}; + + +struct factionDiplomacy +{ +public: + char pad_0000[4]; //0x0000 + int state; /* diplomatic state(war, alliance, peace)(600/0/200) */ + int trade; /* trade rights(0 or 1) */ + int protectorate; /* protectorate or not(15 or 6) */ + float factionStanding; //0x0010 + char pad_0014[116]; //0x0014 +}; //Size: 0x0088 + +struct trackedCharacter +{ +public: + struct N0001F08D* N0001F061; //0x0000 + struct general* character; //0x0004 +}; //Size: 0x0008 + +struct cardinal +{ +public: + struct trackedCharacter* trackedCharacter; //0x0000 + struct N0001F079* cardinalInfo; //0x0004 +}; //Size: 0x0008 + +struct collegeOfCardinals +{ +public: + char pad_0000[4]; //0x0000 + struct namedCharacter* pope; //0x0004 + char pad_0008[4]; //0x0008 + struct cardinal* cardinalsArray; //0x000C + int32_t cardinalsArraySize; //0x0010 + int32_t cardinalNum; //0x0014 + int8_t N0001D9D6; //0x0018 + int8_t getsUsedForCountVotes; //0x0019 + int8_t N0001F1B6; //0x001A + int8_t N0001F1B4; //0x001B + struct N0001F0B9* someOtherArray; //0x001C + int32_t someOtherArraySize; //0x0020 + int32_t someOtherArrayCount; //0x0024 + struct UNICODE_STRING** localizedCardinalNames; //0x0028 + char pad_002C[32]; //0x002C +}; //Size: 0x004C + struct campaign { undefined field0_0x0[4]; undefined field1_0x4[52]; @@ -324,22 +402,21 @@ struct campaign { undefined field5_0x44[232]; int humanPlayers; /* number of player-controlled factions */ int factionIdPow; /* pow(2,factionId) */ - int campaignDifficultyFaction[8]; - undefined field9_0x154[120]; - int battleDifficulty07; - undefined field11_0x1d0[88]; - int battleDifficulty30; + int32_t campaignDifficultyFaction[31]; + int32_t battleDifficultyFaction[31]; struct factionStruct* factionsSortedByDescrStrat[31]; struct factionStruct* factionsSortedByID[31]; int numberOfFactionsWithSlave; - undefined field16_0x328[28]; + char pad_0328[20]; //0x0328 + struct collegeOfCardinals* collegeOfCardinals; //0x033C + struct factionStruct* papalFaction; //0x0340 struct factionStruct* currentFactionTurn; - int field18_0x348; /* FactionTurn? */ + int factionTurnID; /* FactionTurn? */ UNICODE_STRING** currentDescrFile; /* path to descr_battle.txt or to descr_strat.txt */ undefined field20_0x350[28]; - int field21_0x36c; /* TickCount? */ - int MillisecondCount; - float SecondCount; + int tickCount; /* TickCount? */ + int millisecondCount; + float secondCount; int TurnNumber; int field25_0x37c; /* PauseForBattleDialog? */ float TimeScale; @@ -353,15 +430,20 @@ struct campaign { undefined field34_0x3d2[26]; float BrigandSpawnValue; float PirateSpawnValue; - undefined field37_0x3f4[4]; + int8_t N00001211; //0x03F4 + int8_t smthingDateTurnDisplay; //0x03F5 + int8_t restrictAutoResolve; //0x03F6 + char pad_03F7[1]; //0x03F7 int FreeUpkeepForts; int ActiveFactions; /* number factions minus slave */ undefined field40_0x400[12]; int lastrandomseed; - undefined field42_0x410[744]; - int8_t isAdminPasswordExist; - int8_t isHotseatLogon; - undefined field45_0x6fa[2]; + struct crusade crusade; //0x0410 + struct jihad jihad; //0x0584 + struct UNICODE_STRING** someUniStringMaybePassword; //0x06F0 + int8_t isAdminPasswordExist; //0x06F4 + int8_t saveEnabled; //0x06F5 + undefined field45_0x6f6[6]; int8_t hotseatConsole; int8_t hotseatConsole2; undefined field48_0x6fe[14]; @@ -375,18 +457,23 @@ struct campaign { float timeAtStartBattle; int daysInBattle; float currentTimeInBattle; /* 24 max, so calc as daysInBattle*24+currentTimeInBattle */ - undefined field59_0x734[4124]; - struct factionDiplomacy dipArray[31][31]; - undefined field61_0x215d8[48]; + char pad_0734[28]; //0x0734 + float clockTime; //0x0750 + char pad_0754[260]; //0x0754 + int32_t interFactionMarriage[31][31]; //0x0858 + struct factionDiplomacy diplomaticStandings[31][31]; //0x175C + struct settlementList settlementList; //0x215E4 + char* introVid; //0x215F8 + char pad_215FC[16]; //0x215FC struct fortStruct** fortsArray; - undefined field63_0x2160c; - int fortsNum; + int32_t fortsSize; //0x21610 + int32_t fortsNum; //0x21614 struct portBuildingStruct** portsBuildings; - undefined field66_0x21615; - int portsBuildingsNum; + int32_t portsBuildingsSize; //0x2161C + int32_t portsBuildingsNum; //0x21620 struct watchTowerStruct** watchtowers; - undefined field69_0x2161e; - int watchtowersNum; + int32_t watchtowersSize; //0x21628 + int32_t watchtowersNum; //0x2162C }; struct gameDataAllStruct { @@ -1367,34 +1454,378 @@ struct engineRecord { }; struct soldierInBattle { - undefined field_0x0[24]; + undefined field_0x0[8]; + int32_t unitCategory; //0x0008 + int16_t someFlags; //0x000C + int8_t N00008AC5; //0x000E + int8_t N00008AC7; //0x000F + float mass; //0x0010 + float inverseMass; //0x0014 float xCoord; float zCoord; float yCoord; - undefined field_0x24[1440]; -}; + struct soldierInBattle* self; //0x0024 + float someRadius1; //0x0028 + float someRadius2; //0x002C + float someRadius3; //0x0030 + float markerRadius; //0x0034 + float height; //0x0038 + char pad_003C[8]; //0x003C + int16_t rotation; //0x0044 + char pad_0046[2]; //0x0046 + float velocity1; + float velocity2; + float velocity3; + char pad_0054[196]; //0x0054 + struct soldierInBattle *self2; //0x0118 + char pad_011C[4]; //0x011C + float speed; //0x0120 + char pad_0124[4]; //0x0124 + float xCoord_writable; + float zCoord_writable; + float yCoord_writable; + uint16_t angle_writable; //0x0134 + int8_t N0000713A; //0x0136 + int8_t N00009525; //0x0137 + float velocityModifier; //0x0138 + int32_t currentStateGroupID; //0x013C + int32_t currentStateStateID; //0x0140 + int32_t pendingStateGroupID; //0x0144 + int32_t pendingStateStateID; //0x0148 + char pad_014C[4]; //0x014C + float xCoord_destination; + float zCoord_destination; + float yCoord_destination; + int16_t destinationAngle; //0x015C + int16_t thisIsAngleCauseTwoByteMaybe; //0x015E + float destinationRadius; //0x0160 + char pad_0164[16]; //0x0164 + int16_t N00001DC6; //0x0174 + char pad_0176[2]; //0x0176 + int32_t targetStateGroupID; //0x0178 + int32_t targetStateStateID; //0x017C (One = Standing, 2 = Walking, 3 = running) + int32_t moveStateGroupID; //0x0180 + int32_t moveStateStateID; //0x0184 (2 = walking, 3 = running) + int32_t finishStateGroupID; //0x0188 + int32_t finishStateStateID; //0x018C + int32_t options; //0x0190 + int32_t pendingAction; //0x0194 + float stoppingModifier; //0x0198 + float slideRotation; //0x019C + int32_t numTicks; //0x01A0 + char pad_01A4[20]; //0x01A4 + int32_t surfaceID; //0x01B8 + int16_t pathHistoryAndObstacleDirection; //0x01BC + int16_t unk; //0x01BE + char pad_01C0[16]; //0x01C0 + int16_t waypoint; //0x01D0 + char pad_01D2[18]; //0x01D2 + int16_t cone; //0x01E4 + int16_t directionOffset; //0x01E6 + int16_t blockedCounter; //0x01E8 + int16_t N0000954E; //0x01EA + float radiusModifier; //0x01EC + float speedModifier; //0x01F0 + int32_t deflectionCounter; //0x01F4 + float stoppingDistance; //0x01F8 + float externalModifier; //0x01FC + uint32_t locomotionFlags; //0x0200 + char pad[960]; //0x01D2 + +}; + +struct generalInfo +{ +public: + char** generalModelName; //0x0000 + struct unit* unit; //0x0004 + struct namedCharacter* namedChar; //0x0008 + char pad_000C[48]; //0x000C + int8_t N00010FEA; //0x003C + char pad_003D[43]; //0x003D + struct soldierInBattle* soldier; //0x0068 + int8_t isCharacter; //0x006C + int8_t alive; //0x006D + char pad_006E[2]; //0x006E + struct heroAbility* ability; //0x0070 + char pad_0074[144]; //0x0074 +}; //Size: 0x0104 + +struct floatPosData +{ +public: + float rotStart; //0x0000 + float coord2_1; //0x0004 + float coord2_2; //0x0008 + float coord3_2; //0x000C + float coord3_1; //0x0010 + float coord0_2; //0x0014 + float coord0_1; //0x0018 + float unk1; //0x001C + float unk2; //0x0020 + float unk; //0x0024 + float rotation1; //0x0028 + float rotation2; //0x002C + float coord1_1; //0x0030 + float coord1_2; //0x0034 + float val15; //0x0038 + float rotValue1; //0x003C + float rotValue2; //0x0040 +}; //Size: 0x0044 + +struct targetUnitStruct +{ +public: + char pad_0000[4]; //0x0000 + struct unit* target; //0x0004 + char pad_0008[4]; //0x0008 + int32_t targetUnitIndex; //0x000C + char pad_0010[4]; //0x0010 +}; //Size: 0x0014 + +struct targetPos +{ +public: + int32_t typeOrSomething; //0x0000 + int32_t N0001B8DA; //0x0004 + void* getsSet0IfHalted; //0x0008 + struct targetUnitStruct* targetUnit; //0x000C + char pad_0010[4]; //0x0010 + float targetPosX; //0x0014 + float targetPosY; //0x0018 + char pad_001C[24]; //0x001C + float N0001B8E6; //0x0034 + char pad_0038[4]; //0x0038 + float N0001B8E8; //0x003C + char pad_0040[4]; //0x0040 + int32_t N0001B8EA; //0x0044 + char pad_0048[96]; //0x0048 +}; //Size: 0x00A8 + +struct battleMapPosition +{ +public: + int32_t positionIDMaybe; //0x0000 + int32_t numSoldiers; //0x0004 +}; //Size: 0x0008 + +struct engagedUnit +{ +public: + struct unit* unit; //0x0000 + int32_t intValue; //0x0004 + int32_t intValue2; //0x0008 + int32_t intValue3; //0x000C + int32_t intValue4; //0x0010 + int32_t intValue5; //0x0014 + float floatValue; //0x0018 +}; //Size: 0x001C + + +struct unitPositionData +{ +public: + struct engagedUnit* engagedUnits; //0x0000 + int32_t engagedUnitsSize; //0x0004 + int32_t engagedUnitsNum; //0x0008 + struct engagedUnit* engagedUnits2; //0x000C + int32_t engagedUnits2Size; //0x0010 + int32_t engagedUnits2Num; //0x0014 + char pad_0018[16]; //0x0018 + struct unit* unit; //0x0028 + char pad_002C[4]; //0x002C + void* N00002C71; //0x0030 + char pad_0034[4]; //0x0034 + struct unit* N00002C73; //0x0038 + float coord0; //0x003C + float coord1; //0x0040 + float coord2; //0x0044 + float coord3; //0x0048 + float rotation; //0x004C + struct battleMapPosition* isOnWalls; //0x0050 + int32_t isOnWallsSize; //0x0054 + int32_t isOnWallsCount; //0x0058 + struct battleMapPosition *isInTower; //0x005C + int32_t isInTowerSize; //0x0060 + int32_t isInTowerCount; //0x0064 + struct battleMapPosition* isInGateHouse; //0x0068 + int32_t isInGateHouseSize; //0x006C + int32_t isInGateHouseCount; //0x0070 + struct battleMapPosition* positions1; //0x0074 + int32_t positions1Size; //0x0078 + int32_t positions1Count; //0x007C + struct battleMapPosition* positions2; //0x0080 + int32_t positions2Size; //0x0084 + int32_t positions2Count; //0x0088 + struct battleMapPosition* positions3; //0x008C + int32_t positions3Size; //0x0090 + int32_t positions3Count; //0x0094 + struct battleMapPosition* positions4; //0x0098 + int32_t positions4Size; //0x009C + int32_t positions4Count; //0x00A0 + char pad_00A4[12]; //0x00A4 + struct floatPosData floatPosData; //0x00B0 + char pad_00F4[4]; //0x00F4 + struct targetPos targetArray[16]; //0x00F8 + int32_t targetsDone; //0x0B78 + int32_t additionalTargetsOverOne; //0x0B7C + int32_t targetsToGo; //0x0B80 + int8_t hasTargets; //0x0B84 + int8_t isHalted; //0x0B85 + char pad_0B86[6]; //0x0B86 + float lastTargetCoord1; //0x0B8C + float lastTargetCoord2; //0x0B90 + char pad_0B94[20]; //0x0B94 + float N00002F68; //0x0BA8 + float N00002F69; //0x0BAC + float N00002F6A; //0x0BB0 + float N00002F6B; //0x0BB4 + float N00002F6C; //0x0BB8 + float N00002F6D; //0x0BBC + float N00002F6E; //0x0BC0 + float N00002F6F; //0x0BC4 + float N00002F70; //0x0BC8 + float N00002F71; //0x0BCC + float N00002F72; //0x0BD0 + float N00002F73; //0x0BD4 + float N00002F74; //0x0BD8 + float N00002F75; //0x0BDC + float N00002F76; //0x0BE0 + float N00002F77; //0x0BE4 + float N00002F78; //0x0BE8 + char pad_0BEC[20]; //0x0BEC + void** towersUnderFireFrom; //0x0C00 + int32_t towersUnderFireFromSize; //0x0C04 + int32_t towersUnderFireFromCount; //0x0C08 + struct unit** unitsUnderFireFrom; //0x0C0C + int32_t unitsUnderFireFromSize; //0x0C10 + int32_t unitsUnderFireFromCount; //0x0C14 + void** underFireSomething2; //0x0C18 + int32_t underFireSomething2Size; //0x0C1C + int32_t underFireSomething2Count; //0x0C20 + void** underFireSomething3; //0x0C24 + int32_t underFireSomething3Size; //0x0C28 + int32_t underFireSomething3Count; //0x0C2C + char pad_0C30[8]; //0x0C30 + int32_t combatStatus; //0x0C38 +}; //Size: 0x0C3C //unit data struct unit { undefined field0_0x0[4]; struct trackedPointerUnit** trackedUnitPointerP; - undefined field2_0x8[636]; - struct stackStruct* army; + undefined field2_0x8[52]; + int32_t aiActiveSet; //0x003C + undefined field_0040[24]; + struct modelEntry* bmdbEntry; //0x0058 + undefined field3_0x5C[548];//0x005C + struct unitPositionData* unitPositionData; //0x0280 + struct stackStruct* army;//0x0284 undefined field4_0x288[12]; struct eduEntry* eduEntry; - int ID; - undefined field7_0x29c[612]; + int ID; //0x0298 + int battlemapTeam; //0x029C + int actionStatus; //0x02A0 + char pad_02A4[24]; //0x02A4 + void* ThirtyTwoByteObject; //0x02BC + char pad_02C0[8]; //0x02C0 + void* hundredSixtyByteObject; //0x02C8 + char pad_02CC[8]; //0x02CC + int fatigue; //0x02D4 + float killChanceModifier; //0x02D8 + struct Unit* this2; //0x02DC + int moraleLevel; //0x02E0 + int moraleStatusSum; //0x02E4 + char pad_02E8[24]; //0x02E8 + int moraleValue1; //0x0300 + int moraleValue2; //0x0304 + int moraleValue3; //0x0308 + int moraleValue4; //0x030C + int moraleValue5; //0x0310 + int moraleValue6; //0x0314 + int moraleValue7; //0x0318 + int moraleValue8; //0x031C + int moraleValue9; //0x0320 + char pad_0324[372]; //0x0324 + struct unitMorale* moralePartOfUnitLookAbove; //0x0498 + char pad_049C[4]; //0x049C + int someMoraleValue; //0x04A0 + char pad_04A4[4]; //0x04A4 + int16_t N0000271D; //0x04A8 + int8_t N00009770; //0x04AA + int8_t skipsMoraleCalcIFNotZero; //0x04AB + int8_t lockedMorale; //0x04AC + char pad_04AD[11]; //0x04AD + int moraleAreaEffectEnd; //0x04B8 + char pad_04BC[60]; //0x04BC + int hasActiveEffects; //0x04F8 + int activeEffectsOnThisUnit; //0x04FC int expScreen; /* screen experience */ struct general* general; float movePoints; - int number; /* number of soldiers */ - int numberTact; /* number of soldiers on tactical map */ - int numberMax; /* max number of soldiers */ - undefined field14_0x518[216]; + int SoldierCountStrat; /* number of soldiers */ + int SoldierCountMaxStrat; /* number of soldiers on tactical map */ + int SoldierCountBattlemap; /* max number of soldiers */ + int soldierCountMaxBattlemap; /* max number of soldiers */ + char pad_051C[64]; //0x051C + struct generalInfo* officer1; //0x055C + struct generalInfo* officer2; //0x0560 + struct generalInfo* officer3; //0x0560 + struct generalInfo* generalInfo; //0x0568 + struct soldierInBattle* generalSoldier; //0x056C + struct soldierInBattle* officer1Soldier; //0x0570 + struct soldierInBattle* officer2Soldier; //0x0574 + struct soldierInBattle* officer3Soldier; //0x0578 + int32_t numOfficer; //0x057C + int32_t numOfficerInBattle; //0x0580 + int32_t N00002755; //0x0584 + int32_t N00002756; //0x0588 + int32_t N00002757; //0x058C + int32_t N00002758; //0x0590 + int32_t statPri; //0x0594 + char pad_0598[20]; //0x0598 + int32_t weaponType; //0x05AC + int32_t weaponTecType; //0x05B0 + char pad_05B4[8]; //0x05B4 + int32_t minAttackDelayPri; //0x05BC + char pad_05C0[28]; //0x05C0 + int32_t statPriArmour; //0x05DC + int32_t valueAfterInEdu; //0x05E0 + int8_t attackInBattle; //0x05E4 + int16_t armourInBattle; //0x05E5 + char pad_05E7[1]; //0x05E7 + int8_t N0000276E; //0x05E8 + int8_t N00010E95; //0x05E9 + char pad_05EA[6]; //0x05EA UINT32 stats; /* def/atk/etc */ struct soldierInBattle** soldiersBattleArr; /* array of soldiers battle data */ struct soldierData* soldiersArr; /* array of soldiers data */ - undefined field18_0x5fc[6780]; + void* soldierIndices; //0x05FC + void* generalOrMount; //0x0600 + int32_t attachmentCount; //0x0604 + char pad_0608[6172]; //0x0608 + void* UNIT_TASK_INTERFACE; //0x1E24 + char pad_1E28[28]; //0x1E28 + int32_t unitBattleProperties; //0x1E44 + char pad_1E48[4]; //0x1E48 + void* formationsArray; //0x1E4C + char pad_1E50[28]; //0x1E28 + int16_t ranks; //0x1E76 + char pad_1E78[14]; //0x1E78 + int8_t isCloseFormation; //0x1E84 + char pad_1E85[59]; //0x1E85 + float positionX; //0x1EC0 + float N00002FB7; //0x1EC4 + float positionY; //0x1EC8 + char pad_1ECC[400]; //0x1ECC + int32_t maxAmmo; //0x205C + int32_t currentAmmo; //0x2060 + uint8_t statusField1; //0x2064 + uint8_t statusField2; //0x2065 + uint8_t statusField3; //0x2066 + char pad_2067[1]; //0x2067 + int8_t rallyHornCountdown; //0x2068 + char pad_2069[15];; //0x2069 UNICODE_STRING** alias; /* Legio string etc */ undefined field20_0x207c[44]; struct siegeEngine** siegeEngine; @@ -1728,8 +2159,8 @@ struct eduEntry { void* N00000152; void* N00000153; char pad_0394[12]; - void* Attributes; - void* EndOfAttributes; + DWORD* Attributes; + DWORD* EndOfAttributes; void* BytesBeforeNextAttributes; int8_t Attributes2; int8_t Attributes3; diff --git a/M2TWEOP-luaPlugin/luaPlugin/stackStructHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/stackStructHelpers.cpp index 8f000af9..72e6d42d 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/stackStructHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/stackStructHelpers.cpp @@ -36,7 +36,7 @@ namespace stackStructHelpers // Soldier Count else if (sortType == 4) { - return unitA->number > unitB->number; + return unitA->SoldierCountStrat > unitB->SoldierCountStrat; } // Experience else if (sortType == 5) diff --git a/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.cpp b/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.cpp index a963e86b..8c524907 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.cpp +++ b/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.cpp @@ -2,13 +2,38 @@ #include "plugData.h" namespace unitHelpers { + std::unordered_map actionTypes = { + {0,"idling"}, + {1,"hiding"}, + {4,"ready"}, + {5,"reforming"}, + {6,"moving"}, + {7,"withdrawing"}, + {8,"missiles_firing"}, + {9,"missiles_reloading"}, + {10,"charging"}, + {11,"fighting"}, + {12,"pursuing"}, + {13,"routing"}, + {14,"fighting_backs_to_the_walls"}, + {15,"running_amok"}, + {23,"infighting"}, + {16,"go_berserk"}, + {17,"rallying"}, + {18,"dead"}, + {19,"leaving_battle"}, + {20,"entering_battle"}, + {21,"left_battle"}, + {2,"taunting"}, + {24,"bracing"}, + }; int getExp(unit* un) { return un->expScreen; } void setExp(unit* un, int exp) { - (*(*plugData::data.funcs.setUnitParams))(un, un->number, exp, getarmourLVL(un), getweaponLVL(un)); + (*(*plugData::data.funcs.setUnitParams))(un, un->SoldierCountStrat, exp, getarmourLVL(un), getweaponLVL(un)); } int getarmourLVL(unit* un) { @@ -16,7 +41,7 @@ namespace unitHelpers } void setarmourLVL(unit* un, int lvl) { - (*(*plugData::data.funcs.setUnitParams))(un, un->number, un->expScreen, lvl, getweaponLVL(un)); + (*(*plugData::data.funcs.setUnitParams))(un, un->SoldierCountStrat, un->expScreen, lvl, getweaponLVL(un)); } int getweaponLVL(unit* un) { @@ -24,7 +49,7 @@ namespace unitHelpers } void setweaponLVL(unit* un, int lvl) { - (*(*plugData::data.funcs.setUnitParams))(un, un->number, un->expScreen, getarmourLVL(un), lvl); + (*(*plugData::data.funcs.setUnitParams))(un, un->SoldierCountStrat, un->expScreen, getarmourLVL(un), lvl); } int getMaxSoldiersCount(unit* un) { @@ -69,7 +94,7 @@ namespace unitHelpers } void setUnitParams(unit* un, int exp, int armor, int weap) { - (*(*plugData::data.funcs.setUnitParams))(un, un->number, exp, armor, weap); + (*(*plugData::data.funcs.setUnitParams))(un, un->SoldierCountStrat, exp, armor, weap); } float getMovepoints(const unit* un) { @@ -77,6 +102,80 @@ namespace unitHelpers } int getsoldierCountStratMap(const unit* un) { - return un->number; + return un->SoldierCountStrat; } + bool hasBattleProperty(const unit* un, unitBattleProperties prop) + { + return (un->unitBattleProperties & prop) != 0; + } + void setBattleProperty(unit* un, unitBattleProperties prop, bool value) + { + if (value) + { + un->unitBattleProperties |= prop; + } + else + { + un->unitBattleProperties &= ~prop; + } + } + const char* getActionStatus(unit* un) + { + auto it = actionTypes.find(un->actionStatus); + if (it != actionTypes.end()) + { + return it->second; + } + return "unknown"; + } + bool isMovingFastSet(unit* un) + { + return un->statusField2 & 0x1; + } + void setMovingFastSet(unit* un, bool set) + { + un->statusField2 = set ? un->statusField2 | 0x1 : un->statusField2 & ~0x1; + } + bool isOnWalls(unit* un) + { + return un->unitPositionData->isInGateHouseCount + un->unitPositionData->isInTowerCount + un->unitPositionData->isOnWallsCount; + } + bool isEngaged(unit* un) + { + return un->unitPositionData->engagedUnitsNum; + } + bool isUnderFire(unit* un) + { + auto posData = un->unitPositionData; + return posData->towersUnderFireFromCount + posData->unitsUnderFireFromCount + posData->underFireSomething2Count + posData->underFireSomething3Count; + } + unit* getUnitUnderFireFrom(unitPositionData* posData, int index) + { + if (index < posData->unitsUnderFireFromCount) + { + return posData->unitsUnderFireFrom[index]; + } + return nullptr; + } + unit* getEngagedUnit(unitPositionData* posData, int index) + { + if (index < posData->engagedUnitsNum) + { + return posData->engagedUnits[index].unit; + } + return nullptr; + } + unit* getTargetUnit(unitPositionData* posData) + { + if (!posData->hasTargets || posData->isHalted) + { + return nullptr; + } + if (posData->targetArray[posData->targetsToGo].targetUnit) + { + return posData->targetArray[posData->targetsToGo].targetUnit->target; + } + return nullptr; + } + } \ No newline at end of file diff --git a/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.h b/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.h index 3e07ef38..a1b3eef6 100644 --- a/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.h +++ b/M2TWEOP-luaPlugin/luaPlugin/unitHelpers.h @@ -1,24 +1,42 @@ #pragma once #include +#include + #include "realGameTypes.h" #include "luaGetSetFuncs.h" namespace unitHelpers { + + enum unitBattleProperties :int + { + guardMode = 1, + fireAtWill = 2, + skirmish = 4, + }; + int getExp(unit* un); void setExp(unit* un,int exp); int getarmourLVL(unit* un); void setarmourLVL(unit* un,int lvl); int getweaponLVL(unit* un); void setweaponLVL(unit* un,int lvl); - + bool hasBattleProperty(const unit* un, unitBattleProperties prop); + void setBattleProperty(unit* un, unitBattleProperties prop, bool value); int getMaxSoldiersCount(unit* un); - + const char* getActionStatus(unit* un); void setMovepoints(unit* un,float movepoints); void setSoldiersCount(unit* un,int number); void killUnit(unit* un); void setUnitParams(unit* un, int exp, int armor, int weap); float getMovepoints(const unit* un); - + bool isMovingFastSet(unit* un); + void setMovingFastSet(unit* un, bool set); + bool isOnWalls(unit* un); + bool isEngaged(unit* un); + bool isUnderFire(unit* un); + unit* getUnitUnderFireFrom(unitPositionData* posData, int index); + unit* getEngagedUnit(unitPositionData* posData, int index); + unit* getTargetUnit(unitPositionData* posData); int getsoldierCountStratMap(const unit* un); };