Dependencies: lib_2da, lib_anon, lib_array, lib_fn, lib_ini, lib_sfo, lib_struct, lib_sugar, lib_tools
This are edited versions of Cam's DELETE/CLONE/ALTER_EFFECT (shipped with WEIDU) that allows for finer control on the savingthrow and special fields, and also to check the value of a function ('match_function') and apply one ('function'). Functions can be anonymous.
Technically this library depends on lib_anon (and, via that, on lib_sugar, lib_tools and lib_fn), but this only applies if you use anonymous functions. Without them, this is self-contained.
ALTER_EFFECT(check_globals:i=1, check_headers:i=1, header:i="-1", header_type:i="-1", multi_match:i=999, verbose:i, silent:i, match_opcode:i="-1", match_target:i="-1", match_power:i="-1", match_parameter1:i="-1", match_parameter2:i="-1", match_timing:i="-1", match_resist_dispel:i="-1", match_duration:i="-1", match_duration_high:i="-1", match_probability1:i="-1", match_probability2:i="-1", match_dicenumber:i="-1", match_dicesize:i="-1", match_savingthrow:i="-1", match_savebonus:i="-11", match_special:i="-1", match_save_vs_spell:i="-1", match_save_vs_breath:i="-1", match_save_vs_poison:i="-1", match_save_vs_wand:i="-1", match_save_vs_polymorph:i="-1", match_ignore_primary:i="-1", match_ignore_secondary:i="-1", match_bypass_mirror_image:i="-1", match_ignore_difficulty:i="-1", match_drain_hp_to_caster:i="-1", match_transfer_hp_to_target:i="-1", match_fist_damage_only:i="-1", match_drain_to_max_hp:i="-1", match_suppress_feedback:i="-1", match_save_for_half:i="-1", match_made_save:i="-1", match_does_not_wake:i="-1", opcode:i="-1", target:i="-1", power:i="-1", parameter1:i="-11", parameter2:i="-11", timing:i="-1", resist_dispel:i="-1", duration:i="-1", duration_high:i="-1", probability1:i="-1", probability2:i="-1", dicenumber:i="-1", dicesize:i="-1", savingthrow:i="-1", savebonus:i="-11", special:i="-1", save_vs_spell:i="-1", save_vs_breath:i="-1", save_vs_poison:i="-1", save_vs_wand:i="-1", save_vs_polymorph:i="-1", ignore_primary:i="-1", ignore_secondary:i="-1", bypass_mirror_image:i="-1", ignore_difficulty:i="-1", drain_hp_to_caster:i="-1", transfer_hp_to_target:i="-1", fist_damage_only:i="-1", drain_to_max_hp:i="-1", suppress_feedback:i="-1", save_for_half:i="-1", made_save:i="-1", does_not_wake:i="-1", match_resource:s="SAME", resource:s="SAME", match_function:s, function:s)=() patch
CLONE_EFFECT(check_globals:i=1, check_headers:i=1, header:i="-1", header_type:i="-1", multi_match:i=999, verbose:i, silent:i, match_opcode:i="-1", match_target:i="-1", match_power:i="-1", match_parameter1:i="-1", match_parameter2:i="-1", match_timing:i="-1", match_resist_dispel:i="-1", match_duration:i="-1", match_duration_high:i="-1", match_probability1:i="-1", match_probability2:i="-1", match_dicenumber:i="-1", match_dicesize:i="-1", match_savingthrow:i="-1", match_savebonus:i="-11", match_special:i="-1", match_save_vs_spell:i="-1", match_save_vs_breath:i="-1", match_save_vs_poison:i="-1", match_save_vs_wand:i="-1", match_save_vs_polymorph:i="-1", match_ignore_primary:i="-1", match_ignore_secondary:i="-1", match_bypass_mirror_image:i="-1", match_ignore_difficulty:i="-1", match_drain_hp_to_caster:i="-1", match_transfer_hp_to_target:i="-1", match_fist_damage_only:i="-1", match_drain_to_max_hp:i="-1", match_suppress_feedback:i="-1", match_save_for_half:i="-1", match_made_save:i="-1", match_does_not_wake:i="-1", opcode:i="-1", target:i="-1", power:i="-1", parameter1:i="-11", parameter2:i="-11", timing:i="-1", resist_dispel:i="-1", duration:i="-1", duration_high:i="-1", probability1:i="-1", probability2:i="-1", dicenumber:i="-1", dicesize:i="-1", savingthrow:i="-1", savebonus:i="-11", special:i="-1", save_vs_spell:i="-1", save_vs_breath:i="-1", save_vs_poison:i="-1", save_vs_wand:i="-1", save_vs_polymorph:i="-1", ignore_primary:i="-1", ignore_secondary:i="-1", bypass_mirror_image:i="-1", ignore_difficulty:i="-1", drain_hp_to_caster:i="-1", transfer_hp_to_target:i="-1", fist_damage_only:i="-1", drain_to_max_hp:i="-1", suppress_feedback:i="-1", save_for_half:i="-1", made_save:i="-1", does_not_wake:i="-1", match_resource:s="SAME", resource:s="SAME", insert:s="above", match_function:f, function:f)=() patch
DELETE_EFFECT(check_globals:i=1, check_headers:i=1, header:i="-1", header_type:i="-1", multi_match:i=999, verbose:i, match_opcode:i="-1", match_target:i="-1", match_power:i="-1", match_parameter1:i="-1", match_parameter2:i="-1", match_timing:i="-1", match_resist_dispel:i="-1", match_duration:i="-1", match_duration_high:i="-1", match_probability1:i="-1", match_probability2:i="-1", match_dicenumber:i="-1", match_dicesize:i="-1", match_savingthrow:i="-1", match_savebonus:i="-11", match_special:i="-1", match_save_vs_spell:i="-1", match_save_vs_breath:i="-1", match_save_vs_poison:i="-1", match_save_vs_wand:i="-1", match_save_vs_polymorph:i="-1", match_ignore_primary:i="-1", match_ignore_secondary:i="-1", match_bypass_mirror_image:i="-1", match_ignore_difficulty:i="-1", match_drain_hp_to_caster:i="-1", match_transfer_hp_to_target:i="-1", match_fist_damage_only:i="-1", match_drain_to_max_hp:i="-1", match_suppress_feedback:i="-1", match_save_for_half:i="-1", match_made_save:i="-1", match_does_not_wake:i="-1", match_resource:s="SAME", match_function:s)=() patch
These should not be called from outside the library itself.
dw_internal_apply_function()=() patch
dw_internal_check_bit()=(bit_test_passed:s) patch
dw_internal_evaluate_function()=(function_test_passed:s) patch
dw_internal_initialise_bit patch_macro
dw_internal_set_bit()=() patch
Changes consist of (i) new INT_VAR variables; (ii) two functions and one macro, at end; (iii) calls to those functions and macro inserted into the code; (iv) a small insert into the big AND loop that checks if a match is found; (v) allowing parameter1 and parameter2 to take negative values up to -10