Skip to content

Commit

Permalink
Rework how gold is displayed
Browse files Browse the repository at this point in the history
  • Loading branch information
kphoenix137 committed Oct 6, 2024
1 parent 9657ac6 commit 6b38586
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 64 deletions.
144 changes: 81 additions & 63 deletions Source/stores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,12 @@ void SetupErrorScreen(TalkID talkId)

void SetupConfirmScreen()
{
StartStore(OldActiveStore); // FIXME: Should be Confirm screen instead??
StartStore(OldActiveStore);
ClearTextLines(5, 23);

UiFlags itemColor = TempItem.getTextColorWithStatCheck();
SetLineText(20, 8, TempItem.getName(), itemColor, false);
SetLineValue(8, TempItem._iIvalue);
SetLineValue(8, TempItem._iIvalue); // FIXME: Incorrectly displays full item value in cases we should be using displayValue
PrintStoreItem(TempItem, 9, itemColor);

std::string_view prompt;
Expand Down Expand Up @@ -752,13 +752,13 @@ void FilterRepairableItems()
return itemPtr.isEmpty() || itemPtr._iDurability == itemPtr._iMaxDur || itemPtr._iMaxDur == DUR_INDESTRUCTIBLE;
}),
playerItems.end());
}

// Calculate repair costs and update displayValue in the vector
for (IndexedItem &indexedItem : playerItems) {
const Item &itemPtr = *indexedItem.itemPtr;

indexedItem.displayValue = GetRepairCost(itemPtr);
}
int GetRechargeCost(const Item &item)
{
int rechargeCost = GetSpellData(item._iSpell).staffCost();
rechargeCost = (rechargeCost * (item._iMaxCharges - item._iCharges)) / (item._iMaxCharges * 2);
return rechargeCost;
}

void FilterRechargeableItems()
Expand All @@ -770,14 +770,11 @@ void FilterRechargeableItems()
return itemPtr.isEmpty() || itemPtr._iCharges == itemPtr._iMaxCharges || (itemPtr._itype != ItemType::Staff && itemPtr._iMiscId != IMISC_UNIQUE && itemPtr._iMiscId != IMISC_STAFF);
}),
playerItems.end());
}

// Calculate recharge costs and update displayValue in the vector
for (IndexedItem &indexedItem : playerItems) {
const Item &itemPtr = *indexedItem.itemPtr;
int rechargeCost = GetSpellData(itemPtr._iSpell).staffCost();
rechargeCost = (rechargeCost * (itemPtr._iMaxCharges - itemPtr._iCharges)) / (itemPtr._iMaxCharges * 2);
indexedItem.displayValue = rechargeCost;
}
int GetIdentifyCost()
{
return 100;
}

void FilterIdentifiableItems()
Expand All @@ -789,11 +786,6 @@ void FilterIdentifiableItems()
return itemPtr.isEmpty() || itemPtr._iMagical == ITEM_QUALITY_NORMAL || itemPtr._iIdentified;
}),
playerItems.end());

// Set the identification cost for all identifiable items
for (IndexedItem &indexedItem : playerItems) {
indexedItem.displayValue = 100; // Identification cost is 100 gold
}
}

void FilterPlayerItemsForAction(TalkID talkId)
Expand All @@ -820,22 +812,17 @@ void FilterPlayerItemsForAction(TalkID talkId)
}
}

