mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "get/set_object_data" and "get_object_ai_data" script functions (from Mr.Stalin)
Changed read_byte, read_short, read_int, and read_string functions to not require AllowUnsafeScripting.
This commit is contained in:
@@ -267,7 +267,98 @@
|
||||
#define WPN_ANIM_MINIGUN (0x09) // (L)
|
||||
#define WPN_ANIM_ROCKET_LAUNCHER (0x0A) // (M)
|
||||
|
||||
// Compute attack result fields
|
||||
// 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_no_pref (-1)
|
||||
#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 (0)
|
||||
#define ai_disposition_custom (1)
|
||||
#define ai_disposition_coward (2)
|
||||
#define ai_disposition_defensive (3)
|
||||
#define ai_disposition_aggressive (4)
|
||||
#define ai_disposition_berserk (5)
|
||||
|
||||
// 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_TILENUM (0x04)
|
||||
#define OBJ_DATA_CUR_FRM (0x18) // current frame number
|
||||
#define OBJ_DATA_ROTATION (0x1C)
|
||||
#define OBJ_DATA_FID (0x20)
|
||||
#define OBJ_DATA_ELEVATION (0x28)
|
||||
#define OBJ_DATA_PID (0x64)
|
||||
#define OBJ_DATA_CID (0x68)
|
||||
#define OBJ_DATA_SID (0x78)
|
||||
// items
|
||||
#define OBJ_DATA_CUR_CHARGES (0x3C)
|
||||
// critters
|
||||
#define OBJ_DATA_COMBAT_STATE (0x3C) // flags: 1 - combat, 2 - target is out of range, 4 - flee
|
||||
#define OBJ_DATA_CUR_ACTION_POINT (0x40)
|
||||
#define OBJ_DATA_DAMAGE_LAST_TURN (0x48)
|
||||
#define OBJ_DATA_WHO_HIT_ME (0x54)
|
||||
|
||||
// compute attack result data offsets
|
||||
#define C_ATTACK_SOURCE (0x00)
|
||||
#define C_ATTACK_HIT_MODE (0x04)
|
||||
#define C_ATTACK_WEAPON (0x08)
|
||||
|
||||
@@ -246,6 +246,8 @@
|
||||
#define get_ini_section(file, sect) sfall_func2("get_ini_section", file, sect)
|
||||
#define get_ini_sections(file) sfall_func1("get_ini_sections", file)
|
||||
#define get_map_enter_position sfall_func0("get_map_enter_position")
|
||||
#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_string_pointer(text) sfall_func1("get_string_pointer", text)
|
||||
#define intface_hide sfall_func0("intface_hide")
|
||||
@@ -268,6 +270,7 @@
|
||||
#define set_iface_tag_text(tag, text, color) sfall_func3("set_iface_tag_text", tag, text, color)
|
||||
#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value)
|
||||
#define set_map_enter_position(tile, elev, rot) sfall_func3("set_map_enter_position", tile, elev, rot)
|
||||
#define set_object_data(obj, offset, value) sfall_func3("set_object_data", obj, offset, value)
|
||||
#define set_outline(obj, color) sfall_func2("set_outline", obj, color)
|
||||
#define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time)
|
||||
#define set_rest_mode(mode) sfall_func1("set_rest_mode", mode)
|
||||
|
||||
@@ -598,7 +598,7 @@ int arg6 - Target's Damage Resistance (DR) value (affected by critical hit e
|
||||
int arg7 - Target's Damage Threshold (DT) value (affected by critical hit effects, perks, traits, and special unarmed attacks)
|
||||
int arg8 - Bonus ranged damage from the perk
|
||||
int arg9 - Damage Multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2; for critical hits, the value is taken from the critical table; with Silent Death perk and the corresponding attack conditions, the value will be doubled)
|
||||
int arg10 - Combat Difficulty multiplier (125 - rough, 100 - normal, 75 - wimpy)
|
||||
int arg10 - Combat Difficulty multiplier (125 - rough, 100 - normal, 75 - wimpy; for player or party members it's always 100)
|
||||
int arg11 - The calculated amount of damage (usually 0, required when using multiple hook scripts to calculate damage and using the set_sfall_arg function)
|
||||
mixed arg12 - Computed attack results (see C_ATTACK_* for offsets and use read_int(arg12 + offset) to get the data)
|
||||
|
||||
|
||||
@@ -550,6 +550,16 @@ Some utility/math functions are available:
|
||||
> object sfall_func0("loot_obj")
|
||||
- returns a pointer to the target object (container or critter) of the loot screen
|
||||
|
||||
> int sfall_func2("get_object_data", object, int offset)
|
||||
- returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets)
|
||||
|
||||
> void sfall_func3("set_object_data", object, int offset, int data)
|
||||
- sets the data at the specified offset of an object
|
||||
|
||||
> int sfall_func2("get_object_ai_data", object, 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
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
*0x8156 - int read_byte(int address)
|
||||
*0x8157 - int read_short(int address)
|
||||
*0x8158 - int read_int(int address)
|
||||
*0x8159 - string read_string(int address)
|
||||
0x8156 - int read_byte(int address)
|
||||
0x8157 - int read_short(int address)
|
||||
0x8158 - int read_int(int address)
|
||||
0x8159 - string read_string(int address)
|
||||
|
||||
*0x81cf - void write_byte(int address, int value)
|
||||
*0x81d0 - void write_short(int address, int value)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
NOTES: be careful not to use reserved words, including ASM instructions (push, pop, mov, div, etc.)
|
||||
*/
|
||||
|
||||
WRAP_WATCOM_FUNC1(AIcap*, ai_cap, GameObject*, critter)
|
||||
WRAP_WATCOM_FUNC1(Program*, allocateProgram, const char*, filePath)
|
||||
WRAP_WATCOM_FUNC0(void, art_flush)
|
||||
WRAP_WATCOM_FUNC5(long, art_id, long, artType, long, lstIndex, long, animCode, long, weaponCode, long, directionCode)
|
||||
|
||||
@@ -664,4 +664,34 @@ struct LSData {
|
||||
char mapName[16];
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct AIcap {
|
||||
long name;
|
||||
long packet_num;
|
||||
long max_dist;
|
||||
long min_to_hit;
|
||||
long min_hp;
|
||||
long aggression;
|
||||
long hurt_too_much;
|
||||
long secondary_freq;
|
||||
long called_freq;
|
||||
long font;
|
||||
long color;
|
||||
long outline_color;
|
||||
long chance;
|
||||
long combat_message_data[24];
|
||||
long area_attack_mode;
|
||||
long run_away_mode;
|
||||
long best_weapon;
|
||||
long distance;
|
||||
long attack_who;
|
||||
long chem_use;
|
||||
long chem_primary_desire;
|
||||
long chem_primary_desire1;
|
||||
long chem_primary_desire2;
|
||||
long disposition;
|
||||
long body_type;
|
||||
long general_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -460,5 +460,74 @@ void sf_get_loot_object(OpcodeContext& ctx) {
|
||||
ctx.setReturn((GetLoopFlags() & INTFACELOOT) ? LoadGameHook::LootTarget : 0);
|
||||
}
|
||||
|
||||
void sf_get_object_data(OpcodeContext& ctx) {
|
||||
BYTE* object_ptr = (BYTE*)ctx.arg(0).asObject();
|
||||
ctx.setReturn(*(long*)(object_ptr + ctx.arg(1).asInt()), DataType::INT);
|
||||
}
|
||||
|
||||
void sf_set_object_data(OpcodeContext& ctx) {
|
||||
BYTE* object_ptr = (BYTE*)ctx.arg(0).asObject();
|
||||
*(long*)(object_ptr + ctx.arg(1).asInt()) = ctx.arg(2).asInt();
|
||||
}
|
||||
|
||||
void sf_get_object_ai_data(OpcodeContext& ctx) {
|
||||
fo::AIcap* cap = fo::func::ai_cap(ctx.arg(0).asObject());
|
||||
DWORD arrayId, value = -1;
|
||||
switch (ctx.arg(1).asInt()) {
|
||||
case 0:
|
||||
value = cap->aggression;
|
||||
break;
|
||||
case 1:
|
||||
value = cap->area_attack_mode;
|
||||
break;
|
||||
case 2:
|
||||
value = cap->attack_who;
|
||||
break;
|
||||
case 3:
|
||||
value = cap->best_weapon;
|
||||
break;
|
||||
case 4:
|
||||
value = cap->chem_use;
|
||||
break;
|
||||
case 5:
|
||||
value = cap->disposition;
|
||||
break;
|
||||
case 6:
|
||||
value = 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 = cap->run_away_mode;
|
||||
break;
|
||||
case 12:
|
||||
value = cap->secondary_freq;
|
||||
break;
|
||||
case 13:
|
||||
value = cap->called_freq;
|
||||
break;
|
||||
case 14:
|
||||
arrayId = TempArray(3, 0);
|
||||
arrays[arrayId].val[0].set(cap->chem_primary_desire);
|
||||
arrays[arrayId].val[1].set(cap->chem_primary_desire1);
|
||||
arrays[arrayId].val[2].set(cap->chem_primary_desire2);
|
||||
value = arrayId;
|
||||
break;
|
||||
default:
|
||||
ctx.printOpcodeError("get_object_ai_data() - invalid AI parameter.");
|
||||
}
|
||||
ctx.setReturn(value, DataType::INT);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,5 +99,11 @@ void sf_get_dialog_object(OpcodeContext&);
|
||||
|
||||
void sf_get_loot_object(OpcodeContext&);
|
||||
|
||||
void sf_get_object_data(OpcodeContext&);
|
||||
|
||||
void sf_set_object_data(OpcodeContext&);
|
||||
|
||||
void sf_get_object_ai_data(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,12 +233,10 @@ void InitNewOpcodes() {
|
||||
SafeWrite32(0x46ce6c, (DWORD)opcodes); //call that actually jumps to the opcode
|
||||
SafeWrite32(0x46e390, (DWORD)opcodes); //mov that writes to the opcode
|
||||
|
||||
if (AllowUnsafeScripting) {
|
||||
opcodes[0x156] = op_read_byte;
|
||||
opcodes[0x157] = op_read_short;
|
||||
opcodes[0x158] = op_read_int;
|
||||
opcodes[0x159] = op_read_string;
|
||||
}
|
||||
opcodes[0x156] = op_read_byte;
|
||||
opcodes[0x157] = op_read_short;
|
||||
opcodes[0x158] = op_read_int;
|
||||
opcodes[0x159] = op_read_string;
|
||||
opcodes[0x15a] = op_set_pc_base_stat;
|
||||
opcodes[0x15b] = op_set_pc_extra_stat;
|
||||
opcodes[0x15c] = op_get_pc_base_stat;
|
||||
|
||||
Reference in New Issue
Block a user