So I dug up this old post and pretty much worked my way backwards from there, with much help (copying) from NovaRain's old post here. Good news is, the tip about global, indiscriminate knockback - it works great. With melee weapons. Here's the code I used for that: Code: #include "sfall.h" #include "DEFINE.H" #include "itempid.h" procedure map_update_p_proc begin if game_loaded then begin set_attacker_knockback(dude_obj, 0, 8); end end Alas, my guns don't seem to be doing the job. At all. Any of them. The old post I linked to earlier led me to believe that it should indeed work on guns, so I'm probably doing something wrong. It gets worse: I frankensteined up another script that actually checks for the specific weapon and then applies the knockback if it's the right gun. No dice. Hell, this one doesn't even work if I switch the target out to a spear. Code: #include "sfall.h" #include "DEFINE.H" #include "itempid.h" #define get_active_hand(slot) if (active_hand == 0) then slot := INVEN_TYPE_LEFT_HAND; \ else slot := INVEN_TYPE_RIGHT_HAND procedure map_update_p_proc begin if game_loaded then begin variable critter := get_sfall_arg; variable slot, item, i := -1; if (critter == dude_obj) then begin get_active_hand(slot); item := critter_inven_obj(critter, slot); end else begin item := critter_inven_obj(critter, INVEN_TYPE_RIGHT_HAND); end if (obj_pid(item) == PID_SPEAR) then i := 42; end if (i == 42) then begin set_weapon_knockback(self_obj, 0, 5); end end So what am I doing wrong, in both cases? Thank you for your time!
Ordinary guns do not run the knockback calculation in combat, so simply calling knockback functions on them is useless. You need to use CombatDamage hook and add your own knockback calculation.
You can use a modified version of a shotgun mod i did about two weeks ago. See "add knockback". Code: #define SFALL_SC_EVALUATION (true) // short-circuit evaluation /* Include Files */ //#include "define.h" //#include "command.h" #include "..\headers\define.h" #include "..\headers\define_extra.h" #include "..\headers\command.h" #include "..\headers\sfall.h" /* Standard Script Procedures */ procedure start; procedure combatdamage_handler; /* Defines */ #define HOOK_COMBATDAMAGE (5) /******************************************************************* Local Variables which are saved. All Local Variables need to be prepended by LVAR_ *******************************************************************/ /******************************************************************* Imported variables from the Map scripts. These should only be pointers and variables that need not be saved. If a variable Needs to be saved, make it a map variable (MVAR_) *******************************************************************/ /******************************************************************* Local variables which do not need to be saved between map changes. *******************************************************************/ variable the_item; variable dest_obj; /******************************************************************* * PROCEDURES * *******************************************************************/ procedure start begin if (game_loaded) then begin register_hook_proc(HOOK_COMBATDAMAGE, combatdamage_handler); end end procedure combatdamage_handler begin variable target; variable attacker; variable damage_to_target; variable damage_to_attacker; variable se_target; variable se_attacker; variable weapon_used; variable damage_to_target_after; variable body_part_hit; variable damage_multiplier; variable distance_att_tar; variable bullets_hit; variable knockback_amount; variable attack_type; variable computed_data; variable knockback_amount_after; target := get_sfall_arg; attacker := get_sfall_arg; damage_to_target := get_sfall_arg; damage_to_attacker := get_sfall_arg; se_target := get_sfall_arg; se_attacker := get_sfall_arg; weapon_used := get_sfall_arg; body_part_hit := get_sfall_arg; damage_multiplier := get_sfall_arg; bullets_hit := get_sfall_arg; knockback_amount := get_sfall_arg; attack_type := get_sfall_arg; computed_data := get_sfall_arg; // add knockback knockback_amount_after = 'replace with your own int value' //return other sfall args set_sfall_return(damage_to_target); set_sfall_return(damage_to_attacker); set_sfall_return(se_target); set_sfall_return(se_attacker); // return modified knockback set_sfall_return(knockback_amount_after); end end
Got it working but even with knockback_amount_after = 0 the target is sliding about 6 or 7 hexes back. How did I mess this up??
Got it! I don't think the initial knockback distance was defined so reducing it or multiplying by a decimal did nothing. All I did was add 1 Code: //return other sfall args ... set_sfall_return(knockback_amount + 1); and now the target slides back a very restrained one square. Thanks again! I'm sure you've saved me many, many, many hours of work.
Perhaps i was wrong and ':=' should replace '=' in knockback_amount_after = 'replace with your own int value' Glad it's working okay for you. This is the template for most if not all hooks btw. EDIT: And yeah, I think set_sfall_return(knockback_amount + 1); can be set to set_sfall_return(1); as knockback_amount_after was used by me for a calculation in the original script.
Ooo, free template too. Really appreciate it. p.s. I think I understand most of the script but this part: Code: /* Defines */ #define HOOK_COMBATDAMAGE (5) I don't quite get. What does it do?
The #define statement makes it so each time you are writing for example "HOOK_COMBATDAMAGE", the script will change it to "5". the hook "COMBATDAMAGE" has a serial number of "5", and so for sake of convenience, it is defined as such. It is also easier to edit later, if changes are made (for instance, sfall changes and COMBATDAMAGE is now 4 instead of 5.)