Fallout 2 mod FO2 Engine Tweaks (Sfall)

sfall 3.8.2 is released on SourceForge, along with modders pack (only a document update) and win2k version.
Changelog said:
v3.8.2
>Fixed broken call_offset_* functions
>Fixed OverrideMusicDir not using the correct path string
>Fixed a bug in metarule2_explosions function that caused damage type change not to work
>Fixed a crash if calling reg_anim_obj_run_to_tile after reg_anim_combat_check
>Changed sfallgv.sav to be loaded before other save game files to make saved arrays available in the start procedure
>Changed BodyHit_Torso to BodyHit_Torso_Uncalled because it sets both body_torso and body_uncalled hit modifiers

Original engine bug fixes and various features based on the work by Crafty:
>Added a fix for display issues when calling gdialog_mod_barter with critters with no 'Barter' flag set
>Added a fix for the original engine issue that caused items to disappear from inventory when you try to drag them to bag/backpack in the inventory list and are overloaded
>Added a fix for the original engine issue that caused the game not to check player's inventory properly when putting items into the bag/backpack in the hands
>Added a fix for the original engine issue that caused the current carry weight and the range of equipped weapons being lowered temporarily when opening bag/backpack
>Added a fix for a crash when trying to open bag/backpack on the table in the bartering interface
>Added the ability to move items out of bag/backpack and back into the main inventory list by dragging them to character's image (similar to Fallout 1 behavior)
>Changed WorldMapEncounterFix/Rate to work independently of WorldMapFPSPatch
A note for any modder who wants to use hs_invenwield hook script:
When replacing a previously wielded armor or weapon, the unwielding hook will not be executed. You'll need to check if an armor/weapon is already equipped when wielding hook is executed; otherwise, the script could be exploitable or have unexpected side effects.

For example, I want to make party members gain 2 AP when wearing an armor and code hs_invenwield like this:
Code:
// hs_invenwield.ssl
procedure start;
#include ".\HEADERS\DEFINE.H"

procedure start begin
    if not init_hook then begin
        variable critter := get_sfall_arg, item := get_sfall_arg, slot := get_sfall_arg, hooktype := get_sfall_arg;
        if ((slot == INVEN_TYPE_WORN) and (party_member_obj(obj_pid(critter)) != 0)) then begin
            if (hooktype == 1) then begin
                set_critter_extra_stat(critter, STAT_max_move_points, get_critter_extra_stat(critter, STAT_max_move_points) + 2);
            end else begin
                set_critter_extra_stat(critter, STAT_max_move_points, get_critter_extra_stat(critter, STAT_max_move_points) - 2);
            end
            display_msg(hooktype + ", " + obj_name(item) + ", " + get_critter_extra_stat(critter, STAT_max_move_points));
        end
    end
end
The logic is pretty straightforward: if wielding (hooktype == 1) an armor, +2 AP to the critter; else it should be unwielding (what else could happen?), so -2 AP from the critter.
But if I give a leather jacket to Sulik (or anyone) and wield on him with "Use Best Armor" button, then without telling him to remove the jacket, give him a leather armor and wield again - I will see him receiving an unplanned +2 AP. So as long as I keep replacing better armors for party members, they will gain more and more AP.

To fix the exploit and prevent party members from having too many AP, I need to check if there's an armor already equipped:
Code:
// hs_invenwield.ssl
procedure start;
#include ".\HEADERS\DEFINE.H"

procedure start begin
    if not init_hook then begin
        variable critter := get_sfall_arg, item := get_sfall_arg, slot := get_sfall_arg, hooktype := get_sfall_arg;
        if ((slot == INVEN_TYPE_WORN) and (party_member_obj(obj_pid(critter)) != 0)) then begin
            if ((hooktype == 1) and obj_pid(critter_inven_obj(critter, slot)) <= 0) then begin
                set_critter_extra_stat(critter, STAT_max_move_points, get_critter_extra_stat(critter, STAT_max_move_points) + 2);
            end else if (hooktype == 0) then begin
                set_critter_extra_stat(critter, STAT_max_move_points, get_critter_extra_stat(critter, STAT_max_move_points) - 2);
            end
            display_msg(hooktype + ", " + obj_name(item) + ", " + get_critter_extra_stat(critter, STAT_max_move_points));
        end
    end
end
 
Last edited:
>Added a fix for the original engine issue that caused the game not to check player's inventory properly when putting items into the bag/backpack in the hands

Does this mean we can add bags to the game and scripts will recognize items in them now?
 
Does this mean we can add bags to the game and scripts will recognize items in them now?
The fix was only for "when putting items into the bag/backpack in the hands". When you put a bag in your hands, the game doesn't think the bag belonging to the player. So you can keep dragging items into the bag in hands while you're overloaded, but it's not the same for dragging items to bag/backpack in the inventory list. It's mostly for the consistency's sake.

