Backported the patch for party member base protos.

This commit is contained in:
NovaRain
2019-05-02 09:28:28 +08:00
parent f13e6bd9f3
commit f2f260e743
5 changed files with 149 additions and 0 deletions
+10
View File
@@ -474,6 +474,7 @@ const DWORD make_straight_path_func_ = 0x4163C8;
const DWORD map_disable_bk_processes_ = 0x482104;
const DWORD map_enable_bk_processes_ = 0x4820C0;
const DWORD map_load_idx_ = 0x482B34;
const DWORD MapDirErase_ = 0x480040;
const DWORD mem_free_ = 0x4C5C24;
const DWORD mem_malloc_ = 0x4C5AD0;
const DWORD mem_realloc_ = 0x4C5B50;
@@ -556,6 +557,7 @@ const DWORD process_bk_ = 0x4C8BDC;
const DWORD protinst_use_item_ = 0x49BF38;
const DWORD protinst_use_item_on_ = 0x49C3CC;
const DWORD proto_dude_update_gender_ = 0x49F984;
const DWORD proto_list_str_ = 0x49E758;
const DWORD proto_ptr_ = 0x4A2108; // eax - PID, edx - int** - pointer to a pointer to a proto struct
const DWORD pushLongStack_ = 0x46736C; // sometimes used instead of "SetResult"
const DWORD qsort_ = 0x4F05B6;
@@ -1005,6 +1007,14 @@ FrmSubframeData* __fastcall FramePtr(FrmFrameData* frm, long frame, long directi
}
}
void __stdcall MapDirErase(const char* folder, const char* ext) {
__asm {
mov edx, ext;
mov eax, folder;
call MapDirErase_;
}
}
// for the backported AmmoCostHook from 4.x
long __stdcall ItemWAnimWeap(TGameObj* item, DWORD hitMode) {
__asm {
+4
View File
@@ -701,6 +701,7 @@ extern const DWORD make_straight_path_func_; // (TGameObj *aObj<eax>, int aTileF
extern const DWORD map_disable_bk_processes_;
extern const DWORD map_enable_bk_processes_;
extern const DWORD map_load_idx_;
extern const DWORD MapDirErase_;
extern const DWORD mem_free_;
extern const DWORD mem_malloc_;
extern const DWORD mem_realloc_;
@@ -786,6 +787,7 @@ extern const DWORD process_bk_;
extern const DWORD protinst_use_item_;
extern const DWORD protinst_use_item_on_;
extern const DWORD proto_dude_update_gender_;
extern const DWORD proto_list_str_;
extern const DWORD proto_ptr_; // eax - PID, edx - int** - pointer to a pointer to a proto struct
extern const DWORD pushLongStack_;
extern const DWORD qsort_;
@@ -1025,6 +1027,8 @@ long __stdcall NewObjId();
FrmSubframeData* __fastcall FramePtr(FrmFrameData* frm, long frame, long direction);
void __stdcall MapDirErase(const char* folder, const char* ext);
// for the backported AmmoCostHook from 4.x
long __stdcall ItemWAnimWeap(TGameObj* item, DWORD hitMode);
long __stdcall ItemWComputeAmmoCost(TGameObj* item, DWORD* rounds);
+3
View File
@@ -81,6 +81,8 @@ static void _stdcall ResetState(DWORD onLoad) {
InventoryReset();
RegAnimCombatCheck(1);
AfterAttackCleanup();
savPrototypes.clear();
RemoveSavFiles();
ResetExplosionRadius();
PartyControlReset();
}
@@ -264,6 +266,7 @@ static void __stdcall GameInitialization() {
static void __stdcall GameInitialized() {
rcpresInit();
RemoveSavFiles();
if (Use32BitTalkingHeads) TalkingHeadsSetup();
}
+128
View File
@@ -71,6 +71,8 @@ char ini[65] = ".\\";
char translationIni[65];
DWORD modifiedIni;
std::vector<int> savPrototypes;
static char mapName[65];
static char configName[65];
static char patchName[65];
@@ -472,6 +474,124 @@ skip:
}
}
///////////////////////// SAVE PARTY MEMBER PROTOTYPES /////////////////////////
static void __fastcall AddSavPrototype(long pid) {
const std::vector<int>::iterator end_it = savPrototypes.end();
for (std::vector<int>::iterator it = savPrototypes.begin(); it != end_it; ++it) {
const int& _pid = *it;
if (_pid == pid) return;
}
savPrototypes.push_back(pid);
}
static long ChangePrototypeExt(char* path) {
long len = strlen(path);
if (len) {
len -= 4;
if (path[len] == '.') {
path[++len] = 's';
path[++len] = 'a';
path[++len] = 'v';
} else {
len = 0;
}
}
return len;
}
static void __fastcall ExistSavPrototype(long pid, char* path) {
if (savPrototypes.empty()) return;
const std::vector<int>::iterator end_it = savPrototypes.end();
for (std::vector<int>::iterator it = savPrototypes.begin(); it != end_it; ++it) {
const int& _pid = *it;
if (_pid == pid) {
ChangePrototypeExt(path);
break;
}
}
}
static long __fastcall CheckProtoType(long pid, char* path) {
if (pid >> 24 != OBJ_TYPE_CRITTER) return 0;
return ChangePrototypeExt(path);
}
// saves prototypes (all party members) before saving game or exiting the map
static void __declspec(naked) proto_save_pid_hook() {
__asm {
push ecx;
call proto_list_str_;
test eax, eax;
jnz end;
mov ecx, ebx; // party pid
mov edx, edi; // path buffer
call CheckProtoType;
test eax, eax;
jz end;
mov ecx, ebx; // party pid
call AddSavPrototype;
end:
pop ecx;
retn;
}
}
static void __declspec(naked) GameMap2Slot_hack() { // save party pids
__asm {
push ecx;
mov edx, 0x6143F4; // path buffer
call CheckProtoType; // ecx - party pid
pop ecx;
lea eax, [esp + 0x14 + 4];
retn 0x14;
}
}
static void __declspec(naked) SlotMap2Game_hack() { // load party pids
__asm {
push edx;
mov ecx, edi; // party pid
mov edx, 0x6143F4; // path buffer
call CheckProtoType;
test eax, eax;
jz end;
mov ecx, edi;
call AddSavPrototype;
end:
pop edx;
lea eax, [esp + 0x14 + 4];
retn 0x14;
}
}
static void __declspec(naked) proto_load_pid_hook() {
__asm { // eax - party pid
push ecx;
mov ecx, eax;
call proto_list_str_;
test eax, eax;
jnz end;
// check pid type
mov edx, ecx;
shr edx, 24;
cmp edx, OBJ_TYPE_CRITTER;
jnz end;
mov edx, edi; // path buffer
call ExistSavPrototype; // ecx - party pid
xor eax, eax;
end:
pop ecx;
retn;
}
}
void RemoveSavFiles() {
MapDirErase((const char*)0x50A490, (const char*)0x50A480);
}
////////////////////////////////////////////////////////////////////////////////
static char KarmaGainMsg[128];
static char KarmaLossMsg[128];
static void _stdcall SetKarma(int value) {
@@ -1185,6 +1305,14 @@ static void DllMain2() {
dlogr(" Done", DL_INIT);
}
dlog("Applying party member protos save/load patch.", DL_INIT);
savPrototypes.reserve(25);
HookCall(0x4A1CF2, proto_load_pid_hook);
HookCall(0x4A1BEE, proto_save_pid_hook);
MakeCall(0x47F5A5, GameMap2Slot_hack); // save game
MakeCall(0x47FB80, SlotMap2Game_hack); // load game
dlogr(" Done", DL_INIT);
if (GetPrivateProfileInt("Misc", "DisplayKarmaChanges", 0, ini)) {
dlog("Applying display karma changes patch.", DL_INIT);
GetPrivateProfileString("sfall", "KarmaGain", "You gained %d karma.", KarmaGainMsg, 128, translationIni);
+4
View File
@@ -67,12 +67,16 @@ extern char ini[65];
extern char translationIni[65];
extern DWORD modifiedIni;
extern std::vector<int> savPrototypes;
extern char dmModelName[65];
extern char dfModelName[65];
DWORD GetAddedYears(bool isCheck = true);
void SetAddedYears(DWORD years);
void RemoveSavFiles();
template<typename T>
T SimplePatch(DWORD addr, const char* iniSection, const char* iniKey, T defaultValue, T minValue = 0, T maxValue = INT_MAX)
{