Fallout 2 mod FO2 Engine Tweaks (Sfall)

I'm not sure if this is the right place to ask, but is there anyway to control the distance of NPC's being knocked back from explosions and whatnot? They have a tendency to go sliding from one end of the map to the other and it would be good if that could be shortened a little bit, if possible.

Cheers,
CPL
Don't think so.
 
Does "DAM_LOSE_TURN" also happen on a crit miss where an NPC misses his next turn? Then it should be possible to get the bug without the knock out, shouldn't it (at least in theory)?
Also, the map exit isn't the problem in itself but rather that the NPCs entry in the timer event queue is sometimes cleared when you do. Or do I remember wrong here.
I mean sometimes you get what seems like a lighter version of the bug where the NPC gets a bit broken animations when walking around and just stands around in combat until he suddenly falls down and then gets up and are back to normal. I would assume the info on when to get back up is contained in the timer event queue, so in this instance nothing got removed on map exit. When the NPC acts like a container permanently though, I think the info in the timer event queue has been either removed or corrupted. I did some testing of this a long time ago with manually clearing the event queue and stuff but can't remember much. I know for a fact that lit flares can cause mix-ups and confusion on what should get removed in the timer event queue and what shouldn't though.
Anyway, I'm positive that when testing someone else's container bug, knocking out the "broken" NPC again by myself and then waiting for him to come back to his senses while in combat fixed him. So @Daemonjax, give that a try.
 
Does "DAM_LOSE_TURN" also happen on a crit miss where an NPC misses his next turn? Then it should be possible to get the bug without the knock out, shouldn't it (at least in theory)?
Yes. I used a rather forced way to reproduce/test the bug and the fix: making a custom CriticalOverrides.ini to set all critical effects of body parts to DAM_LOSE_TURN for men, women, and brahmin. Hit Sulik, Vic, and Cassidy with my all-10 character with Sniper and Slayer perks (every attack is critical hit). Leave the map and trigger the bug. When I attack them, they are still standing but stuck in "lost next turn" status. Basically with the setup I can just keep attacking any human NPCs and they can't even fight back. :P

I also used hs_afterhitroll to force any attacks of critters that is not dude_obj to critical miss. Let my party members fight enemies in random encounters and I leave the map when they lost their next turn to trigger the bug.
 
Last edited:
So @Daemonjax, give that a try.

I'd rather just reload instead of faffing around doing that (which would probably require saving/reloading anyways due to better criticals). Anyways, my whole point was that the bug occurred without a map change. Just wanted say it's possible and that the bug still exists.

EDIT: Is there a way to get the player's current number of action points and reduce it by a certain number? I'd like to make activating sneak cost action points in combat (because you can currently just deactivate and reactivate sneak at no cost, making it slightly too powerful).

EDIT2: Nevermind, found it!

0x8191 - int get_critter_current_ap(CritterPtr)
0x8192 - void set_critter_current_ap(CritterPtr, int ap)

There's no hook for using the sneak skill, but I think I can fake it. And I think I can increase movement cost while sneaking in combat unless you have the silent running perk, which adds value to it.

This works:

hs_keypress.ssl
Code:
/*
hs_keypress.int

Runs once every time when any key was pressed or released.
DX codes: (see dik.h header)
VK codes: [URL='http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx']http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx[/URL]

int     arg1 - event type: 1 - pressed, 0 - released
int     arg2 - key DX scancode
int     arg3 - key VK code (very similar to ASCII codes)
*/
procedure start;
#define COST (5)

#include ".\HEADERS\dik.h"
#include ".\headers\define_lite.h"

procedure start begin
    variable event, keyDX, AP, bonus;

    if init_hook then begin
    end else begin
        event := get_sfall_arg;
        keyDX := get_sfall_arg;

        if ((event == 0) and (keyDX == DIK_1)) then begin
            if (combat_is_initialized and using_skill(dude_obj, SKILL_SNEAK)) then begin                            
                //display_msg("Sneaking: Start");
                bonus := has_skill(dude_obj, SKILL_SNEAK) / 100;
                AP := get_critter_current_ap(dude_obj) - COST + bonus;
                if (AP < 0) then AP := 0;
                set_critter_current_ap(dude_obj, AP);
           end
       end
    end