// FIXME: Do we do templated function?
void SetupItemList(TalkID talkId, std::vector<Item> &items, int idx, bool selling /*= true*/)
void SetupTownerItemList(TalkID talkId, std::vector<Item> &items, int idx, bool selling /*= true*/)
{
ClearTextLines(5, 21);
PreviousScrollPos = 5;

int startLine = (TownerId == TOWN_PEGBOY) ? 10 : 5;
for (int l = startLine; l < 20 && idx < items.size(); l += 4) {
const Item &item = items[idx];
int price = item._iIdentified ? item._iIvalue : item._ivalue;

if (TownerId == TOWN_PEGBOY) { // FIXME: Centralize Wirt's logic for price calculation
price = gbIsHellfire ? price - (price / 4) : price + (price / 2);
}

int price = GetItemCost(item);
UiFlags itemColor = item.getTextColorWithStatCheck();

SetLineText(20, l, item.getName(), itemColor, true, item._iCurs, true);
SetLineValue(l, price);
PrintStoreItem(item, l + 1, itemColor, true);
Expand All @@ -851,16 +838,32 @@ void SetupItemList(TalkID talkId, std::vector<Item> &items, int idx, bool sellin
}
}

void SetupItemList(TalkID talkId, std::vector<IndexedItem> &items, int idx, bool selling /*= true*/)
void SetupPlayerItemList(TalkID talkId, std::vector<IndexedItem> &items, int idx, bool selling /*= true*/)
{
ClearTextLines(5, 21);
PreviousScrollPos = 5;

int goldAmountDisplay;

for (int l = 5; l < 20 && idx < items.size(); l += 4) {
const Item &item = *items[idx].itemPtr;
UiFlags itemColor = item.getTextColorWithStatCheck();
SetLineText(20, l, item.getName(), itemColor, true, item._iCurs, true);
SetLineValue(l, items[idx].displayValue);
switch (talkId) {
case TalkID::Sell:
goldAmountDisplay = GetSellPrice(item);
break;
case TalkID::Repair:
goldAmountDisplay = GetRepairCost(item);
break;
case TalkID::Recharge:
goldAmountDisplay = GetRechargeCost(item);
break;
case TalkID::Identify:
goldAmountDisplay = GetIdentifyCost();
break;
}
SetLineValue(l, goldAmountDisplay);
PrintStoreItem(item, l + 1, itemColor, true);
NextScrollPos = l;
idx++;
Expand All @@ -874,22 +877,22 @@ void SetupItemList(TalkID talkId, std::vector<IndexedItem> &items, int idx, bool
}
}

void SetupTownerItemList(TalkID talkId, int idx, bool selling = true)
void SetupItemList(TalkID talkId, int idx, bool selling = true)
{
TownerStore *towner = townerStores[TownerId];

switch (talkId) {
case TalkID::BasicBuy:
SetupItemList(talkId, towner->basicItems, idx, selling);
SetupTownerItemList(talkId, towner->basicItems, idx, selling);
break;
case TalkID::Buy:
SetupItemList(talkId, towner->items, idx, selling);
SetupTownerItemList(talkId, towner->items, idx, selling);
break;
case TalkID::Sell:
case TalkID::Repair:
case TalkID::Recharge:
case TalkID::Identify:
SetupItemList(talkId, playerItems, idx, selling);
SetupPlayerItemList(talkId, playerItems, idx, selling);
break;
}
}
Expand Down Expand Up @@ -960,7 +963,7 @@ void SetupBuyScreen(TalkID talkId)
int itemCount = GetItemCount(talkId);

SetLineAsDivider(BuySellMenuDividerLine);
SetupTownerItemList(talkId, ScrollPos);
SetupItemList(talkId, ScrollPos);
UpdateItemStatFlags(talkId);
NumTextLines = std::max(itemCount - ItemLineSpace, 0);
SetBuyScreenHeader(talkId);
Expand Down Expand Up @@ -988,7 +991,7 @@ void SetupSellScreen(TalkID talkId)
SetLineText(20, 1, _("Which item is for sale?"), UiFlags::ColorWhitegold, false);
SetLineAsDivider(BuySellMenuDividerLine);

SetupTownerItemList(talkId, ScrollPos, false);
SetupItemList(talkId, ScrollPos, false);
AddItemListBackButton(talkId, /*selectable=*/true);
}

Expand Down Expand Up @@ -1019,8 +1022,8 @@ void SetupRepairScreen()
SetLineText(20, 1, _("Repair which item?"), UiFlags::ColorWhitegold, false);
SetLineAsDivider(BuySellMenuDividerLine);

// Pass the filtered items to SetupTownerItemList for rendering
SetupTownerItemList(TalkID::Repair, ScrollPos, false);
// Pass the filtered items to SetupItemList for rendering
SetupItemList(TalkID::Repair, ScrollPos, false);
AddItemListBackButton(TalkID::Repair, /*selectable=*/true);
}

Expand Down Expand Up @@ -1050,8 +1053,8 @@ void SetupRechargeScreen()
SetLineText(20, 1, _("Recharge which item?"), UiFlags::ColorWhitegold, false);
SetLineAsDivider(3);

// Pass the filtered items to SetupTownerItemList for rendering
SetupTownerItemList(TalkID::Recharge, ScrollPos, false);
// Pass the filtered items to SetupItemList for rendering
SetupItemList(TalkID::Recharge, ScrollPos, false);
AddItemListBackButton(TalkID::Recharge);
}

Expand Down Expand Up @@ -1081,8 +1084,8 @@ void SetupIdentifyScreen()
SetLineText(20, 1, _("Identify which item?"), UiFlags::ColorWhitegold, false);
SetLineAsDivider(3);

// Pass the filtered items to SetupTownerItemList for rendering
SetupTownerItemList(TalkID::Identify, ScrollPos, false);
// Pass the filtered items to SetupItemList for rendering
SetupItemList(TalkID::Identify, ScrollPos, false);
AddItemListBackButton(TalkID::Identify);
}

Expand Down Expand Up @@ -1171,6 +1174,17 @@ bool ReturnToMainMenu()
return false;
}

int GetItemCost(const Item &item)
{
int price = item._iIdentified ? item._iIvalue : item._ivalue;

if (TownerId == TOWN_PEGBOY) {
price = gbIsHellfire ? price - (price / 4) : price + (price / 2);
}

return price;
}

