Fixed trying to loot corpses with the "NoSteal" flag (#280)

This commit is contained in:
NovaRain
2020-02-06 10:52:19 +08:00
parent e153819bcd
commit 5a5c65291d
5 changed files with 55 additions and 9 deletions
+5 -5
View File
@@ -89,16 +89,16 @@
/* Critter flags */ /* Critter flags */
#define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) #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_NODROP 64 // 0x00000040 - Drop (doesn't drop items)
#define CFLG_NOLIMBS 128 // 0x00000080 - Limbs (cannot lose limbs) #define CFLG_NOLIMBS 128 // 0x00000080 - Limbs (cannot lose limbs)
#define CFLG_NOAGES 256 // 0x00000100 - Ages (dead body does not disappear) #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_INVULN 1024 // 0x00000400 - Invulnerable (cannot be hurt)
#define CFLG_FLATTN 2048 // 0x00000800 - Flatten (leaves no dead body) #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_SPECIAL 4096 // 0x00001000 - Special (has a special type of death)
#define CFLG_RANGED 8192 // 0x00002000 - Range (melee attack is possible at a distance) #define CFLG_RANGED 8192 // 0x00002000 - Range (has extra hand-to-hand range)
#define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked down) #define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked back)
/* Window flags */ /* Window flags */
#define WIN_FLAG_MOVEONTOP (0x4) #define WIN_FLAG_MOVEONTOP (0x4)
+29
View File
@@ -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() void BugFixesInit()
{ {
#ifndef NDEBUG #ifndef NDEBUG
@@ -3132,4 +3156,9 @@ void BugFixesInit()
// Fix the playback of the speech sound file for the death screen // Fix the playback of the speech sound file for the death screen
HookCall(0x481409, main_death_scene_hook); 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);
} }
+18
View File
@@ -287,6 +287,24 @@ enum Skill : long
SKILL_count = 18 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 //XXXXXXXXXXXXXXXXXXXXXXXXXX
//XX Combat Flags defines XX //XX Combat Flags defines XX
//XXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXXXXX
+2 -4
View File
@@ -547,6 +547,7 @@ const DWORD obj_dist_ = 0x48BBD4;
const DWORD obj_dist_with_tile_ = 0x48BC08; const DWORD obj_dist_with_tile_ = 0x48BC08;
const DWORD obj_drop_ = 0x49B8B0; const DWORD obj_drop_ = 0x49B8B0;
const DWORD obj_erase_object_ = 0x48B0FC; const DWORD obj_erase_object_ = 0x48B0FC;
const DWORD obj_examine_ = 0x49AD78;
const DWORD obj_find_first_ = 0x48B3A8; const DWORD obj_find_first_ = 0x48B3A8;
const DWORD obj_find_first_at_ = 0x48B48C; const DWORD obj_find_first_at_ = 0x48B48C;
const DWORD obj_find_first_at_tile_ = 0x48B5A8; const DWORD obj_find_first_at_tile_ = 0x48B5A8;
@@ -1055,11 +1056,8 @@ DWORD __fastcall InterpretGetValue(TProgram* scriptPtr, DWORD &outType) {
mov edx, eax; mov edx, eax;
mov eax, ecx; mov eax, ecx;
call interpretPopLong_; // pops value from Data stack (must be preceded by InterpretPopShort) call interpretPopLong_; // pops value from Data stack (must be preceded by InterpretPopShort)
cmp dx, VAR_TYPE_STR2;
je getStr;
cmp dx, VAR_TYPE_STR; cmp dx, VAR_TYPE_STR;
jne isNotStr; ja isNotStr;
getStr:
mov ebx, eax; mov ebx, eax;
mov eax, ecx; mov eax, ecx;
call interpretGetString_; // retrieve string argument call interpretGetString_; // retrieve string argument
+1
View File
@@ -811,6 +811,7 @@ extern const DWORD obj_dist_;
extern const DWORD obj_dist_with_tile_; extern const DWORD obj_dist_with_tile_;
extern const DWORD obj_drop_; extern const DWORD obj_drop_;
extern const DWORD obj_erase_object_; extern const DWORD obj_erase_object_;
extern const DWORD obj_examine_;
extern const DWORD obj_find_first_; extern const DWORD obj_find_first_;
extern const DWORD obj_find_first_at_; extern const DWORD obj_find_first_at_;
extern const DWORD obj_find_first_at_tile_; // <eax>(int elevation<eax>, int tile<edx>) extern const DWORD obj_find_first_at_tile_; // <eax>(int elevation<eax>, int tile<edx>)