From 04ebbaa1823b9d5da5b41fcf6ff3f0a4a29b5a35 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 17 Nov 2019 08:40:18 +0800 Subject: [PATCH] Added three new script window functions: "show_window", "hide_window", "set_window_flag" Updated documents. --- artifacts/scripting/headers/sfall.h | 13 ++-- artifacts/scripting/hookscripts.txt | 8 +- artifacts/scripting/sfall function notes.txt | 38 +++++++--- sfall/FalloutEngine.cpp | 3 +- sfall/FalloutEngine.h | 2 +- sfall/HeroAppearance.cpp | 23 ++---- sfall/HeroAppearance.h | 6 +- sfall/ScriptExtender.cpp | 3 + sfall/ScriptOps/InterfaceOp.hpp | 79 +++++++++++++++++++- sfall/ScriptOps/MetaruleOp.hpp | 3 + 10 files changed, 134 insertions(+), 44 deletions(-) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 05014025..3b38e21c 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -224,9 +224,9 @@ #define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks // sfall_funcX macros -#define add_global_timer_event(time, param) sfall_func2("add_g_timer_event", time, param) +#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_trait(traitId) sfall_func1("add_trait", traitId) +#define add_trait(traitID) sfall_func1("add_trait", traitID) #define art_cache_clear sfall_func0("art_cache_clear") #define attack_is_aimed sfall_func0("attack_is_aimed") #define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h) @@ -245,6 +245,7 @@ #define get_object_data(obj, offset) sfall_func2("get_object_data", obj, offset) #define get_outline(obj) sfall_func1("get_outline", obj) #define get_sfall_arg_at(argNum) sfall_func1("get_sfall_arg_at", argNum) +#define hide_window(winName) sfall_func1("hide_window", winName) #define intface_hide sfall_func0("intface_hide") #define intface_is_hidden sfall_func0("intface_is_hidden") #define intface_redraw sfall_func0("intface_redraw") @@ -253,13 +254,13 @@ #define item_weight(obj) sfall_func1("item_weight", obj) #define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj) #define loot_obj sfall_func0("loot_obj") -#define metarule_exist(metarule) sfall_func1("metarule_exist", metarule) +#define metarule_exist(metaruleName) sfall_func1("metarule_exist", metaruleName) #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(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude) #define outlined_object sfall_func0("outlined_object") #define real_dude_obj sfall_func0("real_dude_obj") #define remove_all_timer_events sfall_func0("remove_timer_event") -#define remove_timer_event(param) sfall_func1("remove_timer_event", param) +#define remove_timer_event(fixedParam) sfall_func1("remove_timer_event", fixedParam) #define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode) #define set_flags(obj, flags) sfall_func2("set_flags", obj, flags) #define set_iface_tag_text(tag, text, color) sfall_func3("set_iface_tag_text", tag, text, color) @@ -270,6 +271,8 @@ #define set_unique_id(obj) sfall_func1("set_unique_id", obj) #define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1) #define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time) +#define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value) +#define show_window(winName) sfall_func1("show_window", winName) #define spatial_radius(obj) sfall_func1("spatial_radius", obj) #define tile_refresh_display sfall_func0("tile_refresh_display") #define unjam_lock(obj) sfall_func1("unjam_lock", obj) diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 008b0876..bae07e29 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -286,10 +286,10 @@ int ret1 - the new AP cost ------------------------------------------- (DEPRECATED) -hs_hexmoveblocking.int -hs_hexaiblocking.int -hs_hexshootblocking.int -hs_hexsightblocking.int +HOOK_HEXMOVEBLOCKING (hs_hexmoveblocking.int) +HOOK_HEXAIBLOCKING (hs_hexaiblocking.int) +HOOK_HEXSHOOTBLOCKING (hs_hexshootblocking.int) +HOOK_HEXSIGHTBLOCKING (hs_hexsightblocking.int) Runs when checking to see if a hex blocks movement or shooting. (or ai-ing, presumably...) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index b44b549d..3a63b664 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -478,7 +478,7 @@ Some utility/math functions are available: > void sfall_func0("inventory_redraw") > void sfall_func1("inventory_redraw", int invSide) - redraws inventory list in the inventory/use inventory item on/loot/barter screens -- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens), -1 - both sides (same as no argument) +- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens), -1 - both sides (same as without argument) > int sfall_func1("get_current_inven_size", object) - returns the current inventory size of the container or the critter @@ -491,10 +491,11 @@ Some utility/math functions are available: > object sfall_func0("dialog_obj") - returns a pointer to the object (critter) the player is having a conversation or bartering with -> object sfall_func2("obj_under_cursor", bool crSwitch, bool inclDude) +> object sfall_func2("obj_under_cursor", bool onlyCritter, bool includeDude) - returns the object under the cursor on the main game screen -- crSwitch: True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.), False - checks all objects (can't check critters under objects) -- passing False to the inclDude argument will ignore dude_obj +- onlyCritter: True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.) + False - checks all objects (can't check critters under objects) +- passing False to the includeDude argument will ignore dude_obj > object sfall_func0("loot_obj") - returns a pointer to the target object (container or critter) of the loot screen @@ -526,25 +527,42 @@ Some utility/math functions are available: - can take off player's equipped item when the inventory is opened, or the player is in the barter screen - slot: 0 - armor slot, 1 - right slot, 2 - left slot (see INVEN_TYPE_* in define.h) -> void sfall_func1("add_trait", int traitId) +> void sfall_func1("add_trait", int traitID) - adds the specified trait to the player > int sfall_func0("get_inven_ap_cost") - returns the current AP cost to access the inventory in combat -> void sfall_func2("add_g_timer_event", int time, int param) +> void sfall_func2("add_g_timer_event", int time, int fixedParam) - adds a timer event that calls the timed_event_p_proc procedure in the current global script - time: the number of ticks after which the event timer is triggered -- param: the value that is passed to the timed_event_p_proc procedure for the fixed_param function +- fixedParam: the value that is passed to the timed_event_p_proc procedure for the fixed_param function > void sfall_func0("remove_timer_event") - clears all set timer events for the current global script -> void sfall_func1("remove_timer_event", int param) -- removes all timer events with the specified 'param' value for the current global script +> void sfall_func1("remove_timer_event", int fixedParam) +- removes all timer events with the specified 'fixedParam' value for the current global script > mixed sfall_func1("get_sfall_arg_at", int argNum) -- gets the value of hook argument with the specified argument number (argNum, first argument starts from 0) +- gets the value of hook argument with the specified argument number (argNum, first argument of hook starts from 0) + +> void sfall_func0("hide_window") +> void sfall_func1("hide_window", string winName) +- hides the specified or currently active (selected) script window +- winName: the window name, assigned to the window by the CreateWin/create_win function + +> void sfall_func0("show_window") +> void sfall_func1("show_window", string winName) +- displays the specified hidden script window or the one previously hidden with the sfall_func0("hide_window") function +- winName: the window name, assigned to the window by the CreateWin/create_win function + +> void sfall_func3("set_window_flag", string/int winName/winID, int flag, bool value) +- changes the specified flag for the created script or game interface window +- winName: the window name, assigned to the window by the CreateWin/create_win function +- winID: the ID number of the interface or script window obtained with the get_window_under_mouse function, or 0 for the current game interface +- flag: the flag to change (see WIN_FLAG_* constants in define_extra.h) +- value: true - set the flag, false - unset the flag ------------------------ ------ MORE INFO ------- diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 414f0987..3610f1c5 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -192,7 +192,7 @@ DWORD* ptr_stack = reinterpret_cast(_stack); DWORD* ptr_stack_offset = reinterpret_cast(_stack_offset); DWORD* ptr_stat_data = reinterpret_cast(_stat_data); DWORD* ptr_stat_flag = reinterpret_cast(_stat_flag); -DWORD* ptr_sWindows = reinterpret_cast(_sWindows); // total 16 sWindow +DWORD* ptr_sWindows = reinterpret_cast(_sWindows); // total 16 sWindow struct DWORD* ptr_Tag_ = reinterpret_cast(_Tag_); DWORD* ptr_tag_skill = reinterpret_cast(_tag_skill); DWORD* ptr_target_curr_stack = reinterpret_cast(_target_curr_stack); @@ -1101,7 +1101,6 @@ void __stdcall DestroyWin(DWORD winRef) { } } - void __fastcall DisplayInventory(long inventoryOffset, long visibleOffset, long mode) { __asm { mov ebx, mode; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index ec8b65b0..47de154e 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -445,7 +445,7 @@ extern DWORD* ptr_stack; extern DWORD* ptr_stack_offset; extern DWORD* ptr_stat_data; extern DWORD* ptr_stat_flag; -extern DWORD* ptr_sWindows; // total 16 sWindow +extern DWORD* ptr_sWindows; // total 16 sWindow struct extern DWORD* ptr_Tag_; extern DWORD* ptr_tag_skill; extern DWORD* ptr_target_curr_stack; diff --git a/sfall/HeroAppearance.cpp b/sfall/HeroAppearance.cpp index 8bb58e37..1a476992 100644 --- a/sfall/HeroAppearance.cpp +++ b/sfall/HeroAppearance.cpp @@ -473,35 +473,24 @@ UNLSTDfrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef) { /////////////////////////////////////////////////////////////////WINDOW FUNCTIONS//////////////////////////////////////////////////////////////////// -WINinfo* GetWinStruct(int WinRef) { - WINinfo *winStruct; +WINinfo* __stdcall GetWinStruct(long winRef) { __asm { - mov eax, WinRef; + mov eax, winRef; call GNW_find_; - mov winStruct, eax; } - return winStruct; } -BYTE* GetWinSurface(int WinRef) { - BYTE *surface; +BYTE* __stdcall GetWinSurface(DWORD winRef) { __asm { - mov eax, WinRef; + mov eax, winRef; call win_get_buf_; - mov surface, eax; } - return surface; } /////////////////////////////////////////////////////////////////BUTTON FUNCTIONS//////////////////////////////////////////////////////////////////// -int check_buttons() { - int key_code; - __asm { - call get_input_; - mov key_code, eax; - } - return key_code; +long __stdcall check_buttons() { + __asm call get_input_; } /////////////////////////////////////////////////////////////////TEXT FUNCTIONS////////////////////////////////////////////////////////////////////// diff --git a/sfall/HeroAppearance.h b/sfall/HeroAppearance.h index 98d72228..38846e41 100644 --- a/sfall/HeroAppearance.h +++ b/sfall/HeroAppearance.h @@ -18,13 +18,11 @@ #pragma once -#include "FalloutStructs.h" - -WINinfo* GetWinStruct(int WinRef); +WINinfo* __stdcall GetWinStruct(long winRef); void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface); DWORD GetTextWidth(char *TextMsg); DWORD GetMaxCharWidth(); -int check_buttons(void); +long __stdcall check_buttons(); void HeroAppearanceModInit(); void HeroAppearanceModExit(); diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 55f2b887..e7cfbede 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -403,6 +403,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = { {sf_get_object_data, "get_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}}, {sf_get_outline, "get_outline", {DATATYPE_MASK_VALID_OBJ}}, {sf_get_sfall_arg_at, "get_sfall_arg_at", {DATATYPE_MASK_INT}}, + {sf_hide_window, "hide_window", {DATATYPE_MASK_STR}}, {sf_inventory_redraw, "inventory_redraw", {DATATYPE_MASK_INT}}, {sf_item_weight, "item_weight", {DATATYPE_MASK_VALID_OBJ}}, {sf_lock_is_jammed, "lock_is_jammed", {DATATYPE_MASK_VALID_OBJ}}, @@ -417,6 +418,8 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = { {sf_set_outline, "set_outline", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}}, {sf_set_unique_id, "set_unique_id", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}}, {sf_set_unjam_locks_time, "set_unjam_locks_time", {DATATYPE_MASK_INT}}, + {sf_set_window_flag, "set_window_flag", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT}}, + {sf_show_window, "show_window", {DATATYPE_MASK_STR}}, {sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}}, {sf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}}, {sf_unwield_slot, "unwield_slot", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}}, diff --git a/sfall/ScriptOps/InterfaceOp.hpp b/sfall/ScriptOps/InterfaceOp.hpp index 70c9e9b9..0df851bb 100644 --- a/sfall/ScriptOps/InterfaceOp.hpp +++ b/sfall/ScriptOps/InterfaceOp.hpp @@ -19,11 +19,12 @@ #pragma once #include "main.h" + +#include "HeroAppearance.h" #include "input.h" #include "LoadGameHook.h" #include "ScriptExtender.h" - // input_functions static void __declspec(naked) InputFuncsAvailable() { __asm { @@ -429,6 +430,82 @@ static void sf_create_win() { } } +static void sf_show_window() { + if (opHandler.numArgs() > 0) { + const char* name = opHandler.arg(0).strValue(); + sWindow sWin; + for (size_t i = 0; i < 16; i++) { + sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes + if (_stricmp(name, sWin.name) == 0) { + ShowWin(sWin.wID); + return; + } + } + opHandler.printOpcodeError("show_window() - window '%s' is not found.", name); + } else { + __asm call windowShow_; + } +} + +static void sf_hide_window() { + if (opHandler.numArgs() > 0) { + const char* name = opHandler.arg(0).strValue(); + sWindow sWin; + for (size_t i = 0; i < 16; i++) { + sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes + if (_stricmp(name, sWin.name) == 0) { + HideWin(sWin.wID); + return; + } + } + opHandler.printOpcodeError("hide_window() - window '%s' is not found.", name); + } else { + __asm call windowHide_; + } +} + +static void sf_set_window_flag() { + long bitFlag = opHandler.arg(1).rawValue(); + switch (bitFlag) { + case WIN_MoveOnTop: + case WIN_Hidden: + case WIN_Exclusive: + case WIN_Transparent: + break; + default: + return; // unsupported set flag + } + bool mode = opHandler.arg(2).asBool(); + if (opHandler.arg(0).isString()) { + const char* name = opHandler.arg(0).strValue(); + sWindow sWin; + for (size_t i = 0; i < 16; i++) { + sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes + if (_stricmp(name, sWin.name) == 0) { + WINinfo* win = GetWinStruct(sWin.wID); + if (mode) { + sWin.flags |= bitFlag; + win->flags |= bitFlag; + } else { + sWin.flags &= ~bitFlag; + win->flags &= ~bitFlag; + } + return; + } + } + opHandler.printOpcodeError("set_window_flag() - window '%s' is not found.", name); + } else { + long wid = opHandler.arg(0).rawValue(); + WINinfo* win = GetWinStruct((wid > 0) ? wid : *ptr_i_wid); // i_wid - set flag to current game interface window + if (win == nullptr) return; + if (mode) { + win->flags |= bitFlag; + } else { + win->flags &= ~bitFlag; + } + } +} + static void sf_unwield_slot() { long slot = static_cast(opHandler.arg(1).rawValue()); if (slot < INVEN_TYPE_WORN || slot > INVEN_TYPE_LEFT_HAND) { diff --git a/sfall/ScriptOps/MetaruleOp.hpp b/sfall/ScriptOps/MetaruleOp.hpp index 858e21f3..27441fca 100644 --- a/sfall/ScriptOps/MetaruleOp.hpp +++ b/sfall/ScriptOps/MetaruleOp.hpp @@ -138,6 +138,7 @@ static const SfallMetarule metaruleArray[] = { {"get_object_data", sf_get_object_data, 2, 2}, {"get_outline", sf_get_outline, 1, 1}, {"get_sfall_arg_at", sf_get_sfall_arg_at, 1, 1}, + {"hide_window", sf_hide_window, 0, 1}, {"intface_hide", sf_intface_hide, 0, 0}, {"intface_is_hidden", sf_intface_is_hidden, 0, 0}, {"intface_redraw", sf_intface_redraw, 0, 0}, @@ -161,6 +162,8 @@ static const SfallMetarule metaruleArray[] = { {"set_outline", sf_set_outline, 2, 2}, {"set_unique_id", sf_set_unique_id, 1, 2}, {"set_unjam_locks_time", sf_set_unjam_locks_time, 1, 1}, + {"set_window_flag", sf_set_window_flag, 3, 3}, + {"show_window", sf_show_window, 0, 1}, {"spatial_radius", sf_spatial_radius, 1, 1}, {"tile_refresh_display", sf_tile_refresh_display, 0, 0}, {"unjam_lock", sf_unjam_lock, 1, 1},