Skip to content

Commit

Permalink
Add json for swapping marker_creature.nif models per baseform
Browse files Browse the repository at this point in the history
  • Loading branch information
lStewieAl committed Apr 2, 2024
1 parent 6d0ae2c commit 169d316
Show file tree
Hide file tree
Showing 9 changed files with 24,966 additions and 3 deletions.
126 changes: 126 additions & 0 deletions CreatureMarkerSwapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include "SafeWrite.h"
#include "nvse/GameForms.h"
#include "nvse/GameObjects.h"
#include "Utilities.h"

void EditorUI_Log(const char* Format, ...);

#include "libs/nlohmann/json.hpp"
#include <fstream>
#include <string>
using json = nlohmann::json;

namespace CreatureMarkerSwapper
{
std::unordered_map<std::string, std::string> idToMeshPath;

bool SwapMarkerModel(TESActorBase* actorBase, TESObjectREFR* ref, char* dst, size_t sizeInBytes)
{
#if _DEBUG
EditorUI_Log("ActorBase: %s (%08X) - Ref: %s (%08X)",
actorBase->GetEditorID(),
actorBase->refID,
ref ? ref->GetEditorID() : "NULL",
ref ? ref->refID : 0);
#endif
std::string editorID = actorBase->GetEditorID();
auto iter = idToMeshPath.find(editorID);
if (iter != idToMeshPath.end())
{
#if _DEBUG
EditorUI_Log("Swapped %s with %s", actorBase->GetEditorID(), iter._Ptr->_Myval.second);
#endif
strncpy(dst, iter._Ptr->_Myval.second.c_str(), sizeInBytes - 1);
dst[sizeInBytes - 1] = '\0';
return true;
}
return false;
}

void __fastcall LoadCreatureMarker(TESActorBase* actorBase, TESObjectREFR* ref, char* dst, size_t sizeInBytes, const char* format, const char* sMeshes)
{
if (!SwapMarkerModel(actorBase, ref, dst, sizeInBytes))
{
snprintf(dst, sizeInBytes, format, sMeshes);
}
}

__declspec(naked) void LoadCreatureMarkerHook()
{
_asm
{
mov ecx, edi // creature
mov edx, ebp // ref
jmp LoadCreatureMarker
}
}

__declspec(naked) void LoadNPCMarkerHook()
{
_asm
{
mov ecx, ebp // npc
mov edx, esi // ref
jmp LoadCreatureMarker
}
}

void ReadJSON(const char* path)
{
try
{
std::ifstream i(path);
json j;
i >> j;

if (j.is_array())
{
for (auto& elem : j)
{
if (!elem.is_object())
{
EditorUI_Log("JSON error: expected object with EditorID and MeshPath fields.");
continue;
}

idToMeshPath.emplace(elem.contains("EditorID") ? elem["EditorID"].get<std::string>() : "",
elem.contains("MeshPath") ? elem["MeshPath"].get<std::string>() : "");
}
}
}
catch (nlohmann::json::exception& e)
{
EditorUI_Log("The JSON is incorrectly formatted! It will not be applied.");
EditorUI_Log("JSON error: %s", e.what());
}
}

void ProcessJSONsForPath(const char* path)
{
char jsonPath[MAX_PATH];
GetModuleFileNameA(NULL, jsonPath, MAX_PATH);
int pathLen = strlen(path);
char* namePtr = strncpy((char*)(strrchr(jsonPath, '\\') + 1), path, pathLen) + pathLen; // keep pointer "namePtr" to the end of the string
memcpy(namePtr, "*.json", 7);

#if _DEBUG
EditorUI_Log("CreatureMarkerSwapper loading: %s", jsonPath);
#endif
for (DirectoryIterator dirIter(jsonPath); dirIter; ++dirIter)
{
if (!dirIter.IsFile()) continue;
strcpy(namePtr, dirIter.Get());
ReadJSON(jsonPath);
}
}

void Init()
{
WriteRelCall(0x564FD9, UInt32(LoadCreatureMarkerHook));
SafeWriteBuf(0x564FD9 + 5, "\x0F\x1F\x00", 3);
WriteRelCall(0x5728E9, UInt32(LoadNPCMarkerHook));
SafeWriteBuf(0x5728E9 + 5, "\x0F\x1F\x00", 3);

ProcessJSONsForPath("Data\\NVSE\\Plugins\\GeckExtender\\CreatureSwapper\\");
}
}
5 changes: 5 additions & 0 deletions CreatureMarkerSwapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once
namespace CreatureMarkerSwapper
{
void Init();
}
3 changes: 3 additions & 0 deletions ZeGaryHax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "UISpeedHooks.h"
#include "DebugCellShaders.h"
#include "ZeEditBoxHax.h"
#include "CreatureMarkerSwapper.h"

BOOL __stdcall ScriptEditCallback(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Expand Down Expand Up @@ -770,6 +771,8 @@ bool NVSEPlugin_Load(const NVSEInterface* nvse)
// prevent cells getting marked as modified when temp refs are deleted
SafeWrite8(0x63255F, 0xEB); // credits to ShadeMe
}

CreatureMarkerSwapper::Init();

#ifdef _DEBUG
while(!IsDebuggerPresent())
Expand Down
9 changes: 9 additions & 0 deletions ZeGaryHax.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CreatureMarkerSwapper.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Editor.cpp" />
<ClCompile Include="nvse\GameAPI.cpp" />
<ClCompile Include="nvse\GameBSExtraData.cpp">
Expand Down Expand Up @@ -158,9 +162,14 @@
<ClCompile Include="ZeGaryHax.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CreatureMarkerSwapper.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="DebugCellShaders.h" />
<ClInclude Include="Editor.h" />
<ClInclude Include="GECKUtility.h" />
<ClInclude Include="libs\nlohmann\json.hpp" />
<ClInclude Include="nvse\CommandTable.h" />
<ClInclude Include="nvse\GameAPI.h" />
<ClInclude Include="nvse\GameBSExtraData.h" />
Expand Down
8 changes: 8 additions & 0 deletions ZeGaryHax.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<ClCompile Include="nvse\NiTypes.cpp">
<Filter>nvse</Filter>
</ClCompile>
<ClCompile Include="CreatureMarkerSwapper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ZeGaryHax.h" />
Expand Down Expand Up @@ -131,6 +132,10 @@
<ClInclude Include="GECKUtility.h" />
<ClInclude Include="DebugCellShaders.h" />
<ClInclude Include="ZeEditBoxHax.h" />
<ClInclude Include="libs\nlohmann\json.hpp">
<Filter>libs</Filter>
</ClInclude>
<ClInclude Include="CreatureMarkerSwapper.h" />
</ItemGroup>
<ItemGroup>
<None Include="exports.def" />
Expand All @@ -139,6 +144,9 @@
<Filter Include="nvse">
<UniqueIdentifier>{79efc7aa-28af-4ae9-851d-47eb371006d1}</UniqueIdentifier>
</Filter>
<Filter Include="libs">
<UniqueIdentifier>{2bac986a-47af-4ff1-8f78-5a189736d77f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Image Include="bitmap1.bmp" />
Expand Down
Loading

0 comments on commit 169d316

Please sign in to comment.