mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added a check for the DAM_KNOCKED_OUT flag
to wield_obj_critter/inven_unwield script functions. Added climbing ladders to "interrupted player's movement in combat" fix.
This commit is contained in:
@@ -2121,6 +2121,14 @@ static void __declspec(naked) action_use_an_item_on_object_hack() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) action_climb_ladder_hack() {
|
||||||
|
__asm {
|
||||||
|
add ecx, ds:[FO_VAR_combat_free_move];
|
||||||
|
mov eax, 2; // RB_RESERVED
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//static const DWORD wmAreaMarkVisitedState_Error = 0x4C4698;
|
//static const DWORD wmAreaMarkVisitedState_Error = 0x4C4698;
|
||||||
static const DWORD wmAreaMarkVisitedState_Ret = 0x4C46A2;
|
static const DWORD wmAreaMarkVisitedState_Ret = 0x4C46A2;
|
||||||
static void __declspec(naked) wmAreaMarkVisitedState_hack() {
|
static void __declspec(naked) wmAreaMarkVisitedState_hack() {
|
||||||
@@ -2771,6 +2779,7 @@ void BugFixes::init()
|
|||||||
|
|
||||||
// Fix for the player's movement in combat being interrupted when trying to use objects with Bonus Move APs available
|
// Fix for the player's movement in combat being interrupted when trying to use objects with Bonus Move APs available
|
||||||
MakeCall(0x411FD6, action_use_an_item_on_object_hack);
|
MakeCall(0x411FD6, action_use_an_item_on_object_hack);
|
||||||
|
MakeCall(0x411DF7, action_climb_ladder_hack);
|
||||||
|
|
||||||
// Fix for Scout perk being taken into account when setting the visibility of locations with mark_area_known function
|
// Fix for Scout perk being taken into account when setting the visibility of locations with mark_area_known function
|
||||||
// also fix the incorrect coordinates for small/medium location circles that the engine uses to highlight their sub-tiles
|
// also fix the incorrect coordinates for small/medium location circles that the engine uses to highlight their sub-tiles
|
||||||
@@ -2783,7 +2792,7 @@ void BugFixes::init()
|
|||||||
|
|
||||||
// Fix for combat not ending automatically when there are no hostile critters
|
// Fix for combat not ending automatically when there are no hostile critters
|
||||||
MakeCall(0x422CF3, combat_should_end_hack);
|
MakeCall(0x422CF3, combat_should_end_hack);
|
||||||
SafeWrite16(0x422CEA, 0x0C74); // jz 0x422CF8
|
SafeWrite16(0x422CEA, 0x0C74); // jz 0x422CF8 (skip party members)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-18
@@ -531,30 +531,60 @@ skip:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) op_inven_unwield_hook() {
|
||||||
|
using namespace fo;
|
||||||
|
using namespace Fields;
|
||||||
|
__asm {
|
||||||
|
mov ecx, [eax + protoId];
|
||||||
|
and ecx, 0x0F000000;
|
||||||
|
cmp ecx, OBJ_TYPE_CRITTER << 24;
|
||||||
|
jne skip;
|
||||||
|
test byte ptr [eax + damageFlags], DAM_KNOCKED_OUT;
|
||||||
|
jz skip;
|
||||||
|
push 0x505AFC; // "But is already Inactive (Dead/Stunned/Invisible)"
|
||||||
|
call fo::funcoffs::debug_printf_;
|
||||||
|
add esp, 4;
|
||||||
|
retn;
|
||||||
|
skip:
|
||||||
|
jmp fo::funcoffs::inven_unwield_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) op_wield_obj_critter_hook() {
|
||||||
|
using namespace fo;
|
||||||
|
using namespace Fields;
|
||||||
|
__asm {
|
||||||
|
test byte ptr [eax + damageFlags], DAM_KNOCKED_OUT;
|
||||||
|
jz skip;
|
||||||
|
mov eax, -1;
|
||||||
|
retn;
|
||||||
|
skip:
|
||||||
|
jmp fo::funcoffs::inven_wield_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// reimplementation of adjust_fid engine function
|
// reimplementation of adjust_fid engine function
|
||||||
// Differences from vanilla:
|
// Differences from vanilla:
|
||||||
// - doesn't use art_vault_guy_num as default art, uses current critter FID instead
|
// - doesn't use art_vault_guy_num as default art, uses current critter FID instead
|
||||||
// - invokes onAdjustFid delegate that allows to hook into FID calculation
|
// - invokes onAdjustFid delegate that allows to hook into FID calculation
|
||||||
DWORD __stdcall Inventory::adjust_fid_replacement() {
|
DWORD __stdcall Inventory::adjust_fid_replacement() {
|
||||||
using namespace fo;
|
|
||||||
|
|
||||||
DWORD fid;
|
DWORD fid;
|
||||||
if (var::inven_dude->TypeFid() == ObjType::OBJ_TYPE_CRITTER) {
|
if (fo::var::inven_dude->TypeFid() == fo::OBJ_TYPE_CRITTER) {
|
||||||
DWORD frameNum;
|
DWORD frameNum;
|
||||||
DWORD weaponAnimCode = 0;
|
DWORD weaponAnimCode = 0;
|
||||||
if (PartyControl::IsNpcControlled()) {
|
if (PartyControl::IsNpcControlled()) {
|
||||||
// if NPC is under control, use current FID of critter
|
// if NPC is under control, use current FID of critter
|
||||||
frameNum = var::inven_dude->artFid & 0xFFF;
|
frameNum = fo::var::inven_dude->artFid & 0xFFF;
|
||||||
} else {
|
} else {
|
||||||
// vanilla logic:
|
// vanilla logic:
|
||||||
frameNum = var::art_vault_guy_num;
|
frameNum = fo::var::art_vault_guy_num;
|
||||||
auto critterPro = GetProto(var::inven_pid);
|
auto critterPro = fo::GetProto(fo::var::inven_pid);
|
||||||
if (critterPro != nullptr) {
|
if (critterPro != nullptr) {
|
||||||
frameNum = critterPro->fid & 0xFFF;
|
frameNum = critterPro->fid & 0xFFF;
|
||||||
}
|
}
|
||||||
if (var::i_worn != nullptr) {
|
if (fo::var::i_worn != nullptr) {
|
||||||
auto armorPro = GetProto(var::i_worn->protoId);
|
auto armorPro = fo::GetProto(fo::var::i_worn->protoId);
|
||||||
DWORD armorFrameNum = func::stat_level(var::inven_dude, STAT_gender) == GENDER_FEMALE
|
DWORD armorFrameNum = fo::func::stat_level(fo::var::inven_dude, fo::STAT_gender) == fo::GENDER_FEMALE
|
||||||
? armorPro->item.armor.femaleFrameNum
|
? armorPro->item.armor.femaleFrameNum
|
||||||
: armorPro->item.armor.maleFrameNum;
|
: armorPro->item.armor.maleFrameNum;
|
||||||
|
|
||||||
@@ -563,23 +593,23 @@ DWORD __stdcall Inventory::adjust_fid_replacement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto itemInHand = func::intface_is_item_right_hand()
|
auto itemInHand = fo::func::intface_is_item_right_hand()
|
||||||
? var::i_rhand
|
? fo::var::i_rhand
|
||||||
: var::i_lhand;
|
: fo::var::i_lhand;
|
||||||
|
|
||||||
if (itemInHand != nullptr) {
|
if (itemInHand != nullptr) {
|
||||||
auto itemPro = GetProto(itemInHand->protoId);
|
auto itemPro = fo::GetProto(itemInHand->protoId);
|
||||||
if (itemPro->item.type == item_type_weapon) {
|
if (itemPro->item.type == fo::item_type_weapon) {
|
||||||
weaponAnimCode = itemPro->item.weapon.animationCode;
|
weaponAnimCode = itemPro->item.weapon.animationCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fid = func::art_id(OBJ_TYPE_CRITTER, frameNum, 0, weaponAnimCode, 0);
|
fid = fo::func::art_id(fo::OBJ_TYPE_CRITTER, frameNum, 0, weaponAnimCode, 0);
|
||||||
} else {
|
} else {
|
||||||
fid = var::inven_dude->artFid;
|
fid = fo::var::inven_dude->artFid;
|
||||||
}
|
}
|
||||||
var::i_fid = fid;
|
fo::var::i_fid = fid;
|
||||||
onAdjustFid.invoke(fid);
|
onAdjustFid.invoke(fid);
|
||||||
return var::i_fid;
|
return fo::var::i_fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) adjust_fid_hack_replacement() {
|
static void __declspec(naked) adjust_fid_hack_replacement() {
|
||||||
@@ -759,6 +789,11 @@ void Inventory::init() {
|
|||||||
MakeCall(0x4759F1, barter_inventory_hack_scroll);
|
MakeCall(0x4759F1, barter_inventory_hack_scroll);
|
||||||
fo::var::max = 100;
|
fo::var::max = 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check the DAM_KNOCKED_OUT flag for wield_obj_critter/inven_unwield script functions
|
||||||
|
// Note: the flag is not checked for the metarule(METARULE_INVEN_UNWIELD_WHO, x) function
|
||||||
|
HookCall(0x45B0CE, op_inven_unwield_hook);
|
||||||
|
HookCall(0x45693C, op_wield_obj_critter_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
Delegate<DWORD>& Inventory::OnAdjustFid() {
|
Delegate<DWORD>& Inventory::OnAdjustFid() {
|
||||||
|
|||||||
Reference in New Issue
Block a user