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

Possibility of defining currencies #3699

Merged
8 commits merged into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
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
3 changes: 0 additions & 3 deletions data/actions/actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,6 @@
<action itemid="2095" script="other/bird_cage.lua" />
<action itemid="2099" script="other/water_pipe.lua" />
<action itemid="2114" script="other/piggy_bank.lua" />
<action itemid="2148" script="other/change_gold.lua" />
<action itemid="2152" script="other/change_gold.lua" />
<action itemid="2160" script="other/change_gold.lua" />
<action fromid="2376" toid="2404" script="other/destroy.lua" />
<action fromid="2406" toid="2415" script="other/destroy.lua" />
<action fromid="2417" toid="2419" script="other/destroy.lua" />
Expand Down
19 changes: 0 additions & 19 deletions data/actions/scripts/other/change_gold.lua

This file was deleted.

3 changes: 3 additions & 0 deletions data/items/items.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,7 @@
</item>
<item id="2148" article="a" name="gold coin">
<attribute key="weight" value="10" />
<attribute key="worth" value="1" />
</item>
<item id="2149" article="a" name="small emerald">
<attribute key="weight" value="10" />
Expand All @@ -2189,6 +2190,7 @@
</item>
<item id="2152" article="a" name="platinum coin">
<attribute key="weight" value="10" />
<attribute key="worth" value="100" />
</item>
<item id="2153" article="a" name="violet gem">
<attribute key="weight" value="30" />
Expand All @@ -2213,6 +2215,7 @@
</item>
<item id="2160" article="a" name="crystal coin">
<attribute key="weight" value="10" />
<attribute key="worth" value="10000" />
</item>
<item id="2161" article="a" name="strange talisman">
<attribute key="weight" value="290" />
Expand Down
48 changes: 14 additions & 34 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -171,40 +171,20 @@ function Player.canCarryMoney(self, amount)
local totalWeight = 0
local inventorySlots = 0

-- Add crystal coins to totalWeight and inventorySlots
local type_crystal = ItemType(ITEM_CRYSTAL_COIN)
local crystalCoins = math.floor(amount / 10000)
if crystalCoins > 0 then
amount = amount - (crystalCoins * 10000)
while crystalCoins > 0 do
local count = math.min(100, crystalCoins)
totalWeight = totalWeight + type_crystal:getWeight(count)
crystalCoins = crystalCoins - count
inventorySlots = inventorySlots + 1
end
end

-- Add platinum coins to totalWeight and inventorySlots
local type_platinum = ItemType(ITEM_PLATINUM_COIN)
local platinumCoins = math.floor(amount / 100)
if platinumCoins > 0 then
amount = amount - (platinumCoins * 100)
while platinumCoins > 0 do
local count = math.min(100, platinumCoins)
totalWeight = totalWeight + type_platinum:getWeight(count)
platinumCoins = platinumCoins - count
inventorySlots = inventorySlots + 1
end
end

-- Add gold coins to totalWeight and inventorySlots
local type_gold = ItemType(ITEM_GOLD_COIN)
if amount > 0 then
while amount > 0 do
local count = math.min(100, amount)
totalWeight = totalWeight + type_gold:getWeight(count)
amount = amount - count
inventorySlots = inventorySlots + 1
local currencyItems = Game.getCurrencyItems()
for index = #currencyItems, 1, -1 do
local currency = currencyItems[index]
-- Add currency coins to totalWeight and inventorySlots
local worth = currency:getWorth()
local currencyCoins = math.floor(amount / worth)
if crystalCoins > 0 then
MillhioreBT marked this conversation as resolved.
Show resolved Hide resolved
amount = amount - (currencyCoins * worth)
while currencyCoins > 0 do
local count = math.min(100, currencyCoins)
totalWeight = totalWeight + currency:getWeight(count)
currencyCoins = currencyCoins - count
inventorySlots = inventorySlots + 1
end
end
end

Expand Down
17 changes: 11 additions & 6 deletions data/npc/lib/npc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,15 @@ function getMoneyCount(string)
end

function getMoneyWeight(money)
local gold = money
local crystal = math.floor(gold / 10000)
gold = gold - crystal * 10000
local platinum = math.floor(gold / 100)
gold = gold - platinum * 100
return (ItemType(ITEM_CRYSTAL_COIN):getWeight() * crystal) + (ItemType(ITEM_PLATINUM_COIN):getWeight() * platinum) + (ItemType(ITEM_GOLD_COIN):getWeight() * gold)
local weight, currencyItems = 0, Game.getCurrencyItems()
for index = #currencyItems, 1, -1 do
local currency = currencyItems[index]
local worth = currency:getWorth()
local currencyCoins = math.floor(money / worth)
if currencyCoins > 0 then
money = money - (currencyCoins * worth)
weight = weight + currency:getWeight(currencyCoins)
end
end
return weight
end
27 changes: 27 additions & 0 deletions data/scripts/actions/others/change_gold.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local config = {}

local changeGold = Action()

function changeGold.onUse(player, item, fromPosition, target, toPosition, isHotkey)
local coin = config[item:getId()]
if coin.changeTo and item.type == 100 then
item:remove()
player:addItem(coin.changeTo, 1)
elseif coin.changeBack then
item:remove(1)
player:addItem(coin.changeBack, 100)
else
return false
end
return true
end

local currencyItems = Game.getCurrencyItems()
for index, currency in pairs(currencyItems) do
local back, to = currencyItems[index-1], currencyItems[index+1]
local currencyId = currency:getId()
config[currencyId] = { changeBack = back and back:getId(), changeTo = to and to:getId() }
changeGold:id(currencyId)
end

