Backported "add_extra_msg_file" function from 4.1

Re-ordered critical table fixes in Criticals.cpp.
This commit is contained in:
NovaRain
2020-11-03 15:10:33 +08:00
parent 4b2056857b
commit 38a0ddb1eb
9 changed files with 170 additions and 98 deletions
+1
View File
@@ -259,6 +259,7 @@
/* sfall_funcX macros */ /* sfall_funcX macros */
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
#define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam) #define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam)
#define add_iface_tag sfall_func0("add_iface_tag") #define add_iface_tag sfall_func0("add_iface_tag")
#define add_trait(traitID) sfall_func1("add_trait", traitID) #define add_trait(traitID) sfall_func1("add_trait", traitID)
@@ -557,6 +557,15 @@ optional arguments:
- NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4("draw_image", pathFile, frame, x, y)) - NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4("draw_image", pathFile, frame, x, y))
- if draw_image_scaled is called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background - if draw_image_scaled is called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background
> int sfall_func1("add_extra_msg_file", string fileName)
> int sfall_func2("add_extra_msg_file", string fileName, int fileNumber)
- loads the custom message file, and returns the file ID number assigned to it in range from 0x3000 to 0x3FFF for the message_str_game function to get messages from the file
- fileName: the name of the custom message file (including the .msg extension) in "text\<language>\game\" directory
- NOTE: if the msg file does not exist in the current language directory, the function will try to load it from "text\English\game\" directory
optional argument:
- fileNumber: the file ID number for the message_str_game function. The available range is from 0x2000 to 0x2FFF (see ExtraGameMsgFileList setting in ddraw.ini)
use fileNumber only if you want to add a message file without editing ddraw.ini or existing scripts to support the old way
> void sfall_func2("unwield_slot", object critter, int slot) > void sfall_func2("unwield_slot", object critter, int slot)
- unequips an item from the specified slot for a critter or the player - unequips an item from the specified slot for a critter or the player
- can take off player's equipped item when the inventory is opened, or the player is in the barter screen - can take off player's equipped item when the inventory is opened, or the player is in the barter screen
+102 -98
View File
@@ -166,58 +166,120 @@ static void CriticalTableOverride() {
SafeWrite32(0x423FB3, (DWORD)critTable); SafeWrite32(0x423FB3, (DWORD)critTable);
if (mode == 2 || mode == 3) { // bug fixes if (mode == 2 || mode == 3) { // bug fixes
// Children
SetEntry(2, LegRight, 1, FlagsFail, 0);
SetEntry(2, LegRight, 1, Message, 5216);
SetEntry(2, LegRight, 1, MsgFail, 5000);
SetEntry(2, LegRight, 2, FlagsFail, 0);
SetEntry(2, LegRight, 2, Message, 5216);
SetEntry(2, LegRight, 2, MsgFail, 5000);
SetEntry(2, LegLeft, 1, FlagsFail, 0);
SetEntry(2, LegLeft, 1, Message, 5216);
SetEntry(2, LegLeft, 1, MsgFail, 5000);
SetEntry(2, LegLeft, 2, FlagsFail, 0);
SetEntry(2, LegLeft, 2, Message, 5216);
SetEntry(2, LegLeft, 2, MsgFail, 5000);
// Super Mutants
SetEntry(3, LegLeft, 1, MsgFail, 5306);
// Ghouls
SetEntry(4, Head, 4, StatCheck, -1);
// Brahmin
SetEntry(5, Head, 4, StatCheck, -1);
// Radscorpions
SetEntry(6, LegRight, 1, FlagsFail, DAM_KNOCKED_DOWN);
SetEntry(6, LegLeft, 1, FlagsFail, DAM_KNOCKED_DOWN);
SetEntry(6, LegLeft, 2, MsgFail, 5608);
// Centaurs
SetEntry(9, Torso, 3, FlagsFail, DAM_KNOCKED_DOWN);
// Deathclaws
SetEntry(13, LegLeft, 1, FlagsFail, DAM_CRIP_LEG_LEFT);
SetEntry(13, LegLeft, 2, FlagsFail, DAM_CRIP_LEG_LEFT);
SetEntry(13, LegLeft, 3, FlagsFail, DAM_CRIP_LEG_LEFT);
SetEntry(13, LegLeft, 4, FlagsFail, DAM_CRIP_LEG_LEFT);
SetEntry(13, LegLeft, 5, FlagsFail, DAM_CRIP_LEG_LEFT);
// Big Bad Boss
SetEntry(18, Head, 0, Message, 5001);
SetEntry(18, Head, 1, Message, 5001);
SetEntry(18, Head, 2, Message, 5001);
SetEntry(18, Head, 3, Message, 7105);
SetEntry(18, Head, 4, Message, 7101);
SetEntry(18, Head, 4, MsgFail, 7104);
SetEntry(18, Head, 5, Message, 7101);
SetEntry(18, ArmLeft, 0, Message, 5008);
SetEntry(18, ArmLeft, 1, Message, 5008);
SetEntry(18, ArmLeft, 2, Message, 5009);
SetEntry(18, ArmLeft, 3, Message, 5009);
SetEntry(18, ArmLeft, 4, Message, 7102);
SetEntry(18, ArmLeft, 5, Message, 7102);
SetEntry(18, ArmRight, 0, Message, 5008);
SetEntry(18, ArmRight, 1, Message, 5008);
SetEntry(18, ArmRight, 2, Message, 5009);
SetEntry(18, ArmRight, 3, Message, 5009);
SetEntry(18, ArmRight, 4, Message, 7102);
SetEntry(18, ArmRight, 5, Message, 7102);
SetEntry(18, Torso, 4, Message, 7101);
SetEntry(18, Torso, 5, Message, 7101);
SetEntry(18, LegRight, 0, Message, 5023);
SetEntry(18, LegRight, 1, Message, 7101);
SetEntry(18, LegRight, 1, MsgFail, 7103);
SetEntry(18, LegRight, 2, Message, 7101);
SetEntry(18, LegRight, 2, MsgFail, 7103);
SetEntry(18, LegRight, 3, Message, 7103);
SetEntry(18, LegRight, 4, Message, 7103);
SetEntry(18, LegRight, 5, Message, 7103);
SetEntry(18, LegLeft, 0, Message, 5023);
SetEntry(18, LegLeft, 1, Message, 7101);
SetEntry(18, LegLeft, 1, MsgFail, 7103);
SetEntry(18, LegLeft, 2, Message, 7101);
SetEntry(18, LegLeft, 2, MsgFail, 7103);
SetEntry(18, LegLeft, 3, Message, 7103);
SetEntry(18, LegLeft, 4, Message, 7103);
SetEntry(18, LegLeft, 5, Message, 7103);
SetEntry(18, Eyes, 0, Message, 5027);
SetEntry(18, Eyes, 1, Message, 5027);
SetEntry(18, Eyes, 2, Message, 5027);
SetEntry(18, Eyes, 3, Message, 5027);
SetEntry(18, Eyes, 4, Message, 7104);
SetEntry(18, Eyes, 5, Message, 7104);
SetEntry(18, Groin, 0, Message, 5033);
SetEntry(18, Groin, 1, Message, 5027);
SetEntry(18, Groin, 1, MsgFail, 7101);
SetEntry(18, Groin, 2, Message, 7101);
SetEntry(18, Groin, 3, Message, 7101);
SetEntry(18, Groin, 4, Message, 7101);
SetEntry(18, Groin, 5, Message, 7101);
// Fixes for uncalled tables
// Men // Men
SetEntry(0, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // 0 SetEntry(0, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // 0
SetEntry(0, Uncalled, 2, Message, 5019); // 5018 SetEntry(0, Uncalled, 2, Message, 5019); // 5018
// Children // Children
SetEntry(2, LegRight, 1, FlagsFail, 0); // 5216
SetEntry(2, LegRight, 1, Message, 5216); // 5000
SetEntry(2, LegRight, 1, MsgFail, 5000); // 0
SetEntry(2, LegRight, 2, FlagsFail, 0); // 5216
SetEntry(2, LegRight, 2, Message, 5216); // 5000
SetEntry(2, LegRight, 2, MsgFail, 5000); // 0
SetEntry(2, LegLeft, 1, FlagsFail, 0); // 5216
SetEntry(2, LegLeft, 1, Message, 5216); // 5000
SetEntry(2, LegLeft, 1, MsgFail, 5000); // 0
SetEntry(2, LegLeft, 2, FlagsFail, 0); // 5216
SetEntry(2, LegLeft, 2, Message, 5216); // 5000
SetEntry(2, LegLeft, 2, MsgFail, 5000); // 0
SetEntry(2, Uncalled, 1, DmgMult, 4); // 3 SetEntry(2, Uncalled, 1, DmgMult, 4); // 3
SetEntry(2, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // DAM_BYPASS SetEntry(2, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // DAM_BYPASS
SetEntry(2, Uncalled, 2, Message, 5212); // 5211 SetEntry(2, Uncalled, 2, Message, 5212); // 5211
// Super Mutants
SetEntry(3, LegLeft, 1, MsgFail, 5306); // 5312
// Ghouls
SetEntry(4, Head, 4, StatCheck, -1); // STAT_st
// Brahmin
SetEntry(5, Head, 4, StatCheck, -1); // STAT_st
// Radscorpions
SetEntry(6, LegRight, 1, FlagsFail, DAM_KNOCKED_DOWN); // 0
SetEntry(6, LegLeft, 1, FlagsFail, DAM_KNOCKED_DOWN); // 0
SetEntry(6, LegLeft, 2, MsgFail, 5608); // 5008
// Centaurs // Centaurs
SetEntry(9, Torso, 3, FlagsFail, DAM_KNOCKED_DOWN); // 0
SetEntry(9, Uncalled, 3, FlagsFail, DAM_KNOCKED_DOWN); // 0 SetEntry(9, Uncalled, 3, FlagsFail, DAM_KNOCKED_DOWN); // 0
// Deathclaws
SetEntry(13, LegLeft, 1, FlagsFail, DAM_CRIP_LEG_LEFT); // DAM_CRIP_LEG_RIGHT
SetEntry(13, LegLeft, 2, FlagsFail, DAM_CRIP_LEG_LEFT); // DAM_CRIP_LEG_RIGHT
SetEntry(13, LegLeft, 3, FlagsFail, DAM_CRIP_LEG_LEFT); // DAM_CRIP_LEG_RIGHT
SetEntry(13, LegLeft, 4, FlagsFail, DAM_CRIP_LEG_LEFT); // DAM_CRIP_LEG_RIGHT
SetEntry(13, LegLeft, 5, FlagsFail, DAM_CRIP_LEG_LEFT); // DAM_CRIP_LEG_RIGHT
// Geckos // Geckos
SetEntry(15, Uncalled, 0, Message, 6701); // 6700 SetEntry(15, Uncalled, 0, Message, 6701); // 6700
SetEntry(15, Uncalled, 1, Message, 6701); // 6700 SetEntry(15, Uncalled, 1, Message, 6701); // 6700
@@ -234,64 +296,6 @@ static void CriticalTableOverride() {
SetEntry(17, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // 0 SetEntry(17, Uncalled, 2, Flags, DAM_KNOCKED_DOWN | DAM_BYPASS); // 0
// Big Bad Boss // Big Bad Boss
SetEntry(18, Head, 0, Message, 5001); // 7101
SetEntry(18, Head, 1, Message, 5001); // 7102
SetEntry(18, Head, 2, Message, 5001); // 7102
SetEntry(18, Head, 3, Message, 7105); // 7104
SetEntry(18, Head, 4, Message, 7101); // 7105
SetEntry(18, Head, 4, MsgFail, 7104); // 7106
SetEntry(18, Head, 5, Message, 7101); // 7105
SetEntry(18, ArmLeft, 0, Message, 5008); // 7106
SetEntry(18, ArmLeft, 1, Message, 5008); // 7106
SetEntry(18, ArmLeft, 2, Message, 5009); // 7106
SetEntry(18, ArmLeft, 3, Message, 5009); // 7106
SetEntry(18, ArmLeft, 4, Message, 7102); // 7106
SetEntry(18, ArmLeft, 5, Message, 7102); // 7106
SetEntry(18, ArmRight, 0, Message, 5008); // 7106
SetEntry(18, ArmRight, 1, Message, 5008); // 7106
SetEntry(18, ArmRight, 2, Message, 5009); // 7106
SetEntry(18, ArmRight, 3, Message, 5009); // 7106
SetEntry(18, ArmRight, 4, Message, 7102); // 7106
SetEntry(18, ArmRight, 5, Message, 7102); // 7106
SetEntry(18, Torso, 4, Message, 7101); // 7106
SetEntry(18, Torso, 5, Message, 7101); // 7106
SetEntry(18, LegRight, 0, Message, 5023); // 7106
SetEntry(18, LegRight, 1, Message, 7101); // 7106
SetEntry(18, LegRight, 1, MsgFail, 7103); // 7106
SetEntry(18, LegRight, 2, Message, 7101); // 7060
SetEntry(18, LegRight, 2, MsgFail, 7103); // 7106
SetEntry(18, LegRight, 3, Message, 7103); // 7106
SetEntry(18, LegRight, 4, Message, 7103); // 7106
SetEntry(18, LegRight, 5, Message, 7103); // 7106
SetEntry(18, LegLeft, 0, Message, 5023); // 7106
SetEntry(18, LegLeft, 1, Message, 7101); // 7106
SetEntry(18, LegLeft, 1, MsgFail, 7103); // 7124
SetEntry(18, LegLeft, 2, Message, 7101); // 7106
SetEntry(18, LegLeft, 2, MsgFail, 7103); // 7124
SetEntry(18, LegLeft, 3, Message, 7103); // 7106
SetEntry(18, LegLeft, 4, Message, 7103); // 7106
SetEntry(18, LegLeft, 5, Message, 7103); // 7106
SetEntry(18, Eyes, 0, Message, 5027); // 7106
SetEntry(18, Eyes, 1, Message, 5027); // 7106
SetEntry(18, Eyes, 2, Message, 5027); // 7106
SetEntry(18, Eyes, 3, Message, 5027); // 7106
SetEntry(18, Eyes, 4, Message, 7104); // 7106
SetEntry(18, Eyes, 5, Message, 7104); // 7106
SetEntry(18, Groin, 0, Message, 5033); // 7106
SetEntry(18, Groin, 1, Message, 5027); // 7106
SetEntry(18, Groin, 1, MsgFail, 7101); // 7106
SetEntry(18, Groin, 2, Message, 7101); // 7106
SetEntry(18, Groin, 3, Message, 7101); // 7106
SetEntry(18, Groin, 4, Message, 7101); // 7106
SetEntry(18, Groin, 5, Message, 7101); // 7106
SetEntry(18, Uncalled, 2, DmgMult, 3); // 4 SetEntry(18, Uncalled, 2, DmgMult, 3); // 4
SetEntry(18, Uncalled, 4, DmgMult, 4); // 5 SetEntry(18, Uncalled, 4, DmgMult, 4); // 5
SetEntry(18, Uncalled, 4, Message, 7101); // 7106 SetEntry(18, Uncalled, 4, Message, 7101); // 7106
+1
View File
@@ -104,6 +104,7 @@ static void __stdcall ResetState(DWORD onLoad) { // OnGameReset & OnBeforeGameSt
InventoryReset(); InventoryReset();
PartyControl_OnGameLoad(); PartyControl_OnGameLoad();
ResetExplosionRadius(); ResetExplosionRadius();
ClearScriptAddedExtraGameMsg();
BarBoxes_OnGameLoad(); BarBoxes_OnGameLoad();
MetaruleExtenderReset(); MetaruleExtenderReset();
ScriptExtender_OnGameLoad(); ScriptExtender_OnGameLoad();
+37
View File
@@ -51,6 +51,8 @@ const MSGList* gameMsgFiles[] = {
ExtraGameMessageListsMap gExtraGameMsgLists; ExtraGameMessageListsMap gExtraGameMsgLists;
static std::vector<std::string> msgFileList; static std::vector<std::string> msgFileList;
static long msgNumCounter = 0x3000;
// Loads the msg file from the 'english' folder if it does not exist in the current language directory // 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() { static void __declspec(naked) message_load_hook() {
__asm { __asm {
@@ -132,6 +134,41 @@ void ReadExtraGameMsgFiles() {
} }
} }
long __stdcall Message_AddExtraMsgFile(const char* msgName, long msgNumber) {
if (msgNumber) {
if (msgNumber < 0x2000 || msgNumber > 0x2FFF) return -1;
if (gExtraGameMsgLists.count(msgNumber)) return 0; // file has already been added
} else if (msgNumCounter > 0x3FFF) return -3;
std::string path("game\\");
path += msgName;
MSGList* list = new MSGList();
if (!MessageLoad(list, path.c_str())) {
// change current language folder
//path.insert(0, "..\\english\\");
//if (!MessageLoad(list, path.c_str())) {
delete list;
return -2;
//}
}
if (msgNumber == 0) msgNumber = msgNumCounter++;
gExtraGameMsgLists.insert(std::make_pair(msgNumber, list));
return msgNumber;
}
void ClearScriptAddedExtraGameMsg() {
for (ExtraGameMessageListsMap::iterator it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end();) {
if (it->first >= 0x3000 && it->first <= 0x3FFF) {
MessageExit(it->second);
delete it->second;
it = gExtraGameMsgLists.erase(it);
} else {
++it;
}
}
msgNumCounter = 0x3000;
}
void FallbackEnglishLoadMsgFiles() { void FallbackEnglishLoadMsgFiles() {
char value[128]; char value[128];
if (GetGameConfigString(value, "system", "language") && _stricmp(value, "english") != 0) { if (GetGameConfigString(value, "system", "language") && _stricmp(value, "english") != 0) {
+3
View File
@@ -52,6 +52,9 @@ void Message_Exit();
void FallbackEnglishLoadMsgFiles(); void FallbackEnglishLoadMsgFiles();
void ReadExtraGameMsgFiles(); void ReadExtraGameMsgFiles();
void ClearReadExtraGameMsgFiles(); void ClearReadExtraGameMsgFiles();
void ClearScriptAddedExtraGameMsg();
long __stdcall Message_AddExtraMsgFile(const char* msgName, long msgNumber);
MSGNode* GetMsgNode(MSGList* msgList, int msgRef); MSGNode* GetMsgNode(MSGList* msgList, int msgRef);
char* GetMsg(MSGList* msgList, int msgRef, int msgNum); char* GetMsg(MSGList* msgList, int msgRef, int msgNum);
+1
View File
@@ -851,6 +851,7 @@ static void __declspec(naked) op_sfall_ver_build() {
If you don't include opcode in this array, you should take care of all argument validation inside handler itself. If you don't include opcode in this array, you should take care of all argument validation inside handler itself.
*/ */
static const SfallOpcodeMetadata opcodeMetaArray[] = { static const SfallOpcodeMetadata opcodeMetaArray[] = {
{mf_add_extra_msg_file, "add_extra_msg_file", {DATATYPE_MASK_STR, DATATYPE_MASK_INT}},
{mf_add_g_timer_event, "add_g_timer_event", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}}, {mf_add_g_timer_event, "add_g_timer_event", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{mf_add_trait, "add_trait", {DATATYPE_MASK_INT}}, {mf_add_trait, "add_trait", {DATATYPE_MASK_INT}},
{mf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}}, {mf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
+1
View File
@@ -115,6 +115,7 @@ static void mf_metarule_exist() {
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function (max 6) - minArgs/maxArgs - minimum and maximum number of arguments allowed for this function (max 6)
*/ */
static const SfallMetarule metaruleArray[] = { static const SfallMetarule metaruleArray[] = {
{"add_extra_msg_file", mf_add_extra_msg_file, 1, 2},
{"add_iface_tag", mf_add_iface_tag, 0, 0}, {"add_iface_tag", mf_add_iface_tag, 0, 0},
{"add_g_timer_event", mf_add_g_timer_event, 2, 2}, {"add_g_timer_event", mf_add_g_timer_event, 2, 2},
{"add_trait", mf_add_trait, 1, 1}, {"add_trait", mf_add_trait, 1, 1},
+15
View File
@@ -515,6 +515,21 @@ static void __declspec(naked) op_message_str_game() {
_WRAP_OPCODE(op_message_str_game2, 2, 1) _WRAP_OPCODE(op_message_str_game2, 2, 1)
} }
static void mf_add_extra_msg_file() {
long result = Message_AddExtraMsgFile(opHandler.arg(0).strValue(), (opHandler.numArgs() == 2) ? opHandler.arg(1).rawValue() : 0);
switch (result) {
case -1 :
opHandler.printOpcodeError("add_extra_msg_file() - cannot add message file with the specified number.");
break;
case -2 :
opHandler.printOpcodeError("add_extra_msg_file() - error loading message file.");
break;
case -3 :
opHandler.printOpcodeError("add_extra_msg_file() - the limit of adding message files has been exceeded.");
}
opHandler.setReturn(result);
}
static void mf_get_text_width() { static void mf_get_text_width() {
const ScriptValue &textArg = opHandler.arg(0); const ScriptValue &textArg = opHandler.arg(0);