From 989feb1c65079aeb95de5bc139ee7405c60e145b Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 25 May 2021 12:58:03 +0800 Subject: [PATCH] Added "proto_exists" script function Updated gl_auto_closebox example script. --- .../AutoCloseBox/gl_auto_closebox.int | Bin 672 -> 658 bytes .../AutoCloseBox/gl_auto_closebox.ssl | 7 ++++--- artifacts/scripting/headers/sfall.h | 1 + artifacts/scripting/sfall function notes.txt | 3 +++ sfall/FalloutEngine.cpp | 8 ++++++++ sfall/FalloutEngine.h | 3 +++ sfall/FalloutFuncOffs_def.h | 1 + sfall/FalloutFuncs_def.h | 1 + sfall/FalloutStructs.h | 13 +++++++++++++ sfall/FalloutVars_def.h | 1 + sfall/ScriptOps/MetaruleOps.hpp | 1 + sfall/ScriptOps/ObjectsOps.hpp | 11 +++++++++++ 12 files changed, 47 insertions(+), 3 deletions(-) diff --git a/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int b/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int index 64aa7da2000af2bb2b8200d09179d447d80282ab..96d5499abd49888c164251d0495c5c2f49401aac 100644 GIT binary patch delta 67 zcmZ3$I*D~cA!FXeqT`HVldTvRa)vdq9AIQ%U<#Z3gwdEWY_bHCsw6{$5J-%Hu|XJ2 OGk{5^2DZs5Of~?6*$_+s delta 81 zcmbQlx`1^;A!E(NqT`GyldTvRa;7w}9AIQ%U`m<%gwdGMZL$QDsyZV`gn_An4NNmM V2!UzF24OJG03jQMCx 1) then call close in 1; - closeObject = lootObject; - lootObject = 0; + if (get_object_data(lootObject, OBJ_DATA_CUR_FRM) > 1) then begin + closeObject = lootObject; + call close in 0; + end end end end diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 1dc6b0d1..ba8b4e67 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -332,6 +332,7 @@ #define overlay_clear(winType) sfall_func2("interface_overlay", winType, 2) #define overlay_clear_rectangle(winType, x, y, w, h) sfall_func6("interface_overlay", winType, 2, x, y, w, h) #define overlay_destroy(winType) sfall_func2("interface_overlay", winType, 0) +#define proto_exists(pid) sfall_func1("proto_exists", pid) #define real_dude_obj sfall_func0("real_dude_obj") #define remove_all_timer_events sfall_func0("remove_timer_event") #define remove_timer_event(fixedParam) sfall_func1("remove_timer_event", fixedParam) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index ef12cfcf..c02e7392 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -742,6 +742,9 @@ optional arguments: - gvarNumber: the number of the global variable controlling the quest - thresholdValue: the value of the global variable at which the quest is counted as a failure +> bool sfall_func1("proto_exists", int pid) +- returns True if the specified PID number exists in the list of registered protos + ------------------------ ------ MORE INFO ------- ------------------------ diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 8c87fbbd..c63beca0 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -576,6 +576,14 @@ long AnimCodeByWeapon(TGameObj* weapon) { return 0; } +bool CheckProtoID(DWORD pid) { + if (pid == 0) return false; + long type = pid >> 24; + if (type > OBJ_TYPE_MISC) return false; + + return (static_cast(pid & 0xFFFF) < ptr_protoLists[type].totalCount); +} + bool GetProto(long pid, sProto** outProto) { return (fo_proto_ptr(pid, outProto) != -1); } diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 940a1a54..ede38623 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -243,6 +243,7 @@ #define FO_VAR_procTableStrs 0x51C758 // table of procId (from define.h) => procName map #define FO_VAR_proto_main_msg_file 0x6647FC #define FO_VAR_proto_msg_files 0x6647AC +#define FO_VAR_protoLists 0x51C290 #define FO_VAR_ptable 0x59E934 #define FO_VAR_pud 0x59E960 #define FO_VAR_quest_count 0x51C12C @@ -522,6 +523,8 @@ Queue* QueueFind(TGameObj* object, long type); // returns weapon animation code long AnimCodeByWeapon(TGameObj* weapon); +bool CheckProtoID(DWORD pid); + // returns False if the prototype does not exist, or pointer to prototype by PID in the outProto argument bool GetProto(long pid, sProto** outProto); diff --git a/sfall/FalloutFuncOffs_def.h b/sfall/FalloutFuncOffs_def.h index 09759cc0..ecc10ba0 100644 --- a/sfall/FalloutFuncOffs_def.h +++ b/sfall/FalloutFuncOffs_def.h @@ -476,6 +476,7 @@ FUNC(protinst_use_item_on_, 0x49C3CC) FUNC(proto_dude_init_, 0x49FA64) FUNC(proto_dude_update_gender_, 0x49F984) FUNC(proto_list_str_, 0x49E758) +FUNC(proto_make_path_, 0x49E270) FUNC(proto_ptr_, 0x4A2108) // eax - PID, edx - int** - pointer to a pointer to a proto struct FUNC(pushLongStack_, 0x46736C) FUNC(qsort_, 0x4F05B6) diff --git a/sfall/FalloutFuncs_def.h b/sfall/FalloutFuncs_def.h index e270461d..9d015c20 100644 --- a/sfall/FalloutFuncs_def.h +++ b/sfall/FalloutFuncs_def.h @@ -168,6 +168,7 @@ WRAP_WATCOM_FUNC2(long, perk_level, TGameObj*, critter, long, perkId) WRAP_WATCOM_FUNC6(long, pick_death, TGameObj*, attacker, TGameObj*, target, TGameObj*, weapon, long, amount, long, anim, long, hitFromBack) WRAP_WATCOM_FUNC0(void, process_bk) WRAP_WATCOM_FUNC0(void, proto_dude_update_gender) +WRAP_WATCOM_FUNC2(void, proto_make_path, char*, buffer, long, pid) // Places pointer to a prototype structure into ptrPtr and returns 0 on success or -1 on failure WRAP_WATCOM_FUNC2(long, proto_ptr, long, pid, sProto**, ptrPtr) WRAP_WATCOM_FUNC2(void, queue_clear_type, long, qType, void*, func) // removes all events of the given type and performs func before removal diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index c832fe08..223dfd2b 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -593,6 +593,19 @@ struct PremadeChar { char unknown[20]; }; +struct ProtoListBlock { + long* protoMem[16]; + long count; + ProtoListBlock* next; +}; + +struct ProtoList { + ProtoListBlock* block; + ProtoListBlock* lastBlock; + long countBlocks; // current + long totalCount; // total number of prototypes for this type +}; + // In-memory PROTO structure, not the same as PRO file format. struct sProto { struct Tile { diff --git a/sfall/FalloutVars_def.h b/sfall/FalloutVars_def.h index 15f458b0..47508a23 100644 --- a/sfall/FalloutVars_def.h +++ b/sfall/FalloutVars_def.h @@ -166,6 +166,7 @@ PTR_(preload_list_index, DWORD) PTR_(procTableStrs, const char*) // table of procId (from define.h) => procName map PTR_(proto_main_msg_file, MSGList) PTR_(proto_msg_files, MSGList) // array of 6 elements +PTR_(protoLists, ProtoList) // array of 11 elements PTR_(ptable, DWORD) PTR_(pud, DWORD) PTR_(queue, Queue*) diff --git a/sfall/ScriptOps/MetaruleOps.hpp b/sfall/ScriptOps/MetaruleOps.hpp index cb409101..398bbb88 100644 --- a/sfall/ScriptOps/MetaruleOps.hpp +++ b/sfall/ScriptOps/MetaruleOps.hpp @@ -164,6 +164,7 @@ static const SfallMetarule metaruleArray[] = { {"obj_under_cursor", mf_obj_under_cursor, 2, 2}, {"objects_in_radius", mf_objects_in_radius, 3, 4}, {"outlined_object", mf_outlined_object, 0, 0}, + {"proto_exists", mf_proto_exists, 1, 1}, {"real_dude_obj", mf_real_dude_obj, 0, 0}, {"remove_timer_event", mf_remove_timer_event, 0, 1}, {"set_car_intface_art", mf_set_car_intface_art, 1, 1}, diff --git a/sfall/ScriptOps/ObjectsOps.hpp b/sfall/ScriptOps/ObjectsOps.hpp index 39134699..fe50226d 100644 --- a/sfall/ScriptOps/ObjectsOps.hpp +++ b/sfall/ScriptOps/ObjectsOps.hpp @@ -596,6 +596,17 @@ static void mf_get_loot_object() { opHandler.setReturn((GetLoopFlags() & INTFACELOOT) ? ptr_target_stack[*ptr_target_curr_stack] : 0); } +static void mf_proto_exists() { + const ScriptValue &pidArg = opHandler.arg(0); + + if (pidArg.isInt()) { + opHandler.setReturn(CheckProtoID(pidArg.rawValue())); + } else { + OpcodeInvalidArgs("proto_exists"); + opHandler.setReturn(0); + } +} + static bool protoMaxLimitPatch = false; static void __stdcall op_get_proto_data2() {