Added four new script functions:

"get_sfall_arg_at", "show_window", "hide_window", "set_window_flag"

Improved the functionality of "inventory_redraw" function.
This commit is contained in:
NovaRain
2019-11-16 22:36:53 +08:00
parent 996dd293c0
commit 18c10d8911
15 changed files with 179 additions and 26 deletions
+7 -1
View File
@@ -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
+4
View File
@@ -277,9 +277,11 @@
#define get_object_ai_data(obj, aiParam) sfall_func2("get_object_ai_data", obj, aiParam)
#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 get_string_pointer(text) sfall_func1("get_string_pointer", text)
#define has_fake_perk_npc(npc, perk) sfall_func2("has_fake_perk_npc", npc, perk)
#define has_fake_trait_npc(npc, trait) sfall_func2("has_fake_trait_npc", npc, trait)
#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")
@@ -312,6 +314,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)
+3 -2
View File
@@ -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.
+22 -1
View File
@@ -517,9 +517,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
> void sfall_func3("item_make_explosive", int pid, int activePid, int damage)
> void sfall_func4("item_make_explosive", int pid, int activePid, int min, int max)
@@ -647,6 +648,26 @@ optional argument:
> 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)
> void sfall_func0("hide_window")
> void sfall_func1("hide_window", string winName)
- hides the specified or currently selected/active 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
- flag: the flag to change (see WIN_FLAG_* constants in define_extra.h)
- value: true - set the flag, false - unset the flag
------------------------
------ MORE INFO -------
------------------------
+19
View File
@@ -713,6 +713,25 @@ struct Window {
long *drawFunc;
};
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(1)
struct LSData {
char signature[24];
+1
View File
@@ -212,6 +212,7 @@
#define FO_VAR_stack_offset 0x59E844
#define FO_VAR_stat_data 0x51D53C
#define FO_VAR_stat_flag 0x66452A
#define FO_VAR_sWindows 0x6727B0
#define FO_VAR_Tag_ 0x5708B0
#define FO_VAR_tag_skill 0x668070
#define FO_VAR_target_curr_stack 0x59E948
+2 -1
View File
@@ -158,7 +158,7 @@ VAR_(pipmesg, DWORD)
VAR_(preload_list_index, DWORD)
VARA(procTableStrs, const char*, (int)ScriptProc::count) // table of procId (from define.h) => procName map
VARA(proto_msg_files, MessageList, 6) // array of 6 elements
VAR_(proto_main_msg_file, MessageList)
VAR_(proto_main_msg_file, MessageList)
VAR_(ptable, DWORD)
VAR_(pud, DWORD)
VAR_(queue, DWORD)
@@ -181,6 +181,7 @@ VARA(stack, DWORD, 10)
VARA(stack_offset, DWORD, 10)
VARA(stat_data, StatInfo, STAT_real_max_stat) // dynamic array
VAR_(stat_flag, DWORD)
VARA(sWindows, fo::sWindow, 16)
VAR_(Tag_, DWORD)
VAR_(tag_skill, DWORD)
VAR_(target_curr_stack, DWORD)
+9 -5
View File
@@ -133,23 +133,27 @@ void HookScripts::GameModeChangeHook(DWORD exit) {
}
// END HOOKS
DWORD _stdcall GetHSArgCount() {
DWORD HookScripts::GetHSArgCount() {
return argCount;
}
DWORD _stdcall GetHSArg() {
DWORD HookScripts::GetHSArg() {
return (cArg == argCount) ? 0 : args[cArg++];
}
void SetHSArg(DWORD id, DWORD value) {
void HookScripts::SetHSArg(DWORD id, DWORD value) {
if (id < argCount) args[id] = value;
}
DWORD* GetHSArgs() {
DWORD* HookScripts::GetHSArgs() {
return args;
}
void _stdcall SetHSReturn(DWORD value) {
DWORD HookScripts::GetHSArgAt(DWORD id) {
return args[id];
}
void __stdcall HookScripts::SetHSReturn(DWORD value) {
if (cRetTmp < maxRets) {
rets[cRetTmp++] = value;
}
+7 -6
View File
@@ -84,13 +84,14 @@ public:
static void GameModeChangeHook(DWORD exit);
static void KeyPressHook(DWORD* dxKey, bool pressed, DWORD vKey);
};
DWORD _stdcall GetHSArgCount();
DWORD _stdcall GetHSArg();
DWORD* GetHSArgs();
void SetHSArg(DWORD id, DWORD value);
void _stdcall SetHSReturn(DWORD d);
static DWORD GetHSArgCount();
static DWORD GetHSArg();
static DWORD GetHSArgAt(DWORD id);
static DWORD* GetHSArgs();
static void SetHSArg(DWORD id, DWORD value);
static void __stdcall SetHSReturn(DWORD d);
};
// register hook by proc num (special values: -1 - use default (start) procedure, 0 - unregister)
void RegisterHook(fo::Program* script, int id, int procNum, bool specReg);
+1 -1
View File
@@ -80,7 +80,7 @@ static int __fastcall SwitchHandHook_Script(fo::GameObject* item, fo::GameObject
int result = PartyControl::SwitchHandHook(item);
if (result != -1) {
cRetTmp = 0;
SetHSReturn(result);
HookScripts::SetHSReturn(result);
}
result = (cRet > 0) ? rets[0] : -1;
EndHook();
+16 -5
View File
@@ -109,7 +109,7 @@ void __declspec(naked) op_get_sfall_arg() {
__asm {
push ecx;
push eax;
call GetHSArg;
call HookScripts::GetHSArg;
mov edx, eax;
pop eax;
_RET_VAL_INT(ecx);
@@ -118,10 +118,21 @@ void __declspec(naked) op_get_sfall_arg() {
}
}
void sf_get_sfall_arg_at(OpcodeContext& ctx) {
long argVal = 0;
long id = ctx.arg(0).rawValue();
if (id >= static_cast<long>(HookScripts::GetHSArgCount()) || id < 0) {
ctx.printOpcodeError("%s() - invalid value for argument.", ctx.getMetaruleName());
} else {
argVal = HookScripts::GetHSArgAt(id);
}
ctx.setReturn(argVal);
}
void sf_get_sfall_args(OpcodeContext& ctx) {
DWORD argCount = GetHSArgCount();
DWORD argCount = HookScripts::GetHSArgCount();
DWORD id = TempArray(argCount, 0);
DWORD* args = GetHSArgs();
DWORD* args = HookScripts::GetHSArgs();
for (DWORD i = 0; i < argCount; i++) {
arrays[id].val[i].set(*(long*)&args[i]);
}
@@ -129,7 +140,7 @@ void sf_get_sfall_args(OpcodeContext& ctx) {
}
void sf_set_sfall_arg(OpcodeContext& ctx) {
SetHSArg(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
HookScripts::SetHSArg(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
}
void __declspec(naked) op_set_sfall_return() {
@@ -137,7 +148,7 @@ void __declspec(naked) op_set_sfall_return() {
push ecx;
_GET_ARG_INT(end);
push eax;
call SetHSReturn;
call HookScripts::SetHSReturn;
end:
pop ecx;
retn;
+2
View File
@@ -41,6 +41,8 @@ void sf_get_sfall_global_float(OpcodeContext&);
void __declspec() op_get_sfall_arg();
void sf_get_sfall_arg_at(OpcodeContext&);
void sf_get_sfall_args(OpcodeContext&);
void sf_set_sfall_arg(OpcodeContext&);
+74 -2
View File
@@ -318,10 +318,12 @@ void sf_inventory_redraw(OpcodeContext& ctx) {
default:
return;
}
if (!ctx.arg(0).asBool()) {
long redrawSide = (ctx.numArgs() > 0) ? ctx.arg(0).rawValue() : -1; // -1 - both
if (redrawSide <= 0) {
fo::var::stack_offset[fo::var::curr_stack] = 0;
fo::func::display_inventory(0, -1, mode);
} else if (mode >= 2) {
}
if (redrawSide && mode >= 2) {
fo::var::target_stack_offset[fo::var::target_curr_stack] = 0;
fo::func::display_target_inventory(0, -1, fo::var::target_pud, mode);
fo::func::win_draw(fo::var::i_wid);
@@ -350,6 +352,76 @@ void sf_create_win(OpcodeContext& ctx) {
}
}
void sf_show_window(OpcodeContext& ctx) {
if (ctx.numArgs() > 0) {
const char* name = ctx.arg(0).strValue();
for (size_t i = 0; i < 16; i++) {
if (_stricmp(name, fo::var::sWindows[i].name) == 0) {
fo::func::win_show(fo::var::sWindows[i].wID);
return;
}
}
ctx.printOpcodeError("%s() - window '%s' is not found.", ctx.getMetaruleName(), name);
} else {
__asm call fo::funcoffs::windowShow_;
}
}
void sf_hide_window(OpcodeContext& ctx) {
if (ctx.numArgs() > 0) {
const char* name = ctx.arg(0).strValue();
for (size_t i = 0; i < 16; i++) {
if (_stricmp(name, fo::var::sWindows[i].name) == 0) {
fo::func::win_hide(fo::var::sWindows[i].wID);
return;
}
}
ctx.printOpcodeError("%s() - window '%s' is not found.", ctx.getMetaruleName(), name);
} else {
__asm call fo::funcoffs::windowHide_;
}
}
void sf_set_window_flag(OpcodeContext& ctx) {
long bitFlag = ctx.arg(1).rawValue();
switch (bitFlag) {
case fo::WinFlags::MoveOnTop:
case fo::WinFlags::Hidden:
case fo::WinFlags::Exclusive:
case fo::WinFlags::Transparent:
break;
default:
return; // unsupported set flag
}
bool mode = ctx.arg(2).asBool();
if (ctx.arg(0).isString()) {
const char* name = ctx.arg(0).strValue();
for (size_t i = 0; i < 16; i++) {
if (_stricmp(name, fo::var::sWindows[i].name) == 0) {
fo::Window* win =fo::func::GNW_find(fo::var::sWindows[i].wID);
if (mode) {
fo::var::sWindows[i].flags |= bitFlag;
win->flags |= bitFlag;
} else {
fo::var::sWindows[i].flags &= ~bitFlag;
win->flags &= ~bitFlag;
}
return;
}
}
ctx.printOpcodeError("%s() - window '%s' is not found.", ctx.getMetaruleName(), name);
} else {
long wid = ctx.arg(0).rawValue();
fo::Window* win = fo::func::GNW_find((wid > 0) ? wid : fo::var::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 DrawImage(OpcodeContext& ctx, bool isScaled) {
if (*(DWORD*)FO_VAR_currentWindow == -1) {
ctx.printOpcodeError("%s() - no created/selected window for the image.", ctx.getMetaruleName());
@@ -99,6 +99,12 @@ void sf_dialog_message(OpcodeContext&);
void sf_create_win(OpcodeContext&);
void sf_show_window(OpcodeContext&);
void sf_hide_window(OpcodeContext&);
void sf_set_window_flag(OpcodeContext&);
void sf_draw_image(OpcodeContext&);
void sf_draw_image_scaled(OpcodeContext&);
@@ -88,14 +88,16 @@ static const SfallMetarule metarules[] = {
{"get_object_ai_data", sf_get_object_ai_data, 2, 2, {ARG_OBJECT, ARG_INT}},
{"get_object_data", sf_get_object_data, 2, 2, {ARG_OBJECT, ARG_INT}},
{"get_outline", sf_get_outline, 1, 1, {ARG_OBJECT}},
{"get_sfall_arg_at", sf_get_sfall_arg_at, 1, 1, {ARG_INT}},
{"get_string_pointer", sf_get_string_pointer, 1, 1, {ARG_STRING}},
{"has_fake_perk_npc", sf_has_fake_perk_npc, 2, 2, {ARG_OBJECT, ARG_STRING}},
{"has_fake_trait_npc", sf_has_fake_trait_npc, 2, 2, {ARG_OBJECT, ARG_STRING}},
{"hide_window", sf_hide_window, 0, 1, {ARG_STRING}},
{"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, {ARG_INT}},
{"inventory_redraw", sf_inventory_redraw, 0, 1, {ARG_INT}},
{"item_make_explosive", sf_item_make_explosive, 3, 4, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
{"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}},
{"lock_is_jammed", sf_lock_is_jammed, 1, 1, {ARG_OBJECT}},
@@ -124,6 +126,8 @@ static const SfallMetarule metarules[] = {
{"set_selectable_perk_npc", sf_set_selectable_perk_npc, 5, 5, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
{"set_unique_id", sf_set_unique_id, 1, 2, {ARG_OBJECT, ARG_INT}},
{"set_unjam_locks_time", sf_set_unjam_locks_time, 1, 1, {ARG_INT}},
{"set_window_flag", sf_set_window_flag, 3, 3, {ARG_INTSTR, ARG_INT, ARG_INT}},
{"show_window", sf_show_window, 0, 1, {ARG_STRING}},
{"spatial_radius", sf_spatial_radius, 1, 1, {ARG_OBJECT}},
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
{"unjam_lock", sf_unjam_lock, 1, 1, {ARG_OBJECT}},
@@ -132,7 +136,7 @@ static const SfallMetarule metarules[] = {
{"validate_test", sf_test, 2, 5, {ARG_INT, ARG_NUMBER, ARG_STRING, ARG_OBJECT, ARG_ANY}},
#endif
};
//
// returns current contents of metarule table
static void sf_get_metarule_table(OpcodeContext& ctx) {
DWORD arrId = TempArray(metaruleTable.size(), 0);