Skip to content

Commit

Permalink
handle model loading and unloading
Browse files Browse the repository at this point in the history
  • Loading branch information
FynnTW committed Oct 10, 2024
1 parent da2a7c1 commit e097f04
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 28 deletions.
53 changes: 53 additions & 0 deletions M2TWEOP Code/M2TWEOP library/Injects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4906,6 +4906,59 @@ void onLoadBuilding::SetNewCode()
delete a;
}

onLoadModelRigid::onLoadModelRigid(MemWork* mem, LPVOID addr, int ver)
:AATemplate(mem), funcAddress(addr)
{
if (ver == 2)//steam
m_adress = 0xA04FEE;

else if (ver == 1)//kingdoms
m_adress = 0xA0446E;
}

void onLoadModelRigid::SetNewCode()
{
const auto a = new Assembler();
a->push(eax);
a->push(ecx);
a->push(edx);
a->mov(ecx, esi);
a->mov(eax, reinterpret_cast<DWORD>(funcAddress));
a->call(eax);
a->pop(edx);
a->pop(ecx);
a->pop(eax);
a->ret();
m_cheatBytes = static_cast<unsigned char*>(a->make());
delete a;
}

onUnloadModels::onUnloadModels(MemWork* mem, LPVOID addr, int ver)
:AATemplate(mem), funcAddress(addr)
{
if (ver == 2)//steam
m_adress = 0xA0506C;

else if (ver == 1)//kingdoms
m_adress = 0xA044EC;
}

void onUnloadModels::SetNewCode()
{
const auto a = new Assembler();
a->push(ecx);
a->push(edx);
a->mov(eax, reinterpret_cast<DWORD>(funcAddress));
a->call(eax);
a->mov(eax, 0);
a->test(eax, eax);
a->pop(edx);
a->pop(ecx);
a->ret();
m_cheatBytes = static_cast<unsigned char*>(a->make());
delete a;
}

onOffMapModelThing::onOffMapModelThing(MemWork* mem, LPVOID addr, int ver)
:AATemplate(mem), funcAddress(addr)
{
Expand Down
24 changes: 24 additions & 0 deletions M2TWEOP Code/M2TWEOP library/Injects.h
Original file line number Diff line number Diff line change
Expand Up @@ -2093,6 +2093,30 @@ class onHiddenResourceCheck
LPVOID funcAddress;
};

class onLoadModelRigid
:public AATemplate
{
public:
onLoadModelRigid(MemWork* mem, LPVOID addr, int ver);
~onLoadModelRigid() = default;

void SetNewCode();
private:
LPVOID funcAddress;
};

class onUnloadModels
:public AATemplate
{
public:
onUnloadModels(MemWork* mem, LPVOID addr, int ver);
~onUnloadModels() = default;

void SetNewCode();
private:
LPVOID funcAddress;
};

class onLoadBuilding
:public AATemplate
{
Expand Down
2 changes: 2 additions & 0 deletions M2TWEOP Code/M2TWEOP library/dataOffsets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void dataOffsets::initDataOffsets(int gameVer)
offsets.currentRegion = 0x18FD970;
offsets.traitDb = 0x1666F90;
offsets.ancillaryDb = 0x1666F40;
offsets.modelRigidCounts = 0x1B5EFE4;


offsets.fortVtbl = 0x13362F4;
Expand Down Expand Up @@ -200,6 +201,7 @@ void dataOffsets::initDataOffsets(int gameVer)
offsets.currentRegion = 0x18B4800;
offsets.uiStratUiV2 = 0x2C6D1B0;
offsets.isDLC = 0x016A284C;
offsets.modelRigidCounts = 0x1B15EB4;

offsets.audioEnable = reinterpret_cast<bool*>(0x01639f1d);
offsets.audioMaster_vol = reinterpret_cast<int*>(0x01639f60);
Expand Down
1 change: 1 addition & 0 deletions M2TWEOP Code/M2TWEOP library/dataOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class dataOffsets
DWORD buildingChainLimit = NULL;
DWORD guildCooldown = NULL;
DWORD isDLC = NULL;
DWORD modelRigidCounts = NULL;


DWORD unitTypesStart = NULL;
Expand Down
2 changes: 2 additions & 0 deletions M2TWEOP Code/M2TWEOP library/functionsOffsets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ void codes::initCodes(int gameVer)
offsets.buildQueueConflictTest = 0x5EB100;
offsets.removeBuildingSelection = 0x5FA3A0;
offsets.getNextWord = 0xD4F060;
offsets.modelRigidDestructor = 0x933640;
}