end

hs_mouseclick.ssl (this probably will only work properly using hires mod @ 1920x1080 and 2x scale)
Code:
/*
hs_mouseclick.int

Runs once every time when a mouse button was pressed or release.

int     arg1 - event type: 1 - pressed, 0 - released
int     arg2 - button number (0 - left, 1 - right, up to 7)


0x821c - int  get_mouse_x()
0x821d - int  get_mouse_y()
0x821e - int  get_mouse_buttons()
0x821f - int  get_window_under_mouse()
*/
procedure start;
#define COST (5)
//1920x1080 = 960x540(internal) = 651,111(upperleft); 736,141(lowerright)
#define UPPER_LEFT_X (651)
#define LOWER_RIGHT_X (736)
#define UPPER_LEFT_Y (111)
#define LOWER_RIGHT_Y (141)
//1706x960  = 843x480(internal) = 597,51 (upperleft); 682,82 (lowerright)
//#define UPPER_LEFT_X (597)
//#define LOWER_RIGHT_X (682)
//#define UPPER_LEFT_Y (51)
//#define LOWER_RIGHT_Y (82)

#define DOWN (1)
#define UP   (0)
#define LEFT (0)

#include ".\headers\define_lite.h"

variable getNext  := 0;

procedure start begin
    variable event, button, bonus, window, AP, x, y;
 
    if not init_hook then begin
       event := get_sfall_arg;
        button := get_sfall_arg; 
                 
        //if (button == LEFT) then begin
        //    display_msg("" + get_screen_width + "x" + get_screen_height + "_" + get_mouse_x + ";" + get_mouse_y);
        //end              
             
       if (combat_is_initialized) then begin 
           window := get_window_under_mouse;
            if (getNext and (event == UP) and (button == LEFT) and (window == 1 or window == 6)) then begin        
               getNext := 0;
                x := get_mouse_x;
                y := get_mouse_y;              
                //display_msg(" UP x: " + x + ", y: " + y + ", w: " + window);
                if ((x >= UPPER_LEFT_X) and (x <= LOWER_RIGHT_X) and (y >= UPPER_LEFT_Y) and (y <= LOWER_RIGHT_Y)) then begin
                    if (not using_skill(dude_obj, SKILL_SNEAK)) then begin
                        bonus := has_skill(dude_obj, SKILL_SNEAK) / 100;
                        //display_msg("bonus: " + bonus);
                        AP := get_critter_current_ap(dude_obj) - COST + bonus;              
                        if (AP < 0) then AP := 0;
                        set_critter_current_ap(dude_obj, AP);
                    end
                end         
            end else if ((event == DOWN) and (button == LEFT) and (window == 1 or window == 6)) then begin
               getNext := 0;
                x := get_mouse_x;
                y := get_mouse_y;              
                //display_msg(" DOWN x: " + x + ", y: " + y + ", window: " + w);              
                if ((x >= UPPER_LEFT_X) and (x <= LOWER_RIGHT_X) and (y >= UPPER_LEFT_Y) and (y <= LOWER_RIGHT_Y)) then begin
                    getNext := 1;
                end
            end
        end else begin
            getNext := 0;
        end
 
    end
end

hs_movecost.ssl
Code:
/*
hs_movecost.int

Runs when calculating the ap cost of movement

Critter arg1 - the critter doing the moving
int     arg2 - the number of hexes being moved
int     arg3 - the original ap cost

int     ret1 - the new ap cost
*/

procedure start;

#define MULTIPLE (5)
#define TRAIT_SILENT_RUNNING (15)
#include ".\headers\define_lite.h"

variable critter, numHexes, APCost;

procedure start begin

    if not init_hook then begin
       critter := get_sfall_arg;
        numHexes := get_sfall_arg;
        APCost := get_sfall_arg;

       if (critter == dude_obj and using_skill(dude_obj, SKILL_SNEAK) and not has_trait(TRAIT_PERK, DUDE_OBJ, TRAIT_SILENT_RUNNING)) then begin
           APCost := APCost * 2;
           set_sfall_return(APCost);
       end

    end
