Fallout 2 mod FO2 Engine Tweaks (Sfall)

I am trying to understand which skill was used in HOOK_TOHIT and my head is spinning. Any help is appreciated.

There is Attack Type parameters which tells from which hand weapon was used and which type of attack was used (primary/secondary/...). However, this does not completely answers the skill question. Is there a ways to understand which skill weapon uses for each attack type? I could not find any definitive indication of that in documentation, headers and Proto Manager. Someone already gave me hint to use weapon animation to try to deduce the type but this is pretty vague. Does vanilla engine is indeed trying to guess the skill this way?
Also how to determine if secondary melee weapon attack is melee or thrown? Like spear can be thrown but sledgehammer cannot.
 
Does vanilla engine is indeed trying to guess the skill this way?
Yes, that's how the engine chooses skills as the tohit base when someone tries to attack.
Check item_w_subtype procedure in gl_compute_damage example script in the modders pack for a partial logic.
 
It disables itself if the player's resolution is lower than 890x720. The crash upon entering the world map only happens if someone plays the game in HRP's windowed mode and resize the window to smaller size during the gameplay.
It's been more than a dozen releases since the first implementation, so far there's no crash report due to that.
Not 100% sure I understand this, could be that [HRP's windowed mode and resize the window to smaller size during the gameplay] is exactly what I'm doing, or it is not...?

Anyway, I checked with newest sfall (4.3.2). And I still crash. I'm not in window mode, in fact everything is pretty vanilla.
But what I do is I adjust the screen setting in the game menu. Doing that and it crashes.
It requires a new start to adjust.
For example, I set hi-res on 800x600, start game, worldmap interface is small, I adjust to 1280x720 under options/screen settings, load a save/start new game and worldmap interface is still small.
When I do it the other way round, it crashes.
However, when I set “ExpandWorldMap=0” to 1, and hi-res to 800x600 before starting the game (exe), then it works fine [turns itself off], however, this cannot reset until I close and restart the exe.
So this function seems to knock-out the option to use: “Options/Screen Settings” [as going above 890x720 (after it blocked itself) doesn't adjust, going below (after it enabled itself) and it crashes].
Not sure this is the same thing you meant...
but I'm not in window mode. Hi-Res is set to:
; Set WINDOWED=1 to enable windowed mode.
WINDOWED=0
And I'm not doing anything during game-play. I just use "Screen Settings" in the main menu. Which seems a "no-no" with “ExpandWorldMap”. As it seems to require to close and restart Fallout if wanting to cross the 890x720 barrier.
...
Isn't this just an oversight? I'm not really sure, but doesn't changes in “Options/Screen Settings” trigger a new start of Fo2? I'm pretty sure Hi-Res says as much when doing that in the BiS Mapper. Not sure though.
 
Yes, that's how the engine chooses skills as the tohit base when someone tries to attack.
Check item_w_subtype procedure in gl_compute_damage example script in the modders pack for a partial logic.

Awesome example! Thank you.

Even though it is example for HOOK_COMBATDAMAGE and not HOOK_TOHIT I assume that hit_mode parameter in former is the same as Attack Type in latter. Let me try.
 
Example script code of how the engine determines which skill the weapon should use:
Code:
procedure item_w_skill(variable weapon, variable hit_mode) begin
   variable attack_mode, skill := SKILL_UNARMED_COMBAT, dmg_type;

   if weapon and (hit_mode <= ATKTYPE_RWEP2) then begin
      attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS);

      if (hit_mode == ATKTYPE_LWEP2) or (hit_mode == ATKTYPE_RWEP2) then
         attack_mode := (attack_mode bwand 0xF0) / 16; // shift 4 bits to the right
      else
         attack_mode := (attack_mode bwand 0x0F);

      if (attack_mode > ATKMODE_PRI_THROW) then begin
         attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS); // now check the item flags
         if (attack_mode bwand WEAPON_ENERGY) then begin // sfall flag
            skill := SKILL_ENERGY_WEAPONS;
         end else begin
            dmg_type := get_proto_data(obj_pid(weapon), PROTO_WP_DMG_TYPE);
            if (dmg_type != DMG_laser) and (dmg_type != DMG_plasma) and (dmg_type != DMG_electrical) then begin
               if (attack_mode bwand WEAPON_BIGGUN) then begin
                  skill := SKILL_BIG_GUNS;
               end else begin
                  skill := SKILL_SMALL_GUNS;
               end
            end else begin
               skill := SKILL_ENERGY_WEAPONS;
            end
         end
      end else if (attack_mode == ATKMODE_PRI_THROW) then begin
         skill := SKILL_THROWING;
      end else if (attack_mode > ATKMODE_PRI_KICK) then begin
         skill := SKILL_MELEE;
      end
   end

   return skill;
