Having trouble getting set_weapon_knockback to work

Discussion in 'Fallout General Modding' started by vsirin, Nov 26, 2021.

  1. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    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!
     
  2. NovaRain

    NovaRain Casual Modder Modder Moderator

    Mar 10, 2007
    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.
     
    • [Rad] [Rad] x 1
  3. Zorchar

    Zorchar Look, Ma! Two Heads!

    324
    Jun 18, 2018
    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
    
     
    • [Rad] [Rad] x 1
  4. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    Oh my god. I love you.
     
  5. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    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??
     
  6. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    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.
     
  7. Zorchar

    Zorchar Look, Ma! Two Heads!

    324
    Jun 18, 2018
    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.
     
  8. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    Ooo, free template too. Really appreciate it. :drunk:

    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?
     
  9. Zorchar

    Zorchar Look, Ma! Two Heads!

    324
    Jun 18, 2018
    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.)
     
  10. vsirin

    vsirin First time out of the vault

    49
    Nov 21, 2021
    Gotcha, very cool. Danke!