Compare commits

..
6 Commits
Author SHA1 Message Date
NovaRain 38e1eaef64 Updated version number and changelog 2026-02-25 22:04:49 +08:00
NovaRain f408534ce4 Cosmetic edits: renamed some return addr variables in hacks 2026-02-25 21:16:06 +08:00
NovaRain e9c73e6dd3 Updated web document for set_pipboy_available script function 2026-02-24 08:34:20 +08:00
NovaRain bac9e630f9 Added a safeguard to the death animation fix on combat start 2026-02-23 15:23:23 +08:00
NovaRainandGitHub d5c79deb12 Merge pull request #614 from sfall-team/dependabot/bundler/docs/nokogiri-1.19.1
Bump nokogiri from 1.18.9 to 1.19.1 in /docs
2026-02-20 08:51:14 +08:00
dependabot[bot]andGitHub adfc8d851b Bump nokogiri from 1.18.9 to 1.19.1 in /docs
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.18.9 to 1.19.1.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.18.9...v1.19.1)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-version: 1.19.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-20 00:14:16 +00:00
15 changed files with 47 additions and 40 deletions
+7 -4
View File
@@ -1,5 +1,8 @@
# Changelog
## 4.4.9.1
* Fixed a crash bug introduced in 4.4.6 when the player is hit and combat starts at the same time
## 4.4.9
* Fixed the edge-scrolling speed when using the game speed tweak
* Fixed incorrect unarmed damage being displayed in the inventory under specific conditions
@@ -53,7 +56,7 @@
* Added a fix for the duplicate click sound when selecting a location in the Status section of the pipboy
* Added a fix for extra hidden buttons below the location list in the Status section of the pipboy
* Added a fix for map lighting from **Night Vision** perk not updating when loading a saved game
* Added a fix for an animation glitch when death animations and combat start simultaneously
* Added a fix for an animation glitch when death animations and combat start at the same time
* Added a fix to prevent the game from hanging when reloading a weapon overloaded with ammo via the interface bar
* Added a few fixes for issues related to weapons with negative ammo
* Added a tweak to replace death animations on critters with single-frame variants on map load
@@ -320,14 +323,14 @@
* Updated French translation (from HawK-EyE)
## 4.3.0.1
* Fixed a crash bug introduced in 4.3 with the fix for animation registration
* Fixed a crash bug introduced in 4.3 by the fix for animation registration
* Fixed a bug in **AIDrugUsePerfFix** that could cause a hang in combat
* Fixed the extra check for friendly fire not working if the `area_attack_mode` parameter in the AI packet is not set or set to `no_pref`
* Added a fix for `chem_primary_desire` values in party member AI packets not being saved and reset correctly
## 4.3
* Fixed the original engine issues with being unable to register animations in certain situations in the game
* Fixed a crash bug introduced in 4.2.9 with the fix for the **'Leave'** event procedure in `AddRegionProc` function
* Fixed a crash bug introduced in 4.2.9 by the fix for the **'Leave'** event procedure in `AddRegionProc` function
* Fixed a bug in **ObjCanSeeObj_ShootThru_Fix** that could cause a hang in some cases
* Fixed the check of the ammo cost for a shot in **CheckWeaponAmmoCost**
* Fixed `set_critter_burst_disable` script function, which now applies only to weapons with the burst attack as the secondary mode
@@ -567,7 +570,7 @@
* New hook script: `hs_targetobject`
## 4.2.1.1
* Fixed a crash bug introduced in 4.2.1 with the fix for corpses blocking line of fire
* Fixed a crash bug introduced in 4.2.1 by the fix for corpses blocking line of fire
## 4.2.1
* Fixed a bug in `save_array` script function that could corrupt `sfallgv.sav` when saving a new array under the same key
+1 -1
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v4.4.9
;v4.4.9.1
[Main]
;Set to 1 to enable the built-in High Resolution Patch mode that is similar to the hi-res patch by Mash
+4 -1
View File
@@ -906,7 +906,10 @@
opcode: 0x8177
- name: set_pipboy_available
detail: void set_pipboy_available(int available)
doc: Sets the availability of the pipboy in the game. Use 0 to disable the pipboy, and 1 or 2 to enable it (value 2 does not mark the `VSUIT_MOVIE` movie as "played").
doc: |
Sets the availability of the pipboy in the game. Use 0 to disable the pipboy, and 1 or 2 to enable it (value 2 does not change the player's default appearance).
- The availability state will be reset each time the player reloads the game.
- __NOTE:__ starting from sfall 4.4.6/3.8.46, value 1 no longer marks the `VSUIT_MOVIE` movie as "played". Use `mark_movie_played(VSUIT_MOVIE)` instead if you want the old behavior.
opcode: 0x818b
- name: get_kill_counter
detail: int get_kill_counter(int critterType)
+1 -1
View File
@@ -218,7 +218,7 @@ GEM
minitest (5.24.1)
net-http (0.9.1)
uri (>= 0.11.1)
nokogiri (1.18.9-x86_64-linux-gnu)
nokogiri (1.19.1-x86_64-linux-gnu)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
+1 -1
View File
@@ -242,7 +242,7 @@ struct GameObject {
struct {
MiscFlags sceneryFlags; // unused for scenery? (aka updated_flags)
MiscFlags doorFlags; // used for doors states open/locked/jammed (aka cur_open_flags)
long unused[9]; // offset 0x40 (not saved)
long unused[9]; // offset 0x40 (not saved)
} scenery;
};
+8 -8
View File
@@ -49,7 +49,7 @@ static __declspec(naked) void ai_try_attack_hook_FleeFix() {
}
static __declspec(naked) void combat_ai_hook_FleeFix() {
static const DWORD combat_ai_hook_flee_Ret = 0x42B206;
static const DWORD combat_ai_flee_Ret = 0x42B206;
using namespace fo;
__asm {
test byte ptr [ebp], ReTarget; // CombatStateFlag flag (critter.combat_state)
@@ -60,7 +60,7 @@ reTarget:
xor edi, edi;
mov dword ptr [esi + whoHitMe], edi;
add esp, 4;
jmp combat_ai_hook_flee_Ret;
jmp combat_ai_flee_Ret;
}
}
@@ -74,14 +74,14 @@ static __declspec(naked) void ai_try_attack_hook_runFix() {
}
static __declspec(naked) void combat_ai_hack() {
static const DWORD combat_ai_hack_Ret = 0x42B204;
static const DWORD combat_ai_Ret = 0x42B204;
__asm {
mov edx, [ebx + 0x10]; // cap.min_hp
cmp eax, edx;
jl tryHeal; // curr_hp < min_hp
end:
add esp, 4;
jmp combat_ai_hack_Ret; // jump to call ai_check_drugs_
jmp combat_ai_Ret; // jump to call ai_check_drugs_
tryHeal:
push ecx;
push esi; // mov eax, esi;
@@ -383,7 +383,7 @@ static long __fastcall item_weapon_reload_cost_fix(fo::GameObject* source, fo::G
}
static __declspec(naked) void ai_try_attack_hook_cost_reload() {
static const DWORD ai_try_attack_hook_goNext_Ret = 0x42A9F2;
static const DWORD ai_try_attack_goNext_Ret = 0x42A9F2;
__asm {
push ebx; // ammoObj ref
mov ecx, eax; // source
@@ -394,7 +394,7 @@ static __declspec(naked) void ai_try_attack_hook_cost_reload() {
//noAPs: // not enough action points
// add esp, 4; // destroy ret
// mov edi, 10;
// jmp ai_try_attack_hook_goNext_Ret; // end ai_try_attack_
// jmp ai_try_attack_goNext_Ret; // end ai_try_attack_
}
}
@@ -484,7 +484,7 @@ skipMove:
}
static __declspec(naked) void ai_move_away_hook() {
static const DWORD ai_move_away_hook_Ret = 0x4289DA;
static const DWORD ai_move_away_Ret = 0x4289DA;
__asm {
test ebx, ebx;
jl fix; // distance arg < 0
@@ -495,7 +495,7 @@ fix:
cmp ebx, eax;
cmovg ebx, eax; // if (distance > ap) dist = ap
add esp, 4;
jmp ai_move_away_hook_Ret;
jmp ai_move_away_Ret;
}
}
+2 -1
View File
@@ -520,7 +520,8 @@ static void __stdcall combat_begin_anim_stop_hook() {
const fo::AnimationSet& set = animSet[i];
if (set.currentAnim >= 1 &&
(set.animations[set.currentAnim - 1].animType == fo::ANIM_TYPE_ANIMATE_FOREVER ||
((set.animations[set.currentAnim - 1].source->artFid & 0xFF0000) >> 16 >= fo::ANIM_fall_back &&
(set.animations[set.currentAnim - 1].source != nullptr &&
(set.animations[set.currentAnim - 1].source->artFid & 0xFF0000) >> 16 >= fo::ANIM_fall_back &&
(set.animations[set.currentAnim - 1].source->artFid & 0xFF0000) >> 16 <= fo::ANIM_fall_front_blood)))
{
continue;
+4 -4
View File
@@ -47,8 +47,8 @@ static sBook* __fastcall FindBook(DWORD pid) {
return 0;
}
static __declspec(naked) void obj_use_book_hook() {
static const DWORD obj_use_book_hook_back = 0x49BA5A;
static __declspec(naked) void obj_use_book_hack() {
static const DWORD obj_use_book_Ret = 0x49BA5A;
__asm {
mov edi, -1;
mov ecx, eax;
@@ -58,7 +58,7 @@ static __declspec(naked) void obj_use_book_hook() {
mov edi, [eax + 4]; // msgID
mov ecx, [eax + 8]; // skill
skip:
jmp obj_use_book_hook_back;
jmp obj_use_book_Ret;
}
}
@@ -116,7 +116,7 @@ void Books::init() {
}
BooksCount--; // set to last index
MakeJump(0x49B9FB, obj_use_book_hook);
MakeJump(0x49B9FB, obj_use_book_hack);
}
dlog_f(" (%d/%d books)\n", DL_INIT, n, count);
}
+4 -4
View File
@@ -2171,13 +2171,13 @@ skip:
// when there are no more items in the inventory
static __declspec(naked) void ai_check_drugs_hack_break() {
static const DWORD ai_check_drugs_hack_Ret = 0x42878B;
static const DWORD ai_check_drugs_break_Ret = 0x42878B;
__asm {
mov eax, -1;
cmp firstItemDrug, eax;
jne useDrugs; // pid != -1
add esp, 4;
jmp ai_check_drugs_hack_Ret; // break loop
jmp ai_check_drugs_break_Ret; // break loop
useDrugs: // use the first found item
mov dword ptr [esp + 4], eax; // slot set -1
mov edi, firstItemDrug;
@@ -2203,7 +2203,7 @@ checkDrugs:
}
static __declspec(naked) void ai_check_drugs_hack_use() {
static const DWORD ai_check_drugs_hack_Loop = 0x428675;
static const DWORD ai_check_drugs_use_Loop = 0x428675;
__asm {
cmp eax, 3; // counter
jge beginLoop;
@@ -2214,7 +2214,7 @@ beginLoop:
mov firstItemDrug, edi; // keep first found drug item
skip:
add esp, 4;
jmp ai_check_drugs_hack_Loop; // goto begin loop, search next item
jmp ai_check_drugs_use_Loop; // goto begin loop, search next item
}
}*/
+2 -2
View File
@@ -462,12 +462,12 @@ static __declspec(naked) void win_debug_win_draw_hook() {
static long debugWndWidth;
static __declspec(naked) void win_debug_pitch_calc_hack() {
static const DWORD win_debug_pitch_calc_hack_back = 0x4DC542;
static const DWORD win_debug_pitch_calc_Ret = 0x4DC542;
__asm {
mov eax, debugWndWidth;
imul esi;
mov ebp, eax;
jmp win_debug_pitch_calc_hack_back;
jmp win_debug_pitch_calc_Ret;
}
}
+2 -2
View File
@@ -98,7 +98,7 @@ static long __fastcall op_metarule3_ext(long metafunc, long* args) {
}
static __declspec(naked) void op_metarule3_hack() {
static const DWORD op_metarule3_hack_Ret = 0x45732C;
static const DWORD op_metarule3_Ret = 0x45732C;
__asm {
cmp ecx, 111;
jnz extended;
@@ -112,7 +112,7 @@ extended:
//
call op_metarule3_ext; // ecx - metafunc arg
add esp, 4;
jmp op_metarule3_hack_Ret;
jmp op_metarule3_Ret;
}
}
+2 -2
View File
@@ -93,12 +93,12 @@ static __declspec(naked) void register_object_take_out_hack() {
}
static __declspec(naked) void gdAddOptionStr_hack() {
static const DWORD gdAddOptionStr_hack_Ret = 0x4458FA;
static const DWORD gdAddOptionStr_Ret = 0x4458FA;
__asm {
mov ecx, ds:[FO_VAR_gdNumOptions];
add ecx, '1';
push ecx;
jmp gdAddOptionStr_hack_Ret;
jmp gdAddOptionStr_Ret;
}
}
+5 -5
View File
@@ -51,7 +51,7 @@ const char* __stdcall ObjectName::GetName(fo::GameObject* object) {
}
static __declspec(naked) void critter_name_hack() {
static DWORD critter_name_hack_Ret = 0x42D125;
static DWORD critter_name_Ret = 0x42D125;
using namespace fo::Fields;
__asm {
push ebx; // object
@@ -62,12 +62,12 @@ static __declspec(naked) void critter_name_hack() {
retn;
override:
add esp, 4;
jmp critter_name_hack_Ret;
jmp critter_name_Ret;
}
}
static __declspec(naked) void critter_name_hack_check() {
static DWORD critter_name_hack_Ret = 0x42D12F;
static DWORD critter_name_check_Ret = 0x42D12F;
using namespace fo::Fields;
__asm {
mov ecx, [ebx + scriptId];
@@ -77,7 +77,7 @@ static __declspec(naked) void critter_name_hack_check() {
jne default;
add esp, 4;
mov eax, ds:[FO_VAR_name_critter];
jmp critter_name_hack_Ret;
jmp critter_name_check_Ret;
checkScrIdx:
mov ecx, [ebx + scriptIndex];
cmp ecx, -1; // no inherited script index
@@ -86,7 +86,7 @@ checkScrIdx:
jne end;
add esp, 4;
mov eax, ds:[FO_VAR_name_critter];
jmp critter_name_hack_Ret;
jmp critter_name_check_Ret;
default:
mov ecx, [ebx + scriptIndex];
end:
+2 -2
View File
@@ -309,7 +309,7 @@ static long __fastcall get_unarmed_damage(fo::GameObject* source, fo::AttackType
}
static __declspec(naked) void item_w_damage_hack() {
static DWORD item_w_damage_hack_Ret = 0x478553;
static DWORD item_w_damage_Ret = 0x478553;
__asm {
lea eax, [esp + 4]; // min_DMG
lea edx, [esp + 0]; // max_DMG
@@ -320,7 +320,7 @@ static __declspec(naked) void item_w_damage_hack() {
call get_unarmed_damage;
mov ebx, eax; // bonus
pop ecx;
jmp item_w_damage_hack_Ret;
jmp item_w_damage_Ret;
}
}
+2 -2
View File
@@ -25,6 +25,6 @@
#define VERSION_MAJOR 4
#define VERSION_MINOR 4
#define VERSION_BUILD 9
#define VERSION_REV 0
#define VERSION_REV 1
#define VERSION_STRING "4.4.9"
#define VERSION_STRING "4.4.9.1"