end

The only minor problem (besides the fact that I have the mouse xy coordinates hardcoded in the hs_mouseclick script since I don't know how to get a custom variable value from a file) is with detecting the skilldex window under the mouse cursor. Sfall returns either 1 or 6 for it (it seems to alternate between the two values), so I have to check for both... but the character skills menu also (always) returns 1, so it's possible to trigger the AP reduction by clicking in a certain spot (where the sneak button would be if the skilldex was open) in that menu -- but it's it's so unlikely (never gonna happen, really) that I can live with it.

EDIT: I was testing out using a custom resolution of 1706x960 in f2res for hs_mouseclick (and I like it because it maintains the correct screen height and aspect ratio when using the 2x scaling option and still looks reasonably sharp when letting my lcd panel do the scaling instead of my gpu), so here's the #defines for that:

#define UPPER_LEFT_X (597)
#define LOWER_RIGHT_X (682)
#define UPPER_LEFT_Y (51)
#define LOWER_RIGHT_Y (82)
 
Last edited:
But, it's not perfect. In some cases, when I need to pass my array between several scripts (like array of traps), this solution is ok (because I need to somehow pass variable ID between scripts and this is the only way since "imported" variables won't work with global/hook scripts)

Is this still true? I know I'm quoting something from years ago, but I want to make sure I'm not doing something totally stupid.

I just finished testing (like a couple hours ago) exporting an array variable (as well as a few ints) in one hookscript, adding to the imported array in another hookscript, and verified the first one (which exported it) was able to see the change. This was done with hs_afterhitroll and hs_combatdamage.

Everything seems to work perfectly (both imported/exported array and regular int variables) according to my display_msg()'s. Did I just get super lucky? Or was that fixed in the last couple years? Or does it only work between two hookscripts and not between hookscripts and regular non-hookscript scripts?
 
Last edited:
Friends,

how do I change the fade time (you know, text, events) in latest sfall?

I recall there being an option for that, but I can't seem to find it anymore.

When ie. an NPC leaves in dialogue to do something, there should be a fade-out and fade-in. But it takes a microsecond :)

what option should I change to make it work like it was in vanilla? Without direct9 enabled in sfall.ini, it takes a year for the fadeout to begin and end, and with d9 enabled it takes a microsecond.




Question 2:

which of the ammo mods (integrated with sfall) do you consider best for varied gameplay? My biggest problem with them is that they sort of make some NPCs weaker than others, since NPCs can't/won't change ammo depending on what they fight against.




Question 3:

will it ever be possible to manually control NPCs without transfering your tagged skills, perks and traits to them?
 
Last edited:
1) Fade time is managed by HRP, check out f2_res.ini
2) That's really subjective. However, once I've started playing ironman, that's not a question for me. Slipping just once is enough (and it happens more often with YAAM, just to note).
3) Probably yes. Likely in 5 years or so from now, so don't hold your breath.
 
1 ) thanks :)
2 ) so YAMM has a tendency of making big hits slip through your armor? well, that sucks. I think that JHP/AP cannot be truly made equally useful without changing the critical table anyway. If pretty much every crit hit bypasses armor (after better criticals), what's the point of AP ammo anyway? A simple value tweak won't change much (but it will screw over NPCs like Sulik using SMGs, at least before his crit chance goes through the roof ).
I guess I'll pass on using any, then.
3) Any way to motivate sfall modders, then? ;) I know it's not a popular request and stuff, as not many people enjoy big parties (maybe it's because of Per's guide haha), but it's incredibly fun to actually manage your NPCs yourself. Brings a new tactical level of gameplay, even though it might be a bit of an overkill. Maybe it could be done with some sort of a simple script that forcibly removes perks on NPC turns and removes traits (or perhaps, if complete removal is not doable, it should simply change stuff to something that doesn't affect combat, IE. change your tags to traps, gambling and first aid for NPC turns - and perks to a dummyperk with 99 levels doing exactly nothing - and changing traits to sex appeal or so).
 
3) I don't know, ask them. Some times dreams come true fast, some time not. I meant falltergeist though, not sfall.
About big parties - since I've created unlimited party tweak, tried a few configurations (including direct control), I've come to conclusion that actually stock Fallout config is pretty much fine. Controlling over 3 characters per turn is a pain for me. Waiting for over 5 NPC per turns is a pain too. If I want Jagged Alliance, I will just play it, no need to mod Fallout to match.
 
