Created
December 3, 2021 16:03
-
-
Save CherryDT/19bf4d95b1cc7f5872c095870decf483 to your computer and use it in GitHub Desktop.
Source code of XEvasionAgiDecouple DynRPG plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _WIN32_WINNT _WIN32_WINNT_WIN7 | |
#include <DynRPG/DynRPG.h> | |
#include <iostream> | |
#include <sstream> | |
#include <stdio.h> | |
#include <wincon.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <windows.h> | |
bool debugMode = false; | |
int actorAgiVarStart = 0; | |
int monsterAgiVarStart = 0; | |
std::string pluginName = ""; | |
void fail (std::string error) { | |
if (debugMode) std::cout << "ERROR: " << error << std::endl; | |
MessageBox(NULL, error.c_str(), pluginName.c_str(), MB_OK | MB_ICONERROR); | |
ExitProcess(1); | |
} | |
void initConsole () { | |
AllocConsole(); | |
AttachConsole(GetCurrentProcessId()); | |
freopen("CON", "w", stdout); | |
std::cout << "XEvasionAgiDecouple Debug Console" << std::endl; | |
} | |
int __stdcall getAgiForEvasion (RPG::Battler* battler) { | |
if (debugMode) std::cout << "getAgiForEvasion called for " << (battler->isMonster() ? "monster" : "actor") << " " << battler->id << std::endl; | |
int varId = (battler->isMonster() ? monsterAgiVarStart : actorAgiVarStart) - 1 + battler->id; | |
int val = RPG::variables[varId]; | |
if (debugMode) std::cout << std::dec << "Returning V[" << varId << "] which is " << val << std::endl; | |
return val; | |
} | |
// Replaces a mov eax, X instruction by nop and push X and replaces the target of the following call instruction. | |
void replaceCall (uint8_t* addr, void* target) { | |
uint16_t movInstr = *(uint16_t*)addr; | |
if ((movInstr & 0xF0FF) != 0xC08B) { | |
std::stringstream s; | |
s << std::hex << "Unexpected instruction 0x" << movInstr << " at 0x" << std::hex << (uint32_t)addr << std::endl; | |
fail(s.str()); | |
} | |
uint16_t nopAndPushInstr = 0x5090 | (movInstr & 0x0F00); | |
*(uint16_t*)addr = nopAndPushInstr; | |
*(uint32_t*)(addr + 3) = (uint32_t)target - ((uint32_t)addr + 7); | |
} | |
bool onStartup(char *pluginName) { | |
::pluginName = pluginName; | |
std::map<std::string, std::string> configuration = RPG::loadConfiguration(pluginName); | |
debugMode = atoi(configuration["DebugMode"].c_str()) == 1; | |
if (debugMode) initConsole(); | |
actorAgiVarStart = atoi(configuration["ActorAgiVarStart"].c_str()); | |
monsterAgiVarStart = atoi(configuration["MonsterAgiVarStart"].c_str()); | |
if (!actorAgiVarStart) fail("ActorAgiVarStart is not set in plugin configuration!"); | |
if (!monsterAgiVarStart) fail("MonsterAgiVarStart is not set in plugin configuration!"); | |
replaceCall((uint8_t*)0x49B0CB, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B0F0, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B104, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B48F, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B499, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B4BE, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49B4D2, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49C6E5, (void*)getAgiForEvasion); | |
replaceCall((uint8_t*)0x49C6F9, (void*)getAgiForEvasion); | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment