Files
sfall/artifacts/scripting/hookscripts.txt
T

481 lines
22 KiB
Plaintext

-------------------------------------
----------- WHAT IS THIS? -----------
-------------------------------------
Hook scripts are specially named scripts that are run by sfall at specific points to allow mods to override normally hardcoded behaviour in a more flexible way than sfall's normal ini configuration.
In addition to the bit of code it overrides, the script will be run once when first loaded and again at each player reload to allow for setup. Hook scripts have access to a set of arguments supplied to sfall, but aren't required to use them all. They also return one or more values, but again they're optional, and you only need to return a value if you want to override the default.
To aid in mods compatibility, avoid using hs_xxx .int scripts. Instead it is recommended to use a normal global script combined with register_hook_proc or register_hook.
Example setup for a hook-script based mod:
procedure tohit_hook_handler begin
display_msg("Modifying hit_hook " + get_sfall_arg);
set_hit_chance_max(100);
set_sfall_return(100);
end
procedure start begin
if game_loaded then begin
register_hook_proc(HOOK_TOHIT, tohit_hook_handler);
end
end
There are script functions available, specific to hook scripts:
> int init_hook()
The hook script equivilent of game_loaded; it returns 2 when the script is first loaded, 1 when the player reloads and 0 otherwise.
> mixed get_sfall_arg()
Gets the next argument from sfall. Each time it's called it returns the next argument, or otherwise it returns 0 if there are no more arguments left.
> array get_sfall_args()
Returns all hook arguments as a new temp array.
> void set_sfall_return(int value)
Used to return the new values from the script. Each time it's called it sets the next value, or if you've already set all return values it does nothing.
> void set_sfall_arg(int argnum, int value)
Changes argument value. This is usefull if you have several hook scripts attached to one hook point (see below).
> void register_hook(int hooktype)
Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, "start" proc will be execuded in a current global script. You can use all above functions like normal.
> void register_hook_proc(int hooktype, proc procedure)
The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of "start"). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script, no conflicts if you don't use "hs_*.int" scripts) and flexibility (you can place all related hook scripts for specific mod in a single script!).
NOTE: you can hook several scripts to a single hook point, for example if it's different mods from different authors or just some different aspects of one larger mod. In this case scripts are executed in reverse order of how they were registered. When one of the scripts in a chain returns value with "set_sfall_return", the next script may override this value if calls "set_sfall_return" again. Sometimes you need to multiply certain value in a chain of hook scripts.
Example: let's say we have a Mod A which reduces all "to hit" chances by 50%. The code might look like this:
original_chance = get_sfall_arg;
set_sfall_return(original_chance / 2);
Mod B also want to affect hit chances globally, by increasing them by 50%. Now in order for both mods to work well together, we need to add this line to Mod A hook script:
set_sfall_arg(original_chance / 2);
This basically changes hook argument for the next script. Mod B code:
original_chance = get_sfall_arg;
set_sfall_return(original_chance * 1.5);
set_sfall_arg(original_chance * 1.5);
So if you combine both mods together, they will run in chain and the end result will be a 75% from original hit chance (hook register order doesn't matter in this case, if you use "set_sfall_arg" in both hooks).
The defines to use for the hooktype are in sfall.h.
-------------------------------------------
----------- HOOK SCRIPT TYPES -------------
-------------------------------------------
HOOK_TOHIT (hs_tohit.int)
Runs when fallout is calculating the chances of an attack striking a target
Runs after the hit chance is fully calculated normally, including applying the 95% cap
int arg1 - The unmodified hit chance
critter arg2 - The attacker
critter arg3 - The target of the attack
int arg4 - The targeted bodypart
int arg5 - Source tile (may differ from attacker's tile, when AI is considering potential fire position)
int arg6 - Attack Type (one of ATKTYPE_*)
int arg7 - Ranged flag (0 or 1, actually passed 1 even for unarmed attacks, may be a vanilla bug)
int ret1 - the new hit chance
-------------------------------------------
HOOK_AFTERHITROLL (hs_afterhitroll.int)
Runs after fallout has decided if an attack will hit or miss
int arg1 - If the attack will hit. (0 - critical miss, 1 - miss, 2 - hit, 3 - critical hit)
critter arg2 - The attacker
critter arg3 - The target of the attack
int arg4 - The bodypart
int arg5 - The hit chance
int ret1 - Override the hit/miss
int ret2 - Override the targeted bodypart
critter ret3 - Override the target of the attack
-------------------------------------------
HOOK_CALCAPCOST (hs_calcapcost.int)
Runs whenever fallout is calculating the ap cost of using the weapon (or unarmed attack). Doesn't run for using other item types or moving.
Note that the first time a game is loaded, this script doesn't run before the initial interface is drawn, so if the script effects the ap cost of whatever is in the players hands at the time the wrong ap cost will be shown. It will be fixed the next time the interface is redrawn.
You can get the weapon object by checking item slot based on attack type (ATKTYPE_LWEP1, ATKTYPE_LWEP2, etc) and then calling critter_inven_obj().
critter arg1 - The critter performing the action
int arg2 - Attack Type (see ATKTYPE_* constants)
int arg3 - Is aimed attack (1 or 0)
int arg4 - The normal ap cost
int ret1 - The new ap cost
-------------------------------------------
HOOK_DEATHANIM1 (hs_deathanim1.int)
Runs before fallout tries to calculate the death animation. Lets you switch out which weapon fallout sees
int arg1 - The pid of the weapon performing the attack. (May be -1 if the attack is unarmed)
critter arg2 - The attacker
critter arg3 - The target
int arg4 - The amount of damage
int ret1 - The pid of an object to override the attacking weapon with
-------------------------------------------
HOOK_DEATHANIM2 (hs_deathanim2.int)
Runs after fallout has calculated the death animation. Lets you set your own custom frame id, so more powerful than hs_deathanim1, but performs no validation.
When using critter_dmg function, this script will also run. In that case weapon pid will be -1 and target will point to an object with obj_art_fid == 0x20001F5.
item arg1 - The pid of the weapon performing the attack. (May be -1 if the attack is unarmed)
critter arg2 - The attacker
critter arg3 - The target
int arg4 - The amount of damage
int arg5 - The death anim id calculated by fallout
int ret1 - The death anim id to override with
-------------------------------------------
HOOK_COMBATDAMAGE (hs_combatdamage.int)
Runs when:
1) Game calculates how much damage each target will get. This includes primary target as well as all extras (explosions and bursts). This happens BEFORE the actual attack animation.
2) AI decides whether it is safe to use area attack (burst, grenades), if he might hit friendlies.
Does not run for misses, or non-combat damage like dynamite explosions.
critter arg1 - The target
critter arg2 - The attacker
int arg3 - The amount of damage to the target
int arg4 - The amount of damage to the attacker
int arg5 - The special effect flags for the target
int arg6 - The special effect flags for the attacker
int arg7 - The weapon used in the attack
int arg8 - The bodypart that was struck
int arg9 - Roll result of the attack (check with is_success, etc functions; basically: 0-crit. fail, 1-fail, 2-success, 3-crit. success)
int arg10 - Number of bullets actually hit the target (1 for melee attacks)
int arg11 - The amount of knockback to the target
int ret1 - The damage to the target
int ret2 - The damage to the attacker
int ret3 - The special effect flags for the target
int ret4 - The special effect flags for the attacker
int ret5 - The amount of knockback to the target
-------------------------------------------
HOOK_ONDEATH (hs_ondeath.int)
Runs immediately after a critter dies for any reason. No return values; this is just a convinence for when you need to do something after death for a large number of different critters and don't want to have to script each and every one of them.
Critter arg1 - The critter that just died
-------------------------------------------
HOOK_FINDTARGET (hs_findtarget.int)
Runs when the ai is trying to pick a target in combat. Fallout first chooses a list of 4 likely suspects, then normally sorts them in order of weakness/distance/etc depending on the ai caps of the attacker. This hook replaces that sorting function, allowing you to sort the targets in some arbitrary way. Use sfall_return to give the 4 targets, in order of preference. All 4 must be given if you want to override normal sorting; if you want to specify less than 4 targets fill in the extra spaces with 0's. If you do not give 4 targets, the npcs normal sorting mechanism will be used.
The return values can include critters that weren't in the list of possible targets, but the additional targets may still be discarded later on in the combat turn if they are out of the attackers perception or the chance of a successful hit is too low. The list of possible targets often includes duplicated entries.
critter arg1 - The attacker
critter arg2 - A possible target
critter arg3 - A possible target
critter arg4 - A possible target
critter arg5 - A possible target
critter ret1 - The first choice of target
critter ret2 - The second choice of target
critter ret3 - The third choice of target
critter ret4 - The fourth choice of target
-------------------------------------------
HOOK_USEOBJON (hs_useobjon.int)
Runs when:
1) a critter uses an object on another critter. (Or themselves)
2) a critter uses an object from inventory screen AND this object does not have "Use" action flag set and it's not active flare or explosive.
3) player or AI uses any drug
This is fired before the object is used, and the relevent use_obj_on script procedures are run. You can disable default item behavior.
NOTE: you can't remove and/or destroy this object during the hookscript (game will crash otherwise). To remove it, return 1.
Critter arg1 - The target
Critter arg2 - The user
int arg3 - The object used
int ret1 - overrides hard-coded handler and selects what should happen with the item (0 - place it back, 1 - remove it, -1 - use engine handler)
-------------------------------------------
HOOK_USEOBJ (hs_useobj.int)
Runs when:
1) a critter uses an object from inventory which have "Use" action flag set or it's an active flare or dynamite.
2) player uses an object from main interface
This is fired before the object is used, and the relevent use_obj script procedures are run. You can disable default item behavior.
NOTE: you can't remove and/or destroy this object during the hookscript (game will crash otherwise). To remove it, return 1.
Critter arg1 - The user
int arg2 - The object used
int ret1 - overrides hard-coded handler and selects what should happen with the item (0 - place it back, 1 - remove it, -1 - use engine handler)
-------------------------------------------
HOOK_REMOVEINVENOBJ (hs_removeinvenobj.int)
Runs when an object is removed from a critters inventory for any reason
critter arg1 - the critter the object is being removed from
item arg2 - the item that is being removed
int arg3 - a flag, or possibly the number of items to remove
int arg4 - The reason the object is being removed. (Actually, the site from which _item_remove_mult was called)
-------------------------------------------
HOOK_BARTERPRICE (hs_barterprice.int)
Runs whenever the value of goods being purchased is calculated
critter arg1 - the critter doing the bartering (either dude_obj or inven_dude)
critter arg2 - the critter being bartered with
int arg3 - the default value of the goods
critter arg4 - table of requested goods (being bought from NPC)
int arg5 - the amount of actual caps in the barter stack (as opposed to goods)
int arg6 - the value of all goods being traded before skill modifications
critter arg7 - table of offered goods (being sold to NPC)
int arg8 - the total cost of the goods offered by the player
int arg9 - set 1 if the "offers" button was pressed(not for a party member), otherwise 0
int ret1 - the modified value of all of the goods
-------------------------------------------
HOOK_MOVECOST (hs_movecost.int)
Runs when calculating the ap cost of movement
Critter arg1 - the critter doing the moving
int arg2 - the number of hexes being moved
int arg3 - the original ap cost
int ret1 - the new ap cost
-------------------------------------------
(DEPRECATED)
hs_hexmoveblocking.int
hs_hexaiblocking.int
hs_hexshootblocking.int
hs_hexsightblocking.int
Runs when checking to see if a hex blocks movement or shooting. (or ai-ing, presumably...)
NOTE: these hook scripts can become very CPU-intensive and you should avoid using them.
For this reason, they may be removed in future versions.
If you want to check if some tile or path is blocked, use functions: obj_blocking_tile, obj_blocking_line, path_find_to.
If you want script to be called every time NPC moves by hex in combat, use hs_movecost hook.
Critter arg1 - the critter doing the moving
int arg2 - the tile number being checked
int arg3 - the elevation being checked
int arg4 - 1 if the hex would normally be blocking
object* ret1 - 0 if the hex doesn't block, or any sort of object pointer if it does
-------------------------------------------
HOOK_ITEMDAMAGE (hs_itemdamage.int)
Runs when retriving the damage rating of the players used weapon. (Which may be their fists.)
int arg1 - The default min damage
int arg2 - The default max damage
Item arg3 - The weapin used. (0 if unarmed)
Critter arg4 - The critter doing the attacking
int arg5 - The type of attack
int arg6 - non zero if this is an attack using a melee weapon
int ret1 - Either the damage to be used, if ret2 isn't given, or the new minimum damage if it is
int ret2 - The new maximum damage
-------------------------------------------
HOOK_AMMOCOST (hs_ammocost.int)
Runs when calculating ammo cost for a weapon. Doesn't affect damage, only how much ammo is spent.
By default, weapon will shoot when at least 1 round is left, regardless of ammo cost calculations.
To add proper check for ammo before shooting and proper calculation of number of burst rounds, set Misc.CheckWeaponAmmoCost=1 in ddraw.ini
Item arg1 - weapon
int arg2 - Number of bullets in burst (1 for single shots)
int arg3 - Ammo cost calculated by original function (this is basically 2 for Super Cattle Prod and Mega Power Fist)
int arg4 - Type of hook (0 - when substracting ammo after attack, 1 - when checking for "out of ammo" before attack)
int ret1 - new ammo cost value (set to 0 for unlimited ammo)
-------------------------------------------
HOOK_KEYPRESS (hs_keypress.int)
Runs once every time when any key was pressed or released.
DX codes: (see dik.h header)
VK codes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx
int arg1 - event type: 1 - pressed, 0 - released
int arg2 - key DX scancode
int arg3 - key VK code (very similar to ASCII codes)
-------------------------------------------
HOOK_MOUSECLICK (hs_mouseclick.int)
Runs once every time when a mouse button was pressed or release.
int arg1 - event type: 1 - pressed, 0 - released
int arg2 - button number (0 - left, 1 - right, up to 7)
-------------------------------------------
HOOK_USESKILL (hs_useskill.int)
Runs when using any skill on any object.
This is fired before the default handlers are called, which you can override. In this case you should write your own skill use handler entirely, or otherwise nothing will happen (this includes fade in/fade out, time lapsing and messages - all of this can be scripted; to get vanilla text messages - use message_str_game() along with sprintf()).
Suggested use - override first aid/doctor skills to buff/nerf them, override steal skill to disallow observing NPCs inventories in some cases.
Doesn't seem to run when lock picking.
Critter arg1 - The user critter
Obj arg2 - The target object
int arg3 - skill being used
int arg4 - skill bonus from items such as first aid kits
int ret1 - overrides hard-coded handler (-1 - use engine handler, any other value - override)
-------------------------------------------
HOOK_STEAL (hs_steal.int)
Runs when checking an attempt to steal or plant an item in other inventory using Steal skill.
This is fired before the default handlers are called, which you can override. In this case you MUST provide message of the result to player ("You steal the %s", "You are caught planting the %s", etc.).
Example message (vanilla behavior): display_msg(sprintf(mstr_skill(570 + (isSuccess != false) + arg4*2), obj_name(arg3)));
Critter arg1 - Thief
Obj arg2 - The target
Item arg3 - Item being stolen/planted
int arg4 - 0 when stealing, 1 when planting
int ret1 - overrides hard-coded handler (1 - force success, 0 - force fail, -1 - use engine handler)
-------------------------------------------
HOOK_WITHINPERCEPTION (hs_withinperception.int)
Runs when checking if one critter sees another critter. This is used in different situations like combat AI. You can override the result.
NOTE: obj_can_see_obj calls this first when deciding if critter can possibly see another critter with regard to perception, lighting, sneak factors. If check fails, the end result is false. If check succeeds (eg. critter is within perception range), another check is made if there is any blocking tile between two critters (which includes stuff like windows, large bushes, barrels, etc.) and if there is - check still fails. You can override "within perception" check by returning 0 or 1, OR, as a convenience, you can also override blocking check after the perception check by returning 2 instead. In this case you should add "line of sight" check inside your hook script, otherwise critters will detect you through walls.
This is fired after the default calculation is made.
Critter arg1 - Watcher object
Obj arg2 - Target objet
int arg3 - Result of vanilla function: 1 - within perception range, 0 - otherwise
int ret1 - overrides the returned result of the function: 0 - not in range (can't see), 1 - in range (will see if not blocked), 2 - forced detection (will see regardless, only used in obj_can_see_obj scripting function which is called by every critter in the game)
-------------------------------------------
HOOK_INVENTORYMOVE (hs_inventorymove.int)
Runs before moving items between inventory slots in dude interface. You can override the action.
What you can NOT do with this hook:
- force moving items to inapropriate slots (like gun in armor slot)
- block picking up items
What you can do:
- restrict player from using specific weapons or armors
- add AP costs for all inventory movement including reloading
- apply or remove some special scripted effects depending on PC's armor
int arg1 - Target slot (0 - main backpack, 1 - left hand, 2 - right hand, 3 - armor slot, 4 - weapon, when reloading it by dropping ammo)
Item arg2 - Item being moved
Item arg3 - Item being replaced or weapon being reloaded (can be 0)
int ret1 - Override setting (-1 - use engine handler, any other value - prevent relocation of item/reloading weapon)
-------------------------------------------
HOOK_INVENWIELD (hs_invenwield.int)
Runs before wielding or unwielding an armor or a weapon by a critter (except when using inventory by PC).
An example usage would be to change critter art depending on armor being used or to dynamically customize weapon animations.
NOTE: when replacing a previously wielded armor or weapon, the unwielding hook will not be executed.
If you need to rely on this, try checking if armor/weapon already equipped when wielding hook is executed.
Critter arg1 - critter
Obj arg2 - item being wielded or unwielded (weapon/armor), may be 0 when unwielding
int arg3 - slot (INVEN_TYPE_*)
int arg4 - 1 when wielding, 0 when unwielding
int ret1 - overrides hard-coded handler (-1 - use engine handler, any other value - override) - NOT RECOMMENDED
-------------------------------------------
HOOK_ADJUSTFID (hs_adjustfid.int)
Runs after calculating character figure FID on the inventory screen, whenever the game decides that character appearance might change.
Also happens on other screens, like barter.
NOTE: FID has following format: 0x0ABBCDDD, where A is object type, BB - animation code (always 0 in this case), C - weapon code, DDD - FRM index in LST file.
int arg1 - the vanilla fid calculated by the engine according to critter base FID and armor/weapon being used
int ret1 - overrides the calculated FID with provided value
-------------------------------------------
HOOK_COMBATTURN (hs_combatturn.int)
Runs before and after each turn in combat (for both PC and NPC).
int arg1 - event type: 1 - start of turn, 0 - normal end of turn, -1 - combat ended abruptly (by script or by pressing Enter during PC turn)
int arg2 - critter doing the turn
int arg3 - unknown boolean argument
int ret1 - pass 1 at the start of turn to skip the turn, pass -1 at the end of turn to force end of combat
-------------------------------------------
HOOK_CARTRAVEL (hs_cartravel.int)
Runs continously during worldmap travel on car.
int arg1 - vanilla car speed (between 3 and 8 "steps")
int arg2 - vanilla fuel consumption (100 and below)
int ret1 - car speed override (pass -1 if you just want to override fuel consumption)
int ret2 - fuel consumption override