Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature for automatic calculation of barter money #311

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 36 additions & 19 deletions src/inventory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 _barter_compute_value(Object* a1, Object* a2);
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_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);
Expand All @@ -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_ammo_into_weapon(Object* weapon, Object* ammo, Object** a3, int quantity, int keyCode);
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 inventoryQuantityWindowFree(int inventoryWindowType);

Expand Down Expand Up @@ -4756,25 +4756,42 @@ static int _barter_attempt_transaction(Object* a1, Object* a2, Object* a3, Objec
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) {
return maxQuantity;
}

int quantityToMove = -1;
int suggestedValue = 1;
if (item->pid == PROTO_ID_MONEY && !gGameDialogSpeakerIsPartyMember) {
// Calculate change money automatically
int totalCostPlayer = objectGetCost(_ptable);
int totalCostNpc = _barter_compute_value(gDude, _target_stack[0]);
quantityToMove = fromPlayerToNpc ? std::min(totalCostNpc - totalCostPlayer, maxQuantity):
std::min(totalCostPlayer - totalCostNpc, maxQuantity);
}
// If the item is not money or player wants to add extra money
// then open window to set quantity manually
if (quantityToMove <= 0) {
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, maxQuantity);
}
return quantityToMove;
int balance = totalCostPlayer - totalCostNpc;
bool balancePositive = true;
if (balance < 0) {
balancePositive = false;
balance = -balance;
}
// fromPlayer | fromInventory | balancePositive | suggestedVale
// 0 | 0 | 0 | abs(balance)
// 0 | 0 | 1 | 1
// 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);
}
y0lo marked this conversation as resolved.
Show resolved Hide resolved
}
return inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, maxQuantity, suggestedValue);
}

// 0x474DAC
Expand Down Expand Up @@ -4835,7 +4852,7 @@ static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Obj

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)) {
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 (itemMoveForce(_inven_dude, a6, a1, quantityToMove) == -1) {
// There is no space left for that item.
Expand All @@ -4848,7 +4865,7 @@ static void _barter_move_inventory(Object* a1, int quantity, int a3, int a4, Obj
}
} 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)) {
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 (itemMoveForce(a5, a6, a1, quantityToMove) == -1) {
// You cannot pick that up. You are at your maximum weight capacity.
Expand Down Expand Up @@ -4922,7 +4939,7 @@ static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3,

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)) {
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 (itemMoveForce(a5, _inven_dude, a1, quantityToMove) == -1) {
// There is no space left for that item.
Expand All @@ -4935,7 +4952,7 @@ static void _barter_move_from_table_inventory(Object* a1, int quantity, int a3,
}
} 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)) {
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 (itemMoveForce(a5, a4, a1, quantityToMove) == -1) {
// You cannot pick that up. You are at your maximum weight capacity.
Expand Down Expand Up @@ -5596,7 +5613,7 @@ static void _draw_amount(int value, int inventoryWindowType)
}

// 0x47688C
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int max)
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int max, int suggestedValue)
y0lo marked this conversation as resolved.
Show resolved Hide resolved
{
ScopedGameMode gm(GameMode::kCounter);

Expand All @@ -5605,7 +5622,7 @@ static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int ma
int value;
int min;
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_MOVE_ITEMS) {
value = 1;
value = suggestedValue;
if (max > 99999) {
max = 99999;
}
Expand Down