Fallout 2 mod FO2 Engine Tweaks (Sfall)

Discussion in 'Fallout General Modding' started by Dude101, Jul 30, 2007.

  1. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    The dynamic spatial script one Timeslip already confirmed is not going to happen (I also asked before trying my trap setting workaround).

    The line of sight one is of course pretty damn crucial (afaik the best workaround is through the hs_hexshootblocking hookscript and then checking for live targets rather than scenery; you might want to check out my simulated burst cone script which plays around with that).
     
  2. Timeslip

    Timeslip Water Chip? Been There, Done That
    Modder

    921
    Aug 15, 2007
    eep, the request list is twice as long as when I last looked. O.o

    Anyways, I decided tonight was an sfall night, so...

    Done
    Done (tile_under_cursor script function. Note that it doesn't clip; i.e. it'll still return a tile number even if the mouse is over the interface bar at the bottom etc.)
    Done (I abused CritterInvSizeLimitMode; add 4 to get the weight calculation restricted. Will affect all critters)
    Done (ini options, and set_inven_ap_cost script function)
    Done (gdialog_get_barter_mod)

    Also, from the bar up the top that's glaring at me, it appears that I haven't been getting email notifications of PM's, so sorry everyone I've inadvertantly ignored since I logged in last.
     
    Last edited: Feb 6, 2014
  3. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Woah, thanks so much!
     
  4. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    Thanks for the updates!
    Here are my compiles of SVN r263: (see my newest post in the thread for up-to-date version)
    (The dll in "trace" folder is equal to the "debugging" one in modder's pack.)

    BTW, the description related to inventory limit mode in ddraw.ini says:
    ";Add 8 to use the critters extra unused stat instead of for CritterInvSizeLimit for critters other than dude_obj"
    But any number of CritterInvSizeLimitMode greater than 7 will be set to 0 in InventoryInit, or do I misunderstand something? :confused:
     
    Last edited: Apr 3, 2014
  5. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    WOW, that's so awesome!! Thank you for the barter_mod function!! Now we can finally completely replace the pricing calculations of the vanilla! (this was the last show stopper)
    When can we expect the next version? As I understand, I need new version of script compiler with new function supported, right?

    May I make request about Script Editor included in sfall modderspack? It's awesome and all, but one bug really annoys me is how parser works. Very often when I add declaration of a new procedure, and before I add the definition (or when I'm in process of changing procedure arguments), the parser hangs the program completely (looks like he doesn't know what to do when one of the declarations doesn't meet exactly with definitions). Maybe some kind of try { } catch could solve this easily? (stopping the parser when it sees error instead of indefinetely trying to do something)
     
    Last edited: Feb 7, 2014
  6. Timeslip

    Timeslip Water Chip? Been There, Done That
    Modder

    921
    Aug 15, 2007
    Yes, as far as I can tell, the description in the ini has always been wrong, plus it referred to a feature that has never actually existed. And the code has always been bugged such that turning on the size limit for non-party members has never been possible... Here's the new description I added:
    Code:
    ;These options modify the checks to see if a critter can carry an additional item, changing which items are counted towards the weight limit and adding an additional size check
    ;Set the mode to 0 to disable the size check, 1 to apply to pc only, 2 to apply to the pc and party members, or 3 to apply to all critters
    ;Only the PC uses CritterInvSizeLimit. Other critters will use the extra unused stat (STAT_unused = 10)
    ;Add 4 to the mode to limit the weight check to used items only
    
    I'm not actually sure what'll happen if you use this new option and try to move an item from your inventory to your hands when it would take you over the weight limit... Probably should have checked that. >.>
     
    Last edited: Feb 7, 2014
  7. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    Like trying to put a 500 lb item from inventory on active slots in Mode 4?
    Just did the test. With a 1000 lb Assault Rifle in my hands (Total WT displayed in red), I can still run around like nothing and shoot people, plus pick up stuff on the ground.
    Now it's actually more like an unlimited carry weight cheat. :razz:
     
    Last edited: Feb 7, 2014
  8. Timeslip

    Timeslip Water Chip? Been There, Done That
    Modder

    921
    Aug 15, 2007
    I've updated the modders pack with the new compiler. novarain seems to have already taken care of the dll. :)

    Shame. I would have expected it to block you from running and picking more stuff up, if not to actually stop you putting it in your hands. Looks like I have a bit more work to do there. :p
     
  9. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Just for what it's worth: I was hoping it'd work this way. Just wanted to introduce movement/AP/THC penalties; not make it impossible. It's just nice that it's now obvious why you're getting the penalties.
     
  10. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    Sorry, I don't get it. In my test I don't seem to have any penalty.
    Do you mean with your upcoming mod and mode 4 setting, I'll get the movement penalty even not in the combat?
     
  11. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    In my mod. Doesn't matter that you don't get the penalties outside of combat: it's not like unequiping your heavy armor and weapon before entering combat is a sensible tactic anyway. I really dislike the way the original carry weight system worked: it essentially just said to players that they shouldn't take low strength because they'd spend most of their time juggling equipment with their mules (and inexplicably not being able to trade using their items). Now I think it'll be more interesting: low strength isn't a question of more annoyance, but taking decisions based on what armor/weapons combination you can use (also, I no longer have the original system for min ST reqs for weapons, so that doesn't stack).
     
  12. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    I'm interested, if there is some kind of in-depth guide (reference) for all of the SSL + sfall scripting language features?
    For example, it would be cool to have a syntax sugar to define an array like this:
    Code:
    arr := [1, 2, 3, 6, 8];
    basically doing this:
    Code:
    arr := temp_array(4, 5);
    arr[0] := 1;
    arr[1] := 2;
    arr[2] := 3;
    arr[3] := 6;
    arr[4] := 8;
    
    Another question, can you somehow define procedure with variable number of arguments? Like this:
    Code:
    procedure aaabbb(...) begin
       display_str("Arguments: "+arg[0]+", "+arg[1];
    end
    
    If Timeslip will ever read this: it would be great to have ability to define arrays that don't go to a savegame (like create_array) and don't get erased on every frame (like temp_array). This types of arrays are IMHO most useful, because they could've been defined in init of a global or a hook script and then used efficiently throughout the script lifetime, without worrying of savegame corruption (data leak). This is not a big issue, since we can use sfall_global to store array ID in, but it still feels wrong to store unnecessary data inside savegame (both sfall global and an array itself have nothing to do inside a savegame in many cases).

    Another wish: when reading array index that doesn't exist, make some graceful exception (like returning 0 and writing to debug.log), instead of crashing the game with no explanation :)
     
    Last edited: Feb 22, 2014
  13. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    @Timeslip, could you add this ammo formula (doesn't have to be as formula 6 of course)?

    Code:
    // Jim's Formula
    static __declspec(naked) void DamageFunction6() {
        __asm {
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDivisor;            // Retrieve Ammo Divisor
            imul ebp,eax;                // Ammo Divisor = 1 * Ammo Divisor (ebp set to 1 earlier in function)
            mov ebx,dword ptr ss:[esp+0x1c];    // Get number of hits
            xor ecx,ecx;                // Set loop counter to zero
            test ebx,ebx;                // Is number of hits smaller than= 0?
            jle end;        // If yes, jump beyond damage calculation loop
    ajmp:                            // Start of damage calculation loop
            mov edx,dword ptr ds:[esi+0x4];        // Get pointer to weapon (?)
            mov eax,dword ptr ds:[esi];        // Get pointer to critter (?)
            mov ebx,dword ptr ss:[esp+0x18];    // Get Bonus Ranged Damage
            call DamageFunctionSub1;        // Retrieve Raw Damage
            add ebx,eax;                 // Raw Damage = Raw Damage + Bonus Ranged Damage
            mov edx,dword ptr ss:[esp+0x28];    // Get armor DT
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDTMod;            // Retrieve ammo AM (Armor Modifier: adds or removes a percentage of the DT and DR)  
            cmp edx,eax;                // is ammo DT bigger than AM
            jge ijmp;                // If yes, go to end of calc because threshold not met
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDividend;            // Retrieve Ammo Dividend
            imul ebx,eax;                // Raw Damage = Raw Damage * Ammo Dividend
            test ebp,ebp;                // Is Ammo Divisor == 0?
            je djmp;                // If yes, avoid divide by zero error
            mov edx,ebx;
            mov eax,ebx;
            sar edx,0x1f;
            idiv ebp;
            mov ebx,eax;                // Otherwise, Raw Damage = Raw Damage / Ammo Divisor
    djmp:
            mov edx,dword ptr ss:[esp+0x2c];    // Get armor DR
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDTMod;            // Retrieve ammo AM
            imul edx,eax;                // DR modifier = armor DR * ammo AM
            mov dword ptr ss:[esp+0x30],0x64;    //sets some variable to 100
            mov eax,edx;                //(not sure if I have to do this, but Haen does it)
            sar edx,0x1f;                // makes DR modifier the dividend
            idiv dword ptr ss:[esp+0x30];        // DR modifier = DR modifier / 100
            mov edx,dword ptr ss:[esp+0x2c];    // Get armor DR
            sub edx,eax;                // DR = DR - DR modifier (can be negative)
            test edx,edx;                // Is DR >= 0?
            jge gjmp;
            xor edx,edx;                // If no, set DR = 0
            jmp hjmp;
    gjmp:
            cmp edx,0x64;                // Otherwise, is DR bigger than or equal to 100?
            jge ijmp;                // If yes, damage will be zero, so stop calculating and go to bottom of loop
    hjmp:
            imul edx,ebx;                // Otherwise, Resisted Damage = DR * Raw Damage
            mov dword ptr ss:[esp+0x30],0x64;
            mov eax,edx;
            sar edx,0x1f;
            idiv dword ptr ss:[esp+0x30];        // Resisted Damage = Resisted Damage / 100
            sub ebx,eax;                // Raw Damage = Raw Damage - Resisted Damage
            test ebx,ebx;                // Is Raw Damage smaller than 0?
            jle ijmp;                // If yes, don't accumulate damage
            add dword ptr ds:[edi],ebx;        // Otherwise, Accumulated Damage = Accumulated Damage + Raw Damage
    ijmp:
            mov eax,dword ptr ss:[esp+0x1c];    // Get number of hits
            inc ecx;                // counter += 1
            cmp ecx,eax;                // Is counter smaller than number of hits?
            jl ajmp;                // If yes, go back to start of damage calcuation loop (calculate damage for next hit)
    end:
            jmp DamageFunctionReturn;        // Otherwise, exit loop
        }
    }
    Also, another request because of being spoiled: could you allow for disabling the hard-coded effects of cripplings (i.e. forced walking for crippled legs, unable to use 2-handed weapons with crippled arms)? I want to make different degress of crippled effects, that's why I ask.
     
    Last edited by a moderator: Jan 9, 2016
  14. Endocore

    Endocore Look, Ma! Two Heads!
    Modder

    362
    Mar 14, 2010
    Hi Timeslip. Something seems wrong with the set_self sfall scripting function. I made a global variable (let's call it 800) and elsewhere stored a critter pid in it (let's say 16777311 for a random encounter trapper). Let's say I also added a text line 1500 ("I'm thinking of ") to obj_dude.msg. Then in obj_dude.int I wrote (as part of a larger clause of course):

    op_set_self(op_global_var(800));
    op_float_msg(op_dude_obj(), op_message_str(1, 1500) + op_obj_name(op_self_obj()), 5);

    During gameplay the output text was:


    I'm thinking of None
    <none> <none>
    However, when I used the standard (non-sfall scripting) function:

    op_float_msg(op_dude_obj(), op_message_str(1, 1500) + op_proto_data(op_global_var(800), 1), 5);

    I obtained the correct and expected output text:

    I'm thinking of Trapper.

    It's no big deal, as I said I found a way to accomplish what I wanted without set_self, but I thought you'd want to know about the issue.

    Just for the sake of thoroughness, I'll mention that when I tried simply:

    op_float_msg(op_dude_obj(), op_message_str(1, 1500) + op_obj_name(op_global_var(800)), 5);

    I obtained the rather unexpected result:

    I'm thinking of Critter
    <critter><critter>

    Thanks for all your hard work on sfall, keep up the great effort.</critter></critter></none></none>
     
    Last edited: Feb 22, 2014
  15. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    The optimization in sslc is broken. Crazy side effects are observed like merging variables when they shouldn't be merged... It would be cool to be able to set optimize level in Script editor and inside sslc itself, don't merge variables or other crazy unstable stuff at optimize level 1 for example... I don't want to remove optimization altogether, there are useful features like removing unused procedures.

    Edit: I think I've found a serious problem with list_as_array(LIST_CRITTERS) function.
    I use code like this:
    Code:
    foreach crit in list_as_array(LIST_CRITTERS) begin
     ...
    end
    
    Now, in some cases, if I try to access "crit" directly (for example, doing debug_msg("crit: "+crit), game crashes). If I use tile_num(crit), game don't crash but script is failed with error "invalid argument to tile_num" in the logs.
    If I wrap my loop with additional check like so:
    Code:
    foreach crit in list_as_array(LIST_CRITTERS) if (crit) then begin
     ...
    end
    
    It doesn't crash.
     
    Last edited: Feb 23, 2014
  16. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    I was wondering, is it possible to refresh the graphics so as to force the AP counter to display the correct number (specifically, I want to have an option to spend AP's to aim, but can't find a way to have this represented graphically in the counter)? I tried force_graphics_refresh(true) but that's probably meant for something else.
     
  17. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    @Timeslip, there seems to be a bug in the afterhitroll hookscript, the third return argument doesn't change the target, but the attacker strangely enough. If you use it in the intended way, the intended target simply attacks himself.
     
    Last edited by a moderator: Jan 9, 2016
  18. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    My unofficial sfall compiles updated to SVN r263e (3.2.1.2634): (removed due to newer updates)
    (The dll in "trace" folder is equal to the "debugging" one in modder's pack.)

    Glovz updated his damage calculation to v4. The general process is still the same as v3, but now both amX & amY can be any positive integer rather than limited to maximum 9, and the bonus damage is only applied for unarmored (armDT=0 & armDR=0) targets.
     
    Last edited: Sep 3, 2014
  19. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    @Timeslip, sorry, but I inconsiderately added my own version of the ddraw.dll (not the .ini) to my mod. If you want me to take it down I will of course. Is there a chance you could add the following as a separate ammo formula (it has a couple of small changes from the previous one)? I'm overriding Haen's formula currently...

    Code:
    // Jim's Formula
    static __declspec(naked) void DamageFunction5() {
        __asm {
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDivisor;            // Retrieve Ammo Divisor
            imul ebp,eax;                // Ammo Divisor = 1 * Ammo Divisor (ebp set to 1 earlier in function)
            mov ebx,dword ptr ss:[esp+0x1c];    // Get number of hits
            xor ecx,ecx;                // Set loop counter to zero
            test ebx,ebx;                // Is number of hits smaller than= 0?
            jle end;        // If yes, jump beyond damage calculation loop
    ajmp:                            // Start of damage calculation loop
            mov edx,dword ptr ds:[esi+0x4];        // Get pointer to weapon (?)
            mov eax,dword ptr ds:[esi];        // Get pointer to critter (?)
            call DamageFunctionSub1;        // Retrieve Raw Damage
            mov ebx,eax;                 // Move Raw Damage to ebx
            mov edx,dword ptr ss:[esp+0x28];    // Get armor DT
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDTMod;            // Retrieve ammo AM (Armor Modifier: adds or removes a percentage of the DT and DR)  
            cmp edx,eax;                // is ammo DT bigger than AM
            jge ijmp;                // If yes, go to end of calc because threshold not met
            mov edx,dword ptr ss:[esp+0x2c];    // Get armor DR
            mov eax,dword ptr ds:[esi+0x8];        // Get pointer to critter's weapon
            call GetAmmoDTMod;            // Retrieve ammo AM
            imul edx,eax;                // DR modifier = armor DR * ammo AM
            mov dword ptr ss:[esp+0x30],0x64;    //sets some variable to 100
            mov eax,edx;                //(not sure if I have to do this, but Haen does it)
            sar edx,0x1f;                // makes DR modifier the dividend
            idiv dword ptr ss:[esp+0x30];        // DR modifier = DR modifier / 100
            mov edx,dword ptr ss:[esp+0x2c];    // Get armor DR
            sub edx,eax;                // DR = DR - DR modifier (can be negative)
            test edx,edx;                // Is DR >= 0?
            jge gjmp;
            xor edx,edx;                // If no, set DR = 0
            jmp hjmp;
    gjmp:
            cmp edx,0x64;                // Otherwise, is DR bigger than or equal to 100?
            jge ijmp;                // If yes, damage will be zero, so stop calculating and go to bottom of loop
    hjmp:
            imul edx,ebx;                // Otherwise, Resisted Damage = DR * Raw Damage
            mov dword ptr ss:[esp+0x30],0x64;
            mov eax,edx;
            sar edx,0x1f;
            idiv dword ptr ss:[esp+0x30];        // Resisted Damage = Resisted Damage / 100
            sub ebx,eax;                // Raw Damage = Raw Damage - Resisted Damage
            test ebx,ebx;                // Is Raw Damage smaller than 0?
            jle ijmp;                // If yes, don't accumulate damage
            add dword ptr ds:[edi],ebx;        // Otherwise, Accumulated Damage = Accumulated Damage + Raw Damage
    ijmp:
            mov eax,dword ptr ss:[esp+0x1c];    // Get number of hits
            inc ecx;                // counter += 1
            cmp ecx,eax;                // Is counter smaller than number of hits?
            jl ajmp;                // If yes, go back to start of damage calcuation loop (calculate damage for next hit)
    end:
            jmp DamageFunctionReturn;        // Otherwise, exit loop
        }
    }
     
    Last edited by a moderator: Jan 9, 2016
  20. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    My unofficial sfall compiles updated to SVN r263f (3.2.1.2635): (removed due to newer updates)
    (The DLLs in "trace" folders are equal to the "debugging" one in the modder's pack.)

    Glovz's damage calculation fix got updated to v5. The general process is still the same as previous versions, but the code itself got overhauled for some serious optimizations and readability improvements.
    He also added a version with his damage multiplier tweak: Critical Damage = Net Damage + (Net Damage * 25% * Critical Multiplier)
    (In vanilla & Glovz's fix: Critical Damage = ND*CM/2)

    I also added Jim's formula above as function 4. Now DamageFormula setting in sfall INI should be:
    Code:
    ;Choose the damage formula used to calculate combat damage.
    ;Don't set this to anything other than 0 unless another mod you're using explicitly tells you to!
    ;0 - Fallout default
    ;1 - Glovz's Damage Fix
    ;2 - Glovz's Damage Fix with Damage Multiplier tweak
    ;4 - Jim's Formula
    ;5 - Haenlomal's Yet Another Ammo Mod.
    DamageFormula=0
     
    Last edited: Sep 3, 2014
    • [Like] [Like] x 1