void BuyEnter()
{
if (ReturnToMainMenu())
Expand All @@ -1188,22 +1202,14 @@ void BuyEnter()

TownerStore *towner = townerStores[TownerId];
Item &item = (ActiveStore == TalkID::BasicBuy) ? towner->basicItems[idx] : towner->items[idx];
int price = item._iIvalue;

if (TownerId == TOWN_PEGBOY) {
if (gbIsHellfire)
price -= item._iIvalue / 4;
else
price += item._iIvalue / 2;
}
int cost = GetItemCost(item);

if (!CanPlayerAfford(item._iIvalue)) {
if (!CanPlayerAfford(cost)) {
StartStore(TalkID::NoMoney);
} else if (!GiveItemToPlayer(item, false)) {
StartStore(TalkID::NoRoom);
} else {
TempItem = item;
TempItem._iIvalue = price;
StartStore(TalkID::Confirm);
}
}
Expand All @@ -1222,6 +1228,17 @@ bool StoreGoldFit(Item &item)
return cost <= itemRoomForGold + RoomForGold();
}

int GetSellPrice(const Item &item)
{
int price = item._iIvalue;

if (item._iMagical != ITEM_QUALITY_NORMAL && item._iIdentified) {
price = price / 2;
}

return price;
}

/**
* @brief Sells an item from the player's inventory or belt.
*/
Expand All @@ -1231,20 +1248,21 @@ void SellItem()

IndexedItem &itemToSell = playerItems[idx];

// Remove the sold item from the player's inventory or belt
if (itemToSell.location == ItemLocation::Inventory) {
MyPlayer->RemoveInvItem(itemToSell.index);
} else if (itemToSell.location == ItemLocation::Belt) {
MyPlayer->RemoveSpdBarItem(itemToSell.index);
}

int cost = itemToSell.displayValue;
int price = GetSellPrice(*itemToSell.itemPtr);

// Remove the sold item from the playerItems vector
playerItems.erase(playerItems.begin() + idx);

// Add the gold to the player's inventory
AddGoldToInventory(*MyPlayer, cost);
MyPlayer->_pGold += cost;
AddGoldToInventory(*MyPlayer, price);
MyPlayer->_pGold += price;
}

void SellEnter()
Expand Down Expand Up @@ -1315,7 +1333,7 @@ void RepairItem()
}

// Deduct the repair cost from the player's money
TakePlrsMoney(indexedItem.displayValue);
TakePlrsMoney(GetRepairCost(*indexedItem.itemPtr));
}

void RepairEnter()
Expand All @@ -1330,7 +1348,7 @@ void RepairEnter()
int idx = GetItemIndex();

// Check if the player can afford the repair cost
if (!CanPlayerAfford(playerItems[idx].displayValue)) {
if (!CanPlayerAfford(GetRepairCost(*playerItems[idx].itemPtr))) {
StartStore(TalkID::NoMoney);
return;
}
Expand Down Expand Up @@ -1407,7 +1425,7 @@ void BuyItem(Item &item)
/**
* @brief Recharges an item in the player's inventory or body in the witch.
*/
void RechargeItem(int price)
void RechargeItem()
{
int idx = GetItemIndex();
Item *itemPtr = playerItems[idx].itemPtr;
Expand All @@ -1429,7 +1447,7 @@ void RechargeItem(int price)
}

// Deduct the price from the player's gold
TakePlrsMoney(price);
TakePlrsMoney(GetRechargeCost(*playerItems[idx].itemPtr));

// Recalculate the player's inventory
CalcPlrInv(*MyPlayer, true);
Expand All @@ -1448,7 +1466,7 @@ void RechargeEnter()
int idx = GetItemIndex();

// Check if the player can afford the recharge cost
if (!CanPlayerAfford(playerItems[idx].displayValue)) {
if (!CanPlayerAfford(GetRechargeCost(*playerItems[idx].itemPtr))) {
StartStore(TalkID::NoMoney);
return;
}
Expand Down Expand Up @@ -1499,7 +1517,7 @@ void ConfirmEnter(Item &item)
RepairItem();
break;
case TalkID::Recharge:
RechargeItem(item._iIvalue);
RechargeItem();
break;
case TalkID::Identify:
IdentifyItem(item);
Expand Down Expand Up @@ -1534,7 +1552,7 @@ void IdentifyEnter()
int idx = GetItemIndex();

// Check if the player can afford the identification cost
if (!CanPlayerAfford(playerItems[idx].displayValue)) {
if (!CanPlayerAfford(GetIdentifyCost())) {
StartStore(TalkID::NoMoney);
return;
}
Expand Down Expand Up @@ -1847,7 +1865,7 @@ void DrawStoreText(const Surface &out)
selling = false;
break;
}
SetupTownerItemList(ActiveStore, ScrollPos, selling);
SetupItemList(ActiveStore, ScrollPos, selling);
}

CalculateLineHeights();
Expand Down
1 change: 0 additions & 1 deletion Source/stores.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ struct IndexedItem {
Item *itemPtr; // Pointer to the original item
ItemLocation location; // Location in the player's inventory (Inventory, Belt, or Body)
int index; // Index in the corresponding array
int displayValue; // Modified value for display purposes
};

enum class ResourceType {
Expand Down

0 comments on commit 6b38586

Please sign in to comment.