Added ItemMoveSkipDragKey from 4.x

This commit is contained in:
NovaRain
2024-06-06 21:50:48 +08:00
parent e05010c752
commit ea74ff7d0c
3 changed files with 141 additions and 2 deletions
+7 -1
View File
@@ -240,12 +240,18 @@ ReloadWeaponKey=0
;A key to hold down to let you move/drop a whole stack of items at once without the 'Move Items' window
;Set to 0 if you don't want a fast move key, or a DX scancode otherwise
ItemFastMoveKey=29
ItemFastMoveKey=42
;Set to 1 to skip the 'Move Items' window when taking items from containers or corpses and not holding down ItemFastMoveKey
;Requires ItemFastMoveKey to be enabled
FastMoveFromContainer=0
;A key to hold down to let you move items between inventory lists by simply clicking on them
;In the inventory screen, items from the main inventory list will go to appropriate slots
;Set to 0 if you don't want a skip drag key, or a DX scancode otherwise
;Can be mapped to the same key as ItemFastMoveKey for a combined effect
ItemMoveSkipDragKey=29
;A key to press to open a debug game editor
;Set to 0 to disable, or a DX scancode otherwise
;Requires sfall debugging mode and FalloutDebug.exe from the modders pack
+2
View File
@@ -145,6 +145,7 @@
#define FO_VAR_i_worn 0x59E954
#define FO_VAR_idle_func 0x51E234
#define FO_VAR_In_WorldMap 0x672E1C
#define FO_VAR_im_value 0x59E93C
#define FO_VAR_info_line 0x5707D0
#define FO_VAR_interfaceWindow 0x519024
#define FO_VAR_intfaceEnabled 0x518F10
@@ -162,6 +163,7 @@
#define FO_VAR_last_buttons 0x51E2AC
#define FO_VAR_last_button_winID 0x51E404
#define FO_VAR_last_level 0x5707B4
#define FO_VAR_last_target 0x519110
#define FO_VAR_lastMovieH 0x638E64
#define FO_VAR_lastMovieW 0x638E68
#define FO_VAR_lastTime 0x56FB58
+132 -1
View File
@@ -40,6 +40,7 @@ static DWORD invSizeMaxLimit;
static DWORD reloadWeaponKey;
static DWORD itemFastMoveKey;
static DWORD skipFromContainer = 0;
static DWORD itemSkipDragKey;
void Inventory::KeyPressedHook(DWORD dxKey, bool pressed) {
if (pressed && reloadWeaponKey && dxKey == reloadWeaponKey && IsGameLoaded() && (GetLoopFlags() & ~(COMBAT | PCOMBAT)) == 0) {
@@ -683,6 +684,128 @@ static __declspec(naked) void do_move_timer_hack() {
}
}
static void __fastcall DragSkipPrepare() {
fo::var::setInt(FO_VAR_im_value) = -1; // this prevents triggering "look at" at current item after skip
fo::func::gsound_play_sfx_file("iputdown");
}
static __declspec(naked) void move_inventory_hack() {
static const DWORD MoveInventory_SkipPlanting = 0x474966; // cmp esi, 1
static const DWORD MoveInventory_SkipTaking = 0x474A30; // cmp esi, 1
__asm {
pushadc;
}
KeyDown(itemSkipDragKey); // check pressed
__asm {
test eax, eax;
popadc;
jnz skipDrag;
cmp dword ptr [esp + 0x54 - 0x14 + 4], 0; // restore stomped code
retn;
skipDrag:
call DragSkipPrepare;
mov eax, dword ptr [esp + 0x54 - 0x18 + 4]; // isPlanting flag
add esp, 4;
test eax, eax;
jz jmpTaking;
jmp MoveInventory_SkipPlanting;
jmpTaking:
jmp MoveInventory_SkipTaking;
}
}
static DWORD BarterMoveInventory_SkipPlacing;
static DWORD BarterMoveInventory_SkipTaking;
static __declspec(naked) void barter_move_inventory_skip_drag_hack_common() {
__asm {
pushadc;
}
KeyDown(itemSkipDragKey); // check pressed
__asm {
test eax, eax;
popadc;
jnz skipDrag;
lea eax, ds:0[ebx * 4]; // restore stomped code
retn;
skipDrag:
call DragSkipPrepare;
mov eax, dword ptr [esp + 0x38 + 0xC + 4]; // fromDude flag
add esp, 4;
test eax, eax;
jz jmpTaking;
jmp BarterMoveInventory_SkipPlacing;
jmpTaking:
jmp BarterMoveInventory_SkipTaking;
}
}
static __declspec(naked) void barter_move_inventory_skip_drag_hack() {
BarterMoveInventory_SkipPlacing = 0x474F83; // cmp esi, 1
BarterMoveInventory_SkipTaking = 0x475002; // cmp esi, 1
__asm {
jmp barter_move_inventory_skip_drag_hack_common;
}
}
static __declspec(naked) void barter_move_from_table_inventory_skip_drag_hack() {
BarterMoveInventory_SkipPlacing = 0x47524E; // cmp esi, 1
BarterMoveInventory_SkipTaking = 0x4752CB; // cmp esi, 1
__asm {
jmp barter_move_inventory_skip_drag_hack_common;
}
}
static DWORD __fastcall InvenPickupGetSkipAddr(fo::GameObject* item, long itemIndex) {
static const DWORD InvenPickup_SkipInven = 0x4711E8; // mov eax, [esp+20]
static const DWORD InvenPickup_SkipHandL = 0x47127D; // mov edx, ds:_i_lhand
static const DWORD InvenPickup_SkipHandR = 0x47130A; // mov ebx, ds:_i_rhand
static const DWORD InvenPickup_SkipArmor = 0x4713A9; // mov ecx, ds:_i_worn
if (!KeyDown(itemSkipDragKey)) return 0; // don't skip
DragSkipPrepare();
if (itemIndex < 0) {
// From slots to inventory
return InvenPickup_SkipInven;
}
// From inventory to slots
if (fo::func::item_get_type(item) == fo::item_type_armor)
return InvenPickup_SkipArmor; // armor slot, potentially replacing
else if (*fo::ptr::inven_dude == *fo::ptr::obj_dude && fo::func::intface_is_item_right_hand())
return InvenPickup_SkipHandR; // right hand
return InvenPickup_SkipHandL; // left hand;
}
static __declspec(naked) void inven_pickup_skip_drag_hack() {
static const DWORD InvenPickup_Back = 0x470EEA; // mov eax, ds:_i_wid
__asm {
pushadc;
mov ecx, [esp + 0x58 - 0x40 + 16]; // item
mov edx, esi; // item index
call InvenPickupGetSkipAddr;
test eax, eax;
jnz skipDrag;
popadc;
cmp esi, 0xFFFFFFFF; // restore stomped code
jz back;
retn;
back:
add esp, 4;
jmp InvenPickup_Back;
skipDrag:
pop ecx;
pop edx;
add esp, 8;
jmp eax;
}
}
static int invenApCost, invenApCostDef;
static char invenApQPReduction;
@@ -801,7 +924,7 @@ void Inventory::init() {
SafeWrite8(0x476569, 0x91); // xchg ecx, eax
};
itemFastMoveKey = IniReader::GetConfigInt("Input", "ItemFastMoveKey", DIK_LCONTROL);
itemFastMoveKey = IniReader::GetConfigInt("Input", "ItemFastMoveKey", 0);
if (itemFastMoveKey > 0) {
HookCall(0x476897, do_move_timer_hook);
// Do not call the 'Move Items' window when taking items from containers or corpses
@@ -814,6 +937,14 @@ void Inventory::init() {
MakeCall(0x4768A3, do_move_timer_hack);
}
itemSkipDragKey = IniReader::GetConfigInt("Input", "ItemMoveSkipDragKey", 0);
if (itemSkipDragKey > 0) {
MakeCall(0x4747DD, move_inventory_hack);
MakeCall(0x474DBA, barter_move_inventory_skip_drag_hack, 2);
MakeCall(0x47507E, barter_move_from_table_inventory_skip_drag_hack, 2);
MakeCall(0x470EB7, inven_pickup_skip_drag_hack);
}
// Move items from bag/backpack to the main inventory list by dragging them on the character portrait (similar to Fallout 1 behavior)
MakeCall(0x471452, inven_pickup_hack);