Expand Down Expand Up @@ -662,5 +663,6 @@ void codes::initCodes(int gameVer)
offsets.buildQueueConflictTest = 0x005EB560;
offsets.removeBuildingSelection = 0x005FA790;
offsets.getNextWord = 0xD493C0;
offsets.modelRigidDestructor = 0x934110;
}
}
1 change: 1 addition & 0 deletions M2TWEOP Code/M2TWEOP library/functionsOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class codes
DWORD switchCharacterFaction = NULL;
DWORD switchNamedCharacterFaction = NULL;
DWORD switchArmyFaction = NULL;
DWORD modelRigidDestructor = NULL;
DWORD changeCharacterTileStuff = NULL;
DWORD initPlaceCharacter = NULL;
DWORD getNextWord = NULL;
Expand Down
13 changes: 13 additions & 0 deletions M2TWEOP Code/M2TWEOP library/managerF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,19 @@ void managerF::execPatches()
toLoadBuilding->Enable();
f1 << "Done" << '\n';

f1 << "Start applying onLoadModelRigid patch" << '\n';
onLoadModelRigid* toLoadModelRigid = new onLoadModelRigid(mem, (LPVOID)patchesForGame::onLoadModelRigid, globals::dataS.gameVersion);
toLoadModelRigid->SetNewCode();
toLoadModelRigid->Enable();
f1 << "Done" << '\n';


f1 << "Start applying onUnloadModels patch" << '\n';
onUnloadModels* toUnloadModels = new onUnloadModels(mem, (LPVOID)patchesForGame::onUnloadModels, globals::dataS.gameVersion);
toUnloadModels->SetNewCode();
toUnloadModels->Enable();
f1 << "Done" << '\n';

f1 << "Start applying onOffMapModelThing patch" << '\n';
onOffMapModelThing* toOffMapModelThing = new onOffMapModelThing(mem, (LPVOID)patchesForGame::onOffMapModelThing, globals::dataS.gameVersion);
toOffMapModelThing->SetNewCode();
Expand Down
10 changes: 10 additions & 0 deletions M2TWEOP Code/M2TWEOP library/patchesForGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,16 @@ void patchesForGame::onRemoveFromUnitQueue(const unitRQ* queue, const int index)
gameEvents::onRemoveFromUnitQueue(item);
}

void patchesForGame::onLoadModelRigid(model_Rigid* model)
{
stratModelsChange::pushGameModel(model);
}

void patchesForGame::onUnloadModels()
{
stratModelsChange::clearModels();
}

building* patchesForGame::onGetBuildingById(const settlementBuildings* buildings, const int index)
{
if (index < 0)
Expand Down
2 changes: 2 additions & 0 deletions M2TWEOP Code/M2TWEOP library/patchesForGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class patchesForGame
static int __fastcall onCanWithdrawPreBattle(const settlementStruct* settlement);
static int __fastcall onCalculateCommand(const characterRecord* general);
static void __fastcall onRemoveFromUnitQueue(const unitRQ* queue, int index);
static void __fastcall onLoadModelRigid(model_Rigid* model);
static void __fastcall onUnloadModels();
static building* __fastcall onGetBuildingById(const settlementBuildings* buildings, int index);
static int __fastcall onCheckSettHasBuilding(const settlementBuildings* buildings, int index);
static void __fastcall getPossibleConstructions(exportDescrBuildings* edb, settlementStruct* sett, void* data, void* caps, void* bonus, bool checkQueue, bool forceTemple);
Expand Down
80 changes: 53 additions & 27 deletions M2TWEOP Code/M2TWEOP library/stratModelsChange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,36 @@ namespace stratModelsChange
needFixHiding = 1,
needChange = 2
};
modelsChangeStatus changeModelsNeededNow = modelsChangeStatus::changed;
modelsChangeStatus CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::changed;

