help with HOOK_TOHIT?

Discussion in 'Fallout General Modding' started by QuantumApprentice, Apr 13, 2021.

  1. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    I know I asked on the discord, but I feel like this needs a longer explanation with more pics than discord easily allows for.

    Over the weekend I spent some time messing with hook scripts to see if I could figure out how they worked.
    I think I have a basic understanding of them, but the TOHIT hook was giving me some weird values that I'm not understanding. According to the sfall sight, this function should show me the To-Hit chance for a critter to make an attack.
    Code:
    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     arg0 - The hit chance (capped)
    critter arg1 - The attacker
    critter arg2 - The target of the attack
    
    The hit chance? That sounds like a good way to test how Armor Class works, so I figured I'd write a script to catch the to hit chance for a critter's attack and display it, then change my armor and see how much it helps.
    The example on the hooks page seemed simple enough, so I basically copied it.
    Here's the original:
    Code:
    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
    
    And here's what I came up with and attached to the critter I'm testing.
    To be clear, I tried a bunch of different variations through friday's and saturday's stream, but I ended up just using this one to get the most consistent and simplest results.
    Code:
    procedure tohit_hook_handler begin
       display_msg("Modifying hit_hook " + get_sfall_arg + ", " + get_sfall_arg + ", " + get_sfall_arg);
    end
    
    procedure start begin
       if game_loaded then begin
          register_hook_proc(HOOK_TOHIT, tohit_hook_handler);
       end
    end
    
    procedure combat_p_proc begin
       call tohit_hook_handler;
    end
    
    These are the results I'm getting:
    modifying hit_hook results cropped.png

    I realize this isn't a global script, but everything described on the global scripts page makes it sound intermittent, and I just want the result from a simple engine calculation. If making a global script will give me the results I want then I'll keep trying, but I feel like this shouldn't be that complicated.

    As you can see above, I consistently get these results, either a 0 or a 1 for the first "get_sfall_arg", a seemingly random 9 digit number for the second "get_sfall_arg", and consistently a 0 for the third.
    As I understand it, the first get_sfall_arg should show me the hit chance...but it clearly doesn't in my script, and I have no idea what the other two are either.
    Is my understanding correct?

    The HOOK_TOHIT page mentions hs_tohit.int, which I don't have and haven't yet been able to find in either the sfall modders pack, sfall itself, or the RP mod or UP mod, at least not the versions I have. But the hooks page says not to use it, which is fine by me if I can get this one to work, but neither explain what it did before that it doesn't do now...which makes me wonder if it wasn't supposed to parse the results or something?
    NovaRain did say it doesn't need to be named hs_tohit.int anymore, but if it's not then what script do I need if I need one?

    If possible, I would ideally like to just run the engine calculation and get a result to repeatedly update to display without entering combat. But I'm not sure if I it's possible to get aiming results without calling the combat module and entering combat, or how I would do so if it is.

    Any help is appreciated :)
    Thank you!
     
    Last edited: Apr 13, 2021
  2. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    ok, so NovaRain has been educating me on Global Scripts, and the results are starting to make sense. sorry for the long post.

    For anybody new to global scripts as I am, apparently as long as the first three letters or the filename are "gl_" then sfall will load them in memory and run all of them on map start, then continue to run them as you play.

    NovaRain dropped this code for me:
    Code:
    // gl_tohitcheck.ssl
    
    #include ".\headers\define.h"
    #include ".\headers\sfall\sfall.h"
    #include ".\headers\sfall\define_extra.h"
    
    procedure start;
    procedure hook_test;
    
    procedure start begin
       if game_loaded then begin
          register_hook_proc(HOOK_TOHIT, hook_test);
       end
    end
    
    procedure hook_test begin
       variable
          toHit    := get_sfall_arg,
          attacker := get_sfall_arg,
          target   := get_sfall_arg,
          bodyPart := get_sfall_arg,
          srcTile  := get_sfall_arg,
          atkType  := get_sfall_arg,
          rngFlag  := get_sfall_arg,
          rawToHit := get_sfall_arg;
    
       if (attacker == dude_obj) then begin
          display_msg("Player ToHit: " + toHit + ", target: " + obj_name(target) + ", body part: " + bodyPart + ", raw value: " + rawToHit);
       end
    end
    
    and while it isn't perfect for what I'm trying to do, it did work in game and produce recognizable results.
    Thanks again @NovaRain !

    Now to figure out how to make object pointers to the critters.
     
    Last edited: Apr 13, 2021
  3. Mr.Stalin

    Mr.Stalin Agent of Enclave Modder

    468
    Oct 29, 2015
    Code:
    procedure combat_p_proc begin
       call tohit_hook_handler;
    end
    you can't do that.
     
  4. Mr.Stalin

    Mr.Stalin Agent of Enclave Modder

    468
    Oct 29, 2015
    You can't make them, the game makes them)
    The hook is triggered when you move the cursor of the sight to the critter, there you will get a pointer to this NPC
    Code:
    target   := get_sfall_arg,
     
  5. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    lol yeah...NovaRain explained the basics of how global scripts work, but is there a more technical explanation why attaching a hook script to a critter won't work? I've been slowly reading through the sfall thread but I haven't found that explanation yet.

    Well, I've found 6 commands so far that produce object pointers:
    Code:
    party_member_obj
    create_obj
    export/import variable
    obj_under_cursor
    dude_obj
    self_obj
    But the target name that gets listed in the display for "obj_name(target)" doesn't seem to work as an object pointer. It's possible I'm formatting it wrong though, or something else simple that I don't understand yet. Is there a specific way to get a pointer from "target"?
     
  6. Lexx

    Lexx Testament to the ghoul lifespan
    Moderator Modder

    Apr 24, 2005
    Because it makes no sense. A hook script will always run in the background of the game, attaching it to an object would mean that it either 1. will be triggered too slow / in the wrong moment, or 2. will be triggered multiple times, which would duplicate the effect.

    Hook script must be initialized once on game start and that's it. From that moment on they will wait until the game does something that triggers them ... that moment is when they "hook" into it and inject their code.

    These commands don't "produce" pointers, they give you the object pointers.

    I am using obj_name(x) in my TMA script and it works. This will return the name entry from SCRNAME.MSG for the script that is attached to the object. This is NOT a pointer, just returning a string. You are using a pointer to get this string.
     
  7. burn

    burn Mildly Dipped
    Modder

    574
    Apr 22, 2012
    Uhm, the definition? Script attached to a critter is a critter script. Hook is run at a certain event.
    Theoretically, you can use the same script for a critter and in a hook. However, even theoretically I can't imagine a scenario where that would be actually needed.
     
  8. Mr.Stalin

    Mr.Stalin Agent of Enclave Modder

    468
    Oct 29, 2015
    The hook can be registered in the critter script, the hook must be used correctly, not as you did.
    will also need the hook unregistration when exiting the map.
     
  9. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    I have a million questions about this, wish I wasn't falling asleep right now.
     
  10. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    When you say hook is run at a certain event, I don't understand how that differentiates it from critter scripts, or why it can't be used in one.

    Why does a hook script always run in the background?
    Is there a separate sfall engine running that ferry's the requests from the script to the engine?
    I originally thought the new sfall commands simply gave access to the parts of memory that sfall has access to, but the way you describe running global scripts doesn't make it sound exactly like that.
    Is anyone willing to elaborate on my misunderstanding of how sfall works?

    What's the correct way to register the hook from a critter script? The bgforge explanation seems to focus on global scripts and I'm not able to find anything that references critter scripts.
    What's hook unregistration? How do you do it and why?
     
  11. Lexx

    Lexx Testament to the ghoul lifespan
    Moderator Modder

    Apr 24, 2005
    Because it is waiting for the specific action to happen which it wants to "hook into". It has to run all the time and check for that.

    Well, for example critter_p_proc will not run constantly through combat. Other procedures might only run after a specific action has happened, which means it triggers too late, etc.


    Just forget about registering hooks from a critter script. It's more complicated than necessary. Use a global script for all your new stuff and done.
     
    Last edited: Apr 19, 2021
  12. Mr.Stalin

    Mr.Stalin Agent of Enclave Modder

    468
    Oct 29, 2015
    In any script, a hook can be registered, depending on the task set, the only rule in contrast to the global script (which is constantly in memory) it is not necessary to register and unregister the hook whenever you enter the map and leave it, because the scripts bound to the map object are deleted from memory when you exit and the hook will not be able to execute its handler procedure, which can cause the game to crash.

    Code:
    variable registered;
    
    procedure start begin
       if registered == false then begin
          register_hook_proc(HOOK_TOHIT, tohit_hook_proc);
          registered = true;
       end
    end
    
    procedure map_exit_p_proc begin
         register_hook_proc(HOOK_TOHIT, 0); // unregister
    end
    
     
  13. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    Awesome! Thanks for explaining...a little anyway :)

    It's probably the case that I simply don't understand what a ddraw.dll file does.
    For instance, I saw some stuff in the bgforge page about a virtual file system...does that mean the ddraw.dll is some sort of emulated operating system? Or is it just that sfall has an emulated OS?
    Every once in a while I try to google search stuff about how to create a ddraw.dll file so I can understand what exactly is going on inside, but nearly every time google gives me links to error fixes and .dll file downloads for multiple pages of search results. Google isn't giving me any useful results, can you help me out here?
     
  14. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    The original ddraw.dll in the system is for handling DirectDraw stuff.
    sfall makes use of the behavior of a program loading its required DLLs under Windows (NT kernel, not win9x). It works as a wrapper to call the real one in the system and inject its own code (engine fixes, options, hooks, etc.) in the game engine's memory space. That's why some anti-virus programs see sfall as a threat due to its memory injection nature. There are many similar DirectDraw wrappers around for other old games, so you should check DirectX SDK documents for the detail about how to use DirectX APIs and build DLLs for them.
     
    Last edited: Apr 29, 2021
  15. QuantumApprentice

    QuantumApprentice Still Mildly Glowing

    257
    Feb 9, 2018
    Cool! thanks for pointing me in the right direction, had no clue what terminology to use. Are there any specific SDK documents you think I should read first?