mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "add_extra_msg_file" and "metarule_exist" script functions.
This commit is contained in:
@@ -244,6 +244,7 @@
|
|||||||
#define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks
|
#define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks
|
||||||
|
|
||||||
// sfall_funcX macros
|
// sfall_funcX macros
|
||||||
|
#define add_extra_msg_file(name, number) sfall_func2("add_extra_msg_file", name, number)
|
||||||
#define add_iface_tag sfall_func0("add_iface_tag")
|
#define add_iface_tag sfall_func0("add_iface_tag")
|
||||||
#define art_cache_clear sfall_func0("art_cache_clear")
|
#define art_cache_clear sfall_func0("art_cache_clear")
|
||||||
#define attack_is_aimed sfall_func0("attack_is_aimed")
|
#define attack_is_aimed sfall_func0("attack_is_aimed")
|
||||||
@@ -280,6 +281,7 @@
|
|||||||
#define item_weight(obj) sfall_func1("item_weight", obj)
|
#define item_weight(obj) sfall_func1("item_weight", obj)
|
||||||
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
||||||
#define loot_obj sfall_func0("loot_obj")
|
#define loot_obj sfall_func0("loot_obj")
|
||||||
|
#define metarule_exist(metarule) sfall_func1("metarule_exist", metarule)
|
||||||
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
|
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
|
||||||
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
||||||
#define outlined_object sfall_func0("outlined_object")
|
#define outlined_object sfall_func0("outlined_object")
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ Some utility/math functions are available:
|
|||||||
> string message_str_game(int fileId, int messageId)
|
> string message_str_game(int fileId, int messageId)
|
||||||
- works exactly the same as message_str, except you get messages from files in "text\<language>\game\" directory
|
- works exactly the same as message_str, except you get messages from files in "text\<language>\game\" directory
|
||||||
- use GAME_MSG_* defines or mstr_* macros from sfall.h to use specific msg file
|
- use GAME_MSG_* defines or mstr_* macros from sfall.h to use specific msg file
|
||||||
- Additional game msg files added by ExtraGameMsgFileList setting will have consecutive fileIds assigned beginning from 0x2000. (e.g. if you set ExtraGameMsgFileList=foo,bar in ddraw.ini, foo.msg will be associated with 0x2000 and bar.msg with 0x2001.)
|
- Additional game msg files added by ExtraGameMsgFileList setting will have consecutive fileIds assigned beginning from 0x2000 to 0x2FFF. (e.g. if you set ExtraGameMsgFileList=foo,bar in ddraw.ini, foo.msg will be associated with 0x2000 and bar.msg with 0x2001.)
|
||||||
- if a file has a specific number assigned in ExtraGameMsgFileList, its fileId will be (0x2000 + assigned number). (e.g. with ExtraGameMsgFileList=foo,bar:2,foobar in ddraw.ini, bar.msg will be associated with 0x2002 and foobar.msg with 0x2003.)
|
- if a file has a specific number assigned in ExtraGameMsgFileList, its fileId will be (0x2000 + assigned number). (e.g. with ExtraGameMsgFileList=foo,bar:2,foobar in ddraw.ini, bar.msg will be associated with 0x2002 and foobar.msg with 0x2003.)
|
||||||
|
|
||||||
> int sneak_success
|
> int sneak_success
|
||||||
@@ -374,8 +374,11 @@ Some utility/math functions are available:
|
|||||||
> array sfall_func0("get_metarule_table")
|
> array sfall_func0("get_metarule_table")
|
||||||
- returns names of all currently available scripting functions (via sfall_funcX)
|
- returns names of all currently available scripting functions (via sfall_funcX)
|
||||||
|
|
||||||
|
> bool sfall_func1("metarule_exist", string metaruleName)
|
||||||
|
- returns True if the specified name of metarule (sfall_funcX) function exists in the current version of sfall
|
||||||
|
|
||||||
> int sfall_func1("spatial_radius", object object)
|
> int sfall_func1("spatial_radius", object object)
|
||||||
- return radius of spatial script, associated with given dummy-object (returned by create_spatial)
|
- returns radius of spatial script, associated with given dummy-object (returned by create_spatial)
|
||||||
|
|
||||||
> object sfall_func2("critter_inven_obj2", object invenObj, int type)
|
> object sfall_func2("critter_inven_obj2", object invenObj, int type)
|
||||||
- works just like vanilla critter_inven_obj, but correctly reports item in player's inactive hand slot
|
- works just like vanilla critter_inven_obj, but correctly reports item in player's inactive hand slot
|
||||||
@@ -606,6 +609,11 @@ optional arguments:
|
|||||||
> int sfall_func2("has_fake_trait_npc", object npc, string nameTrait)
|
> int sfall_func2("has_fake_trait_npc", object npc, string nameTrait)
|
||||||
- these functions are similar to has_fake_*/set_fake_*/set_selectable_perk functions, but apply to the specified party member NPC (including dude_obj)
|
- these functions are similar to has_fake_*/set_fake_*/set_selectable_perk functions, but apply to the specified party member NPC (including dude_obj)
|
||||||
|
|
||||||
|
> void sfall_func2("add_extra_msg_file", string fileName, int fileNumber)
|
||||||
|
- loads the custom message file and assigns it with the specified ID number
|
||||||
|
- fileName: the name of the custom message file (including the .msg extension) in "text\<language>\game\" directory
|
||||||
|
- fileNumber: the file ID number for the message_str_game function to get messages from the file. The available range is from 0x3000 to 0x3FFF
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
------ MORE INFO -------
|
------ MORE INFO -------
|
||||||
------------------------
|
------------------------
|
||||||
|
|||||||
+34
-12
@@ -54,7 +54,7 @@ const fo::MessageList* gameMsgFiles[] = {
|
|||||||
#undef CASTMSG
|
#undef CASTMSG
|
||||||
|
|
||||||
ExtraGameMessageListsMap gExtraGameMsgLists;
|
ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||||
std::vector<std::string> msgFileList;
|
static std::vector<std::string> msgFileList;
|
||||||
|
|
||||||
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef) {
|
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef) {
|
||||||
if (msgList != nullptr && msgList->numMsgs > 0) {
|
if (msgList != nullptr && msgList->numMsgs > 0) {
|
||||||
@@ -89,11 +89,11 @@ char* GetMsg(fo::MessageList *msgList, int msgRef, int msgNum) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadExtraGameMsgFiles() {
|
static void ReadExtraGameMsgFiles() {
|
||||||
if (msgFileList.size() > 0) {
|
if (!msgFileList.empty()) {
|
||||||
int number = 0;
|
int number = 0;
|
||||||
for (auto& msgName : msgFileList) {
|
for (auto& msgName : msgFileList) {
|
||||||
std::string path = "game\\";
|
std::string path("game\\");
|
||||||
auto n = msgName.find(':');
|
auto n = msgName.find(':');
|
||||||
if (n == std::string::npos) {
|
if (n == std::string::npos) {
|
||||||
path += msgName;
|
path += msgName;
|
||||||
@@ -108,25 +108,47 @@ void ReadExtraGameMsgFiles() {
|
|||||||
} else {
|
} else {
|
||||||
delete list;
|
delete list;
|
||||||
}
|
}
|
||||||
number++;
|
if (++number == 4096) break;
|
||||||
|
}
|
||||||
|
msgFileList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long Message::AddExtraMsgFile(const char* msgName, long msgNumber) {
|
||||||
|
if (msgNumber < 0x3000 || msgNumber > 0x3FFF || gExtraGameMsgLists.count(msgNumber)) return -1;
|
||||||
|
std::string path("game\\");
|
||||||
|
path += msgName;
|
||||||
|
fo::MessageList* list = new fo::MessageList();
|
||||||
|
if (fo::func::message_load(list, path.c_str())) {
|
||||||
|
gExtraGameMsgLists.emplace(msgNumber, list);
|
||||||
|
} else {
|
||||||
|
delete list;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearScriptAddedExtraGameMsg() { // C++11
|
||||||
|
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end();) {
|
||||||
|
if (it->first >= 0x3000 && it->first <= 0x3FFF) {
|
||||||
|
fo::func::message_exit(it->second.get());
|
||||||
|
it = gExtraGameMsgLists.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearReadExtraGameMsgFiles() {
|
static void ClearReadExtraGameMsgFiles() {
|
||||||
ExtraGameMessageListsMap::iterator it;
|
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
|
||||||
|
|
||||||
for (it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
|
|
||||||
fo::func::message_exit(it->second.get());
|
fo::func::message_exit(it->second.get());
|
||||||
}
|
}
|
||||||
|
//gExtraGameMsgLists.clear();
|
||||||
gExtraGameMsgLists.clear();
|
|
||||||
msgFileList.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Message::init() {
|
void Message::init() {
|
||||||
msgFileList = GetConfigList("Misc", "ExtraGameMsgFileList", "", 512);
|
msgFileList = GetConfigList("Misc", "ExtraGameMsgFileList", "", 512);
|
||||||
LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles;
|
LoadGameHook::OnBeforeGameStart() += ReadExtraGameMsgFiles;
|
||||||
|
LoadGameHook::OnGameReset() += ClearScriptAddedExtraGameMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Message::exit() {
|
void Message::exit() {
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public:
|
|||||||
const char* name() { return "Message"; }
|
const char* name() { return "Message"; }
|
||||||
void init();
|
void init();
|
||||||
void exit() override;
|
void exit() override;
|
||||||
|
|
||||||
|
static long AddExtraMsgFile(const char* msgName, long msgNumber);
|
||||||
};
|
};
|
||||||
|
|
||||||
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef);
|
fo::MessageNode *GetMsgNode(fo::MessageList *msgList, int msgRef);
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ static MetaruleTableType metaruleTable;
|
|||||||
- arg1, arg2, ... - argument types for automatic validation
|
- arg1, arg2, ... - argument types for automatic validation
|
||||||
*/
|
*/
|
||||||
static const SfallMetarule metarules[] = {
|
static const SfallMetarule metarules[] = {
|
||||||
|
{"add_extra_msg_file", sf_add_extra_msg_file, 2, 2, {ARG_STRING, ARG_INT}},
|
||||||
{"add_iface_tag", sf_add_iface_tag, 0, 0},
|
{"add_iface_tag", sf_add_iface_tag, 0, 0},
|
||||||
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
||||||
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
||||||
@@ -95,6 +96,7 @@ static const SfallMetarule metarules[] = {
|
|||||||
{"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}},
|
{"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}},
|
||||||
{"lock_is_jammed", sf_lock_is_jammed, 1, 1, {ARG_OBJECT}},
|
{"lock_is_jammed", sf_lock_is_jammed, 1, 1, {ARG_OBJECT}},
|
||||||
{"loot_obj", sf_get_loot_object, 0, 0},
|
{"loot_obj", sf_get_loot_object, 0, 0},
|
||||||
|
{"metarule_exist", sf_metarule_exist, 1, 1},
|
||||||
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1, {ARG_ANY}},
|
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1, {ARG_ANY}},
|
||||||
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2, {ARG_INT, ARG_INT}},
|
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2, {ARG_INT, ARG_INT}},
|
||||||
{"outlined_object", sf_outlined_object, 0, 0},
|
{"outlined_object", sf_outlined_object, 0, 0},
|
||||||
@@ -136,6 +138,20 @@ static void sf_get_metarule_table(OpcodeContext& ctx) {
|
|||||||
ctx.setReturn(arrId, DataType::INT);
|
ctx.setReturn(arrId, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sf_metarule_exist(OpcodeContext& ctx) {
|
||||||
|
bool result = false;
|
||||||
|
auto funcXName = ctx.arg(0).asString();
|
||||||
|
if (funcXName[0] != '\0') {
|
||||||
|
for (auto it = metaruleTable.begin(); it != metaruleTable.end(); it++) {
|
||||||
|
if (it->first == funcXName) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.setReturn(result);
|
||||||
|
}
|
||||||
|
|
||||||
void InitMetaruleTable() {
|
void InitMetaruleTable() {
|
||||||
for (auto metarule = std::begin(metarules); metarule != std::end(metarules); ++metarule) {
|
for (auto metarule = std::begin(metarules); metarule != std::end(metarules); ++metarule) {
|
||||||
metaruleTable[metarule->name] = metarule;
|
metaruleTable[metarule->name] = metarule;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ void sf_test(OpcodeContext&);
|
|||||||
// returns current contents of metarule table
|
// returns current contents of metarule table
|
||||||
void sf_get_metarule_table(OpcodeContext&);
|
void sf_get_metarule_table(OpcodeContext&);
|
||||||
|
|
||||||
|
void sf_metarule_exist(OpcodeContext&);
|
||||||
|
|
||||||
void InitMetaruleTable();
|
void InitMetaruleTable();
|
||||||
|
|
||||||
void HandleMetarule(OpcodeContext& ctx);
|
void HandleMetarule(OpcodeContext& ctx);
|
||||||
|
|||||||
@@ -287,18 +287,22 @@ void sf_message_str_game(OpcodeContext& ctx) {
|
|||||||
msg = fo::GetMessageStr(&fo::var::proto_msg_files[fileId - 0x1000], msgId);
|
msg = fo::GetMessageStr(&fo::var::proto_msg_files[fileId - 0x1000], msgId);
|
||||||
} else if (fileId >= 0x2000) { // Extra game message files.
|
} else if (fileId >= 0x2000) { // Extra game message files.
|
||||||
ExtraGameMessageListsMap::iterator it = gExtraGameMsgLists.find(fileId);
|
ExtraGameMessageListsMap::iterator it = gExtraGameMsgLists.find(fileId);
|
||||||
|
|
||||||
if (it != gExtraGameMsgLists.end()) {
|
if (it != gExtraGameMsgLists.end()) {
|
||||||
msg = GetMsg(it->second.get(), msgId, 2);
|
msg = GetMsg(it->second.get(), msgId, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg == nullptr) {
|
if (msg == nullptr) {
|
||||||
msg = "Error";
|
msg = "Error";
|
||||||
}
|
}
|
||||||
ctx.setReturn(msg);
|
ctx.setReturn(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sf_add_extra_msg_file(OpcodeContext& ctx) {
|
||||||
|
long result = Message::AddExtraMsgFile(ctx.arg(0).strValue(), ctx.arg(1).rawValue());
|
||||||
|
if (result == -1) ctx.printOpcodeError("%s() - cannot add message file with the specified number.", ctx.getMetaruleName());
|
||||||
|
ctx.setReturn(result);
|
||||||
|
}
|
||||||
|
|
||||||
void sf_floor2(OpcodeContext& ctx) {
|
void sf_floor2(OpcodeContext& ctx) {
|
||||||
ctx.setReturn(static_cast<int>(floor(ctx.arg(0).asFloat())));
|
ctx.setReturn(static_cast<int>(floor(ctx.arg(0).asFloat())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ void sf_round(OpcodeContext&);
|
|||||||
|
|
||||||
void sf_message_str_game(OpcodeContext&);
|
void sf_message_str_game(OpcodeContext&);
|
||||||
|
|
||||||
|
void sf_add_extra_msg_file(OpcodeContext&);
|
||||||
|
|
||||||
void sf_floor2(OpcodeContext&);
|
void sf_floor2(OpcodeContext&);
|
||||||
|
|
||||||
void sf_get_string_pointer(OpcodeContext&);
|
void sf_get_string_pointer(OpcodeContext&);
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ void WorldMapInterfacePatch() {
|
|||||||
SafeWrite32(0x4C2C92, 181); // index of DNARWOFF.FRM
|
SafeWrite32(0x4C2C92, 181); // index of DNARWOFF.FRM
|
||||||
SafeWrite8(0x4C2D04, 0x46); // dec esi > inc esi
|
SafeWrite8(0x4C2D04, 0x46); // dec esi > inc esi
|
||||||
|
|
||||||
// Fix the position of the target marker for location circles
|
// Fix the position of the target marker for small/medium location circles
|
||||||
MakeCall(0x4C03AA, wmWorldMap_hack, 2);
|
MakeCall(0x4C03AA, wmWorldMap_hack, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user