end
 
Anybody knows how darkness affect ranged accuracy? I have seen somewhere it says -10% at 1 hex, -25% at 2, and -40% at 3 and farther. However, this seems to be related to the light dude emits. There is no other formulas as how it depends on darkness level, etc.
I see this function "tile_light" returns lightness at the tile. So, I guess, this what is used to determine hit chance penalty for object on the tile but could not find any specifics.
 
Another question about accuracy. Ugh. Sorry but all internet formulas are just wrong and incomplete.

It seems that with PE >= 5 and for weapon long/scope range there is indeed a distance within which the accuracy does not change. Seems like a cap of some sort but I could not find any explanation of that phenomena. Anybody is aware of the matter? Thank you.
 
For example, I set hi-res on 800x600, start game, worldmap interface is small, I adjust to 1280x720 under options/screen settings, load a save/start new game and worldmap interface is still small.
When I do it the other way round, it crashes.
You can not do this, the exe must be patched when the game starts.
 
Trying to introduce QoL change when lockpick skill accounts for lockpicks in inventory even if user didn't explicitly use them on object.

First, let me know if this is already implemented by any mod or sfall. Seems to be a natural thing to try.

Then, I see this code in game engine (obj_use_skill_on_):

Code:
0049D0EB            mov     ebx, esi                  ; target
0049D0ED            mov     edx, edi                  ; source
0049D0EF            mov     eax, ecx                  ; src_sid
0049D0F1            call    scr_set_objs_
0049D0F6            mov     edx, ebp
0049D0F8            mov     eax, ecx
0049D0FA            call    scr_set_action_num_
0049D0FF            mov     edx, use_skill_on_p_proc  ; proc
0049D104            mov     eax, ecx                  ; sid
0049D106            call    exec_script_proc_         ; use_skill_on_p_proc
0049D10B            lea     edx, [esp+28h+buf]        ; outScript
0049D10F            mov     eax, ecx                  ; result
0049D111            call    scr_ptr_                  ; возврашает скриппт по его SID
0049D116            cmp     eax, 0FFFFFFFFh
0049D119            jz      short loc_49D135
0049D11B            mov     ebx, [esp+28h+buf]
0049D11F            mov     ebx, [ebx+Script.override] ; 1 = переопределить стандартное поведение объекта
0049D122
0049D122 loc_49D122:                                  ; obj_use_skill_on_+71j
0049D122            test    ebx, ebx
0049D124            jnz     short loc_49D133
0049D126            mov     ebx, ebp                  ; skill
0049D128            mov     edx, esi                  ; target
0049D12A            mov     eax, edi                  ; source
0049D12C            xor     ecx, ecx                  ; bonus
0049D12E            call    skill_use_                ; HOOK_USESKILL
0049D133
0049D133 loc_49D133:                                  ; obj_use_skill_on_+ACj
0049D133            xor     eax, eax
0049D135

Apparently it circumvents HOOK_USESKILL if there is a
Code:
use_skill_on_p_proc
with
Code:
script_overrides
call in it. And there are tons of such scripts for generic doors/locks as well as location generic. That is why this hook is not called for most of the doors in the game.

Questions to sfall developers.
  • Would it be possible to hook any of the calls above the 0049D12E to intercept the action before it is called by script? This would guarantee the hook for skill use on for any action including lockpicking.
  • If not the above, is it possible to write a map location based SSL script overriding lockpicking?
  • If not the above, then most likely I would need to modify each and every map location script that contains lockpicking procedures. That is less desirable as it could be incompatible with other mods.
 
Have you tried HOOK_USESKILLON?

Yes. That one triggers. I then can search for lockpicks in the inventory and call use_obj_on_obj standard function or fallback to default if none found.

Now the problem came from the least expected direction. It turns out that lock type is hardcoded in object script like that:
Code:
#define LOCK_STATUS                     STATE_STANDARD_LOCK
or
#define LOCK_STATUS                     STATE_ELECTRIC_LOCK

