mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added DialogGenderWords option to specify gender words for dialog msg
* they will be displayed depending on the player's gender. * currently does not work for messages constructed with message_str.
This commit is contained in:
@@ -263,6 +263,10 @@ 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)
|
||||
DialogGenderWords=0
|
||||
|
||||
;To change the default and starting player models, uncomment the next four lines.
|
||||
;The default models can also be changed ingame via script
|
||||
;MaleStartModel=hmwarr
|
||||
|
||||
@@ -58,6 +58,64 @@ static std::vector<std::string> msgFileList;
|
||||
|
||||
static long msgNumCounter = 0x3000;
|
||||
|
||||
static long heroIsFemale = -1;
|
||||
|
||||
#define MSG_GENDER_CHECK_FLG (0x8)
|
||||
|
||||
// Searches the special character in the text and removes the word depending on the player's gender
|
||||
// example: MaleWord^FemaleWord
|
||||
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();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
// set flag
|
||||
unsigned long outValue;
|
||||
fo::func::message_find(msgFile, msgData->number, &outValue);
|
||||
((fo::MessageNode*)(msgFile[1] + (outValue * 16)))->flags |= MSG_GENDER_CHECK_FLG;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __declspec(naked) scr_get_msg_str_speech_hook() {
|
||||
__asm {
|
||||
call fo::funcoffs::message_search_;
|
||||
cmp eax, 1;
|
||||
jne end;
|
||||
push ecx;
|
||||
lea ecx, [esp + 8]; // message data
|
||||
mov edx, [esp + 0x1C - 0x0C + 8]; // message file
|
||||
call ReplaceGenderWord;
|
||||
pop ecx;
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
// Loads the msg file from the 'english' folder if it does not exist in the current language directory
|
||||
static void __declspec(naked) message_load_hook() {
|
||||
__asm {
|
||||
@@ -81,14 +139,14 @@ noFile:
|
||||
}
|
||||
}
|
||||
|
||||
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef) {
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgRef) {
|
||||
if (msgList != nullptr && msgList->numMsgs > 0) {
|
||||
fo::MessageNode *msgNode = msgList->nodes;
|
||||
long last = msgList->numMsgs - 1;
|
||||
long first = 0;
|
||||
long mid;
|
||||
|
||||
//Use Binary Search to find msg
|
||||
// Use Binary Search to find msg
|
||||
while (first <= last) {
|
||||
mid = (first + last) / 2;
|
||||
if (msgRef > msgNode[mid].number)
|
||||
@@ -102,7 +160,7 @@ fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* GetMsg(fo::MessageList *msgList, int msgRef, int msgNum) {
|
||||
char* GetMsg(fo::MessageList* msgList, int msgRef, int msgNum) {
|
||||
fo::MessageNode *msgNode = GetMsgNode(msgList, msgRef);
|
||||
if (msgNode) {
|
||||
if (msgNum == 2) {
|
||||
@@ -171,6 +229,7 @@ static void ClearScriptAddedExtraGameMsg() { // C++11
|
||||
}
|
||||
}
|
||||
msgNumCounter = 0x3000;
|
||||
heroIsFemale = -1;
|
||||
}
|
||||
|
||||
static void FallbackEnglishLoadMsgFiles() {
|
||||
@@ -189,6 +248,13 @@ static void ClearReadExtraGameMsgFiles() {
|
||||
void Message::init() {
|
||||
msgFileList = GetConfigList("Misc", "ExtraGameMsgFileList", "", 512);
|
||||
|
||||
if (GetConfigInt("Misc", "DialogGenderWords", 0)) {
|
||||
dlog("Applying dialog gender words patch.", DL_INIT);
|
||||
HookCall(0x4A6CEE, scr_get_msg_str_speech_hook);
|
||||
SafeWrite16(0x484C62, 0x9090); // message_search_
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
LoadGameHook::OnGameInit() += FallbackEnglishLoadMsgFiles;
|
||||
LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles;
|
||||
LoadGameHook::OnBeforeGameClose() += ClearReadExtraGameMsgFiles;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
static long AddExtraMsgFile(const char* msgName, long msgNumber);
|
||||
};
|
||||
|
||||
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef);
|
||||
char* GetMsg(fo::MessageList *MsgList, int msgRef, int msgNum);
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgRef);
|
||||
char* GetMsg(fo::MessageList* msgList, int msgRef, int msgNum);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user