Well, I don't consider it JA, more like Fallout Tactics setting in a game that's just plain better. :)

I'll try asking..
 
Is this still true? I know I'm quoting something from years ago, but I want to make sure I'm not doing something totally stupid.

I just finished testing (like a couple hours ago) exporting an array variable (as well as a few ints) in one hookscript, adding to the imported array in another hookscript, and verified the first one (which exported it) was able to see the change. This was done with hs_afterhitroll and hs_combatdamage.

Everything seems to work perfectly (both imported/exported array and regular int variables) according to my display_msg()'s. Did I just get super lucky? Or was that fixed in the last couple years? Or does it only work between two hookscripts and not between hookscripts and regular non-hookscript scripts?
Sfall arrays have gone through some drastic changes. See here. Are you exporting variables via "exported/imported" keywords? Not sure how it's related though. I think my comment was related to the fact that every array you create (with the old sfall) will end up in savegame and if you somehow didn't save it's ID, it will be cluttering your save file. Now you need to explicitly call save_array.
 
sfall 3.7.3 is released on SourceForge, along with modders pack (only some document updates) and win2k version.
Changelog said:
v3.7.3
>Changed the displayed version number to the same as the internal version number
>Added the ability to read additional game msg files, as opposed to dialog msg files (From Vennor)
>Added an option to display sfall built-in credits at the bottom of credits.txt contents instead of at the top

Original engine bug fixes and various features based on the work by Crafty:
>Fixed get_screen_width/height functions not returning correct values when using the hi-res patch
>Fixed incorrect savegame path detection when reading/writing sfallgv.sav and sfallfs.sav under certain circumstances
>Improved the unlimited ammo exploit fix to prevent crashes with some faulty scripting
>Added a fix for the original engine issue that caused action points being initialized incorrectly at the beginning of each turn, thus giving a hidden bonus to your opponent's armor class and reducing your hit chance
>Added a fix for destroy_p_proc not being called if the critter is killed by explosives when you leave the map
>Added a fix for incorrect death animations being used when killing critters with kill_critter_type function
>Added a fix for the original engine issue that caused fallout checking the horizontal position on the y-axis instead of x when setting coordinates on the world map
>Changed the way SpeedInterfaceCounterAnims=2 works. Now it updates the hp/ac counters instantly in all cases
>Added an option to display numbered dialogue options

Vennor from Mutants Rising team added a new modding feature that can read extra game msg files from DATA\Text\English\Game directory. For detailed info on how to setup extra game msg files and read the messages, you can check the comments in the pull request on GitHub or the function notes from modderspack.
 
Last edited:
I'm wondering what this one is about:
>Added a fix for the original engine issue that caused fallout checking the horizontal position on the y-axis instead of x when setting coordinates on the world map
How does this bug (and now the fix) affect the game?
 
I'm wondering what this one is about:
How does this bug (and now the fix) affect the game?
Without the fix, when your car runs out of fuel in the last two rows on the worldmap, the "Car Outta Power" circle will appear at northwest of the map near Arroyo instead of at your current stopped location. Similar situation should also happen on triggering some special encounters in the last two rows.
 
Without the fix, when your car runs out of fuel in the last two rows on the worldmap, the "Car Outta Power" circle will appear at northwest of the map near Arroyo instead of at your current stopped location. Similar situation should also happen on triggering some special encounters in the last two rows.
Oh that one. I was talking about it in the RP thread not so long ago, thinking it would never get fixed without Timeslip. So I'm happy to see this fix. Thanks.
 
Congrats for the relese NovaRain, the fixes of Crafty dont make a few bugs on wikia being marked as fixed? Or am i mistaken?
 
Back
Top