changeGold:register()
13 changes: 8 additions & 5 deletions data/scripts/actions/tools/gold_converter.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
local config = {
[ITEM_GOLD_COIN] = {changeTo = ITEM_PLATINUM_COIN},
[ITEM_PLATINUM_COIN] = {changeBack = ITEM_GOLD_COIN, changeTo = ITEM_CRYSTAL_COIN},
[ITEM_CRYSTAL_COIN] = {changeBack = ITEM_PLATINUM_COIN}
}
local config = {}

local goldConverter = Action()

Expand Down Expand Up @@ -32,5 +28,12 @@ function goldConverter.onUse(player, item, fromPosition, target, toPosition, isH
return true
end

local currencyItems = Game.getCurrencyItems()
for index, currency in pairs(currencyItems) do
local back, to = currencyItems[index-1], currencyItems[index+1]
local currencyId = currency:getId()
config[currencyId] = { changeBack = back and back:getId(), changeTo = to and to:getId() }
end

goldConverter:id(26378)
goldConverter:register()
41 changes: 14 additions & 27 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1562,39 +1562,26 @@ void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
return;
}

uint32_t crystalCoins = money / 10000;
money -= crystalCoins * 10000;
while (crystalCoins > 0) {
const uint16_t count = std::min<uint32_t>(100, crystalCoins);
for (const auto& it : Item::items.currencyItems) {
const uint64_t worth = it.first;

Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, count);

ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
if (ret != RETURNVALUE_NOERROR) {
internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
uint32_t currencyCoins = money / worth;
if (currencyCoins <= 0) {
continue;
}

crystalCoins -= count;
}
money -= currencyCoins * worth;
while (currencyCoins > 0) {
const uint16_t count = std::min<uint32_t>(100, currencyCoins);

uint16_t platinumCoins = money / 100;
if (platinumCoins != 0) {
Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins);
Item* remaindItem = Item::CreateItem(it.second, count);

ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
if (ret != RETURNVALUE_NOERROR) {
internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
}

money -= platinumCoins * 100;
}

if (money != 0) {
Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money);
ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
if (ret != RETURNVALUE_NOERROR) {
internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
}

ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
if (ret != RETURNVALUE_NOERROR) {
internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
currencyCoins -= count;
}
}
}
Expand Down
14 changes: 1 addition & 13 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,19 +1637,7 @@ bool Item::canDecay() const

uint32_t Item::getWorth() const
{
switch (id) {
case ITEM_GOLD_COIN:
return count;

case ITEM_PLATINUM_COIN:
return count * 100;

case ITEM_CRYSTAL_COIN:
return count * 10000;

default:
return 0;
}
return items[id].worth * count;
}

LightInfo Item::getLightInfo() const
Expand Down
13 changes: 13 additions & 0 deletions src/items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const std::unordered_map<std::string, ItemParseAttributes_t> ItemParseAttributes
{"blocking", ITEM_PARSE_BLOCKING},
{"allowdistread", ITEM_PARSE_ALLOWDISTREAD},
{"storeitem", ITEM_PARSE_STOREITEM},
{"worth", ITEM_PARSE_WORTH},
};

const std::unordered_map<std::string, ItemTypes_t> ItemTypesMap = {
Expand Down Expand Up @@ -226,6 +227,7 @@ void Items::clear()
items.clear();
clientIdToServerIdMap.clear();
nameToItems.clear();
currencyItems.clear();
inventory.clear();
}

Expand Down Expand Up @@ -1368,6 +1370,17 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
break;
}

case ITEM_PARSE_WORTH: {
MillhioreBT marked this conversation as resolved.
Show resolved Hide resolved
uint64_t worth = pugi::cast<uint64_t>(valueAttribute.value());
if (currencyItems.find(worth) != currencyItems.end()) {
std::cout << "[Warning - Items::parseItemNode] Duplicated currency item " << id << " with worth: " << worth << std::endl;
MillhioreBT marked this conversation as resolved.
Show resolved Hide resolved
} else {
currencyItems.insert(CurrencyMap::value_type(worth, id));
it.worth = worth;
}
break;
}

default: {
// It should not ever get to here, only if you add a new key to the map and don't configure a case for it.
std::cout << "[Warning - Items::parseItemNode] Not configured key value: " << keyAttribute.as_string() << std::endl;
Expand Down
5 changes: 5 additions & 0 deletions src/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ enum ItemParseAttributes_t {
ITEM_PARSE_BLOCKING,
ITEM_PARSE_ALLOWDISTREAD,
ITEM_PARSE_STOREITEM,
ITEM_PARSE_WORTH,
};

struct Abilities {
Expand Down Expand Up @@ -330,6 +331,7 @@ class ItemType
uint16_t rotateTo = 0;
int32_t runeMagLevel = 0;
int32_t runeLevel = 0;
uint64_t worth = 0;

CombatType_t combatType = COMBAT_NONE;

Expand Down Expand Up @@ -396,6 +398,8 @@ class Items
using NameMap = std::unordered_map<std::string, uint16_t>;
using InventoryVector = std::vector<uint16_t>;

using CurrencyMap = std::map<uint64_t, uint16_t, std::greater<uint64_t>>;

Items();

// non-copyable
Expand Down Expand Up @@ -433,6 +437,7 @@ class Items
}

NameMap nameToItems;
CurrencyMap currencyItems;

private:
std::vector<ItemType> items;
Expand Down
Loading