mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added functional to the option FemaleDialogMsgs for possibility using the 'cuts_female' directory for female phrases.
This commit is contained in:
@@ -13,6 +13,9 @@
|
|||||||
#define FO_VAR_art_name 0x56C9E4
|
#define FO_VAR_art_name 0x56C9E4
|
||||||
#define FO_VAR_art_vault_guy_num 0x5108A4
|
#define FO_VAR_art_vault_guy_num 0x5108A4
|
||||||
#define FO_VAR_art_vault_person_nums 0x5108A8
|
#define FO_VAR_art_vault_person_nums 0x5108A8
|
||||||
|
#define FO_VAR_aTextSCuts 0x501A8C
|
||||||
|
#define FO_VAR_aTextSCutsS 0x503530
|
||||||
|
#define FO_VAR_aTextSCutsSS 0x50B01C
|
||||||
#define FO_VAR_bboxslot 0x5970E0
|
#define FO_VAR_bboxslot 0x5970E0
|
||||||
#define FO_VAR_bckgnd 0x5707A4
|
#define FO_VAR_bckgnd 0x5707A4
|
||||||
#define FO_VAR_black_palette 0x663FD0
|
#define FO_VAR_black_palette 0x663FD0
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace sfall
|
|||||||
_asm call SetInLoop }
|
_asm call SetInLoop }
|
||||||
|
|
||||||
static Delegate<> onGameInit;
|
static Delegate<> onGameInit;
|
||||||
|
static Delegate<> onGameExit;
|
||||||
static Delegate<> onGameReset;
|
static Delegate<> onGameReset;
|
||||||
static Delegate<> onBeforeGameStart;
|
static Delegate<> onBeforeGameStart;
|
||||||
static Delegate<> onAfterGameStarted;
|
static Delegate<> onAfterGameStarted;
|
||||||
@@ -290,6 +291,10 @@ static void __stdcall GameInitialized() {
|
|||||||
onGameInit.invoke();
|
onGameInit.invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __stdcall GameExit() {
|
||||||
|
onGameExit.invoke();
|
||||||
|
}
|
||||||
|
|
||||||
static void __declspec(naked) main_init_system_hook() {
|
static void __declspec(naked) main_init_system_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
pushad;
|
pushad;
|
||||||
@@ -329,6 +334,15 @@ static void __declspec(naked) before_game_exit_hook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) after_game_exit_hook() {
|
||||||
|
__asm {
|
||||||
|
pushad;
|
||||||
|
call GameExit;
|
||||||
|
popad;
|
||||||
|
jmp fo::funcoffs::main_menu_create_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void __declspec(naked) WorldMapHook() {
|
static void __declspec(naked) WorldMapHook() {
|
||||||
__asm {
|
__asm {
|
||||||
_InLoop(1, WORLDMAP);
|
_InLoop(1, WORLDMAP);
|
||||||
@@ -556,6 +570,7 @@ void LoadGameHook::init() {
|
|||||||
0x47F491, // PrepLoad_ (the very first step during save game loading)
|
0x47F491, // PrepLoad_ (the very first step during save game loading)
|
||||||
});
|
});
|
||||||
HookCalls(before_game_exit_hook, {0x480ACE, 0x480BC7});
|
HookCalls(before_game_exit_hook, {0x480ACE, 0x480BC7});
|
||||||
|
HookCalls(after_game_exit_hook, {0x480AEB, 0x480BE4});
|
||||||
|
|
||||||
HookCalls(WorldMapHook, {0x483668, 0x4A4073});
|
HookCalls(WorldMapHook, {0x483668, 0x4A4073});
|
||||||
HookCalls(WorldMapHook2, {0x4C4855});
|
HookCalls(WorldMapHook2, {0x4C4855});
|
||||||
@@ -585,6 +600,10 @@ Delegate<>& LoadGameHook::OnGameInit() {
|
|||||||
return onGameInit;
|
return onGameInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delegate<>& LoadGameHook::OnGameExit() {
|
||||||
|
return onGameExit;
|
||||||
|
}
|
||||||
|
|
||||||
Delegate<>& LoadGameHook::OnGameReset() {
|
Delegate<>& LoadGameHook::OnGameReset() {
|
||||||
return onGameReset;
|
return onGameReset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public:
|
|||||||
// Invoked when the game has initialized (game_init_ was called).
|
// Invoked when the game has initialized (game_init_ was called).
|
||||||
static Delegate<>& OnGameInit();
|
static Delegate<>& OnGameInit();
|
||||||
|
|
||||||
|
// Invoked when the game exits to main menu
|
||||||
|
static Delegate<>& OnGameExit();
|
||||||
|
|
||||||
// Invoked when game state is being reset (before loading a save, after quitting, etc.)
|
// Invoked when game state is being reset (before loading a save, after quitting, etc.)
|
||||||
static Delegate<>& OnGameReset();
|
static Delegate<>& OnGameReset();
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,35 @@
|
|||||||
namespace sfall
|
namespace sfall
|
||||||
{
|
{
|
||||||
|
|
||||||
static const char* msgFemaleFolder = "dialog_female\\%s.msg";
|
static long femaleMsgs;
|
||||||
|
|
||||||
|
static const char* cutsEndGameFemale = "text\\%s\\cuts_female\\";
|
||||||
|
static const char* cutsSubFemale = "text\\%s\\cuts_female\\%s";
|
||||||
|
static const char* cutsDeathFemale = "text\\%s\\cuts_female\\%s%s";
|
||||||
|
static const char* msgFemaleFolder = "dialog_female\\%s.msg";
|
||||||
|
|
||||||
static bool isFemale = false;
|
static bool isFemale = false;
|
||||||
static bool femaleCheck = false; // flag for check female dialog file
|
static bool femaleCheck = false; // flag for check female dialog file
|
||||||
static DWORD format;
|
static DWORD format;
|
||||||
|
static bool cutsPatch = false;
|
||||||
|
|
||||||
static void CheckPlayerGender() {
|
static void CheckPlayerGender() {
|
||||||
isFemale = fo::HeroIsFemale();
|
isFemale = fo::HeroIsFemale();
|
||||||
|
|
||||||
|
if (femaleMsgs > 1) {
|
||||||
|
if (isFemale) {
|
||||||
|
if (cutsPatch) return;
|
||||||
|
cutsPatch = true;
|
||||||
|
SafeWrite32(0x43FA9F, (DWORD)cutsEndGameFemale);
|
||||||
|
SafeWrite32(0x44EB5B, (DWORD)cutsSubFemale);
|
||||||
|
SafeWrite32(0x48152E, (DWORD)cutsDeathFemale);
|
||||||
|
} else if (cutsPatch) {
|
||||||
|
SafeWrite32(0x43FA9F, FO_VAR_aTextSCuts);
|
||||||
|
SafeWrite32(0x44EB5B, FO_VAR_aTextSCutsS);
|
||||||
|
SafeWrite32(0x48152E, FO_VAR_aTextSCutsSS);
|
||||||
|
cutsPatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DWORD scr_get_dialog_msg_file_Back = 0x4A6BD2;
|
static const DWORD scr_get_dialog_msg_file_Back = 0x4A6BD2;
|
||||||
@@ -67,6 +89,16 @@ exist:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) gnw_main_hack() {
|
||||||
|
__asm {
|
||||||
|
push eax;
|
||||||
|
call CheckPlayerGender;
|
||||||
|
pop eax;
|
||||||
|
mov edx, 4; // overwritten engine code
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void __declspec(naked) removeDatabase() {
|
static void __declspec(naked) removeDatabase() {
|
||||||
__asm {
|
__asm {
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
@@ -144,12 +176,24 @@ void LoadOrder::init() {
|
|||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetConfigInt("Misc", "FemaleDialogMsgs", 0)) {
|
femaleMsgs = GetConfigInt("Misc", "FemaleDialogMsgs", 0);
|
||||||
|
if (femaleMsgs) {
|
||||||
dlog("Applying alternative female dialog files patch.", DL_INIT);
|
dlog("Applying alternative female dialog files patch.", DL_INIT);
|
||||||
MakeJump(0x4A6BCD, scr_get_dialog_msg_file_hack1);
|
MakeJump(0x4A6BCD, scr_get_dialog_msg_file_hack1);
|
||||||
MakeJump(0x4A6BF5, scr_get_dialog_msg_file_hack2);
|
MakeJump(0x4A6BF5, scr_get_dialog_msg_file_hack2);
|
||||||
dlogr(" Done", DL_INIT);
|
|
||||||
LoadGameHook::OnAfterGameStarted() += CheckPlayerGender;
|
LoadGameHook::OnAfterGameStarted() += CheckPlayerGender;
|
||||||
|
if (femaleMsgs > 1) {
|
||||||
|
MakeCall(0x480A95, gnw_main_hack); // before new game start from main menu. TODO: need moved to address 0x480A9A (it busy in movies.cpp)
|
||||||
|
LoadGameHook::OnGameExit() += []() {
|
||||||
|
if (cutsPatch) { // restore
|
||||||
|
SafeWrite32(0x43FA9F, FO_VAR_aTextSCuts);
|
||||||
|
SafeWrite32(0x44EB5B, FO_VAR_aTextSCutsS);
|
||||||
|
SafeWrite32(0x48152E, FO_VAR_aTextSCutsSS);
|
||||||
|
cutsPatch = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user