I only tested the flint/sharpened spear quest in Arroyo, and the game did remove the flint from my bag. BUT the bag cheat/exploit for keeping items that are supposed to be removed by scripts is still there.
Per's guide said:
The Bag is responsible for an inventory bug which sometimes lets you keep items that are really supposed to disappear from your inventory, depending on which script command is being used to remove them. Items are "protected" if they're below the Bag in your inventory, apparently because the engine can't handle the container item type properly.
 
I've opened an issue for it on GitHub. phobos2077 might look into this later.

EDIT: it's fixed.
 
Last edited:
>Fixed a crash if calling reg_anim_obj_run_to_tile after reg_anim_combat_check
Code:
reg_anim_combat_check(0);
   reg_anim_begin();
   reg_anim_animate_forever(self_obj, ANIM_stand);
   reg_anim_end();
SafeWrite8(0x45AE53, reg_anim_combat_check); // reg_anim_animate_forever
This will not work for forever animations, the game will simply hang (loops on clocks cursor).

Code:
procedure damage_p_proc begin

   reg_anim_combat_check(0);
   reg_anim_begin();
   reg_anim_animate(Door, ANIM_stand, 0);
   reg_anim_end();

end
This also not work. Game loops on clocks after animation.
Others have not yet been tested.

@Phobos:

Я Crafty как-то давно просил чтобы он подобное сделал, чтобы анимация работала в режиме боя но только для функции Anim(), в общем он сделал, и игра не виснет по окончании анимации.
Теперь на его sfall'е совместно с reg_anim_combat_check(0) и reg_anim_animate работает без зависания игры (без конечная прокрутка часиков).
Другие функции я пока не проверял. В общем посмотрите что он там изменил, подробно можно на форуме http://fforum.kochegarov.com/ почитать.
 
Last edited:
This will not work for forever animations, the game will simply hang (loops on clocks cursor).
What else do you expect? I thought they are supposed to be used out of combat to animate things forever (like fire furnaces on Arroyo Temple entrance). In combat the game "waits" until animations are completed. If I'm not mistaken, it is designed that way.

Code:
procedure damage_p_proc begin

   reg_anim_combat_check(0);
   reg_anim_begin();
   reg_anim_animate(Door, ANIM_stand, 0);
   reg_anim_end();

end
This also not work. Game loops on clocks after animation.
Others have not yet been tested.
Have you tried passing -1 as third argument to reg_anim_animate() ?

I used these functions with reg_anim_combat_check in my mod successfully in the past. It used to animate death of critters when they are killed in the trap during their combat turn - works fine.

Я Crafty как-то давно просил чтобы он подобное сделал, чтобы анимация работала в режиме боя но только для функции Anim(), в общем он сделал, и игра не виснет по окончании анимации.
Теперь на его sfall'е совместно с reg_anim_combat_check(0) и reg_anim_animate работает без зависания игры (без конечная прокрутка часиков).
Некоторые вещи которые он "фиксит" для вас в движке можно решить скриптово. Так что это вообще не показатель :)
Как мне кажется, sfall должен предоставлять доступ к низкоуровневым функциям движка которые ранее были недоступны через скрипты, а также фиксить очевидные баги в коде. Пытаться на уровне sfall исправить корявый дизайн - гиблое дело, затратно и лишь усложняет и без того чрезмерно сложный код sfall.

English: In my opinion, sfall should not attempt to fix bad design of the game engine (we have falltergeist for this :D ), only fix obvious and simple bugs and provide access to low-level engine functions that already exist and used by game itself. Sfall codebase is a huge mess already - a lot of stuff that is too complex to understand or maintain. Let's try to keep it simple, guys :)


My thoughts on current state of the project(s). At this point we have 2 groups of people working on 2 different forks of sfall - both have different vision on what sfall should do and what shouldn't. You cannot expect us to merge all Crafty's changes, simply because Crafty has very different opinion on how to make the project "better". We all people who work in our spare time on sfall (oftentimes it seems people forget about this a lot, when request stuff...). We don't get paid for this, so we need some other benefits for our time. It's not fun for me to work with a lot of ASM code and complex remapping of game logic - so it's not fun to merge most of Crafty's work :)
Much more interesting to work with the C++ part, making the whole code base easier to understand and maintain. Some people said that ASM code is easier to understand than C++. I still don't agree with this. Only because now there is like 4 people working on this, 2 of them like ASM and so it seems they are a lot. But in general, there are more people (potential modders) who more likely to understand C++ code better.
On the other hand, Crafty's fork is moving in another direction - he rewrite high-level code with low-level code where it's not strictly required (like Combat Control module).