struct stratModelCharacterRecord
{
const char* modelId;
const char* skeletonname;
const char* caspath;
const char* shadowcaspath;
const char* texturepath;
const char* skeletonName;
const char* casPath;
const char* shadowCasPath;
const char* texturePath;
float scale;
stratModelArrayEntry* entry;
};

map<UINT32, stratModelRecord*>stratModels;
vector<stratModelCharacterRecord*>characterStratModels;
map<UINT32, stratModelRecord*>STRAT_MODELS;
vector<stratModelCharacterRecord*>CHARACTER_STRAT_MODELS;

std::vector<model_Rigid*> GAME_MODELS{};

void pushGameModel(model_Rigid* model)
{
GAME_MODELS.push_back(model);
}

void addModelToGame(const std::string& path, const UINT32 modelId, const bool isSettlement)
{
auto* modRec = new stratModelRecord();
modRec->path = path;
modRec->modelId = modelId;
modRec->isSettlement = isSettlement;
stratModels[modelId] = modRec;
STRAT_MODELS[modelId] = modRec;
}

void addModelToGameNoBool(const std::string& path, const UINT32 modelId)
Expand Down Expand Up @@ -68,7 +75,7 @@ namespace stratModelsChange

void setModel(const int x, const int y, const UINT32 modelId, const UINT32 modelId2)
{
if (stratModels.find(modelId) == stratModels.end())
if (STRAT_MODELS.find(modelId) == STRAT_MODELS.end())
return;
for (size_t i = 0; i < stratModelChangeList.size(); i++)
{
Expand Down Expand Up @@ -97,7 +104,7 @@ namespace stratModelsChange
eopSettlementDataDb::get()->getSettlementData(tile->regionId, sett->minorSettlementIndex)->modelId = modelId;
}
stratModelChangeList.push_back(rec);
changeModelsNeededNow = modelsChangeStatus::needChange;
CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::needChange;
}

