From 3c5dc6853a5172c24699a76188007cbd68d300ef Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sat, 16 Nov 2019 22:54:09 +0800 Subject: [PATCH] Added "get_sfall_arg_at" script function Improved the functionality of "inventory_redraw" function. --- artifacts/scripting/headers/define_extra.h | 8 +++- artifacts/scripting/headers/sfall.h | 1 + artifacts/scripting/hookscripts.txt | 5 ++- artifacts/scripting/sfall function notes.txt | 6 ++- sfall/FalloutEngine.cpp | 41 +++++++++++++++++++- sfall/FalloutEngine.h | 12 +++++- sfall/FalloutStructs.h | 21 ++++++++++ sfall/HeroAppearance.cpp | 38 ------------------ sfall/HookScripts.cpp | 4 ++ sfall/HookScripts.h | 1 + sfall/ScriptExtender.cpp | 13 +++++++ sfall/ScriptOps/InterfaceOp.hpp | 14 +++---- sfall/ScriptOps/MetaruleOp.hpp | 3 +- 13 files changed, 113 insertions(+), 54 deletions(-) diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 895e02d1..1c752d76 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -87,7 +87,6 @@ #define FLAG_SEEN (0x40000000) #define FLAG_SHOOTTHRU (0x80000000) - /* Critter Flags */ #define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) #define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from) @@ -101,6 +100,13 @@ #define CFLG_RANGED 8192 // 0x00002000 - Range (melee attack is possible at a distance) #define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked down) +/* Window Flags */ +#define WIN_FLAG_MOVEONTOP (0x4) +#define WIN_FLAG_HIDDEN (0x8) +#define WIN_FLAG_EXCLUSIVE (0x10) +#define WIN_FLAG_TRANSPARENT (0x20) + + //remove inven obj defines #define RMOBJ_CONSUME_DRUG 4666772 #define RMOBJ_CONTAINER 4683293 // same as RMOBJ_TRADE diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 5e35ea4c..05014025 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -244,6 +244,7 @@ #define get_metarule_table sfall_func0("get_metarule_table") #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 intface_hide sfall_func0("intface_hide") #define intface_is_hidden sfall_func0("intface_is_hidden") #define intface_redraw sfall_func0("intface_redraw") diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 28f4aa34..008b0876 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -30,6 +30,7 @@ The hook script equivalent of game_loaded; it returns 2 when the script is first > mixed get_sfall_arg() Gets the next argument from sfall. Each time it's called it returns the next argument, or otherwise it returns 0 if there are no more arguments left. +You can arbitrarily get the value of any argument using the sfall_func1("get_sfall_arg_at", argNum) function. > array get_sfall_args() Returns all hook arguments as a new temp array. @@ -37,8 +38,8 @@ Returns all hook arguments as a new temp array. > void set_sfall_return(int value) Used to return the new values from the script. Each time it's called it sets the next value, or if you've already set all return values it does nothing. -> void set_sfall_arg(int argnum, int value) -Changes argument value. The argument number (argnum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see below). +> void set_sfall_arg(int argNum, int value) +Changes argument value. The argument number (argNum) is 0-indexed. This is useful if you have several hook scripts attached to one hook point (see below). > void register_hook(int hooktype) Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, "start" proc will be executed in a current global script. You can use all above functions like normal. diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 39fa77b6..b44b549d 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -475,9 +475,10 @@ Some utility/math functions are available: - adds one custom box to the current boxes, and returns the number of the added tag (-1 if the tags limit is exceeded) - The maximum number of boxes is limited to 126 tags +> 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) +- 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) > int sfall_func1("get_current_inven_size", object) - returns the current inventory size of the container or the critter @@ -542,6 +543,9 @@ Some utility/math functions are available: > void sfall_func1("remove_timer_event", int param) - removes all timer events with the specified 'param' 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) + ------------------------ ------ MORE INFO ------- ------------------------ diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index d62005b9..414f0987 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -192,10 +192,11 @@ 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_Tag_ = reinterpret_cast(_Tag_); DWORD* ptr_tag_skill = reinterpret_cast(_tag_skill); DWORD* ptr_target_curr_stack = reinterpret_cast(_target_curr_stack); -DWORD* ptr_target_pud = reinterpret_cast(_target_pud); +DWORD** ptr_target_pud = reinterpret_cast(_target_pud); DWORD* ptr_target_stack = reinterpret_cast(_target_stack); DWORD* ptr_target_stack_offset = reinterpret_cast(_target_stack_offset); DWORD* ptr_target_str = reinterpret_cast(_target_str); @@ -214,7 +215,7 @@ DWORD* ptr_title_font = reinterpret_cast(_title_font); DWORD* ptr_trait_data = reinterpret_cast(_trait_data); DWORD* ptr_view_page = reinterpret_cast(_view_page); DWORD* ptr_wd_obj = reinterpret_cast(_wd_obj); -DWORD* ptr_window = reinterpret_cast(_window); // total 50 +DWORD* ptr_window = reinterpret_cast(_window); // total 50 WINinfo* BYTE* ptr_WhiteColor = reinterpret_cast(_WhiteColor); DWORD* ptr_wmAreaInfoList = reinterpret_cast(_wmAreaInfoList); DWORD* ptr_wmLastRndTime = reinterpret_cast(_wmLastRndTime); @@ -691,6 +692,8 @@ const DWORD win_register_button_ = 0x4D8260; const DWORD win_register_button_disable_ = 0x4D8674; const DWORD win_register_button_sound_func_ = 0x4D87F8; const DWORD win_show_ = 0x4D6DAC; +const DWORD windowHide_ = 0x4B7610; +const DWORD windowShow_ = 0x4B7648; const DWORD wmFindCurSubTileFromPos_ = 0x4C0C00; const DWORD wmInterfaceScrollTabsStart_ = 0x4C219C; const DWORD wmMapIsSaveable_ = 0x4BFA64; @@ -1058,6 +1061,32 @@ long __fastcall WordWrap(const char* text, int maxWidth, DWORD* buf, BYTE* count } } +DWORD __stdcall AddWin(long x, long y, long width, long height, long bgColorIndex, long flags) { + __asm { + push flags; + push bgColorIndex; + mov ecx, height; + mov ebx, width; + mov edx, y; + mov eax, x; + call win_add_; + } +} + +void __stdcall ShowWin(DWORD winRef) { + __asm { + mov eax, winRef; + call win_show_; + } +} + +void __stdcall HideWin(DWORD winRef) { + __asm { + mov eax, winRef; + call win_hide_; + } +} + void __stdcall RedrawWin(DWORD winRef) { __asm { mov eax, winRef; @@ -1065,6 +1094,14 @@ void __stdcall RedrawWin(DWORD winRef) { } } +void __stdcall DestroyWin(DWORD winRef) { + __asm { + mov eax, winRef; + call win_delete_; + } +} + + void __fastcall DisplayInventory(long inventoryOffset, long visibleOffset, long mode) { __asm { mov ebx, mode; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index bb54d3a8..ec8b65b0 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -224,6 +224,7 @@ #define _stack_offset 0x59E844 #define _stat_data 0x51D53C #define _stat_flag 0x66452A +#define _sWindows 0x6727B0 #define _Tag_ 0x5708B0 #define _tag_skill 0x668070 #define _target_curr_stack 0x59E948 @@ -444,10 +445,11 @@ 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_Tag_; extern DWORD* ptr_tag_skill; extern DWORD* ptr_target_curr_stack; -extern DWORD* ptr_target_pud; +extern DWORD** ptr_target_pud; extern DWORD* ptr_target_stack; extern DWORD* ptr_target_stack_offset; extern DWORD* ptr_target_str; @@ -466,7 +468,7 @@ extern DWORD* ptr_title_font; extern DWORD* ptr_trait_data; extern DWORD* ptr_view_page; extern DWORD* ptr_wd_obj; -extern DWORD* ptr_window; // total 50 +extern DWORD* ptr_window; // total 50 WINinfo* extern BYTE* ptr_WhiteColor; extern DWORD* ptr_wmAreaInfoList; extern DWORD* ptr_wmLastRndTime; @@ -933,6 +935,8 @@ extern const DWORD win_register_button_; extern const DWORD win_register_button_disable_; extern const DWORD win_register_button_sound_func_; extern const DWORD win_show_; +extern const DWORD windowHide_; +extern const DWORD windowShow_; extern const DWORD wmFindCurSubTileFromPos_; extern const DWORD wmInterfaceScrollTabsStart_; extern const DWORD wmMapIsSaveable_; @@ -1087,7 +1091,11 @@ long __fastcall GetGameConfigString(const char* outValue, const char* section, c long __fastcall WordWrap(const char* text, int maxWidth, DWORD* buf, BYTE* count); +DWORD __stdcall AddWin(long x, long y, long width, long height, long bgColorIndex, long flags); +void __stdcall ShowWin(DWORD winRef); +void __stdcall HideWin(DWORD winRef); void __stdcall RedrawWin(DWORD winRef); +void __stdcall DestroyWin(DWORD winRef); void __fastcall DisplayInventory(long inventoryOffset, long visibleOffset, long mode); diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index ff8ffd0c..1a81cc3f 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -256,6 +256,27 @@ struct WINinfo { }; #pragma pack(pop) +#pragma pack(push, 1) +struct sWindow { + char name[32]; + long wID; + long width; + long height; + long unknown1; + long unknown2; + long unknown3; + long unknown4; + long *buttons; + long numButtons; + long unknown5; + long unknown6; + long clearColour; + long flags; + long unknown7; + long unknown8; +}; +#pragma pack(pop) + #pragma pack(push, 1) struct Queue { DWORD time; diff --git a/sfall/HeroAppearance.cpp b/sfall/HeroAppearance.cpp index 58e96fc5..8bb58e37 100644 --- a/sfall/HeroAppearance.cpp +++ b/sfall/HeroAppearance.cpp @@ -473,28 +473,6 @@ UNLSTDfrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef) { /////////////////////////////////////////////////////////////////WINDOW FUNCTIONS//////////////////////////////////////////////////////////////////// -int AddWin(DWORD x, DWORD y, DWORD width, DWORD height, DWORD BGColourIndex, DWORD flags) { - int WinRef; - __asm { - push flags; - push BGColourIndex; - mov ecx, height; - mov ebx, width; - mov edx, y; - mov eax, x; - call win_add_; - mov WinRef, eax; - } - return WinRef; -} - -void DestroyWin(int WinRef) { - __asm { - mov eax, WinRef; - call win_delete_; - } -} - WINinfo* GetWinStruct(int WinRef) { WINinfo *winStruct; __asm { @@ -515,22 +493,6 @@ BYTE* GetWinSurface(int WinRef) { return surface; } -void ShowWin(int WinRef) { - __asm { - mov eax, WinRef; - call win_show_; - } -} - -/* -void HideWin(int WinRef) { - __asm { - mov eax, WinRef; - call win_hide_; - } -} -*/ - /////////////////////////////////////////////////////////////////BUTTON FUNCTIONS//////////////////////////////////////////////////////////////////// int check_buttons() { diff --git a/sfall/HookScripts.cpp b/sfall/HookScripts.cpp index cf128f2f..d1065d9c 100644 --- a/sfall/HookScripts.cpp +++ b/sfall/HookScripts.cpp @@ -1511,6 +1511,10 @@ DWORD* _stdcall GetHSArgs() { return args; } +DWORD _stdcall GetHSArgAt(DWORD id) { + return args[id]; +} + void _stdcall SetHSReturn(DWORD value) { if (cRetTmp < maxRets) { rets[cRetTmp++] = value; diff --git a/sfall/HookScripts.h b/sfall/HookScripts.h index 067e2836..9b04b7f9 100644 --- a/sfall/HookScripts.h +++ b/sfall/HookScripts.h @@ -52,6 +52,7 @@ enum HookType DWORD _stdcall GetHSArgCount(); DWORD _stdcall GetHSArg(); DWORD* _stdcall GetHSArgs(); +DWORD _stdcall GetHSArgAt(DWORD id); void _stdcall SetHSArg(DWORD id, DWORD value); void _stdcall SetHSReturn(DWORD d); diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 337231e6..55f2b887 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -38,6 +38,7 @@ static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId); static long _stdcall HandleTimedEventScripts(); static void RunGlobalScripts1(); +static void sf_get_sfall_arg_at(); static void sf_add_g_timer_event(); static void sf_remove_timer_event(); @@ -401,6 +402,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = { {sf_get_flags, "get_flags", {DATATYPE_MASK_VALID_OBJ}}, {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_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}}, @@ -699,6 +701,17 @@ static void __declspec(naked) GetSfallArg() { } } +static void sf_get_sfall_arg_at() { + long argVal = 0; + long id = opHandler.arg(0).rawValue(); + if (id >= static_cast(GetHSArgCount()) || id < 0) { + opHandler.printOpcodeError("get_sfall_arg_at() - invalid value for argument."); + } else { + argVal = GetHSArgAt(id); + } + opHandler.setReturn(argVal); +} + static DWORD _stdcall GetSfallArgs2() { DWORD argCount = GetHSArgCount(); DWORD id = TempArray(argCount, 0); diff --git a/sfall/ScriptOps/InterfaceOp.hpp b/sfall/ScriptOps/InterfaceOp.hpp index 7ceb1bbd..70c9e9b9 100644 --- a/sfall/ScriptOps/InterfaceOp.hpp +++ b/sfall/ScriptOps/InterfaceOp.hpp @@ -400,14 +400,14 @@ static void sf_inventory_redraw() { default: return; } - if (!opHandler.arg(0).asBool()) { - int* stack_offset = (int*)_stack_offset; - stack_offset[*ptr_curr_stack * 4] = 0; + long redrawSide = (opHandler.numArgs() > 0) ? opHandler.arg(0).rawValue() : -1; // -1 - both + if (redrawSide <= 0) { + ptr_stack_offset[*ptr_curr_stack] = 0; DisplayInventory(0, -1, mode); - } else if (mode >= 2) { - int* target_stack_offset = (int*)_target_stack_offset; - target_stack_offset[*ptr_target_curr_stack * 4] = 0; - DisplayTargetInventory(0, -1, (DWORD*)*ptr_target_pud, mode); + } + if (redrawSide && mode >= 2) { + ptr_target_stack_offset[*ptr_target_curr_stack] = 0; + DisplayTargetInventory(0, -1, *ptr_target_pud, mode); RedrawWin(*ptr_i_wid); } } diff --git a/sfall/ScriptOps/MetaruleOp.hpp b/sfall/ScriptOps/MetaruleOp.hpp index 36f53881..858e21f3 100644 --- a/sfall/ScriptOps/MetaruleOp.hpp +++ b/sfall/ScriptOps/MetaruleOp.hpp @@ -137,11 +137,12 @@ static const SfallMetarule metaruleArray[] = { {"get_metarule_table", sf_get_metarule_table, 0, 0}, {"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}, {"intface_hide", sf_intface_hide, 0, 0}, {"intface_is_hidden", sf_intface_is_hidden, 0, 0}, {"intface_redraw", sf_intface_redraw, 0, 0}, {"intface_show", sf_intface_show, 0, 0}, - {"inventory_redraw", sf_inventory_redraw, 1, 1}, + {"inventory_redraw", sf_inventory_redraw, 0, 1}, {"item_weight", sf_item_weight, 1, 1}, {"lock_is_jammed", sf_lock_is_jammed, 1, 1}, {"loot_obj", sf_get_loot_object, 0, 0},