Rewrote DialogGenderWords option to allow more than one word (#274)

Re-fixed setting DIALOG game mode flag.
This commit is contained in:
NovaRain
2020-01-06 00:20:22 +08:00
parent 310a0df8f6
commit 323738f584
3 changed files with 41 additions and 33 deletions
+4 -3
View File
@@ -119,7 +119,7 @@ ExpandWorldMap=0
;The minimum supported version of High Resolution Patch is 4.1.8
ActionPointsBar=0
;Set to 1 to enable drawing a dotted line when travelling on the world map (similar to Fallout 1)
;Set to 1 to enable drawing a dotted line when traveling on the world map (similar to Fallout 1)
WorldTravelMarkers=0
;Uncomment these lines to change the appearance of the markers
;The color index in Fallout default palette (valid range: 1..255; default is 133)
@@ -263,8 +263,9 @@ DataLoadOrderPatch=1
;Set to 2 to also load subtitle files from text\<language>\cuts_female\ for female PC
FemaleDialogMsgs=0
;Set to 1 to enable using the special '^' character in dialog msg files to specify the gender words
;that will be displayed in the dialogue depending on the player's gender (example: MaleWord^FemaleWord)
;Set to 1 to enable using the special '^' character in dialog msg files to specify the gender text
;that will be displayed in the dialogue depending on the player's gender
;The text must be enclosed in angle brackets (example: <MaleText^FemaleText>)
DialogGenderWords=0
;To change the default and starting player models, uncomment the next four lines.
+4 -10
View File
@@ -529,16 +529,10 @@ static void __declspec(naked) DialogHookStart() {
}
}
static void __declspec(naked) DialogHook() {
static void __declspec(naked) DialogHookEnd() {
__asm {
test inLoop, DIALOG; // check byte flag
jz changeMode;
jmp fo::funcoffs::gdProcess_;
changeMode:
_InLoop(1, DIALOG);
call fo::funcoffs::gdProcess_;
_InLoop(0, DIALOG);
retn;
_InLoop2(0, DIALOG);
jmp fo::funcoffs::gdialogFreeSpeech_;
}
}
@@ -720,7 +714,7 @@ void LoadGameHook::init() {
HookCalls(HelpMenuHook, {0x443A50});
HookCalls(CharacterHook, {0x443320}); // 0x4A73EB, 0x4A740A for character creation
MakeCall(0x445285, DialogHookStart); // gdialogInitFromScript_
HookCall(0x445748, DialogHook);
HookCall(0x4452CD, DialogHookEnd); // gdialogExitFromScript_ (old 0x445748)
HookCalls(PipboyHook, {0x443463, 0x443605});
HookCalls(SkilldexHook, {0x4434AC, 0x44C7BD});
HookCalls(HandleInventoryHook, {0x443357});
+33 -20
View File
@@ -60,8 +60,8 @@ static long msgNumCounter = 0x3000;
static long heroIsFemale = -1;
// Searches the special character in the text and removes the word depending on the player's gender
// example: MaleWord^FemaleWord
// Searches the special character in the text and removes the text depending on the player's gender
// example: <MaleText^FemaleText>
static long __fastcall ReplaceGenderWord(fo::MessageNode* msgData, DWORD* msgFile) {
if (!InDialog() || msgData->flags & MSG_GENDER_CHECK_FLG) return 1;
if (heroIsFemale < 0) heroIsFemale = fo::HeroIsFemale();
@@ -69,27 +69,40 @@ static long __fastcall ReplaceGenderWord(fo::MessageNode* msgData, DWORD* msgFil
unsigned char* _pos = (u_char*)msgData->message;
unsigned char* pos;
while ((pos = (u_char*)std::strchr((char*)_pos, '^')) != 0) { // pos - pointer to the character position
_pos = pos + 1; // next start position
if (heroIsFemale) {
// keep the right word
for (u_char* n = pos - 1; ; n--) {
if (*n == ' ' || n < (u_char*)msgData->message) {
_pos = n + 1;
do *++n = *++pos; while (*pos); // shift all chars to the left
break; // exit for
_pos = pos; // next find position
for (u_char* n = pos - 1; ; n--) {
if (n < (u_char*)msgData->message) {
_pos++; // error, open char not found
break;
} else if (*n == '<') {
if (heroIsFemale) { // remove left(male) side
pos++;
// shift all chars to the left
do {
*n++ = *pos++;
if (*pos == '>') { // skip close char
_pos = n; // set next find position
do *n++ = *++pos; while (*pos); // continue shift (with '\0')
break;
}
} while (*pos);
} else { // remove right(female) side
pos = n;
pos++;
// shift all chars to the left
do {
*n++ = *pos++;
if (pos == _pos) { // skip '^' char
while (*++pos && *pos != '>'); // skip female side
do *n++ = *++pos; while (*pos); // continue shift (with '\0')
break;
}
} while (*pos);
}
break; // exit for
}
} else {
// keep the left word
for (u_char* n = pos + 1; *n; n++) {
if (*n == ' ') {
do *pos++ = *n++; while (*n); // shift all chars to the left
break; // exit for
}
}
*pos = '\0';
if (_pos > pos) break;
}
if (_pos > pos) break;
}
// set flag
unsigned long outValue;