From 5719a23f9b0729f04ed1fa5dc6cc680c58d514d4 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 31 Jan 2017 18:57:07 +0300 Subject: Move units into db directory. --- src/CMakeLists.txt | 4 +- src/Makefile.am | 4 +- src/client.cpp | 4 +- src/gui/popups/itempopup.cpp | 5 +- src/gui/widgets/characterdisplay.cpp | 6 +- src/gui/widgets/selldialog.cpp | 8 +- src/gui/windowmanager_unittest.cc | 5 +- src/gui/windows/bankwindow.cpp | 6 +- src/gui/windows/buydialog.cpp | 7 +- src/gui/windows/charselectdialog.cpp | 5 +- src/gui/windows/inventorywindow.cpp | 9 +- src/gui/windows/statuswindow.cpp | 16 +- src/gui/windows/tradewindow.cpp | 5 +- src/net/eathena/playerhandler.cpp | 7 +- src/net/eathena/vendingrecv.cpp | 5 +- src/net/tmwa/playerhandler.cpp | 7 +- src/resources/db/unitsdb.cpp | 328 +++++++++++++++++++++++++++++++++++ src/resources/db/unitsdb.h | 56 ++++++ src/resources/item/shopitem.cpp | 6 +- src/units.cpp | 326 ---------------------------------- src/units.h | 56 ------ 21 files changed, 444 insertions(+), 431 deletions(-) create mode 100644 src/resources/db/unitsdb.cpp create mode 100644 src/resources/db/unitsdb.h delete mode 100644 src/units.cpp delete mode 100644 src/units.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa38c3a17..5a1afb416 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -814,6 +814,8 @@ SET(SRCS resources/db/statdb.h resources/db/statuseffectdb.cpp resources/db/statuseffectdb.h + resources/db/unitsdb.cpp + resources/db/unitsdb.h resources/db/weaponsdb.cpp resources/db/weaponsdb.h resources/soundeffect.cpp @@ -1335,8 +1337,6 @@ SET(SRCS input/touch/touchactions.h input/touch/touchmanager.cpp input/touch/touchmanager.h - units.cpp - units.h variabledata.h vector.cpp vector.h diff --git a/src/Makefile.am b/src/Makefile.am index 6f1f226d3..21a08ef6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -879,8 +879,6 @@ SRC = ${BASE_SRC} \ gui/shortcut/spellshortcut.h \ statuseffect.cpp \ statuseffect.h \ - units.cpp \ - units.h \ particle/animationparticle.cpp \ particle/animationparticle.h \ being/being.cpp \ @@ -1320,6 +1318,8 @@ SRC = ${BASE_SRC} \ resources/db/statdb.h \ resources/db/statuseffectdb.cpp \ resources/db/statuseffectdb.h \ + resources/db/unitsdb.cpp \ + resources/db/unitsdb.h \ resources/db/weaponsdb.cpp \ resources/db/weaponsdb.h \ resources/iteminfo.h \ diff --git a/src/client.cpp b/src/client.cpp index 344d5d7a4..1739b8468 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -33,7 +33,6 @@ #include "settings.h" #include "soundmanager.h" #include "spellmanager.h" -#include "units.h" #include "being/localplayer.h" #include "being/playerinfo.h" @@ -126,6 +125,7 @@ #include "resources/db/skillunitdb.h" #include "resources/db/statdb.h" #include "resources/db/statuseffectdb.h" +#include "resources/db/unitsdb.h" #include "resources/db/weaponsdb.h" #include "resources/resourcemanager/resourcemanager.h" @@ -1380,7 +1380,7 @@ int Client::gameExec() EmoteDB::load(); // ModDB::load(); StatusEffectDB::load(); - Units::loadUnits(); + UnitsDb::loadUnits(); EquipmentWindow::prepareSlotNames(); ActorSprite::load(); diff --git a/src/gui/popups/itempopup.cpp b/src/gui/popups/itempopup.cpp index a659a94bd..5cdc1dd20 100644 --- a/src/gui/popups/itempopup.cpp +++ b/src/gui/popups/itempopup.cpp @@ -25,7 +25,6 @@ #include "actormanager.h" #include "configuration.h" -#include "units.h" #include "gui/gui.h" @@ -39,6 +38,8 @@ #include "resources/iteminfo.h" +#include "resources/db/unitsdb.h" + #include "resources/image/image.h" #include "resources/item/item.h" @@ -222,7 +223,7 @@ void ItemPopup::setItem(const ItemInfo &item, mItemEffect->setTextWrapped(item.getEffect(), 196); // TRANSLATORS: popup label mItemWeight->setTextWrapped(strprintf(_("Weight: %s"), - Units::formatWeight(item.getWeight()).c_str()), 196); + UnitsDb::formatWeight(item.getWeight()).c_str()), 196); mItemCards->setTextWrapped(getCardsString(cards), 196); int minWidth = mItemName->getWidth() + space; diff --git a/src/gui/widgets/characterdisplay.cpp b/src/gui/widgets/characterdisplay.cpp index 8ebc311f7..696b8c2bf 100644 --- a/src/gui/widgets/characterdisplay.cpp +++ b/src/gui/widgets/characterdisplay.cpp @@ -22,8 +22,6 @@ #include "gui/widgets/characterdisplay.h" -#include "units.h" - #include "gui/gui.h" #include "gui/windows/charselectdialog.h" @@ -37,6 +35,8 @@ #include "utils/gettext.h" #include "utils/stringutils.h" +#include "resources/db/unitsdb.h" + #include "net/character.h" #include "debug.h" @@ -139,7 +139,7 @@ void CharacterDisplay::mouseMoved(MouseEvent &event A_UNUSED) CAST_U32( mCharacter->data.mAttributes[Attributes::PLAYER_LEVEL])), // TRANSLATORS: character money - strprintf(_("Money: %s"), Units::formatCurrency( + strprintf(_("Money: %s"), UnitsDb::formatCurrency( mCharacter->data.mAttributes[Attributes::MONEY]).c_str())); } else diff --git a/src/gui/widgets/selldialog.cpp b/src/gui/widgets/selldialog.cpp index 39584050d..7f96e14ff 100644 --- a/src/gui/widgets/selldialog.cpp +++ b/src/gui/widgets/selldialog.cpp @@ -22,8 +22,6 @@ #include "gui/widgets/selldialog.h" -#include "units.h" - #include "enums/gui/layouttype.h" #include "gui/windows/setupwindow.h" @@ -43,6 +41,8 @@ #include "utils/gettext.h" #include "utils/stringutils.h" +#include "resources/db/unitsdb.h" + #include "resources/item/shopitem.h" #include "debug.h" @@ -358,8 +358,8 @@ void SellDialog::updateButtonsAndLabels() { // TRANSLATORS: sell dialog label mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), - Units::formatCurrency(income).c_str(), - Units::formatCurrency(mPlayerMoney + income).c_str())); + UnitsDb::formatCurrency(income).c_str(), + UnitsDb::formatCurrency(mPlayerMoney + income).c_str())); } if (item) item->update(); diff --git a/src/gui/windowmanager_unittest.cc b/src/gui/windowmanager_unittest.cc index 048d23550..b9c848821 100644 --- a/src/gui/windowmanager_unittest.cc +++ b/src/gui/windowmanager_unittest.cc @@ -23,7 +23,6 @@ #include "configuration.h" #include "graphicsmanager.h" #include "settings.h" -#include "units.h" #include "textcommand.h" #include "being/being.h" @@ -105,6 +104,8 @@ #include "resources/sdlimagehelper.h" +#include "resources/db/unitsdb.h" + #include "resources/item/item.h" #include "resources/map/map.h" @@ -160,7 +161,7 @@ TEST_CASE("Windows tests", "windowmanager") gui = new Gui(); gui->postInit(mainGraphics); touchManager.init(); - Units::loadUnits(); + UnitsDb::loadUnits(); charServerHandler = new EAthena::CharServerHandler; serverFeatures = new EAthena::ServerFeatures; inventoryHandler = new EAthena::InventoryHandler; diff --git a/src/gui/windows/bankwindow.cpp b/src/gui/windows/bankwindow.cpp index c55c11250..d6e33148c 100644 --- a/src/gui/windows/bankwindow.cpp +++ b/src/gui/windows/bankwindow.cpp @@ -20,8 +20,6 @@ #include "gui/windows/bankwindow.h" -#include "units.h" - #include "net/bankhandler.h" #include "gui/windows/setupwindow.h" @@ -34,6 +32,8 @@ #include "utils/gettext.h" #include "utils/stringutils.h" +#include "resources/db/unitsdb.h" + #include "debug.h" BankWindow *bankWindow = nullptr; @@ -89,7 +89,7 @@ void BankWindow::bankMoneyChanged(const int money) { // TRANSLATORS: bank window money label mBankMoneyLabel->setCaption(strprintf(_("Money in bank: %s"), - Units::formatCurrency(money).c_str())); + UnitsDb::formatCurrency(money).c_str())); } void BankWindow::action(const ActionEvent &event) diff --git a/src/gui/windows/buydialog.cpp b/src/gui/windows/buydialog.cpp index d2c4e3a6a..c5fdac885 100644 --- a/src/gui/windows/buydialog.cpp +++ b/src/gui/windows/buydialog.cpp @@ -24,7 +24,6 @@ #include "actormanager.h" #include "configuration.h" -#include "units.h" #include "being/being.h" @@ -57,6 +56,8 @@ #include "resources/iteminfo.h" +#include "resources/db/unitsdb.h" + #include "utils/delete2.h" #include @@ -738,8 +739,8 @@ void BuyDialog::updateButtonsAndLabels() mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); // TRANSLATORS: buy dialog label mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), - Units::formatCurrency(price).c_str(), - Units::formatCurrency(mMoney - price).c_str())); + UnitsDb::formatCurrency(price).c_str(), + UnitsDb::formatCurrency(mMoney - price).c_str())); } void BuyDialog::setVisible(Visible visible) diff --git a/src/gui/windows/charselectdialog.cpp b/src/gui/windows/charselectdialog.cpp index 537ae57d4..f7edbfc24 100644 --- a/src/gui/windows/charselectdialog.cpp +++ b/src/gui/windows/charselectdialog.cpp @@ -24,7 +24,6 @@ #include "client.h" #include "configuration.h" -#include "units.h" #include "listeners/charrenamelistener.h" #include "listeners/pincodelistener.h" @@ -48,6 +47,8 @@ #include "net/logindata.h" #include "net/serverfeatures.h" +#include "resources/db/unitsdb.h" + #include "debug.h" // Character slots per row in the dialog @@ -251,7 +252,7 @@ void CharSelectDialog::action(const ActionEvent &event) character->data.mAttributes[Attributes::PLAYER_LEVEL]), CAST_U32( character->data.mAttributes[Attributes::PLAYER_EXP]), - Units::formatCurrency( + UnitsDb::formatCurrency( character->data.mAttributes[Attributes::MONEY]).c_str()); CREATEWIDGET(OkDialog, data->getName(), msg, // TRANSLATORS: ok dialog button diff --git a/src/gui/windows/inventorywindow.cpp b/src/gui/windows/inventorywindow.cpp index 440d8ab6d..7e303af28 100644 --- a/src/gui/windows/inventorywindow.cpp +++ b/src/gui/windows/inventorywindow.cpp @@ -23,7 +23,6 @@ #include "gui/windows/inventorywindow.h" #include "configuration.h" -#include "units.h" #include "being/playerinfo.h" @@ -65,6 +64,8 @@ #include "resources/iteminfo.h" +#include "resources/db/unitsdb.h" + #include "resources/item/item.h" #include "utils/delete2.h" @@ -701,7 +702,7 @@ void InventoryWindow::mouseMoved(MouseEvent &event) { // TRANSLATORS: money label textPopup->show(rect.x + x, rect.y + y, strprintf(_("Money: %s"), - Units::formatCurrency(PlayerInfo::getAttribute( + UnitsDb::formatCurrency(PlayerInfo::getAttribute( Attributes::MONEY)).c_str())); } else @@ -856,8 +857,8 @@ void InventoryWindow::updateWeight() mWeightBar->setProgress(static_cast(total) / static_cast(max)); mWeightBar->setText(strprintf("%s/%s", - Units::formatWeight(total).c_str(), - Units::formatWeight(max).c_str())); + UnitsDb::formatWeight(total).c_str(), + UnitsDb::formatWeight(max).c_str())); } void InventoryWindow::slotsChanged(const Inventory *const inventory) diff --git a/src/gui/windows/statuswindow.cpp b/src/gui/windows/statuswindow.cpp index 933e80dee..9b1fa0770 100644 --- a/src/gui/windows/statuswindow.cpp +++ b/src/gui/windows/statuswindow.cpp @@ -25,7 +25,6 @@ #include "configuration.h" #include "gamemodifiers.h" #include "settings.h" -#include "units.h" #include "being/localplayer.h" #include "being/playerinfo.h" @@ -49,6 +48,7 @@ #include "net/inventoryhandler.h" #include "net/playerhandler.h" +#include "resources/db/unitsdb.h" #include "resources/db/statdb.h" #include "resources/item/item.h" @@ -215,8 +215,9 @@ StatusWindow::StatusWindow() : updateXPBar(mXpBar, false); // TRANSLATORS: status window label - mMoneyLabel->setCaption(strprintf(_("Money: %s"), Units::formatCurrency( - PlayerInfo::getAttribute(Attributes::MONEY)).c_str())); + mMoneyLabel->setCaption(strprintf(_("Money: %s"), + UnitsDb::formatCurrency(PlayerInfo::getAttribute( + Attributes::MONEY)).c_str())); mMoneyLabel->adjustSize(); updateLevelLabel(); @@ -356,7 +357,7 @@ void StatusWindow::attributeChanged(const AttributesT id, case Attributes::MONEY: // TRANSLATORS: status window label mMoneyLabel->setCaption(strprintf(_("Money: %s"), - Units::formatCurrency(newVal).c_str())); + UnitsDb::formatCurrency(newVal).c_str())); mMoneyLabel->adjustSize(); break; @@ -510,8 +511,9 @@ void StatusWindow::updateWeightBar(ProgressBar *const bar) progress = static_cast(totalWeight) / static_cast(maxWeight); } - bar->setText(strprintf("%s/%s", Units::formatWeight( - totalWeight).c_str(), Units::formatWeight(maxWeight).c_str())); + bar->setText(strprintf("%s/%s", + UnitsDb::formatWeight(totalWeight).c_str(), + UnitsDb::formatWeight(maxWeight).c_str())); bar->setProgress(progress); } } @@ -522,7 +524,7 @@ void StatusWindow::updateMoneyBar(ProgressBar *const bar) return; const int money = PlayerInfo::getAttribute(Attributes::MONEY); - bar->setText(Units::formatCurrency(money)); + bar->setText(UnitsDb::formatCurrency(money)); if (money > 0) { const float progress = static_cast(money) diff --git a/src/gui/windows/tradewindow.cpp b/src/gui/windows/tradewindow.cpp index 825615dc7..995db35eb 100644 --- a/src/gui/windows/tradewindow.cpp +++ b/src/gui/windows/tradewindow.cpp @@ -24,7 +24,6 @@ #include "configuration.h" #include "game.h" -#include "units.h" #include "being/localplayer.h" #include "being/playerinfo.h" @@ -50,6 +49,8 @@ #include "gui/widgets/tabs/chat/chattab.h" +#include "resources/db/unitsdb.h" + #include "resources/item/item.h" #include "net/serverfeatures.h" @@ -191,7 +192,7 @@ void TradeWindow::setMoney(const int amount) mGotMoney = amount; // TRANSLATORS: trade window money label mMoneyLabel->setCaption(strprintf(_("You get %s"), - Units::formatCurrency(amount).c_str())); + UnitsDb::formatCurrency(amount).c_str())); mMoneyLabel->adjustSize(); } diff --git a/src/net/eathena/playerhandler.cpp b/src/net/eathena/playerhandler.cpp index 35baf812d..81f072da4 100644 --- a/src/net/eathena/playerhandler.cpp +++ b/src/net/eathena/playerhandler.cpp @@ -22,7 +22,6 @@ #include "net/eathena/playerhandler.h" -#include "units.h" #include "notifymanager.h" #include "party.h" @@ -41,6 +40,8 @@ #include "net/eathena/inventoryhandler.h" #include "net/eathena/sp.h" +#include "resources/db/unitsdb.h" + #include "debug.h" extern Net::PlayerHandler *playerHandler; @@ -617,12 +618,12 @@ void PlayerHandler::setStat(Net::MessageIn &msg, if (newMoney > oldMoney) { NotifyManager::notify(NotifyTypes::MONEY_GET, - Units::formatCurrency(newMoney - oldMoney)); + UnitsDb::formatCurrency(newMoney - oldMoney)); } else if (newMoney < oldMoney) { NotifyManager::notify(NotifyTypes::MONEY_SPENT, - Units::formatCurrency(oldMoney - newMoney).c_str()); + UnitsDb::formatCurrency(oldMoney - newMoney).c_str()); } PlayerInfo::setAttribute(Attributes::MONEY, newMoney); diff --git a/src/net/eathena/vendingrecv.cpp b/src/net/eathena/vendingrecv.cpp index 4431acac2..f5168abac 100644 --- a/src/net/eathena/vendingrecv.cpp +++ b/src/net/eathena/vendingrecv.cpp @@ -23,7 +23,6 @@ #include "actormanager.h" #include "itemcolormanager.h" #include "notifymanager.h" -#include "units.h" #include "being/localplayer.h" #include "being/playerinfo.h" @@ -43,6 +42,8 @@ #include "resources/iteminfo.h" +#include "resources/db/unitsdb.h" + #include "resources/inventory/inventory.h" #include "resources/item/shopitem.h" @@ -243,7 +244,7 @@ void VendingRecv::processReport(Net::MessageIn &msg) str = strprintf(_("Sold item %s amount %d. You got: %s"), info.getLink().c_str(), amount, - Units::formatCurrency(money).c_str()); + UnitsDb::formatCurrency(money).c_str()); } else { diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index 43ebaa483..d9ec46fe3 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -22,7 +22,6 @@ #include "net/tmwa/playerhandler.h" -#include "units.h" #include "notifymanager.h" #include "party.h" @@ -41,6 +40,8 @@ #include "net/tmwa/protocolout.h" #include "net/tmwa/sp.h" +#include "resources/db/unitsdb.h" + #include "debug.h" extern Net::PlayerHandler *playerHandler; @@ -317,12 +318,12 @@ void PlayerHandler::setStat(Net::MessageIn &msg, if (newMoney > oldMoney) { NotifyManager::notify(NotifyTypes::MONEY_GET, - Units::formatCurrency(newMoney - oldMoney)); + UnitsDb::formatCurrency(newMoney - oldMoney)); } else if (newMoney < oldMoney) { NotifyManager::notify(NotifyTypes::MONEY_SPENT, - Units::formatCurrency(oldMoney - newMoney).c_str()); + UnitsDb::formatCurrency(oldMoney - newMoney).c_str()); } PlayerInfo::setAttribute(Attributes::MONEY, newMoney); diff --git a/src/resources/db/unitsdb.cpp b/src/resources/db/unitsdb.cpp new file mode 100644 index 000000000..7e1e8f880 --- /dev/null +++ b/src/resources/db/unitsdb.cpp @@ -0,0 +1,328 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resources/db/unitsdb.h" + +#include "configuration.h" +#include "logger.h" + +#include "resources/beingcommon.h" + +#include + +#include "debug.h" + +struct UnitLevel final +{ + A_DEFAULT_COPY(UnitLevel) + + std::string symbol; + int count; + int round; + std::string separator; +}; + +struct UnitDescription final +{ + A_DEFAULT_COPY(UnitDescription) + + std::vector levels; + double conversion; + bool mix; +}; + +enum UnitType +{ + UNIT_WEIGHT = 0, + UNIT_CURRENCY = 1, + UNIT_END +}; + +static std::string formatUnit(const int value, const int type); + +static std::string splitNumber(std::string str, const std::string &separator); + +struct UnitDescription units[UNIT_END]; + +void UnitsDb::loadUnits() +{ + { // Setup default weight + UnitDescription ud; + + ud.conversion = 1.0; + ud.mix = false; + + const UnitLevel bu = + { + "g", + 1, + 0, + "" + }; + ud.levels.push_back(bu); + + const UnitLevel ul = + { + "kg", + 1000, + 2, + "" + }; + ud.levels.push_back(ul); + + units[UNIT_WEIGHT] = ud; + } + + { // Setup default currency + UnitDescription ud; + + ud.conversion = 1.0; + ud.mix = false; + + UnitLevel bu = {"¤", 1, 0, ""}; + ud.levels.push_back(bu); + + units[UNIT_CURRENCY] = ud; + } + + loadXmlFile(paths.getStringValue("unitsFile"), SkipError_false); + loadXmlFile(paths.getStringValue("unitsPatchFile"), SkipError_true); + loadXmlDir("unitsPatchDir", loadXmlFile); +} + +void UnitsDb::loadXmlFile(const std::string &fileName, + const SkipError skipError) +{ + XML::Document doc(fileName, UseResman_true, skipError); + const XmlNodePtrConst root = doc.rootNode(); + + if (!root || !xmlNameEqual(root, "units")) + { + logger->log("Error loading unit definition file: " + + paths.getStringValue("unitsFile")); + return; + } + + for_each_xml_child_node(node, root) + { + if (xmlNameEqual(node, "include")) + { + const std::string name = XML::getProperty(node, "name", ""); + if (!name.empty()) + loadXmlFile(name, skipError); + continue; + } + else if (xmlNameEqual(node, "unit")) + { + UnitDescription ud; + int level = 1; + const std::string type = XML::getProperty(node, "type", ""); + ud.conversion = XML::getProperty(node, "conversion", 1); + ud.mix = XML::getProperty(node, "mix", "no") == "yes"; + + UnitLevel bu; + bu.symbol = XML::getProperty(node, "base", "¤"); + bu.count = 1; + bu.round = XML::getProperty(node, "round", 2); + bu.separator = XML::getProperty(node, "separator", " "); + + ud.levels.push_back(bu); + + for_each_xml_child_node(uLevel, node) + { + if (xmlNameEqual(uLevel, "level")) + { + const UnitLevel ul = + { + XML::getProperty(uLevel, "symbol", + strprintf("¤%d", level)), + XML::getProperty(uLevel, "count", -1), + XML::getProperty(uLevel, "round", bu.round), + XML::getProperty(uLevel, "separator", bu.separator) + }; + + if (ul.count > 0) + { + ud.levels.push_back(ul); + level++; + } + else + { + logger->log("Error bad unit count: %d for %s in %s", + ul.count, ul.symbol.c_str(), + bu.symbol.c_str()); + } + } + } + + // Add one more level for saftey + const UnitLevel lev = + { + "", + INT_MAX, + 0, + "" + }; + ud.levels.push_back(lev); + + if (type == "weight") + units[UNIT_WEIGHT] = ud; + else if (type == "currency") + units[UNIT_CURRENCY] = ud; + else + logger->log("Error unknown unit type: %s", type.c_str()); + } + } +} + +static std::string formatUnit(const int value, + const int type) +{ + const UnitDescription ud = units[type]; + UnitLevel ul; + + // Shortcut for 0; do the same for values less than 0 (for now) + if (value <= 0) + { + ul = ud.levels[0]; + return strprintf("0%s", ul.symbol.c_str()); + } + else + { + double amount = ud.conversion * value; + const unsigned int sz = CAST_U32(ud.levels.size()); + + // If only the first level is needed, act like mix if false + if (ud.mix && !ud.levels.empty() && ud.levels[1].count < amount) + { + std::string output; + UnitLevel pl = ud.levels[0]; + ul = ud.levels[1]; + int levelAmount = CAST_S32(amount); + int nextAmount = 0; + + if (ul.count) + levelAmount /= ul.count; + + amount -= static_cast(levelAmount * ul.count); + + if (amount > 0) + { + output = splitNumber(strprintf("%.*f", pl.round, + amount), pl.separator).append(pl.symbol); + } + + for (unsigned int i = 2; i < sz; i++) + { + pl = ul; + ul = ud.levels[i]; + + if (ul.count) + { + nextAmount = levelAmount / ul.count; + levelAmount %= ul.count; + } + + if (levelAmount > 0) + { + output = splitNumber(strprintf("%d", levelAmount), + pl.separator).append(pl.symbol).append(output); + } + + if (!nextAmount) + break; + levelAmount = nextAmount; + } + + return output; + } + else + { + ul.round = 0; + for (unsigned int i = 0; i < sz; i++) + { + ul = ud.levels[i]; + if (amount < ul.count && ul.count > 0) + { + ul = ud.levels[i - 1]; + break; + } + if (ul.count) + amount /= ul.count; + } + + return splitNumber(strprintf("%.*f", ul.round, amount), + ul.separator).append(ul.symbol); + } + } +} + +std::string UnitsDb::formatCurrency(const int value) +{ + return formatUnit(value, UNIT_CURRENCY); +} + +std::string UnitsDb::formatWeight(const int value) +{ + return formatUnit(value, UNIT_WEIGHT); +} + +static std::string splitNumber(std::string str, + const std::string &separator) +{ + std::string lastPart; + const size_t point = str.find('.'); + if (point != std::string::npos) + { + lastPart = str.substr(point); + str = str.substr(0, point); + } + std::string result; + + if (!str.empty()) + { + size_t sz = str.size(); + while (sz >= 3) + { + if (sz >= 6) + { + result = std::string(separator).append(str.substr( + sz - 3)).append(result); + } + else + { + result = str.substr(sz - 3).append(result); + } + str = str.substr(0, str.size() - 3); + sz = str.size(); + } + if (!str.empty()) + { + if (!result.empty()) + result = std::string(str).append(separator).append(result); + else + result = str; + } + } + + return result + lastPart; +} diff --git a/src/resources/db/unitsdb.h b/src/resources/db/unitsdb.h new file mode 100644 index 000000000..b8c81cfc3 --- /dev/null +++ b/src/resources/db/unitsdb.h @@ -0,0 +1,56 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RESOURCES_DB_UNITSDB_H +#define RESOURCES_DB_UNITSDB_H + +#include "enums/simpletypes/skiperror.h" + +#include + +#include "localconsts.h" + +class UnitsDb final +{ + public: + A_DELETE_COPY(UnitsDb) + + /** + * Loads and parses the units.xml file (if found). + */ + static void loadUnits(); + + static void loadXmlFile(const std::string &fileName, + const SkipError skipError); + + /** + * Formats the given number in the correct currency format. + */ + static std::string formatCurrency(const int value) A_WARN_UNUSED; + + /** + * Formats the given number in the correct weight/mass format. + */ + static std::string formatWeight(const int value) A_WARN_UNUSED; +}; + +#endif // RESOURCES_DB_UNITSDB_H diff --git a/src/resources/item/shopitem.cpp b/src/resources/item/shopitem.cpp index 74b4f2de8..b3d088b36 100644 --- a/src/resources/item/shopitem.cpp +++ b/src/resources/item/shopitem.cpp @@ -22,14 +22,14 @@ #include "resources/item/shopitem.h" -#include "units.h" - #include "resources/iteminfo.h" #include "utils/stringutils.h" #include "net/serverfeatures.h" +#include "resources/db/unitsdb.h" + #include "debug.h" ShopItem::ShopItem(const int inventoryIndex, @@ -99,7 +99,7 @@ void ShopItem::updateDisplayName(const int quantity) if (mPrice) { mDisplayName.append(" (").append( - Units::formatCurrency(mPrice)).append(") "); + UnitsDb::formatCurrency(mPrice)).append(") "); } if (mShowQuantity && quantity > 1) mDisplayName.append("[").append(toString(quantity)).append("]"); diff --git a/src/units.cpp b/src/units.cpp deleted file mode 100644 index cc68c7463..000000000 --- a/src/units.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "units.h" - -#include "configuration.h" -#include "logger.h" - -#include "resources/beingcommon.h" - -#include - -#include "debug.h" - -struct UnitLevel final -{ - A_DEFAULT_COPY(UnitLevel) - - std::string symbol; - int count; - int round; - std::string separator; -}; - -struct UnitDescription final -{ - A_DEFAULT_COPY(UnitDescription) - - std::vector levels; - double conversion; - bool mix; -}; - -enum UnitType -{ - UNIT_WEIGHT = 0, - UNIT_CURRENCY = 1, - UNIT_END -}; - -static std::string formatUnit(const int value, const int type); - -static std::string splitNumber(std::string str, const std::string &separator); - -struct UnitDescription units[UNIT_END]; - -void Units::loadUnits() -{ - { // Setup default weight - UnitDescription ud; - - ud.conversion = 1.0; - ud.mix = false; - - const UnitLevel bu = - { - "g", - 1, - 0, - "" - }; - ud.levels.push_back(bu); - - const UnitLevel ul = - { - "kg", - 1000, - 2, - "" - }; - ud.levels.push_back(ul); - - units[UNIT_WEIGHT] = ud; - } - - { // Setup default currency - UnitDescription ud; - - ud.conversion = 1.0; - ud.mix = false; - - UnitLevel bu = {"¤", 1, 0, ""}; - ud.levels.push_back(bu); - - units[UNIT_CURRENCY] = ud; - } - - loadXmlFile(paths.getStringValue("unitsFile"), SkipError_false); - loadXmlFile(paths.getStringValue("unitsPatchFile"), SkipError_true); - loadXmlDir("unitsPatchDir", loadXmlFile); -} - -void Units::loadXmlFile(const std::string &fileName, - const SkipError skipError) -{ - XML::Document doc(fileName, UseResman_true, skipError); - const XmlNodePtrConst root = doc.rootNode(); - - if (!root || !xmlNameEqual(root, "units")) - { - logger->log("Error loading unit definition file: " - + paths.getStringValue("unitsFile")); - return; - } - - for_each_xml_child_node(node, root) - { - if (xmlNameEqual(node, "include")) - { - const std::string name = XML::getProperty(node, "name", ""); - if (!name.empty()) - loadXmlFile(name, skipError); - continue; - } - else if (xmlNameEqual(node, "unit")) - { - UnitDescription ud; - int level = 1; - const std::string type = XML::getProperty(node, "type", ""); - ud.conversion = XML::getProperty(node, "conversion", 1); - ud.mix = XML::getProperty(node, "mix", "no") == "yes"; - - UnitLevel bu; - bu.symbol = XML::getProperty(node, "base", "¤"); - bu.count = 1; - bu.round = XML::getProperty(node, "round", 2); - bu.separator = XML::getProperty(node, "separator", " "); - - ud.levels.push_back(bu); - - for_each_xml_child_node(uLevel, node) - { - if (xmlNameEqual(uLevel, "level")) - { - const UnitLevel ul = - { - XML::getProperty(uLevel, "symbol", - strprintf("¤%d", level)), - XML::getProperty(uLevel, "count", -1), - XML::getProperty(uLevel, "round", bu.round), - XML::getProperty(uLevel, "separator", bu.separator) - }; - - if (ul.count > 0) - { - ud.levels.push_back(ul); - level++; - } - else - { - logger->log("Error bad unit count: %d for %s in %s", - ul.count, ul.symbol.c_str(), - bu.symbol.c_str()); - } - } - } - - // Add one more level for saftey - const UnitLevel lev = - { - "", - INT_MAX, - 0, - "" - }; - ud.levels.push_back(lev); - - if (type == "weight") - units[UNIT_WEIGHT] = ud; - else if (type == "currency") - units[UNIT_CURRENCY] = ud; - else - logger->log("Error unknown unit type: %s", type.c_str()); - } - } -} - -static std::string formatUnit(const int value, const int type) -{ - const UnitDescription ud = units[type]; - UnitLevel ul; - - // Shortcut for 0; do the same for values less than 0 (for now) - if (value <= 0) - { - ul = ud.levels[0]; - return strprintf("0%s", ul.symbol.c_str()); - } - else - { - double amount = ud.conversion * value; - const unsigned int sz = CAST_U32(ud.levels.size()); - - // If only the first level is needed, act like mix if false - if (ud.mix && !ud.levels.empty() && ud.levels[1].count < amount) - { - std::string output; - UnitLevel pl = ud.levels[0]; - ul = ud.levels[1]; - int levelAmount = CAST_S32(amount); - int nextAmount = 0; - - if (ul.count) - levelAmount /= ul.count; - - amount -= static_cast(levelAmount * ul.count); - - if (amount > 0) - { - output = splitNumber(strprintf("%.*f", pl.round, - amount), pl.separator).append(pl.symbol); - } - - for (unsigned int i = 2; i < sz; i++) - { - pl = ul; - ul = ud.levels[i]; - - if (ul.count) - { - nextAmount = levelAmount / ul.count; - levelAmount %= ul.count; - } - - if (levelAmount > 0) - { - output = splitNumber(strprintf("%d", levelAmount), - pl.separator).append(pl.symbol).append(output); - } - - if (!nextAmount) - break; - levelAmount = nextAmount; - } - - return output; - } - else - { - ul.round = 0; - for (unsigned int i = 0; i < sz; i++) - { - ul = ud.levels[i]; - if (amount < ul.count && ul.count > 0) - { - ul = ud.levels[i - 1]; - break; - } - if (ul.count) - amount /= ul.count; - } - - return splitNumber(strprintf("%.*f", ul.round, amount), - ul.separator).append(ul.symbol); - } - } -} - -std::string Units::formatCurrency(const int value) -{ - return formatUnit(value, UNIT_CURRENCY); -} - -std::string Units::formatWeight(const int value) -{ - return formatUnit(value, UNIT_WEIGHT); -} - -static std::string splitNumber(std::string str, const std::string &separator) -{ - std::string lastPart; - const size_t point = str.find('.'); - if (point != std::string::npos) - { - lastPart = str.substr(point); - str = str.substr(0, point); - } - std::string result; - - if (!str.empty()) - { - size_t sz = str.size(); - while (sz >= 3) - { - if (sz >= 6) - { - result = std::string(separator).append(str.substr( - sz - 3)).append(result); - } - else - { - result = str.substr(sz - 3).append(result); - } - str = str.substr(0, str.size() - 3); - sz = str.size(); - } - if (!str.empty()) - { - if (!result.empty()) - result = std::string(str).append(separator).append(result); - else - result = str; - } - } - - return result + lastPart; -} diff --git a/src/units.h b/src/units.h deleted file mode 100644 index 0cbf05f9e..000000000 --- a/src/units.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef UNITS_H -#define UNITS_H - -#include "enums/simpletypes/skiperror.h" - -#include - -#include "localconsts.h" - -class Units final -{ - public: - A_DELETE_COPY(Units) - - /** - * Loads and parses the units.xml file (if found). - */ - static void loadUnits(); - - static void loadXmlFile(const std::string &fileName, - const SkipError skipError); - - /** - * Formats the given number in the correct currency format. - */ - static std::string formatCurrency(const int value) A_WARN_UNUSED; - - /** - * Formats the given number in the correct weight/mass format. - */ - static std::string formatWeight(const int value) A_WARN_UNUSED; -}; - -#endif // UNITS_H -- cgit v1.2.3-70-g09d2