Which puzzles me how am I going to determine the type of the lock in hook if I have object pointer only? Sure, I can get script number (?) by
Code:
get_script(ObjectPtr)
but what does it give me? Am I able to extract this assigned hardcoded value?
 
Example script code of how the engine determines which skill the weapon should use:
Code:
procedure item_w_skill(variable weapon, variable hit_mode) begin
   variable attack_mode, skill := SKILL_UNARMED_COMBAT, dmg_type;

   if weapon and (hit_mode <= ATKTYPE_RWEP2) then begin
      attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS);

      if (hit_mode == ATKTYPE_LWEP2) or (hit_mode == ATKTYPE_RWEP2) then
         attack_mode := (attack_mode bwand 0xF0) / 16; // shift 4 bits to the right
      else
         attack_mode := (attack_mode bwand 0x0F);

      if (attack_mode > ATKMODE_PRI_THROW) then begin
         attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS); // now check the item flags
         if (attack_mode bwand WEAPON_ENERGY) then begin // sfall flag
            skill := SKILL_ENERGY_WEAPONS;
         end else begin
            dmg_type := get_proto_data(obj_pid(weapon), PROTO_WP_DMG_TYPE);
            if (dmg_type != DMG_laser) and (dmg_type != DMG_plasma) and (dmg_type != DMG_electrical) then begin
               if (attack_mode bwand WEAPON_BIGGUN) then begin
                  skill := SKILL_BIG_GUNS;
               end else begin
                  skill := SKILL_SMALL_GUNS;
               end
            end else begin
               skill := SKILL_ENERGY_WEAPONS;
            end
         end
      end else if (attack_mode == ATKMODE_PRI_THROW) then begin
         skill := SKILL_THROWING;
      end else if (attack_mode > ATKMODE_PRI_KICK) then begin
         skill := SKILL_MELEE;
      end
   end

   return skill;
end

what is hit_mode in this code?
 
what is hit_mode in this code?

See constants this variable is compared to in the code? Search by these constants and you'll get the full hit_mode list. This is from sfall.h, for example.
Code:
//The attack types returned by get_attack_type
#define ATKTYPE_LWEP1           (0)
#define ATKTYPE_LWEP2           (1)
#define ATKTYPE_RWEP1           (2)
#define ATKTYPE_RWEP2           (3)
#define ATKTYPE_PUNCH           (4)
#define ATKTYPE_KICK            (5)
#define ATKTYPE_LWEP_RELOAD     (6)
#define ATKTYPE_RWEP_RELOAD     (7)
#define ATKTYPE_STRONGPUNCH     (8)
#define ATKTYPE_HAMMERPUNCH     (9)
#define ATKTYPE_HAYMAKER       (10)
#define ATKTYPE_JAB            (11)
#define ATKTYPE_PALMSTRIKE     (12)
#define ATKTYPE_PIERCINGSTRIKE (13)
#define ATKTYPE_STRONGKICK     (14)
#define ATKTYPE_SNAPKICK       (15)
#define ATKTYPE_POWERKICK      (16)
#define ATKTYPE_HIPKICK        (17)
#define ATKTYPE_HOOKKICK       (18)
#define ATKTYPE_PIERCINGKICK   (19)
 
thnx,attack type then

edit :

Example script code of how the engine determines which skill the weapon should use:
Code:
procedure item_w_skill(variable weapon, variable hit_mode) begin
   variable attack_mode, skill := SKILL_UNARMED_COMBAT, dmg_type;

   if weapon and (hit_mode <= ATKTYPE_RWEP2) then begin
      attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS);

      if (hit_mode == ATKTYPE_LWEP2) or (hit_mode == ATKTYPE_RWEP2) then
         attack_mode := (attack_mode bwand 0xF0) / 16; // shift 4 bits to the right
      else
         attack_mode := (attack_mode bwand 0x0F);

      if (attack_mode > ATKMODE_PRI_THROW) then begin
         attack_mode := get_proto_data(obj_pid(weapon), PROTO_IT_FLAGS); // now check the item flags
         if (attack_mode bwand WEAPON_ENERGY) then begin // sfall flag
            skill := SKILL_ENERGY_WEAPONS;
         end else begin
            dmg_type := get_proto_data(obj_pid(weapon), PROTO_WP_DMG_TYPE);
            if (dmg_type != DMG_laser) and (dmg_type != DMG_plasma) and (dmg_type != DMG_electrical) then begin
               if (attack_mode bwand WEAPON_BIGGUN) then begin
                  skill := SKILL_BIG_GUNS;
               end else begin
                  skill := SKILL_SMALL_GUNS;
               end
            end else begin
               skill := SKILL_ENERGY_WEAPONS;
            end
         end
      end else if (attack_mode == ATKMODE_PRI_THROW) then begin
         skill := SKILL_THROWING;
      end else if (attack_mode > ATKMODE_PRI_KICK) then begin
         skill := SKILL_MELEE;
      end
   end

   return skill;
