diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 02cbe1860..37e8cb98a 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -516,6 +516,11 @@ #define CRITICAL_VALUE_FAIL_MSG (6) // This is shown instead of Message if the stat check fails. +#define DIFFICULTY_EASY (0) +#define DIFFICULTY_NORMAL (1) +#define DIFFICULTY_HARD (2) + + /* Playback mode defines for the soundplay function */ #define soundraw (0x80000000) // sfall flag #define Stereo8bit (soundstereo) diff --git a/artifacts/scripting/headers/lib.arrays.h b/artifacts/scripting/headers/lib.arrays.h index 4d2b04090..37e0a58a0 100644 --- a/artifacts/scripting/headers/lib.arrays.h +++ b/artifacts/scripting/headers/lib.arrays.h @@ -121,7 +121,7 @@ procedure remove_array_block(variable arr, variable blocksize, variable index); /** * Converts any array to string for debugging purposes */ -#define debug_array_str(arr) debug_array_str_deep(arr, 1) +#define debug_array_str(arr) debug_array_str_deep(arr, 1, false) // Prints contents of a given array to main message window, for debugging purposes. #define display_array(arr) display_msg(debug_array_str(arr)) @@ -502,6 +502,28 @@ end #undef ARRAY_SET_BLOCK_SIZE +/** + * Returns a new array containing only those items from *arr* for which *filterFunc* returns true. + * @arg {array} arr - Array to use values from. Can be map or list. + * @arg {string} filterFunc - A name of procedure that accepts value from arr and returns true if it should be copied to the new array. + * @arg {bool} negate - If true, reverses the result of filterFunc so that only "false" values will be copied to the new array. + * @ret {array} + */ +procedure array_filter(variable arr, variable filterFunc, variable negate := false) begin + variable k, v, + isMap := array_is_map(arr), + retArr := temp_array_map if isMap else temp_array_list(0); + foreach (k: v in arr) begin + if ((filterFunc(v) != 0) == (not negate)) then begin + if (isMap) then + set_array(retArr, k, v); + else + call array_push(retArr, v); + end + end + return retArr; +end + /** * Creates a new array filled from a given array by transforming each value using given procedure name. * @arg {array} arr - Array to use values from. @@ -721,16 +743,17 @@ end * Formats array contents into a string with a given level of recursion. For debugging. * @arg {array} arr * @arg {int} levels - recursion level + * @arg {bool} prefix - true to include a prefix with item count * @ret {string} */ -procedure debug_array_str_deep(variable arr, variable levels) begin +procedure debug_array_str_deep(variable arr, variable levels, variable prefix := false) begin #define _newline if (levels > 1) then s += "\n"; #define _indent ii := 0; while (ii < levels - 1) do begin s += " "; ii++; end #define _value(v) (v if (levels <= 1 or not array_exists(v)) else debug_array_str_deep(v, levels - 1)) variable i := 0, ii, k, v, s, len; len := len_array(arr); if (array_is_map(arr)) then begin // print assoc array - s := "Map("+len+"): {"; + s := ("Map("+len+"): {") if prefix else "{"; while i < len do begin _newline k := array_key(arr, i); @@ -744,7 +767,7 @@ procedure debug_array_str_deep(variable arr, variable levels) begin _newline s += "}"; end else begin // print list - s := "List("+len+"): ["; + s := ("List("+len+"): [") if prefix else "["; _newline while i < len do begin _newline diff --git a/artifacts/scripting/headers/lib.strings.h b/artifacts/scripting/headers/lib.strings.h index 9ea9b7f04..90b315ccb 100644 --- a/artifacts/scripting/headers/lib.strings.h +++ b/artifacts/scripting/headers/lib.strings.h @@ -200,6 +200,15 @@ procedure to_string(variable val) begin return ""+val; end +/** + * Returns true if given string is 0 or empty string. For use as a delegate. + * @arg {string} str + * @ret {bool} + */ +procedure string_null_or_empty(variable str) begin + return str == 0 or str == ""; +end + /** DEPRECATED, use string_format instead! diff --git a/artifacts/scripting/hooks.yml b/artifacts/scripting/hooks.yml index 233e35572..c7c50dec2 100644 --- a/artifacts/scripting/hooks.yml +++ b/artifacts/scripting/hooks.yml @@ -731,6 +731,8 @@ int arg0 - event type: 0 - when a random encounter occurs, 1 - when the player enters from the world map int arg1 - the map ID that the encounter will load (see MAPS.h or Maps.txt) int arg2 - 1 when the encounter occurs is a special encounter, 0 otherwise + int arg3 - encounter table index or -1 if not an encounter + int arg4 - encounter index in the table, or -1 if not an encounter int ret0 - overrides the map ID, or pass -1 for event type 0 to cancel the encounter and continue traveling int ret1 - pass 1 to cancel the encounter and load the specified map from the ret0 (only for event type 0) diff --git a/sfall/FalloutEngine/VariableOffsets.h b/sfall/FalloutEngine/VariableOffsets.h index c08d44778..c91e4107f 100644 --- a/sfall/FalloutEngine/VariableOffsets.h +++ b/sfall/FalloutEngine/VariableOffsets.h @@ -95,6 +95,8 @@ #define FO_VAR_Educated 0x57082C #define FO_VAR_elevation 0x631D2C #define FO_VAR_EncounterMapID 0x672E4C +#define FO_VAR_EncounterTableNum 0x672E50 +#define FO_VAR_EncounterNum 0x672E54 #define FO_VAR_endgame_subtitle_done 0x570BD0 #define FO_VAR_endgame_subtitle_characters 0x51866C #define FO_VAR_endgame_voiceover_loaded 0x570AB8 diff --git a/sfall/Modules/HookScripts/MiscHs.cpp b/sfall/Modules/HookScripts/MiscHs.cpp index 3afc7c1f8..551e0967e 100644 --- a/sfall/Modules/HookScripts/MiscHs.cpp +++ b/sfall/Modules/HookScripts/MiscHs.cpp @@ -592,11 +592,13 @@ static void __declspec(naked) ExplosiveTimerHook() { // Hook does not work for scripted encounters and meeting Horrigan static long __fastcall EncounterHook_Script(long encounterMapID, long eventType, long encType) { BeginHook(); - argCount = 3; + argCount = 5; args[0] = eventType; // 1 - enter local map from the world map args[1] = encounterMapID; args[2] = (encType == 3); // 1 - special random encounter + args[3] = fo::var::getInt(FO_VAR_EncounterTableNum); + args[4] = fo::var::getInt(FO_VAR_EncounterNum); RunHookScript(HOOK_ENCOUNTER);