So again, please don't expect us to merge stuff from another fork, just because it exists. If the idea is useful and there is no scripting solution already available, we can re-implement it.
 
Last edited:
What else do you expect?
ничего не ожидаю) просто контактирую факт, что оно не будет работать, зачем делать лишнюю правку для движка.

Have you tried passing -1 as third argument to reg_anim_animate() ?
This not used, always = -1

I used these functions with reg_anim_combat_check in my mod successfully in the past. It used to animate death of critters when they are killed in the trap during their combat turn - works fine.
metalure2_explosion... у тебя тоже замечательно работало ;)
Но в обработчике damage_p_proc это к сожалению не работает, по той же причине почему и не работает Anim(), естественно до правки Crafty.

Некоторые вещи которые он "фиксит" для вас в движке можно решить скриптово. Так что это вообще не показатель :)
Пытаться на уровне sfall исправить корявый дизайн - гиблое дело, затратно и лишь усложняет и без того чрезмерно сложный код sfall.
1. Проигрывание анимации в бою ну никак не решить скриптово.
2. Ну а что поделать если движок ограничен в плане модинга.

Как мне кажется, sfall должен предоставлять доступ к низкоуровневым функциям движка которые ранее были недоступны через скрипты, а также фиксить очевидные баги в коде.
Оно и заметно как вы исправляете баги, не в обиду вам будет сказано, но только Crafty и фиксит эти баги. - Сколько раз писал исправьте краш игры при клике по пустому месту в инвентаре(use который) игрока. Ведь даже искать ничего не надо в движке просто скопировать, то что исправил Crafty у себя, элементарные вещи ведь.
- Скопировали потом переписываете по мере возможности на ваш понятный С++
Мне вот как простому обывателю все равно на каком там (в сфалле) языке написан фикс для исправления бага, мне главное конечный результат.
А вы простите тяните кота за яйики :)
 
Но в обработчике damage_p_proc это к сожалению не работает, по той же причине почему и не работает Anim(), естественно до правки Crafty.
Надо смотреть и разбираться. В хук-скриптах это точно работало... Пишите issue на гитхаб с полноценными примерами.

2. Ну а что поделать если движок ограничен в плане модинга.
Выносить движковые функции в скрипты - и все. Чинить функции которые откровенно сломаны. Но не пытаться что-либо переделывать внутри движка, просто потому-что кому-то показалось что "так надо".

Оно и заметно как вы исправляете баги, не в обиду вам будет сказано, но только Crafty и фиксит эти баги. - Сколько раз писал исправьте краш игры при клике по пустому месту в инвентаре(use который) игрока. Ведь даже искать ничего не надо в движке просто скопировать, то что исправил Crafty у себя, элементарные вещи ведь.
Вот именно из за такого отношения и не хочется заниматься переносом. Писали - куда? Хорошо что он фиксит, плохо что в нашу версию sfall просто так "фиксы" не перенесешь (за исключением изолированных небольших правок). Просто копировать нельзя... Нужно разобраться что код конкретно делает, иначе не гарантировать корректность. В итоге тратишь кучу времени на перенос чужого кода - а какбы и заслуги твоей в этом нет... Хорошо что есть NovaRain которому не влом этим заниматься :)

- Скопировали потом переписываете по мере возможности на ваш понятный С++
Мне вот как простому обывателю все равно на каком там (в сфалле) языке написан фикс для исправления бага, мне главное конечный результат.
На гитхабе его репа сто лет не обновлялась, только в архивах. Скоро видимо и вовсе не достать будет. Какая-то нездоровая тенденция прятать исходники пошла.

Вот честное слово, лучше бы поделился с народом своими наработки по реверсу движка. Вот там реально огромная работа им проделана и большая заслуга - но все это впустую, если ему вдруг надоест этим заниматься - база IDA так и останется пылиться на жестком диске...

Сделайте нормальный репозиторий на гитхабе и перестаньте крысить свои наработки...
 
Last edited:
Надо смотреть и разбираться. В хук-скриптах это точно работало...
Не отрицаю, что это где-то работает.

Пишите issue на гитхаб с полноценными примерами.
Вы что издеваетесь?) чего там разбираться, создавать что-то на гитхаб,
когда уже все готово и требуется перенести основной код asm-вставки (из AnimationsAtOnceLimit.cpp) и подправить код сфалла.
Code:
static void __declspec(naked) anim_set_end_hook() {
 __asm {
  mov  edi, _anim_set
  cmp  dword ptr AnimationsLimit, 32
  jbe  skip
  mov  edi, anim_set
  add  edi, 2656                          // Учитываем пустышку
skip:
  test dl, 0x2                              // Установлен флаг боя?
  jz   end                                   // Нет
  call combat_anim_finished_
end:
  mov  [edi][esi], ebx
  push 0x415DF2
  retn
 }
}
Делов всего на 30 минут времени, даже я особо не разбирающийся в этом, перенес и теперь работает и с официальной dll 3.8.2.