end

thank you very much for this @NovaRain
 
Last edited:
Do I understand correctly that formulas in stats.ini affect all critters?

Vanilla critter HP = (15 + 1 * 8 + 2 * 5) + 17 = 50

upload_2021-11-25_21-20-27.png



Example stats.ini for testing:
Code:
;max hp
[7]
base=100
multi0=0
multi2=0

New critter HP = (100 + 0 * 5) + 17 = 117

upload_2021-11-25_21-7-47.png


So it looks like all stats including HP bonus are same on proto but critter max HP now calculated using updated formula.

If this is the case, would it be possible to apply changes in stats.ini to dude only or add some additional parameter that allows that?
 
sfall 4.3.3 and 3.8.33 are released on SourceForge, along with their respective modders packs.
Changelog said:
v4.3.3
>Implemented an integrated High Resolution Patch mode, which has almost the same functionality as the original hi-res patch and has better integration with sfall's graphics features/improvements
>Fixed a bug introduced in 4.3.1 that broke the fix for party members with drug addictions
>Fixed a bug introduced in 4.3.1 that caused AI to be unable to use some weapons
>Fixed a bug introduced in 4.3.1 that caused the music not to be played after loading a saved game on the same map
>Fixed critical bugs in FadeBackgroundMusic that caused crashes in various situations
>Fixed incorrect display of name and damage values for unarmed attacks in the inventory in some cases
>Fixed the black screen issue in DX9 mode when returning to the game after using Alt+Tab
>Fixed the mouse cursor lag in the save/load game screens
>Fixed broken object descriptions for a modified version of fallout2.exe that supports Chinese characters
>Fixed and expanded the mouse drop area for the PC's and NPC's inventory on the barter screen
>Changed the 'Radiated' on the character screen to be highlighted in gray when the player still has an impending radiation effect
>Changed SkipCompatModeCheck to not require sfall debugging mode
>Removed UseCommandLine from ddraw.ini. Now sfall will always check command line arguments for another ini file
>Removed ArraysBehavior and RemoveWindowRounding from ddraw.ini because there is little reason to turn them off
>Removed SkipSizeCheck from ddraw.ini and the executable file size check from sfall
>Removed the dependency on d3dcompiler_43.dll for DX9 graphics modes
>Added a fix for incorrect value of the limit number of floating text messages
>Added a tweak to allow printing new floating text messages when their limit is exceeded
>Added a debug option to set up a key to toggle the display of the hex grid on the map on or off (like in the mapper)
The built-in HRP is the biggest feature in the release. It's designed to be a drop-in replacement for the original HRP by Mash, reads most of the settings from f2_res.ini of the original HRP and uses HRP's f2_res.dat for art files and map edge data as well.
The built-in HRP is enabled by default (HiResMode in [Main] section of ddraw.ini), and sfall will pop up a notification and offer to disable the original HRP by Mash if you start the game with an exe patched to load the original HRP (e.g. Fallout2HR.exe).

There are a few differences from Mash's HRP:
  • The basic graphics mode of the built-in HRP is now DirectDraw 7. That means in f2_res.ini setting GRAPHICS_MODE=0 is the same as =1.
  • Now you cannot resize the window during the game if you were using the windowed mode from the original HRP.
  • Currently HRP's in-game setting menu and the fog of war feature are not implemented yet.
  • Setting CPU_USAGE_FIX=1 in f2_res.ini now works exactly the same as ProcessorIdle=1 in ddraw.ini, so there won't be any conflict or extra slowdowns if you happen to set both of them.
  • BARTER_PC_INV_DROP_FIX is now part of general fixes in sfall (check the changelog above).
 
Last edited:
Back
Top