Added "string_pos" function from 4.x

Added a check to PartyControl::OrderAttackPatch().
Updated function documents.
Updated scripting headers.
This commit is contained in:
NovaRain
2023-07-05 22:20:14 +08:00
parent 2941157174
commit 3a08488895
13 changed files with 154 additions and 92 deletions
@@ -170,9 +170,26 @@
#define self_elevation (elevation(self_obj)) #define self_elevation (elevation(self_obj))
#define self_pid (obj_pid(self_obj)) #define self_pid (obj_pid(self_obj))
// team
#define self_team has_trait(TRAIT_OBJECT,self_obj,OBJECT_TEAM_NUM) #define self_team has_trait(TRAIT_OBJECT,self_obj,OBJECT_TEAM_NUM)
#define get_team(cr) has_trait(TRAIT_OBJECT,cr,OBJECT_TEAM_NUM)
#define set_team(cr,team) critter_add_trait(cr,TRAIT_OBJECT,OBJECT_TEAM_NUM,team)
#define set_self_team(team) set_team(self_obj,team)
// ai
#define self_ai has_trait(TRAIT_OBJECT,self_obj,OBJECT_AI_PACKET) #define self_ai has_trait(TRAIT_OBJECT,self_obj,OBJECT_AI_PACKET)
#define get_ai(cr) has_trait(TRAIT_OBJECT,cr,OBJECT_AI_PACKET)
#define set_ai(cr,ai) critter_add_trait(cr,TRAIT_OBJECT,OBJECT_AI_PACKET,ai)
#define set_self_ai(ai) set_ai(self_obj,ai)
// visibility
#define self_visible obj_is_visible_flag(self_obj) #define self_visible obj_is_visible_flag(self_obj)
#define set_obj_invisible(cr) set_obj_visibility(cr,true)
#define set_obj_visible(cr) set_obj_visibility(cr,false)
#define set_self_invisible set_obj_visibility(self_obj,true)
#define set_self_visible set_obj_visibility(self_obj,false)
#define is_visible(cr) has_trait(TRAIT_OBJECT,cr,OBJECT_VISIBILITY) // aka obj_is_visible_flag(x)
#define self_cur_hits (get_critter_stat(self_obj,STAT_current_hp)) #define self_cur_hits (get_critter_stat(self_obj,STAT_current_hp))
#define self_max_hits (get_critter_stat(self_obj,STAT_max_hp)) #define self_max_hits (get_critter_stat(self_obj,STAT_max_hp))
+53 -12
View File
@@ -35,6 +35,9 @@ procedure array_keys(variable array);
// list of array values (useful for maps) // list of array values (useful for maps)
procedure array_values(variable array); procedure array_values(variable array);
// makes given array permanent and returns it
procedure array_fixed(variable array);
// returns temp array containing a subarray starting from $index with $count elements // returns temp array containing a subarray starting from $index with $count elements
// negative $index means index from the end of array // negative $index means index from the end of array
// negative $count means leave this many elements from the end of array // negative $count means leave this many elements from the end of array
@@ -91,6 +94,11 @@ procedure get_empty_array_index(variable array);
procedure add_array_set(variable array, variable item); procedure add_array_set(variable array, variable item);
procedure remove_array_set(variable array, variable item); procedure remove_array_set(variable array, variable item);
// Creates a new array filled from a given array by transforming each value using given procedure name.
procedure array_transform(variable arr, variable valueFunc);
// Create a new temp array filled from a given array by transforming each key and value using given procedure name.
procedure array_transform_kv(variable arr, variable keyFunc, variable valueFunc);
@@ -223,6 +231,11 @@ procedure array_values(variable array) begin
return tmp; return tmp;
end end
procedure array_fixed(variable array) begin
fix_array(array);
return array;
end
procedure array_slice(variable array, variable index, variable count) begin procedure array_slice(variable array, variable index, variable count) begin
variable tmp, i, n; variable tmp, i, n;
n := len_array(array); n := len_array(array);
@@ -401,14 +414,25 @@ procedure remove_array_set(variable array, variable item) begin
end end
end end
// Transform every value in array using given callback // Creates a new array filled from a given array by transforming each value using given procedure name.
procedure array_map_func(variable arr, variable callback) begin procedure array_transform(variable arr, variable valueFunc) begin
variable k, v; variable k, v, retArr := temp_array_map if array_is_map(arr) else temp_array(len_array(arr), 0);
foreach (k: v in arr) foreach (k: v in arr) begin
arr[k] := callback(v); retArr[k] := valueFunc(v);
return arr; end
return retArr;
end end
// Create a new temp array filled from a given array by transforming each key and value using given procedure name.
procedure array_transform_kv(variable arr, variable keyFunc, variable valueFunc) begin
variable k, v, retArr := temp_array_map;
foreach (k: v in arr) begin
retArr[keyFunc(k)] := valueFunc(v);
end
return retArr;
end
#define ARRAY_EMPTY_INDEX (-1) #define ARRAY_EMPTY_INDEX (-1)
/** /**
@@ -484,6 +508,7 @@ procedure array_append(variable arr1, variable arr2) begin
return arr1; return arr1;
end end
// Loads a "saved" array. If it doesn't exist, creates it (with a given size).
procedure load_create_array(variable name, variable size) begin procedure load_create_array(variable name, variable size) begin
variable arr; variable arr;
arr := load_array(name); arr := load_array(name);
@@ -494,6 +519,7 @@ procedure load_create_array(variable name, variable size) begin
return arr; return arr;
end end
// Creates and returns a new "saved" array. If array already existed with this name, frees it.
procedure get_saved_array_new(variable name, variable size) begin procedure get_saved_array_new(variable name, variable size) begin
variable arr; variable arr;
arr := load_array(name); arr := load_array(name);
@@ -584,30 +610,45 @@ end
Different utility functions... Different utility functions...
*/ */
procedure debug_array_str(variable arr) begin #define debug_array_str(arr) debug_array_str_deep(arr, 1)
variable i := 0, k, s, len;
procedure debug_array_str_deep(variable arr, variable levels) begin
#define _newline if (levels > 1) then s += "\n";
#define _indent string_repeat(" ", levels - 1)
#define _value(v) (v if (levels <= 1 or not array_exists(v)) else debug_array_str_deep(v, levels - 1))
variable i := 0, k, v, s, len;
len := len_array(arr); len := len_array(arr);
if (array_is_map(arr)) then begin // print assoc array if (array_is_map(arr)) then begin // print assoc array
s := "Map("+len+"): {"; s := "Map("+len+"): {";
while i < len do begin while i < len do begin
_newline
k := array_key(arr, i); k := array_key(arr, i);
s += k + ": "+ get_array(arr, k); v := get_array(arr, k);
s += _indent + k + ": " + _value(v);
if i < (len - 1) then s += ", "; if i < (len - 1) then s += ", ";
i++; i++;
end end
if (strlen(s) > 254) then s := substr(s, 0, 251) + "..."; //if (strlen(s) > 254) then s := substr(s, 0, 251) + "...";
_newline
s += "}"; s += "}";
end else begin // print list end else begin // print list
s := "List("+len+"): ["; s := "List("+len+"): [";
_newline
while i < len do begin while i < len do begin
s += arr[i]; _newline
v := get_array(arr, i);
s += _indent + _value(v);
if i < (len - 1) then s += ", "; if i < (len - 1) then s += ", ";
i++; i++;
end end
if (strlen(s) > 254) then s := substr(s, 0, 251) + "..."; //if (strlen(s) > 254) then s := substr(s, 0, 251) + "...";
_newline
s += "]"; s += "]";
end end
return s; return s;
#undef _newline
#undef _indent
#undef _value
end end
procedure _PURGE_all_saved_arrays begin procedure _PURGE_all_saved_arrays begin
+8 -5
View File
@@ -51,13 +51,15 @@ procedure remove_items_pid(variable invenObj, variable itemPid, variable quantit
variable begin variable begin
item; item;
toRemoveQty; toRemoveQty;
actualQty;
end end
if (not(invenObj)) then return; if (not(invenObj)) then return;
toRemoveQty := obj_is_carrying_obj_pid(invenObj, itemPid); actualQty := obj_is_carrying_obj_pid(invenObj, itemPid);
if (quantity < toRemoveQty and quantity != -1) then begin if (quantity > actualQty or quantity < 0) then begin
toRemoveQty := quantity; quantity := actualQty;
end end
while (toRemoveQty > 0) do begin toRemoveQty := quantity;
while (quantity > 0) do begin
item := obj_carrying_pid_obj(invenObj, itemPid); item := obj_carrying_pid_obj(invenObj, itemPid);
if (obj_type(invenObj) == OBJ_TYPE_CRITTER) then begin if (obj_type(invenObj) == OBJ_TYPE_CRITTER) then begin
if (critter_inven_obj(invenObj, INVEN_TYPE_WORN) == item) then begin if (critter_inven_obj(invenObj, INVEN_TYPE_WORN) == item) then begin
@@ -66,9 +68,10 @@ procedure remove_items_pid(variable invenObj, variable itemPid, variable quantit
inven_unwield(invenObj); inven_unwield(invenObj);
end end
end end
toRemoveQty -= rm_mult_objs_from_inven(invenObj, item, toRemoveQty); quantity -= rm_mult_objs_from_inven(invenObj, item, quantity);
destroy_object(item); destroy_object(item);
end end
return toRemoveQty;
end end
procedure remove_item_obj(variable invenObj, variable item) begin procedure remove_item_obj(variable invenObj, variable item) begin
+3 -8
View File
@@ -5,13 +5,8 @@
Numbers... Numbers...
*/ */
#define above(a, b) (unsigned_comp(a, b) > 0)
#define above_equal(a, b) (unsigned_comp(a, b) >= 0)
#define below(a, b) (unsigned_comp(a, b) < 0)
#define below_equal(a, b) (unsigned_comp(a, b) <= 0)
// for sfall 4.2.3/3.8.23 // for sfall 4.2.3/3.8.23
pure procedure unsigned_comp(variable a, variable b) begin pure procedure unsigned_int_compare(variable a, variable b) begin
if ((a bwxor b) == 0) then return 0; // a == b if ((a bwxor b) == 0) then return 0; // a == b
return 1 if ((b == 0) orElse a div b) else -1; return 1 if ((b == 0) orElse a div b) else -1;
end end
@@ -21,10 +16,10 @@ end
#define math_max(x, y) (x if x > y else y) #define math_max(x, y) (x if x > y else y)
#define math_min(x, y) (x if x < y else y) #define math_min(x, y) (x if x < y else y)
#define in_range(x, from, to) (x >= from and x <= to) #define math_in_range(x, from, to) (x >= from and x <= to)
procedure get_clamped(variable val, variable a, variable b) begin procedure math_clamp(variable val, variable a, variable b) begin
variable min, max; variable min, max;
if (a < b) then begin if (a < b) then begin
min := a; min := a;
+21 -61
View File
@@ -13,17 +13,10 @@
#define is_in_string(str, sub) (string_pos(str, sub) != -1) #define is_in_string(str, sub) (string_pos(str, sub) != -1)
#define string_starts_with(str, sub) (substr(str, 0, strlen(sub)) == sub) #define string_starts_with(str, sub) (substr(str, 0, strlen(sub)) == sub)
#define string_format_array(fmt, arr) sprintf_array(fmt, arr)
/** // Replaces all occurances of substring in a string with another substring
* Returns position of first occurance of substr in str, or -1 if not found #define string_replace(str, search, replace) (string_join(string_split(str, search), replace))
*/ #define sprintf2(fmt, arg1, arg2) string_format2(fmt, arg1, arg2)
procedure string_pos(variable str, variable subst) begin
variable lst, n;
lst := string_split(str, subst);
if (len_array(lst) < 2) then
return -1;
return strlen(lst[0]);
end
/** /**
* Join array of strings using delimeter * Join array of strings using delimeter
@@ -41,44 +34,6 @@ procedure string_join(variable array, variable join) begin
return str; return str;
end end
/**
* replaces all occurances of substring in a string with another substring
*/
#define string_replace(str, search, replace) (string_join(string_split(str, search), replace))
/**
* sprintf with two arguments
*/
procedure sprintf2(variable str, variable arg1, variable arg2) begin
variable split, len, i, j, arg;
split := string_split(str, "%");
len := len_array(split);
str := "";
if (len > 0) then begin
str := split[0];
j := 0;
for (i := 1; i < len; i++) begin
if (split[i] == "") then begin
if (i < len - 1) then begin
str += "%" + split[i+1];
i++;
end
end else begin
if (j == 0) then
arg := arg1;
else if (j == 1) then
arg := arg2;
else
arg := 0;
str += sprintf("%" + split[i], arg);
j++;
end
end
end
return str;
end
/** /**
* sprintf with unlimited number of arguments * sprintf with unlimited number of arguments
*/ */
@@ -151,18 +106,6 @@ procedure string_repeat(variable str, variable count) begin
return out; return out;
end end
/**
* Workaround for string_split bug in sfall 3.3
* DEPRECATED as of sfall 3.4 (bug fixed)
*/
procedure string_split_safe(variable str, variable split) begin
variable lst;
str += split;
lst := string_split(str, split);
resize_array(lst, len_array(lst) - 1);
return lst;
end
/** /**
* The same as sfall string_split, but returns array of integers instead * The same as sfall string_split, but returns array of integers instead
* Useful in cunjunction with is_in_array() * Useful in cunjunction with is_in_array()
@@ -186,8 +129,25 @@ procedure string_split_ints(variable str, variable split) begin
return result; return result;
end end
// atoi proc wrapper, for use as callback
procedure string_to_int(variable str) begin
return atoi(str);
end
// atof proc wrapper, for use as callback
procedure string_to_float(variable str) begin
return atof(str);
end
// converts any value to a string, for use as callback
procedure to_string(variable val) begin
return ""+val;
end
/** /**
DEPRECATED, use string_format instead!
String parse functions. Idea taken from KLIMaka on TeamX forums. String parse functions. Idea taken from KLIMaka on TeamX forums.
Placeholders in format %d% are replaced from string. d refers to variable index (starting from 1). Placeholders in format %d% are replaced from string. d refers to variable index (starting from 1).
You can repeat one placeholder multiple times, or use placeholders in any order. You can repeat one placeholder multiple times, or use placeholders in any order.
+6 -3
View File
@@ -149,7 +149,7 @@
// sort map in descending order by key value // sort map in descending order by key value
#define sort_map_reverse(array) resize_array(array, -7) #define sort_map_reverse(array) resize_array(array, -7)
// remove element from map or just replace value with 0 for list // remove element from map or just replace value with 0 for list
#define unset_array(array, item) set_array(array, item, 0) #define unset_array(array, key) set_array(array, key, 0)
// same as "key_pressed" but checks VK codes instead of DX codes // same as "key_pressed" but checks VK codes instead of DX codes
#define key_pressed_vk(key) (key_pressed(key bwor 0x80000000)) #define key_pressed_vk(key) (key_pressed(key bwor 0x80000000))
@@ -282,6 +282,8 @@
/* SFALL_FUNCX MACROS */ /* SFALL_FUNCX MACROS */
#define FUNC_SELECTOR_7(_1,_2,_3,_4,_5,_6,_7,FUNC,...) FUNC
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name) #define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
#define add_global_timer_event(time, fixedParam) sfall_func2("add_g_timer_event", time, fixedParam) #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_iface_tag sfall_func0("add_iface_tag")
@@ -387,6 +389,8 @@
#define spatial_radius(obj) sfall_func1("spatial_radius", obj) #define spatial_radius(obj) sfall_func1("spatial_radius", obj)
#define string_compare(str1, str2) sfall_func2("string_compare", str1, str2) #define string_compare(str1, str2) sfall_func2("string_compare", str1, str2)
#define string_compare_locale(str1, str2, codePage) sfall_func3("string_compare", str1, str2, codePage) #define string_compare_locale(str1, str2, codePage) sfall_func3("string_compare", str1, str2, codePage)
#define string_pos(haystack, needle) sfall_func2("string_pos", haystack, needle)
#define string_pos_from(haystack, needle, pos) sfall_func3("string_pos", haystack, needle, pos)
#define string_format1(format, a1) sfall_func2("string_format", format, a1) #define string_format1(format, a1) sfall_func2("string_format", format, a1)
#define string_format2(format, a1, a2) sfall_func3("string_format", format, a1, a2) #define string_format2(format, a1, a2) sfall_func3("string_format", format, a1, a2)
#define string_format3(format, a1, a2, a3) sfall_func4("string_format", format, a1, a2, a3) #define string_format3(format, a1, a2, a3) sfall_func4("string_format", format, a1, a2, a3)
@@ -394,8 +398,7 @@
#define string_format5(format, a1, a2, a3, a4, a5) sfall_func6("string_format", format, a1, a2, a3, a4, a5) #define string_format5(format, a1, a2, a3, a4, a5) sfall_func6("string_format", format, a1, a2, a3, a4, a5)
#define string_format6(format, a1, a2, a3, a4, a5, a6) sfall_func7("string_format", format, a1, a2, a3, a4, a5, a6) #define string_format6(format, a1, a2, a3, a4, a5, a6) sfall_func7("string_format", format, a1, a2, a3, a4, a5, a6)
#define string_format7(format, a1, a2, a3, a4, a5, a6, a7) sfall_func8("string_format", format, a1, a2, a3, a4, a5, a6, a7) #define string_format7(format, a1, a2, a3, a4, a5, a6, a7) sfall_func8("string_format", format, a1, a2, a3, a4, a5, a6, a7)
#define string_format_MACRO(_0,_1,_2,_3,_4,_5,_6,FUNC,...) FUNC #define string_format(format, ...) FUNC_SELECTOR_7(__VA_ARGS__,string_format7,string_format6,string_format5,string_format4,string_format3,string_format2,string_format1)(format, __VA_ARGS__)
#define string_format(...) string_format_MACRO(__VA_ARGS__, string_format6, string_format5, string_format4, string_format3, string_format2, string_format1)(__VA_ARGS__)
#define string_tolower(text) sfall_func2("string_to_case", text, 0) #define string_tolower(text) sfall_func2("string_to_case", text, 0)
#define string_toupper(text) sfall_func2("string_to_case", text, 1) #define string_toupper(text) sfall_func2("string_to_case", text, 1)
#define tile_by_position(x, y) sfall_func2("tile_by_position", x, y) #define tile_by_position(x, y) sfall_func2("tile_by_position", x, y)
+14 -3
View File
@@ -327,11 +327,11 @@ FUNCTION REFERENCE
- You can use this to search for a substring in a string like this: `strlen(get_array(string_split(haystack, needle), 0))` - You can use this to search for a substring in a string like this: `strlen(get_array(string_split(haystack, needle), 0))`
----- -----
##### `string substr(string text, start, length)` ##### `string substr(string text, int start, int length)`
- Cuts a substring from a string starting at `start` up to `length` characters. The first character position is 0 (zero). - Cuts a substring from a string starting at `start` up to `length` characters. The first character position is 0 (zero).
- If `start` is negative - it indicates starting position from the end of the string (for example, `substr("test", -2, 2)` will return last 2 charactes: "st"). - If `start` is negative - it indicates a position starting from the end of the string (for example, `substr("test", -2, 2)` will return last 2 charactes: "st").
- If `length` is negative - it means so many characters will be omitted from the end of string (example: `substr("test", 0, -2)` will return string without last 2 characters: "te"). - If `length` is negative - it means so many characters will be omitted from the end of string (example: `substr("test", 0, -2)` will return string without last 2 characters: "te").
- If `length` is zero - it will return a string from the starting position to the end of the string (new behavior for sfall 4.2.2/3.8.22). - If `length` is zero - it will return a string from the starting position to the end of the string (**new behavior** since sfall 4.2.2/3.8.22).
----- -----
##### `int strlen(string text)` ##### `int strlen(string text)`
@@ -1084,6 +1084,7 @@ sfall_funcX metarule functions
- Allows changing "bonus move" points (yellow lights on the interface bar) that can only be used for movement, not attacking - Allows changing "bonus move" points (yellow lights on the interface bar) that can only be used for movement, not attacking
- Can be called from `HOOK_COMBATTURN` at the start of the turn (will not work on `dude_obj`) - Can be called from `HOOK_COMBATTURN` at the start of the turn (will not work on `dude_obj`)
- Can be called from `HOOK_STDPROCEDURE` with `combat_proc` event (will work on both NPCs and `dude_obj`) - Can be called from `HOOK_STDPROCEDURE` with `combat_proc` event (will work on both NPCs and `dude_obj`)
---- ----
#### get_ini_config #### get_ini_config
`array sfall_func2("get_ini_config", string file, bool searchDB)` `array sfall_func2("get_ini_config", string file, bool searchDB)`
@@ -1093,6 +1094,16 @@ sfall_funcX metarule functions
True - searches the file in database (DAT) files. If not found, then it will try the regular file system True - searches the file in database (DAT) files. If not found, then it will try the regular file system
- Subsequent calls for the same file will return the same array, unless it was disposed using `free_array` - Subsequent calls for the same file will return the same array, unless it was disposed using `free_array`
----
#### string_pos
`int sfall_func2("string_pos", string haystack, string needle)`
`int sfall_func3("string_pos", string haystack, string needle, int pos)`
- Returns the position of the first occurrence of a `needle` string in a `haystack` string, or -1 if not found. The first character position is 0 (zero)
**Optional argument:**
- `pos`: the position at which to start the search. If negative, it indicates a position starting from the end of the string
**** ****
_See other documentation files (arrays.md, hookscripts.md) for related functions reference._ _See other documentation files (arrays.md, hookscripts.md) for related functions reference._
+4
View File
@@ -680,12 +680,16 @@ static void __declspec(naked) combat_ai_hook_target() {
} }
void PartyControl::OrderAttackPatch() { void PartyControl::OrderAttackPatch() {
static bool orderAttackPatch = false;
if (orderAttackPatch) return;
MakeCall(0x44C4A7, gmouse_handle_event_hack, 2); MakeCall(0x44C4A7, gmouse_handle_event_hack, 2);
HookCall(0x44C75F, gmouse_handle_event_hook); HookCall(0x44C75F, gmouse_handle_event_hook);
HookCall(0x44C69A, gmouse_handle_event_hook_restore); HookCall(0x44C69A, gmouse_handle_event_hook_restore);
MakeCall(0x44B830, gmouse_bk_process_hack); MakeCall(0x44B830, gmouse_bk_process_hack);
HookCall(0x42B235, combat_ai_hook_target); HookCall(0x42B235, combat_ai_hook_target);
orderAttackPatch = true;
} }
static void NpcAutoLevelPatch() { static void NpcAutoLevelPatch() {
@@ -153,6 +153,7 @@ static const SfallMetarule metarules[] = {
{"show_window", mf_show_window, 0, 1, -1, {ARG_STRING}}, {"show_window", mf_show_window, 0, 1, -1, {ARG_STRING}},
{"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}}, {"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}},
{"string_compare", mf_string_compare, 2, 3, 0, {ARG_STRING, ARG_STRING, ARG_INT}}, {"string_compare", mf_string_compare, 2, 3, 0, {ARG_STRING, ARG_STRING, ARG_INT}},
{"string_pos", mf_string_pos, 2, 3, -1, {ARG_STRING, ARG_STRING, ARG_INT}},
{"string_format", mf_string_format, 2, 8, 0, {ARG_STRING, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY}}, {"string_format", mf_string_format, 2, 8, 0, {ARG_STRING, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY, ARG_ANY}},
{"string_to_case", mf_string_to_case, 2, 2, -1, {ARG_STRING, ARG_INT}}, {"string_to_case", mf_string_to_case, 2, 2, -1, {ARG_STRING, ARG_INT}},
{"tile_by_position", mf_tile_by_position, 2, 2, -1, {ARG_INT, ARG_INT}}, {"tile_by_position", mf_tile_by_position, 2, 2, -1, {ARG_INT, ARG_INT}},
@@ -198,6 +198,25 @@ void mf_string_compare(OpcodeContext& ctx) {
} }
} }
void mf_string_pos(OpcodeContext& ctx) {
const char* const haystack = ctx.arg(0).strValue();
int pos = 0;
if (ctx.numArgs() > 2) {
int len = strlen(haystack);
pos = ctx.arg(2).intValue();
if (pos >= len) {
ctx.setReturn(-1);
return;
} else if (pos < 0) {
pos += len;
}
}
const char* needle = strstr(haystack + pos, ctx.arg(1).strValue());
ctx.setReturn(
needle != nullptr ? (int)(needle - haystack) : -1
);
}
// A safer version of sprintf for using in user scripts. // A safer version of sprintf for using in user scripts.
static const char* sprintf_lite(OpcodeContext& ctx, const char* opcodeName) { static const char* sprintf_lite(OpcodeContext& ctx, const char* opcodeName) {
const char* format = ctx.arg(0).strValue(); const char* format = ctx.arg(0).strValue();
+2
View File
@@ -37,6 +37,8 @@ void op_strlen(OpcodeContext&);
void mf_string_compare(OpcodeContext&); void mf_string_compare(OpcodeContext&);
void mf_string_pos(OpcodeContext&);
void op_sprintf(OpcodeContext&); void op_sprintf(OpcodeContext&);
void mf_string_format(OpcodeContext&); void mf_string_format(OpcodeContext&);
+4
View File
@@ -135,6 +135,10 @@ unsigned long ScriptValue::rawValue() const {
return _val.dw; return _val.dw;
} }
long ScriptValue::intValue() const {
return _val.i;
}
const char* ScriptValue::strValue() const { const char* ScriptValue::strValue() const {
return _val.str; return _val.str;
} }
+2
View File
@@ -57,6 +57,8 @@ public:
unsigned long rawValue() const; unsigned long rawValue() const;
long intValue() const;
float floatValue() const; float floatValue() const;
const char* strValue() const; const char* strValue() const;