mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Backported "get_object_ai_data" script function
Updated headers and documents. Edited error messages for some script functions.
This commit is contained in:
@@ -363,6 +363,79 @@
|
||||
#define WPN_ANIM_MINIGUN (0x09) // (L)
|
||||
#define WPN_ANIM_ROCKET_LAUNCHER (0x0A) // (M)
|
||||
|
||||
// AI data parameters
|
||||
#define AI_CAP_AGGRESSION (0)
|
||||
#define AI_CAP_AREA_ATTACK_MODE (1)
|
||||
#define AI_CAP_ATTACK_WHO (2)
|
||||
#define AI_CAP_BEST_WEAPON (3)
|
||||
#define AI_CAP_CHEM_USE (4)
|
||||
#define AI_CAP_DISPOSITION (5)
|
||||
#define AI_CAP_DISTANCE (6)
|
||||
#define AI_CAP_MAX_DISTANCE (7)
|
||||
#define AI_CAP_MIN_HP (8)
|
||||
#define AI_CAP_MIN_TO_HIT (9)
|
||||
#define AI_CAP_HURT_TOO_MUCH (10) // DAM_BLIND/DAM_CRIP_* flags
|
||||
#define AI_CAP_RUN_AWAY_MODE (11)
|
||||
#define AI_CAP_SECONDARY_FREQ (12)
|
||||
#define AI_CAP_CALLED_FREQ (13)
|
||||
#define AI_CAP_CHEM_PRIMARY_DESIRE (14) // array pid list
|
||||
|
||||
// AI attack area mode values
|
||||
#define ai_area_always (0)
|
||||
#define ai_area_sometimes (1)
|
||||
#define ai_area_be_sure (2)
|
||||
#define ai_area_be_careful (3)
|
||||
#define ai_area_be_absolutely_sure (4)
|
||||
|
||||
// AI attack who mode values
|
||||
#define ai_attack_whomever_attacking_me (0)
|
||||
#define ai_attack_strongest (1)
|
||||
#define ai_attack_weakest (2)
|
||||
#define ai_attack_whomever (3)
|
||||
#define ai_attack_closest (4)
|
||||
|
||||
// AI run away mode values
|
||||
#define ai_run_away_none (0)
|
||||
#define ai_run_away_coward (1)
|
||||
#define ai_run_away_finger_hurts (3)
|
||||
#define ai_run_away_bleeding (4)
|
||||
#define ai_run_away_not_feeling_good (5)
|
||||
#define ai_run_away_tourniquet (6)
|
||||
#define ai_run_away_never (7)
|
||||
|
||||
// AI disposition values
|
||||
#define ai_disposition_none (-1)
|
||||
#define ai_disposition_custom (0)
|
||||
#define ai_disposition_coward (1)
|
||||
#define ai_disposition_defensive (2)
|
||||
#define ai_disposition_aggressive (3)
|
||||
#define ai_disposition_berserk (4)
|
||||
|
||||
// AI distance values
|
||||
#define ai_distance_stay_close (0)
|
||||
#define ai_distance_charge (1)
|
||||
#define ai_distance_snipe (2)
|
||||
#define ai_distance_on_your_own (3)
|
||||
#define ai_distance_stay (4)
|
||||
|
||||
// AI best weapon pref values
|
||||
#define ai_weapon_no_pref (0)
|
||||
#define ai_weapon_melee (1)
|
||||
#define ai_weapon_melee_over_ranged (2)
|
||||
#define ai_weapon_ranged_over_melee (3)
|
||||
#define ai_weapon_ranged (4)
|
||||
#define ai_weapon_unarmed (5)
|
||||
#define ai_weapon_unarmed_over_thrown (6)
|
||||
#define ai_weapon_random (7)
|
||||
|
||||
// AI chem use mode values
|
||||
#define ai_chem_clean (0)
|
||||
#define ai_chem_stims_when_hurt_little (1) // use only stimpak/super stimpak/healing powder
|
||||
#define ai_chem_stims_when_hurt_lots (2) // use only stimpak/super stimpak/healing powder
|
||||
#define ai_chem_sometimes (3)
|
||||
#define ai_chem_anytime (4)
|
||||
#define ai_chem_always (5)
|
||||
|
||||
// common object data offsets
|
||||
#define OBJ_DATA_ID (0x00)
|
||||
#define OBJ_DATA_TILENUM (0x04)
|
||||
|
||||
@@ -432,6 +432,14 @@ procedure array_transform_kv(variable arr, variable keyFunc, variable valueFunc)
|
||||
return retArr;
|
||||
end
|
||||
|
||||
procedure array_to_set(variable arr) begin
|
||||
variable v, retArr := temp_array_map;
|
||||
foreach (v in arr) begin
|
||||
retArr[v] := 1;
|
||||
end
|
||||
return retArr;
|
||||
end
|
||||
|
||||
|
||||
#define ARRAY_EMPTY_INDEX (-1)
|
||||
|
||||
@@ -614,9 +622,9 @@ end
|
||||
|
||||
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 _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, k, v, s, len;
|
||||
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+"): {";
|
||||
@@ -624,7 +632,8 @@ procedure debug_array_str_deep(variable arr, variable levels) begin
|
||||
_newline
|
||||
k := array_key(arr, i);
|
||||
v := get_array(arr, k);
|
||||
s += _indent + k + ": " + _value(v);
|
||||
_indent
|
||||
s += k + ": " + _value(v);
|
||||
if i < (len - 1) then s += ", ";
|
||||
i++;
|
||||
end
|
||||
@@ -637,7 +646,8 @@ procedure debug_array_str_deep(variable arr, variable levels) begin
|
||||
while i < len do begin
|
||||
_newline
|
||||
v := get_array(arr, i);
|
||||
s += _indent + _value(v);
|
||||
_indent
|
||||
s += _value(v);
|
||||
if i < (len - 1) then s += ", ";
|
||||
i++;
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define COUNTERWIN (0x100000) // counter window for moving multiple items or setting a timer
|
||||
#define SPECIAL (0x80000000)
|
||||
|
||||
// Valid arguments to register_hook
|
||||
// Valid arguments to register_hook_proc
|
||||
#define HOOK_TOHIT (0)
|
||||
#define HOOK_AFTERHITROLL (1)
|
||||
#define HOOK_CALCAPCOST (2)
|
||||
@@ -321,6 +321,7 @@
|
||||
#define get_inven_ap_cost sfall_func0("get_inven_ap_cost")
|
||||
#define get_map_enter_position sfall_func0("get_map_enter_position")
|
||||
#define get_metarule_table sfall_func0("get_metarule_table")
|
||||
#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_pc_stat_max(stat) sfall_func1("get_stat_max", stat)
|
||||
|
||||
@@ -249,27 +249,27 @@ FUNCTION REFERENCE
|
||||
|
||||
**Some additional `reg_anim_*` functions were introduced. They all work in the same convention as vanilla functions and use the same underlying code.**
|
||||
|
||||
##### `void reg_anim_destroy(object)`
|
||||
##### `void reg_anim_destroy(object obj)`
|
||||
- Given object is destroyed at the end of current animation set.
|
||||
|
||||
-----
|
||||
##### `void reg_anim_animate_and_hide(object, animID, delay)`
|
||||
##### `void reg_anim_animate_and_hide(object obj, int animID, int delay)`
|
||||
- Exactly like `reg_anim_animate` but the object will automatically disappear after the last animation frame (but not destroyed).
|
||||
|
||||
-----
|
||||
##### `void reg_anim_light(object, light, delay)`
|
||||
##### `void reg_anim_light(object obj, int light, int delay)`
|
||||
- Change light of any object. light argument is a light radius (0-8), but you can use highest 2 bytes to pass light intensity as well (example: `0xFFFF0008` - intensity 65535 and radius 8). If highest 2 bytes are 0, intensity will not be changed. Intensity range is from 0 to 65535 (0xFFFF).
|
||||
|
||||
-----
|
||||
##### `void reg_anim_change_fid(object, fid, delay)`
|
||||
##### `void reg_anim_change_fid(object obj, int fid, int delay)`
|
||||
- Should work like `art_change_fid_num` but in `reg_anim` sequence.
|
||||
|
||||
-----
|
||||
##### `void reg_anim_take_out(object, holdFrameID, delay)`
|
||||
##### `void reg_anim_take_out(object obj, holdFrameID, int delay)`
|
||||
- Plays "take out weapon" animation for given **holdFrameID**. It is not required to have such weapon in critter's inventory.
|
||||
|
||||
-----
|
||||
##### `void reg_anim_turn_towards(object, tile/target, delay)`
|
||||
##### `void reg_anim_turn_towards(object obj, int/object tile/target, int delay)`
|
||||
- Makes object change its direction to face given tile number or target object.
|
||||
|
||||
-----
|
||||
@@ -281,15 +281,15 @@ FUNCTION REFERENCE
|
||||
- Was made as a quick-and-dirty hack to enable dynamic changes to some explosion parameters for ranged attacks. All changed parameters are automatically reset to vanilla state after each attack action. Following macros are available in **sfall.h**:
|
||||
|
||||
-----
|
||||
##### `void set_attack_explosion_pattern(x, y)`
|
||||
##### `void set_attack_explosion_pattern(int x, int y)`
|
||||
- Currently `y` is not used and `x` means: 1 - reduced explosion pattern (3 effects are spawned instead of 7), 0 - full pattern.
|
||||
|
||||
-----
|
||||
##### `void set_attack_explosion_art(x, y)`
|
||||
##### `void set_attack_explosion_art(int x, int y)`
|
||||
- `y` is not used and `x` is a misc frame ID (last 3 bytes, without object type) to use for the next explosion.
|
||||
|
||||
-----
|
||||
##### `void set_attack_explosion_radius(x)`
|
||||
##### `void set_attack_explosion_radius(int x)`
|
||||
- Changes radius at which explosion will hit secondary targets for the next attack (from the experiments it is limited to something around 8 by the engine)
|
||||
|
||||
-----
|
||||
@@ -297,32 +297,32 @@ FUNCTION REFERENCE
|
||||
- If you call this right before using a weapon with fire damage type (e.g. in `HOOK_AFTERHITROLL`), it will produce explosion effects (and radius damage) just like "explosion" type, but all targets will still receive fire damage.
|
||||
|
||||
-----
|
||||
##### `void set_explosion_radius(grenade, rocket)`
|
||||
##### `void set_explosion_radius(int grenade, int rocket)`
|
||||
- Sets a permanent radius of the explosion for grenades and/or rockets. Passing 0 means not changing the corresponding radius.
|
||||
- Changed radius will be reset each time the player reloads the game.
|
||||
|
||||
-----
|
||||
##### `array get_explosion_damage(itemPid)`
|
||||
##### `array get_explosion_damage(int itemPid)`
|
||||
- Returns an array of the minimum and maximum damage of the explosive item.
|
||||
|
||||
-----
|
||||
##### `void set_dynamite_damage(minDmg, maxDmg)`
|
||||
##### `void set_dynamite_damage(int minDmg, int maxDmg)`
|
||||
- Sets the minimum and maximum damage for Dynamite.
|
||||
- Changed damage will be reset each time the player reloads the game.
|
||||
|
||||
-----
|
||||
##### `void set_plastic_damage(minDmg, maxDmg)`
|
||||
##### `void set_plastic_damage(int minDmg, int maxDmg)`
|
||||
- Sets the minimum and maximum damage for Plastic Explosives.
|
||||
- Changed damage will be reset each time the player reloads the game.
|
||||
|
||||
-----
|
||||
##### `void set_explosion_max_targets(x)`
|
||||
##### `void set_explosion_max_targets(int x)`
|
||||
- Sets the maximum number of additional targets for an explosion, valid range: 1..6 (default is 6)
|
||||
|
||||
---
|
||||
### Some utility/math functions are available:
|
||||
|
||||
##### `array string_split(string text, split)`
|
||||
##### `array string_split(string text, string split)`
|
||||
- Takes a string and a separator, searches the string for all instances of the separator, and returns a temp array filled with the pieces of the string split at each instance. If you give an empty string as the separator, the string is split into individual characters.
|
||||
- You can use this to search for a substring in a string like this: `strlen(get_array(string_split(haystack, needle), 0))`
|
||||
|
||||
@@ -494,7 +494,7 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### spatial_radius
|
||||
`int sfall_func1("spatial_radius", object object)`
|
||||
`int sfall_func1("spatial_radius", object obj)`
|
||||
- Returns radius of spatial script, associated with given dummy-object (returned by `create_spatial`)
|
||||
|
||||
----
|
||||
@@ -545,17 +545,17 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### item_weight
|
||||
`int sfall_func1("item_weight", object)`
|
||||
`int sfall_func1("item_weight", object obj)`
|
||||
- Gets the current weight of an object
|
||||
|
||||
----
|
||||
#### get_outline
|
||||
`int sfall_func1("get_outline", object)`
|
||||
`int sfall_func1("get_outline", object obj)`
|
||||
- Gets the current outline color for an object
|
||||
|
||||
----
|
||||
#### set_outline
|
||||
`void sfall_func2("set_outline", object, int color)`
|
||||
`void sfall_func2("set_outline", object obj, int color)`
|
||||
- Sets the outline color of an object (see `OUTLINE_*` constants in **sfall.h**)
|
||||
- Can also set a custom color from the game palette by shifting the color index value left by 8 bits: `0xCC00` where `CC` is the palette index (**available since sfall 4.2.7/3.8.27**)
|
||||
- Passing 0 will disable the outline
|
||||
@@ -563,12 +563,12 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### get_flags
|
||||
`int sfall_func1("get_flags", object)`
|
||||
`int sfall_func1("get_flags", object obj)`
|
||||
- Gets the current value of object flags (see **define_extra.h** for available flags)
|
||||
|
||||
-----
|
||||
##### set_flags
|
||||
`void sfall_func2("set_flags", object, int flags)`
|
||||
`void sfall_func2("set_flags", object obj, int flags)`
|
||||
- Sets the current flags of an object
|
||||
- All flags are rewritten with given integer, so first get current flags with `get_flags` and use `bwor`/`bwand` to set/remove specific flag
|
||||
|
||||
@@ -584,7 +584,7 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### set_dude_obj
|
||||
`object sfall_func1("set_dude_obj", critter)`
|
||||
`object sfall_func1("set_dude_obj", int critter)`
|
||||
- Take control of a given critter
|
||||
- Passing 0 will reset control back to "real" dude
|
||||
|
||||
@@ -638,12 +638,12 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### lock_is_jammed
|
||||
`int sfall_func1("lock_is_jammed", object)`
|
||||
`int sfall_func1("lock_is_jammed", object obj)`
|
||||
- Returns 1 if the lock (container or scenery) is currently jammed, 0 otherwise
|
||||
|
||||
----
|
||||
#### unjam_lock
|
||||
`void sfall_func1("unjam_lock", object)`
|
||||
`void sfall_func1("unjam_lock", object obj)`
|
||||
- Unjams a lock immediately without having to wait until the next day, or leave the map and then return after 24 hours
|
||||
- __NOTE:__ does not work in `use_skill_on_p_proc` procedure
|
||||
|
||||
@@ -731,7 +731,7 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### get_current_inven_size
|
||||
`int sfall_func1("get_current_inven_size", object)`
|
||||
`int sfall_func1("get_current_inven_size", object obj)`
|
||||
- Returns the current inventory size of the container or the critter
|
||||
|
||||
----
|
||||
@@ -778,14 +778,20 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### get_object_data
|
||||
`int sfall_func2("get_object_data", object, int offset)`
|
||||
`int sfall_func2("get_object_data", object obj, int offset)`
|
||||
- Returns the data at the specified offset of an object (see `OBJ_DATA_*` constants in **define_extra.h** for offsets)
|
||||
|
||||
----
|
||||
#### set_object_data (object, offset, data)
|
||||
`void sfall_func3("set_object_data", object, int offset, int data)`
|
||||
#### set_object_data
|
||||
`void sfall_func3("set_object_data", object obj, int offset, int data)`
|
||||
- Sets the data at the specified offset of an object
|
||||
|
||||
----
|
||||
#### get_object_ai_data
|
||||
`int sfall_func2("get_object_ai_data", object obj, int aiParam)`
|
||||
- Returns the setting value from the AI packet of an object (critter)
|
||||
- Use `AI_CAP_*` constants from **define_extra.h** for the aiParam argument to get AI value
|
||||
|
||||
-----
|
||||
##### art_cache_clear
|
||||
`void sfall_func0("art_cache_clear")`
|
||||
@@ -799,8 +805,8 @@ sfall_funcX metarule functions
|
||||
|
||||
----
|
||||
#### set_unique_id
|
||||
`int sfall_func1("set_unique_id", object)`\
|
||||
`int sfall_func2("set_unique_id", object, int flag)`
|
||||
`int sfall_func1("set_unique_id", object obj)`\
|
||||
`int sfall_func2("set_unique_id", object obj, int flag)`
|
||||
- Assigns a unique ID number to the object and returns it. If a unique ID number has already been assigned to an object, then ID number is returned without reassignment
|
||||
- Items with unique IDs will not stack with other items of the same type in the inventory
|
||||
- To just get the current ID number of an object, use `sfall_func2("get_object_data", object, OBJ_DATA_ID)`
|
||||
|
||||
@@ -96,7 +96,7 @@ void mf_critter_inven_obj2(OpcodeContext& ctx) {
|
||||
ctx.setReturn(critter->invenSize);
|
||||
break;
|
||||
default:
|
||||
ctx.printOpcodeError("%s() - invalid type.", ctx.getMetaruleName());
|
||||
ctx.printOpcodeError("%s() - invalid type number.", ctx.getMetaruleName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"get_inven_ap_cost", mf_get_inven_ap_cost, 0, 0},
|
||||
{"get_map_enter_position", mf_get_map_enter_position, 0, 0},
|
||||
{"get_metarule_table", mf_get_metarule_table, 0, 0},
|
||||
{"get_object_ai_data", mf_get_object_ai_data, 2, 2, -1, {ARG_OBJECT, ARG_INT}},
|
||||
{"get_object_data", mf_get_object_data, 2, 2, 0, {ARG_OBJECT, ARG_INT}},
|
||||
{"get_outline", mf_get_outline, 1, 1, 0, {ARG_OBJECT}},
|
||||
{"get_sfall_arg_at", mf_get_sfall_arg_at, 1, 1, 0, {ARG_INT}},
|
||||
|
||||
@@ -486,6 +486,65 @@ void mf_set_object_data(OpcodeContext& ctx) {
|
||||
*(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue()) = ctx.arg(2).rawValue();
|
||||
}
|
||||
|
||||
void mf_get_object_ai_data(OpcodeContext& ctx) {
|
||||
fo::AIcap* cap = fo::func::ai_cap(ctx.arg(0).object());
|
||||
DWORD arrayId, value = -1;
|
||||
switch (ctx.arg(1).rawValue()) {
|
||||
case 0:
|
||||
value = cap->aggression;
|
||||
break;
|
||||
case 1:
|
||||
value = (long)cap->area_attack_mode;
|
||||
break;
|
||||
case 2:
|
||||
value = (long)cap->attack_who;
|
||||
break;
|
||||
case 3:
|
||||
value = (long)cap->pref_weapon;
|
||||
break;
|
||||
case 4:
|
||||
value = (long)cap->chem_use;
|
||||
break;
|
||||
case 5:
|
||||
value = (long)cap->disposition;
|
||||
break;
|
||||
case 6:
|
||||
value = (long)cap->distance;
|
||||
break;
|
||||
case 7:
|
||||
value = cap->max_dist;
|
||||
break;
|
||||
case 8:
|
||||
value = cap->min_hp;
|
||||
break;
|
||||
case 9:
|
||||
value = cap->min_to_hit;
|
||||
break;
|
||||
case 10:
|
||||
value = cap->hurt_too_much; // DAM_BLIND/DAM_CRIP_* flags
|
||||
break;
|
||||
case 11:
|
||||
value = (long)cap->run_away_mode;
|
||||
break;
|
||||
case 12:
|
||||
value = cap->secondary_freq;
|
||||
break;
|
||||
case 13:
|
||||
value = cap->called_freq;
|
||||
break;
|
||||
case 14:
|
||||
arrayId = CreateTempArray(3, 0);
|
||||
arrays[arrayId].val[0].set(cap->chem_primary_desire[0]);
|
||||
arrays[arrayId].val[1].set(cap->chem_primary_desire[1]);
|
||||
arrays[arrayId].val[2].set(cap->chem_primary_desire[2]);
|
||||
value = arrayId;
|
||||
break;
|
||||
default:
|
||||
ctx.printOpcodeError("%s() - invalid aiParam number.", ctx.getMetaruleName());
|
||||
}
|
||||
ctx.setReturn(value);
|
||||
}
|
||||
|
||||
void mf_set_unique_id(OpcodeContext& ctx) {
|
||||
fo::GameObject* obj = ctx.arg(0).object();
|
||||
long id;
|
||||
|
||||
@@ -97,6 +97,8 @@ void mf_get_object_data(OpcodeContext&);
|
||||
|
||||
void mf_set_object_data(OpcodeContext&);
|
||||
|
||||
void mf_get_object_ai_data(OpcodeContext&);
|
||||
|
||||
void mf_set_unique_id(OpcodeContext&);
|
||||
|
||||
void mf_objects_in_radius(OpcodeContext&);
|
||||
|
||||
@@ -209,13 +209,13 @@ void mf_set_rest_mode(OpcodeContext& ctx) {
|
||||
void mf_set_rest_on_map(OpcodeContext& ctx) {
|
||||
long mapId = ctx.arg(0).rawValue();
|
||||
if (mapId < 0) {
|
||||
ctx.printOpcodeError("%s() - invalid map number argument.", ctx.getMetaruleName());
|
||||
ctx.printOpcodeError("%s() - invalid map number.", ctx.getMetaruleName());
|
||||
ctx.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
long elev = ctx.arg(1).rawValue();
|
||||
if (elev < -1 || elev > 2) {
|
||||
ctx.printOpcodeError("%s() - invalid map elevation argument.", ctx.getMetaruleName());
|
||||
ctx.printOpcodeError("%s() - invalid map elevation.", ctx.getMetaruleName());
|
||||
ctx.setReturn(-1);
|
||||
} else {
|
||||
Worldmap::SetRestMapLevel(mapId, elev, ctx.arg(2).asBool());
|
||||
@@ -226,7 +226,7 @@ void mf_get_rest_on_map(OpcodeContext& ctx) {
|
||||
long result = -1;
|
||||
long elev = ctx.arg(1).rawValue();
|
||||
if (elev < 0 || elev > 2) {
|
||||
ctx.printOpcodeError("%s() - invalid map elevation argument.", ctx.getMetaruleName());
|
||||
ctx.printOpcodeError("%s() - invalid map elevation.", ctx.getMetaruleName());
|
||||
} else {
|
||||
result = Worldmap::GetRestMapLevel(elev, ctx.arg(0).rawValue());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user