Но не пытаться что-либо переделывать внутри движка, просто потому-что кому-то показалось что "так надо".
Вот поэтому я и просил сделать что-то на подобное USER-HOOK, что бы не было такого что кому-то надо а команде разработчиков фалла не надо) - вынес в скрипт и и забыл.

если ему вдруг надоест этим заниматься - база IDA так и останется пылиться на жестком диске...
с IDA да не хочет делиться эдакий гад)

Эх, кое чему не суждено сбыться.
Новому движку для F2 :)
 
Last edited:
Делов всего на 30 минут времени, даже я особо не разбирающийся в этом, перенес и теперь работает и с официальной dll 3.8.2.
Вот молодец, так бы сразу и сделал :) Идеально конечно - pull request, но можешь и просто закинуть в issue (в следующий раз).

Вот поэтому я и просил сделать что-то на подобное USER-HOOK, что бы не было такого что кому-то надо а команде разработчиков фалла не надо) - вынес в скрипт и и забыл.
А я и не против сделать. Для отладки полезно будет. Базовую идею сделать не сложно, но ты бы предложил подробнее что как должно работать (например надо ли какие-нибудь регистры автоматом чтобы передавались в get_sfall_args).

Новому движку для F2 :)
Вот че сразу так, а? :) Да там уже считай все самое сложное написано (форматы, рендеринг, освещение, даже головы вроде есть). Осталось только игровую логику прикрутить.
 
Идеально конечно - pull request.
Ага) как только разберусь с этой непонятной штукой.

Базовую идею сделать не сложно, но ты бы предложил подробнее что как должно работать (например надо ли какие-нибудь регистры автоматом чтобы передавались в get_sfall_args).
Вообще без понятия...
Ну вот к примеру такая задача на примере сегодняшнего кода с ams вставкой(что привел выше), требуется его вставить в наш так называемый скрипт, чтобы не делать pull-request для вас и не пересобирать под себя сфалл.
Сможешь это реализовать отдельно не залезая в код сфала считай задача выполнена, а дальше напильником. :)
Но что-то мне кажется это не реально сделать, много нюансов будет.
 
Last edited:
Does anyone have any ideas about tidying up the settings in ddraw.ini? Right now there's a mess, most settings are bundled together in MISC section - they can be split into many small sections for each module.
Also some settings in Debugging section doesn't belong there anymore. Namely the SkipSizeCheck and ExtraCRC - some people use them for playing, not for debugging (there are some patched EXE's which are compatible with sfall, yet has some changes in size and/or content). Also some modders use unsafe scripting extensively for their mods...

Russian:
Есть у кого мысли по поводу раскидать опции в ddraw.ini по разным секциям? Сейчас почти все запихано в MISC. Кроме того в секции Debugging есть опции которые уже не какбы относятся к отладке...
 
Also some settings in Debugging section doesn't belong there anymore. Namely the SkipSizeCheck and ExtraCRC - some people use them for playing, not for debugging (there are some patched EXE's which are compatible with sfall, yet has some changes in size and/or content). Also some modders use unsafe scripting extensively for their mods...
If we don't go for the splitting, the easy way is to move those two to [Misc] IMO. I think it's better that unsafe script functions and some other stuff still require enabling sfall debug mode first.
Or just make those two not require enabling sfall debug mode and keep them in [Debugging] for the compatibility with existing INI files. Maybe add a note about this in the INI.
Or simply remove the master switch in [Debugging] and make all options in the section available freely, like the old "trace/debugging" dll in old modders pack, but it could be kinda dangerous.
 
Last edited:
The main thing that was backwards compatible with old configs, otherwise the configs need to be redone for the new version.

Главное что-бы была обратная совместимость со старыми конфигами, иначе конфиги нужно будет переделывать под новый вариант.
 
The main thing that was backwards compatible with old configs, otherwise the configs need to be redone for the new version.

Главное что-бы была обратная совместимость со старыми конфигами, иначе конфиги нужно будет переделывать под новый вариант.

Yeah, this is why I'm very reluctant to change configs. We can rewrite all code and get away with it as long as the same configs and scripts continue to work for people :)
(unless someone makes config convertion tool which is a hassle)
 
Does anyone still uses any of the Glovz damage formulas? I would really like to remove those from sfall, since you can write any formula you want with a global script.
 
Back
Top