diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 0f0f1723..4d86e1dd 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -662,7 +662,7 @@ ReloadReserve=-1 ;Set to 1 to change the counter in the 'Move Items' window to start with maximum number, except in the barter screen ItemCounterDefaultMax=0 -;Set to 1 to set default value in 'Move Items' window to amount of caps that will balance the tables +;Set to 1 to enable caps auto-balancing: when dragging caps between tables in the barter screen, 'Move Items' window will be shown with correct number pre-filled that balances the tables ItemCounterAutoCaps=0 ;Set to 1 to leave the music playing in dialogue with talking heads diff --git a/sfall/Modules/HookScripts/MiscHs.cpp b/sfall/Modules/HookScripts/MiscHs.cpp index 91f4d87c..c97e559d 100644 --- a/sfall/Modules/HookScripts/MiscHs.cpp +++ b/sfall/Modules/HookScripts/MiscHs.cpp @@ -100,14 +100,14 @@ static void __declspec(naked) OverrideCost_BarterPriceHook() { } } -void BarterGetTableCosts(long* outPcTableCost, long* outNpcTableCost) { +void BarterPriceHook_GetLastCosts(long& outPcTableCost, long& outNpcTableCost) { if (!HookScripts::HookHasScript(HOOK_BARTERPRICE)) { - *outPcTableCost = fo::func::item_total_cost(fo::var::ptable); - *outNpcTableCost = fo::func::barter_compute_value(fo::var::obj_dude, fo::var::target_stack[0]); + outPcTableCost = fo::func::item_total_cost(fo::var::ptable); + outNpcTableCost = fo::func::barter_compute_value(fo::var::obj_dude, fo::var::target_stack[0]); return; } - *outPcTableCost = lastTableCostPC; - *outNpcTableCost = lastTableCostNPC; + outPcTableCost = lastTableCostPC; + outNpcTableCost = lastTableCostNPC; } static fo::GameObject* sourceSkillOn = nullptr; diff --git a/sfall/Modules/HookScripts/MiscHs.h b/sfall/Modules/HookScripts/MiscHs.h index 2a5a2829..7db60974 100644 --- a/sfall/Modules/HookScripts/MiscHs.h +++ b/sfall/Modules/HookScripts/MiscHs.h @@ -21,6 +21,6 @@ void Inject_RollCheckHook(); long PerceptionRangeHook_Invoke(fo::GameObject* watcher, fo::GameObject* target, long type, long result); -void BarterGetTableCosts(long* outPcTableCost, long* outNpcTableCost); +void BarterPriceHook_GetLastCosts(long& outPcTableCost, long& outNpcTableCost); } diff --git a/sfall/Modules/Inventory.cpp b/sfall/Modules/Inventory.cpp index c6f9cb44..f72ca1cf 100644 --- a/sfall/Modules/Inventory.cpp +++ b/sfall/Modules/Inventory.cpp @@ -620,31 +620,27 @@ end: } static long CalculateSuggestedMoveCount(fo::GameObject* item, long maxQuantity, bool fromPlayer, bool fromInventory) { - if (maxQuantity <= 1) { - return maxQuantity; - } - long suggestedValue = 1; + // This is an exact copy of logic from https://github.com/alexbatalov/fallout2-ce/pull/311 if (item->protoId == fo::PID_BOTTLE_CAPS && !fo::var::dialog_target_is_party) { // Calculate change money automatically long totalCostPlayer; long totalCostNpc; - BarterGetTableCosts(&totalCostPlayer, &totalCostNpc); + BarterPriceHook_GetLastCosts(totalCostPlayer, totalCostNpc); // Actor's balance: negative - the actor must add money to balance the tables and vice versa long balance = fromPlayer ? totalCostPlayer - totalCostNpc : totalCostNpc - totalCostPlayer; - - if ( (balance < 0 && fromInventory) || (balance > 0 && !fromInventory) ) { - suggestedValue = min(std::abs(balance), maxQuantity); + if ((balance < 0 && fromInventory) || (balance > 0 && !fromInventory)) { + return min(std::abs(balance), maxQuantity); } } - return suggestedValue; + return 1; } static bool itemCounterDefaultMax; static bool itemCounterAutoCaps; -static long __fastcall CalculateDefaultMoveCount(fo::GameObject* item, DWORD retAddr, DWORD maxValue) { +static long __fastcall CalculateDefaultMoveCount(DWORD maybeItem, DWORD retAddr, DWORD maxValue) { maxValue = min(maxValue, 99999); // capped like in vanilla if ((GetLoopFlags() & BARTER) != 0) { - if (itemCounterAutoCaps && maxValue > 0) { + if (itemCounterAutoCaps && maxValue > 1) { bool fromPlayer; bool fromInventory; switch (retAddr) { @@ -667,7 +663,8 @@ static long __fastcall CalculateDefaultMoveCount(fo::GameObject* item, DWORD ret default: return 1; } - return CalculateSuggestedMoveCount(item, maxValue, fromPlayer, fromInventory); + // maybeItem may not contain object pointer in all cases, but it does in all 4 from above. + return CalculateSuggestedMoveCount((fo::GameObject*)maybeItem, maxValue, fromPlayer, fromInventory); } return 1; } @@ -676,13 +673,13 @@ static long __fastcall CalculateDefaultMoveCount(fo::GameObject* item, DWORD ret static void __declspec(naked) do_move_timer_hack() { __asm { - pushadc; + push ecx; push ebp; // max - mov edx, dword ptr[esp + 40]; // return address - mov ecx, dword ptr[esp + 28]; // item + mov edx, dword ptr[esp + 32]; // return address + mov ecx, dword ptr[esp + 20]; // item, potentially call CalculateDefaultMoveCount; mov ebx, eax; - popadc; + pop ecx; retn; } }