void setModelOneVar(int x, int y, UINT32 modelId)
Expand All @@ -109,7 +116,7 @@ namespace stratModelsChange
{
try
{
return stratModels.at(modelId);
return STRAT_MODELS.at(modelId);
}
catch (...)
{
Expand All @@ -122,7 +129,7 @@ namespace stratModelsChange
{
try
{
return stratModels.at(modelId)->modelP;
return STRAT_MODELS.at(modelId)->modelP;
}
catch (...)
{
Expand All @@ -145,10 +152,10 @@ namespace stratModelsChange

void checkAndChangeStratModels()
{
if (changeModelsNeededNow == modelsChangeStatus::changed)
if (CHANGE_MODELS_NEEDED_NOW == modelsChangeStatus::changed)
return;

changeModelsNeededNow = modelsChangeStatus::changed;
CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::changed;
for (const stratModelChangeRecord* changeMod : stratModelChangeList) //static models
{
const stratModelRecord* mod1 = findStratModel(changeMod->modelId);
Expand Down Expand Up @@ -190,19 +197,19 @@ namespace stratModelsChange
// return;

// ReSharper disable once CppUseElementsView
for (const auto& [index, record] : stratModels)
for (const auto& [index, record] : STRAT_MODELS)
{
record->modelP = loadModel(record->path, record->isSettlement);
}
MODELS_LOADED = true;
changeModelsNeededNow = modelsChangeStatus::needChange;
CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::needChange;
}

void loadCharModels() //rebuild character CAS entries to be sure no pointers were cleaned up
{
for (const stratModelCharacterRecord* modRec : characterStratModels)
for (const stratModelCharacterRecord* modRec : CHARACTER_STRAT_MODELS)
{
*modRec->entry = *buildCharacterCas(modRec->skeletonname, modRec->caspath, modRec->shadowcaspath, modRec->modelId, modRec->texturepath, modRec->scale);
*modRec->entry = *buildCharacterCas(modRec->skeletonName, modRec->casPath, modRec->shadowCasPath, modRec->modelId, modRec->texturePath, modRec->scale);
}
}

Expand All @@ -225,11 +232,30 @@ namespace stratModelsChange
const uint32_t flags = isSettlement ? 2428 : 2332;
GAME_FUNC(char(__thiscall*)(model_Rigid*, DWORD, char*, uint32_t, int ,int, int, bool)
, loadModelRigid)(modelRigid, casModel, textureName, flags, 2, 1, 1, true);
pushGameModel(modelRigid);
GAME_FUNC(void(__thiscall*)(simpleCas*), closeCas)(&cas);
GAME_FUNC(void(__thiscall*)(simpleCas*), simpleCasDestructor)(&cas);
return modelRigid;
}

void closeModel(model_Rigid* model)
{
if (!model)
return;
callClassFunc<model_Rigid*, void>(model, 0x0);
GAME_FUNC(void(__thiscall*)(model_Rigid*), modelRigidDestructor)(model);
}

void clearModels()
{
for (model_Rigid* model : GAME_MODELS)
{
closeModel(model);
}
GAME_MODELS.clear();
*reinterpret_cast<int*>(dataOffsets::offsets.modelRigidCounts) = 0;
}

void setCharacterModel(character* gen, const char* model) //add character to be changed to the queue
{
if (!gen || !model)
Expand All @@ -253,7 +279,7 @@ namespace stratModelsChange
const auto charData = eopCharacterDataDb::get()->getOrCreateData(gen->characterRecord->giveValidLabel(), gen->getTypeID());
charData->model = model;

changeModelsNeededNow = modelsChangeStatus::needChange;
CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::needChange;
}

void changeStratModel(character* gen, const char* model)
Expand Down Expand Up @@ -290,13 +316,13 @@ namespace stratModelsChange

gen->genType = characterFacEntry; //assign new array to general

changeModelsNeededNow = modelsChangeStatus::needChange;
CHANGE_MODELS_NEEDED_NOW = modelsChangeStatus::needChange;
}


stratModelArrayEntry* findCharacterStratModel(const char* modelId) //find eop model from vector
{
for (const stratModelCharacterRecord* newRec : characterStratModels)
for (const stratModelCharacterRecord* newRec : CHARACTER_STRAT_MODELS)
{
if (strcmp(modelId, newRec->modelId) == 0) {
return newRec->entry;
Expand Down Expand Up @@ -431,19 +457,19 @@ namespace stratModelsChange
newRec->modelId = typeNameCopy2;
const auto skeletonCopy = new char[strlen(skeletonname)];
strcpy(skeletonCopy, skeletonname);
newRec->skeletonname = skeletonCopy;
newRec->skeletonName = skeletonCopy;
const auto caspathCopy = new char[strlen(caspath)];
strcpy(caspathCopy, caspath);
newRec->caspath = caspathCopy;
newRec->casPath = caspathCopy;
const auto shadowpathCopy = new char[strlen(shadowcaspath)];
strcpy(shadowpathCopy, shadowcaspath);
newRec->shadowcaspath = shadowpathCopy;
newRec->shadowCasPath = shadowpathCopy;
const auto textureCopy = new char[strlen(texturepath)];
strcpy(textureCopy, texturepath);
newRec->texturepath = textureCopy;
newRec->texturePath = textureCopy;
newRec->scale = scale;
newRec->entry = buildCharacterCas(newRec->skeletonname, newRec->caspath, newRec->shadowcaspath, newRec->modelId, newRec->texturepath, newRec->scale);
characterStratModels.push_back(newRec);
newRec->entry = buildCharacterCas(newRec->skeletonName, newRec->casPath, newRec->shadowCasPath, newRec->modelId, newRec->texturePath, newRec->scale);
CHARACTER_STRAT_MODELS.push_back(newRec);
}


Expand Down
4 changes: 3 additions & 1 deletion M2TWEOP Code/M2TWEOP library/stratModelsChange.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ namespace stratModelsChange
void update();
void loadModels();
model_Rigid* loadModel(const std::string& path, bool isSettlement = false);

void pushGameModel(model_Rigid* model);
void closeModel(model_Rigid* model);
void clearModels();
//add model to a game
//pass path to model and its id(used for change models)
//example of path - eopData/models_strat/northern_european_large_castle.CAS
Expand Down

0 comments on commit e097f04

Please sign in to comment.