Set recomended ammount of money to be moved for barter

The feature works in any direction to move from/to player/npc and from/to inventory/table
This commit is contained in:
Ivan Sokolov 2023-06-21 21:13:06 +08:00
parent 0e806d9be3
commit a949178e30
1 changed files with 35 additions and 18 deletions

View File

@ -263,7 +263,7 @@ static void inventoryWindowOpenContextMenu(int eventCode, int inventoryWindowTyp
static int _move_inventory(Object* a1, int a2, Object* a3, bool a4); static int _move_inventory(Object* a1, int a2, Object* a3, bool a4);
static int _barter_compute_value(Object* a1, Object* a2); static int _barter_compute_value(Object* a1, Object* a2);
static int _barter_attempt_transaction(Object* a1, Object* a2, Object* a3, Object* a4); static int _barter_attempt_transaction(Object* a1, Object* a2, Object* a3, Object* a4);
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayerToNpc); static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayer, bool fromInventory);
static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Object* a5, Object* a6, bool a7); static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Object* a5, Object* a6, bool a7);
static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3, Object* a4, Object* a5, bool a6); static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3, Object* a4, Object* a5, bool a6);
static void inventoryWindowRenderInnerInventories(int win, Object* a2, Object* a3, int a4); static void inventoryWindowRenderInnerInventories(int win, Object* a2, Object* a3, int a4);
@ -272,7 +272,7 @@ static void _container_exit(int keyCode, int inventoryWindowType);
static int _drop_into_container(Object* a1, Object* a2, int a3, Object** a4, int quantity); static int _drop_into_container(Object* a1, Object* a2, int a3, Object** a4, int quantity);
static int _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** a3, int quantity, int keyCode); static int _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** a3, int quantity, int keyCode);
static void _draw_amount(int value, int inventoryWindowType); static void _draw_amount(int value, int inventoryWindowType);
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int a3); static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int max, int suggestedValue=1);
static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item); static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item);
static int inventoryQuantityWindowFree(int inventoryWindowType); static int inventoryQuantityWindowFree(int inventoryWindowType);
@ -4756,25 +4756,42 @@ static int _barter_attempt_transaction(Object* a1, Object* a2, Object* a3, Objec
return 0; return 0;
} }
static int _barter_get_quantity_moved_items(Object* item, int maxQuantity, bool fromPlayerToNpc) { static int _barter_get_quantity_moved_items(
Object* item,
int maxQuantity,
bool fromPlayer,
bool fromInventory
) {
if (maxQuantity <= 1) { if (maxQuantity <= 1) {
return maxQuantity; return maxQuantity;
} }
int quantityToMove = -1; int suggestedValue = 1;
if (item->pid == PROTO_ID_MONEY && !gGameDialogSpeakerIsPartyMember) { if (item->pid == PROTO_ID_MONEY && !gGameDialogSpeakerIsPartyMember) {
// Calculate change money automatically // Calculate change money automatically
int totalCostPlayer = objectGetCost(_ptable); int totalCostPlayer = objectGetCost(_ptable);
int totalCostNpc = _barter_compute_value(gDude, _target_stack[0]); int totalCostNpc = _barter_compute_value(gDude, _target_stack[0]);
quantityToMove = fromPlayerToNpc ? std::min(totalCostNpc - totalCostPlayer, maxQuantity): int balance = totalCostPlayer - totalCostNpc;
std::min(totalCostPlayer - totalCostNpc, maxQuantity); bool balancePositive = true;
if (balance < 0) {
balancePositive = false;
balance = -balance;
} }
// If the item is not money or player wants to add extra money // fromPlayer | fromInventory | balancePositive | suggestedVale
// then open window to set quantity manually // 0 | 0 | 0 | abs(balance)
if (quantityToMove <= 0) { // 0 | 0 | 1 | 1
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, maxQuantity); // 0 | 1 | 0 | 1
// 0 | 1 | 1 | balance
// 1 | 0 | 0 | 1
// 1 | 0 | 1 | balance
// 1 | 1 | 0 | abs(balance)
// 1 | 1 | 1 | 1
// if balance 0 then suggestedVale is 1
if (balance != 0 && !(fromPlayer ^ fromInventory ^ balancePositive)) {
suggestedValue = std::min(balance, maxQuantity);
} }
return quantityToMove; }
return inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, maxQuantity, suggestedValue);
} }
// 0x474DAC // 0x474DAC
@ -4835,7 +4852,7 @@ static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Obj
if (a7) { if (a7) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y)) { if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y)) {
int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a7); int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a7, true);
if (quantityToMove != -1) { if (quantityToMove != -1) {
if (itemMoveForce(_inven_dude, a6, a1, quantityToMove) == -1) { if (itemMoveForce(_inven_dude, a6, a1, quantityToMove) == -1) {
// There is no space left for that item. // There is no space left for that item.
@ -4848,7 +4865,7 @@ static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Obj
} }
} else { } else {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y)) { if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y)) {
int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a7); int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a7, true);
if (quantityToMove != -1) { if (quantityToMove != -1) {
if (itemMoveForce(a5, a6, a1, quantityToMove) == -1) { if (itemMoveForce(a5, a6, a1, quantityToMove) == -1) {
// You cannot pick that up. You are at your maximum weight capacity. // You cannot pick that up. You are at your maximum weight capacity.
@ -4922,7 +4939,7 @@ static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3,
if (a6) { if (a6) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y)) { if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y)) {
int quantityToMove = quantity > 1 ? inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, a1, quantity) : 1; int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a6, false);
if (quantityToMove != -1) { if (quantityToMove != -1) {
if (itemMoveForce(a5, _inven_dude, a1, quantityToMove) == -1) { if (itemMoveForce(a5, _inven_dude, a1, quantityToMove) == -1) {
// There is no space left for that item. // There is no space left for that item.
@ -4935,7 +4952,7 @@ static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3,
} }
} else { } else {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) { if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) {
int quantityToMove = quantity > 1 ? inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, a1, quantity) : 1; int quantityToMove = _barter_get_quantity_moved_items(a1, quantity, a6, false);
if (quantityToMove != -1) { if (quantityToMove != -1) {
if (itemMoveForce(a5, a4, a1, quantityToMove) == -1) { if (itemMoveForce(a5, a4, a1, quantityToMove) == -1) {
// You cannot pick that up. You are at your maximum weight capacity. // You cannot pick that up. You are at your maximum weight capacity.
@ -5596,7 +5613,7 @@ static void _draw_amount(int value, int inventoryWindowType)
} }
// 0x47688C // 0x47688C
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int max) static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int max, int suggestedValue)
{ {
ScopedGameMode gm(GameMode::kCounter); ScopedGameMode gm(GameMode::kCounter);
@ -5605,7 +5622,7 @@ static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int ma
int value; int value;
int min; int min;
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_MOVE_ITEMS) { if (inventoryWindowType == INVENTORY_WINDOW_TYPE_MOVE_ITEMS) {
value = 1; value = suggestedValue;
if (max > 99999) { if (max > 99999) {
max = 99999; max = 99999;
} }