Modifying reload AP with sfall hook script

Discussion in 'Fallout General Modding' started by NovaRain, Apr 18, 2012.

  1. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    I was trying to make the normal .44 revolver cost more AP for reloading, since I don't think reloading revolver with speedloader should be "faster" (i.e. cost less AP) than semi-auto pistol with magazine. The default setting of .44 revolvers makes Desert Eagle a less favorable choice in FO2 IMO.

    The first thing comes to my mind is changing the effect of "weapon fast reload" perk to increase reload AP by 1, so that I can reassign the perk on normal .44 revolver. But I don't know how to change weapon perks, and there's no similar mod for reference for a dummy like me. Then I remembered Magnus's F2WR changes the AP cost of unarmed special attacks, might be worth checking out, I thought. After spending a few days reading documents, trying to understand the meaning of the code (I have almost zero programming experience), and lots of try & error (with some funny/stupid results), I managed to get what I want.

    So here's the code, based on Magnus's F2WR script:
    (Special thanks to Magnus and Timeslip.)
    Code:
    // hs_calcapcost.ssl
    
    procedure start;
    #include "sfall.h"
    #include "DEFINE.H"
    
    procedure start begin
      variable critter, type, aimed, i;
      if not init_hook then begin
        critter:=get_sfall_arg;
        type:=get_sfall_arg;
        aimed:=get_sfall_arg;
        i:=-1;
        if (type == ATKTYPE_PALMSTRIKE) or (type == ATKTYPE_PIERCINGSTRIKE) or (type == ATKTYPE_JAB) then begin
          i:=4 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0);
        end
        if (type == ATKTYPE_HIPKICK) or (type == ATKTYPE_HOOKKICK) or (type == ATKTYPE_PIERCINGKICK) then begin
          i:=5 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0);
        end
        if ((type == hit_left_weapon_reload) or (type == hit_right_weapon_reload)) and ((obj_pid(critter_inven_obj(critter, INVEN_TYPE_RIGHT_HAND)) == PID_44_MAGNUM_REVOLVER) or (obj_pid(critter_inven_obj(critter, INVEN_TYPE_LEFT_HAND)) == PID_44_MAGNUM_REVOLVER)) then begin
          i:=3;
        end
        if i != -1 then begin
          if aimed then i++;
          set_sfall_return(i);
        end
      end
    end
    I know, the 'if' statement for checking .44 revolver pid is a mess, but at least it did the trick. I did some basic tests, but still not quite sure if it also works for NPCs though. It could be better organized and expanded to make more weapons have their own custom reload AP.

    Is there any other way to implement the idea? Or making the code cleaner/simpler? Any suggestions are appreciated. :oops:
     
    • [Like] [Like] x 1
  2. Ardent

    Ardent A Smooth-Skin
    Modder

    681
    Jul 24, 2009
    An interesting idea indeed, NovaRain. Nice job and really nice of you to post it here, I bet somebody (me?) might use it for their own mods :P

    As for cleaning up the code, you could perhaps add an extra variable in which you type the PID of the weapon you want to modify. Something like that:

    Code:
    variable weap_pid;
    weap_pid:=PID_44_MAGNUM_REVOLVER;
    
    if ((type == hit_left_weapon_reload) or (type == hit_right_weapon_reload)) and ((obj_pid(critter_inven_obj(critter, INVEN_TYPE_RIGHT_HAND)) == weap_pid) or (obj_pid(critter_inven_obj(critter, INVEN_TYPE_LEFT_HAND)) == weap_pid)) then begin 
          i:=3; 
        end
    That way you can simply paste the code for multiple weapons and only change the PID in the definition of the variable weap_pid before each IF.

    Also, looking at the code, it seems it should work for all critters wielding this weapon, not only the player character.

    Again thanks and sorry I can't be of much help here.
     
    • [Like] [Like] x 1
  3. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    Thanks, Ardent. I was thinking to use nested IFs like this:
    Code:
    if (type == hit_left_weapon_reload) or (type == hit_right_weapon_reload) then begin
      if (obj_pid(critter_inven_obj(critter, INVEN_TYPE_RIGHT_HAND)) == PID_44_MAGNUM_REVOLVER) or (obj_pid(critter_inven_obj(critter, INVEN_TYPE_LEFT_HAND)) == PID_44_MAGNUM_REVOLVER) then begin
        i:=3;
      end
      if (obj_pid(critter_inven_obj(critter, INVEN_TYPE_RIGHT_HAND)) == PID_ASSAULT_RIFLE) or (obj_pid(critter_inven_obj(critter, INVEN_TYPE_LEFT_HAND)) == PID_ASSAULT_RIFLE) then begin
        i:=1;
      end
    end
    Might be interesting to make a new "quick reload" perk to reduce all reload AP by 1, guess I just play FNV too much. :P

    EDIT: here's the improved one:
    Code:
    procedure start;
    
    #include ".\HEADERS\DEFINE.H"
    #include ".\HEADERS\sfall.h"
    
    #define get_active_hand(slot)  if (active_hand == 0) then slot := INVEN_TYPE_LEFT_HAND; \
                                   else slot := INVEN_TYPE_RIGHT_HAND
    
    procedure start begin
       if game_loaded then begin
          register_hook(HOOK_CALCAPCOST);
       end else begin
          variable
             critter := get_sfall_arg,
             atkType := get_sfall_arg,
             aimed := get_sfall_arg,
             slot, item, i := -1;
    
          if (atkType == ATKTYPE_PALMSTRIKE) or (atkType == ATKTYPE_PIERCINGSTRIKE) or (atkType == ATKTYPE_JAB) then begin
             i := 4 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0);
          end else if (atkType == ATKTYPE_HIPKICK) or (atkType == ATKTYPE_HOOKKICK) or (atkType == ATKTYPE_PIERCINGKICK) then begin
             i := 5 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0);
          end
    
          if (atkType == hit_left_weapon_reload) or (atkType == hit_right_weapon_reload) then begin
             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 (item > 0) then begin
                if obj_pid(item) == PID_44_MAGNUM_REVOLVER then i := 3;
                else if obj_pid(item) == PID_44_MAGNUM_SPEEDLOADER then i := 2;
             end
          end
    
          if (i != -1) then begin
             if aimed then i++;
             set_sfall_return(i);
          end
       end
    end
    
     
    Last edited: Oct 18, 2018
    • [Like] [Like] x 1