diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 8b50977f..55504fa1 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -89,16 +89,16 @@ /* Critter flags */ #define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) -#define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from) +#define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot be stolen from) #define CFLG_NODROP 64 // 0x00000040 - Drop (doesn't drop items) #define CFLG_NOLIMBS 128 // 0x00000080 - Limbs (cannot lose limbs) #define CFLG_NOAGES 256 // 0x00000100 - Ages (dead body does not disappear) -#define CFLG_NOHEAL 512 // 0x00000200 - Heal (damage is not cured with time) +#define CFLG_NOHEAL 512 // 0x00000200 - Heal (damage is not healed with time) #define CFLG_INVULN 1024 // 0x00000400 - Invulnerable (cannot be hurt) #define CFLG_FLATTN 2048 // 0x00000800 - Flatten (leaves no dead body) -#define CFLG_SPECIAL 4096 // 0x00001000 - Special (there is a special type of death) -#define CFLG_RANGED 8192 // 0x00002000 - Range (melee attack is possible at a distance) -#define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked down) +#define CFLG_SPECIAL 4096 // 0x00001000 - Special (has a special type of death) +#define CFLG_RANGED 8192 // 0x00002000 - Range (has extra hand-to-hand range) +#define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked back) /* Window flags */ #define WIN_FLAG_MOVEONTOP (0x4) diff --git a/sfall/BugFixes.cpp b/sfall/BugFixes.cpp index 3d0c12f3..ddb77509 100644 --- a/sfall/BugFixes.cpp +++ b/sfall/BugFixes.cpp @@ -2482,6 +2482,30 @@ static void __declspec(naked) main_death_scene_hook() { } } +static void __declspec(naked) action_loot_container_hack() { + __asm { + cmp dword ptr [esp + 0x10 + 4], 0x44C1D9 + 5; + je fix; + xor eax, eax; // set ZF + retn; +fix: + sub esp, 4; + mov edx, esp; + call proto_ptr_; + mov edx, [esp]; + add esp, 4; + test [edx + 0x20], CFLG_NoSteal; // critter flags + jnz look; + retn; +look: + mov eax, esi; + mov edx, edi; + call obj_examine_; + or eax, 1; // unset ZF + retn; + } +} + void BugFixesInit() { #ifndef NDEBUG @@ -3132,4 +3156,9 @@ void BugFixesInit() // Fix the playback of the speech sound file for the death screen HookCall(0x481409, main_death_scene_hook); + + // Fix for trying to loot corpses with the "NoSteal" flag + SafeWrite8(0x4123F2, 0x64); // protoId + BlockCall(0x4123F3); + MakeCall(0x4123F8, action_loot_container_hack, 1); } diff --git a/sfall/Define.h b/sfall/Define.h index 516650fb..a69ca416 100644 --- a/sfall/Define.h +++ b/sfall/Define.h @@ -287,6 +287,24 @@ enum Skill : long SKILL_count = 18 }; +enum CritterFlags : long +{ + CFLG_Sneak = 0x01, // Can sneak ? + CFLG_Barter = 0x02, // Can trade with + CFLG_Level = 0x04, // Level received ? + CFLG_Addict = 0x08, // Drug addiction ? + CFLG_NoSteal = 0x20, // Can't be stolen from + CFLG_NoDrop = 0x40, // Doesn't drop items + CFLG_NoLimbs = 0x80, // Can't lose limbs + CFLG_DeadAges = 0x100, // Dead body does not disappear + CFLG_NoHeal = 0x200, // Damage is not healed with time + CFLG_Invlunerable = 0x400, // Is Invlunerable (cannot be hurt) + CFLG_NotFlattens = 0x800, // Doesn't flatten on death (leaves no dead body) + CFLG_SpecialDeath = 0x1000, // Has a special type of death + CFLG_RangeHth = 0x2000, // Has extra hand-to-hand range + CFLG_NoKnockBack = 0x4000, // Can't be knocked back +}; + //XXXXXXXXXXXXXXXXXXXXXXXXXX //XX Combat Flags defines XX //XXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index e2189b03..217a8bdf 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -547,6 +547,7 @@ const DWORD obj_dist_ = 0x48BBD4; const DWORD obj_dist_with_tile_ = 0x48BC08; const DWORD obj_drop_ = 0x49B8B0; const DWORD obj_erase_object_ = 0x48B0FC; +const DWORD obj_examine_ = 0x49AD78; const DWORD obj_find_first_ = 0x48B3A8; const DWORD obj_find_first_at_ = 0x48B48C; const DWORD obj_find_first_at_tile_ = 0x48B5A8; @@ -1055,11 +1056,8 @@ DWORD __fastcall InterpretGetValue(TProgram* scriptPtr, DWORD &outType) { mov edx, eax; mov eax, ecx; call interpretPopLong_; // pops value from Data stack (must be preceded by InterpretPopShort) - cmp dx, VAR_TYPE_STR2; - je getStr; cmp dx, VAR_TYPE_STR; - jne isNotStr; -getStr: + ja isNotStr; mov ebx, eax; mov eax, ecx; call interpretGetString_; // retrieve string argument diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index a1c1dc3f..be07dca7 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -811,6 +811,7 @@ extern const DWORD obj_dist_; extern const DWORD obj_dist_with_tile_; extern const DWORD obj_drop_; extern const DWORD obj_erase_object_; +extern const DWORD obj_examine_; extern const DWORD obj_find_first_; extern const DWORD obj_find_first_at_; extern const DWORD obj_find_first_at_tile_; // (int elevation, int tile)