From acf585aa5354367b771c7e3b136671d5bc938c79 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 13 Apr 2013 18:21:51 +0200 Subject: Removed unused IntMap typedef --- src/gui/ministatuswindow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/ministatuswindow.cpp b/src/gui/ministatuswindow.cpp index 9c55a9c8..a4fd358f 100644 --- a/src/gui/ministatuswindow.cpp +++ b/src/gui/ministatuswindow.cpp @@ -167,8 +167,6 @@ void MiniStatusWindow::event(Event::Channel channel, AnimatedSprite *sprite = effect->getIcon(); - typedef std::vector IntMap; - if (!sprite) { // delete sprite, if necessary -- cgit v1.2.3-70-g09d2 From 1a99d37d059df95f6a144c4f9e9fa85dacefd185 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 27 Apr 2013 16:43:59 +0200 Subject: Always read the attributes.xml file This way it can also be used when connecting to a tmwAthena server for customizing the min/max of attributes and the amount of starting points. Mantis-issue: 501 Reviewed-by: Ablu --- mana.files | 7 +- src/CMakeLists.txt | 4 +- src/net/manaserv/attributes.cpp | 408 ------------------------------------ src/net/manaserv/attributes.h | 70 ------- src/net/manaserv/charhandler.cpp | 4 +- src/net/manaserv/generalhandler.cpp | 5 +- src/net/manaserv/playerhandler.cpp | 6 +- src/net/tmwa/charserverhandler.cpp | 6 +- src/net/tmwa/generalhandler.cpp | 19 +- src/resources/attributes.cpp | 405 +++++++++++++++++++++++++++++++++++ src/resources/attributes.h | 68 ++++++ 11 files changed, 508 insertions(+), 494 deletions(-) delete mode 100644 src/net/manaserv/attributes.cpp delete mode 100644 src/net/manaserv/attributes.h create mode 100644 src/resources/attributes.cpp create mode 100644 src/resources/attributes.h diff --git a/mana.files b/mana.files index be668387..dbfddc00 100644 --- a/mana.files +++ b/mana.files @@ -18,7 +18,8 @@ data/help/index.txt data/help/support.txt data/help/windows.txt data/icons/CMakeLists.txt -docs/FAQ.txt +data/sfx/CMakeLists.txt +data/sfx/system/CMakeLists.txt docs/HACKING.txt docs/example.mana docs/items.txt @@ -340,8 +341,6 @@ src/net/logindata.h src/net/loginhandler.h src/net/manaserv/adminhandler.cpp src/net/manaserv/adminhandler.h -src/net/manaserv/attributes.cpp -src/net/manaserv/attributes.h src/net/manaserv/beinghandler.cpp src/net/manaserv/beinghandler.h src/net/manaserv/buysellhandler.cpp @@ -468,6 +467,8 @@ src/resources/ambientlayer.cpp src/resources/ambientlayer.h src/resources/animation.cpp src/resources/animation.h +src/resources/attributes.cpp +src/resources/attributes.h src/resources/beinginfo.cpp src/resources/beinginfo.h src/resources/dye.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f7483cfa..32ac5426 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -365,6 +365,8 @@ SET(SRCS resources/ambientlayer.h resources/animation.cpp resources/animation.h + resources/attributes.cpp + resources/attributes.h resources/beinginfo.cpp resources/beinginfo.h resources/dye.cpp @@ -593,8 +595,6 @@ SET(SRCS_TMWA SET(SRCS_MANA net/manaserv/adminhandler.cpp net/manaserv/adminhandler.h - net/manaserv/attributes.cpp - net/manaserv/attributes.h net/manaserv/beinghandler.cpp net/manaserv/beinghandler.h net/manaserv/buysellhandler.cpp diff --git a/src/net/manaserv/attributes.cpp b/src/net/manaserv/attributes.cpp deleted file mode 100644 index e754a6a9..00000000 --- a/src/net/manaserv/attributes.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2010-2012 The Mana Developers - * - * This file is part of The Mana 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 "net/manaserv/attributes.h" - -#include "log.h" -#include "playerinfo.h" - -#include "gui/statuswindow.h" - -#include "resources/itemdb.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" -#include "utils/xml.h" - -#include -#include - -#define DEFAULT_ATTRIBUTESDB_FILE "attributes.xml" -#define DEFAULT_POINTS 60 -#define DEFAULT_MIN_PTS 1 -#define DEFAULT_MAX_PTS 20 - -namespace ManaServ { -namespace Attributes { - - typedef struct - { - unsigned int id; - std::string name; - std::string description; - /** Whether the attribute value can be modified by the player */ - bool modifiable; - /**< Attribute scope. */ - std::string scope; - /** The playerInfo core Id the attribute is linked with or -1 if not */ - int playerInfoId; - } Attribute; - - /** Map for attributes. */ - typedef std::map AttributeMap; - static AttributeMap attributes; - - /** tags = effects on attributes. */ - typedef std::map< std::string, std::string > TagMap; - static TagMap tags; - - /** List of modifiable attribute names used at character's creation. */ - static std::vector attributeLabels; - - /** Characters creation points. */ - static unsigned int creationPoints = 0; - static unsigned int attributeMinimum = 0; - static unsigned int attributeMaximum = 0; - - unsigned int getCreationPoints() - { - return creationPoints; - } - - unsigned int getAttributeMinimum() - { - return attributeMinimum; - } - - unsigned int getAttributeMaximum() - { - return attributeMaximum; - } - - std::vector& getLabels() - { - return attributeLabels; - } - - /** - * Fills the list of base attribute labels. - */ - static void fillLabels() - { - // Fill up the modifiable attribute label list. - attributeLabels.clear(); - AttributeMap::const_iterator it, it_end; - for (it = attributes.begin(), it_end = attributes.end(); it != it_end; - it++) - { - if (it->second.modifiable && - (it->second.scope == "character" || it->second.scope == "being")) - attributeLabels.push_back(it->second.name + ":"); - } - } - - /** - * Fills the list of base attribute labels. - */ - static int getPlayerInfoIdFromAttrType(std::string attrType) - { - toLower(attrType); - if (attrType == "level") - return ::LEVEL; - else if (attrType == "hp") - return ::HP; - else if (attrType == "max-hp") - return ::MAX_HP; - else if (attrType == "mp") - return ::MP; - else if (attrType == "max-mp") - return ::MAX_MP; - else if (attrType == "exp") - return ::EXP; - else if (attrType == "exp-needed") - return ::EXP_NEEDED; - else if (attrType == "money") - return ::MONEY; - else if (attrType == "total-weight") - return ::TOTAL_WEIGHT; - else if (attrType == "max-weight") - return ::MAX_WEIGHT; - else if (attrType == "skill-points") - return ::SKILL_POINTS; - else if (attrType == "char-points") - return ::CHAR_POINTS; - else if (attrType == "corr-points") - return ::CORR_POINTS; - else if (attrType == "none") - return -2; // Used to hide the attribute display. - - return -1; // Not linked to a playerinfo stat. - } - - int getPlayerInfoIdFromAttrId(int attrId) - { - AttributeMap::const_iterator it = attributes.find(attrId); - - if (it != attributes.end()) - { - return it->second.playerInfoId; - } - - return -1; - } - - static void loadBuiltins() - { - { - Attribute a; - a.id = 16; - a.name = _("Strength"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("str", _("Strength %+.1f"))); - } - - { - Attribute a; - a.id = 17; - a.name = _("Agility"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("agi", _("Agility %+.1f"))); - } - - { - Attribute a; - a.id = 18; - a.name = _("Dexterity"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("dex", _("Dexterity %+.1f"))); - } - - { - Attribute a; - a.id = 19; - a.name = _("Vitality"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("vit", _("Vitality %+.1f"))); - } - - { - Attribute a; - a.id = 20; - a.name = _("Intelligence"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("int", _("Intelligence %+.1f"))); - } - - { - Attribute a; - a.id = 21; - a.name = _("Willpower"); - a.description = ""; - a.modifiable = true; - a.scope = "character"; - a.playerInfoId = -1; - - attributes[a.id] = a; - tags.insert(std::make_pair("wil", _("Willpower %+.1f"))); - } - } - - void load() - { - logger->log("Initializing attributes database..."); - - XML::Document doc(DEFAULT_ATTRIBUTESDB_FILE); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "attributes")) - { - logger->log("Attributes: Error while loading " - DEFAULT_ATTRIBUTESDB_FILE ". Using Built-ins."); - loadBuiltins(); - fillLabels(); - return; - } - - for_each_xml_child_node(node, rootNode) - { - if (xmlStrEqual(node->name, BAD_CAST "attribute")) - { - int id = XML::getProperty(node, "id", 0); - - if (!id) - { - logger->log("Attributes: Invalid or missing stat ID in " - DEFAULT_ATTRIBUTESDB_FILE "!"); - continue; - } - else if (attributes.find(id) != attributes.end()) - { - logger->log("Attributes: Redefinition of stat ID %d", id); - } - - std::string name = XML::getProperty(node, "name", ""); - - if (name.empty()) - { - logger->log("Attributes: Invalid or missing stat name in " - DEFAULT_ATTRIBUTESDB_FILE "!"); - continue; - } - - // Create the attribute. - Attribute a; - a.id = id; - a.name = name; - a.description = XML::getProperty(node, "desc", ""); - a.modifiable = XML::getBoolProperty(node, "modifiable", false); - a.scope = XML::getProperty(node, "scope", "none"); - a.playerInfoId = getPlayerInfoIdFromAttrType( - XML::getProperty(node, "player-info", "")); - - attributes[id] = a; - - unsigned int count = 0; - for_each_xml_child_node(effectNode, node) - { - if (!xmlStrEqual(effectNode->name, BAD_CAST "modifier")) - continue; - ++count; - std::string tag = XML::getProperty(effectNode, "tag", ""); - if (tag.empty()) - { - if (name.empty()) - { - logger->log("Attribute modifier in attribute %u:%s: " - "Empty name definition " - "on empty tag definition, skipping.", - a.id, a.name.c_str()); - --count; - continue; - } - tag = name.substr(0, name.size() > 3 ? 3 : name.size()); - tag = toLower(tag) + toString(count); - } - - std::string effect = XML::getProperty(effectNode, "effect", ""); - if (effect.empty()) - { - if (name.empty()) - { - logger->log("Attribute modifier in attribute %u:%s: " - "Empty name definition " - "on empty effect definition, skipping.", - a.id, a.name.c_str()); - --count; - continue; - } - else - effect = name + " %+f"; - } - tags.insert(std::make_pair(tag, effect)); - } - logger->log("Found %d tags for attribute %d.", count, id); - - }// End attribute - else if (xmlStrEqual(node->name, BAD_CAST "points")) - { - creationPoints = XML::getProperty(node, "start",DEFAULT_POINTS); - attributeMinimum = XML::getProperty(node, "minimum", - DEFAULT_MIN_PTS); - attributeMaximum = XML::getProperty(node, "maximum", - DEFAULT_MAX_PTS); - logger->log("Loaded points: start: %i, min: %i, max: %i.", - creationPoints, attributeMinimum, attributeMaximum); - } - else - { - continue; - } - } - logger->log("Found %d tags for %d attributes.", int(tags.size()), - int(attributes.size())); - - fillLabels(); - - // Sanity checks on starting points - float modifiableAttributeCount = (float) attributeLabels.size(); - float averageValue = ((float) creationPoints) / modifiableAttributeCount; - if (averageValue > attributeMaximum || averageValue < attributeMinimum - || creationPoints < 1) - { - logger->log("Attributes: Character's point values make " - "the character's creation impossible. " - "Switch back to defaults."); - creationPoints = DEFAULT_POINTS; - attributeMinimum = DEFAULT_MIN_PTS; - attributeMaximum = DEFAULT_MAX_PTS; - } - } - - void unload() - { - attributes.clear(); - } - - void informItemDB() - { - std::list dbStats; - - TagMap::const_iterator it, it_end; - for (it = tags.begin(), it_end = tags.end(); it != it_end; ++it) - dbStats.push_back(ItemStat(it->first, - it->second)); - - setStatsList(dbStats); - } - - void informStatusWindow() - { - AttributeMap::const_iterator it, it_end; - for (it = attributes.begin(), it_end = attributes.end(); it != it_end; - it++) - { - if (it->second.playerInfoId == -1 && - (it->second.scope == "character" || it->second.scope == "being")) - { - statusWindow->addAttribute(it->second.id, - it->second.name, - it->second.modifiable, - it->second.description); - } - } - } - -} // namespace Attributes -} // namespace ManaServ diff --git a/src/net/manaserv/attributes.h b/src/net/manaserv/attributes.h deleted file mode 100644 index e004d16c..00000000 --- a/src/net/manaserv/attributes.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2010-2012 The Mana Developers - * - * This file is part of The Mana 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 NET_MANASERV_ATTRIBUTES_H -#define NET_MANASERV_ATTRIBUTES_H - -#include -#include - -namespace ManaServ { -namespace Attributes { - - void load(); - - void unload(); - - void informItemDB(); - - void informStatusWindow(); - - /** - * Returns the list of base attribute labels. - */ - std::vector& getLabels(); - - /** - * Give back the corresponding playerinfo Id from the attribute id - * defined in the xml file. - */ - int getPlayerInfoIdFromAttrId(int attrId); - - /** - * Give the attribute points given to a character - * at its creation. - */ - unsigned int getCreationPoints(); - - /** - * Give the minimum attribute point possible - * at character's creation. - */ - unsigned int getAttributeMinimum(); - - /** - * Give the maximum attribute point possible - * at character's creation. - */ - unsigned int getAttributeMaximum(); - -} // namespace Attributes -} // namespace ManaServ - -#endif // NET_MANASERV_ATTRIBUTES_H diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index e809bfac..ece8e108 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -39,8 +39,8 @@ #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/manaserv_protocol.h" -#include "net/manaserv/attributes.h" +#include "resources/attributes.h" #include "resources/hairdb.h" #include "utils/dtor.h" diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp index d1fa41fe..c6b2af18 100644 --- a/src/net/manaserv/generalhandler.cpp +++ b/src/net/manaserv/generalhandler.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -47,9 +47,10 @@ #include "net/manaserv/partyhandler.h" #include "net/manaserv/playerhandler.h" #include "net/manaserv/specialhandler.h" -#include "net/manaserv/attributes.h" #include "net/manaserv/tradehandler.h" +#include "resources/attributes.h" + #include "utils/gettext.h" #include diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index 484e551a..c1f78f67 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -20,7 +20,6 @@ */ #include "net/manaserv/playerhandler.h" -#include "net/manaserv/beinghandler.h" #include "client.h" #include "effectmanager.h" @@ -43,7 +42,8 @@ #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/manaserv_protocol.h" -#include "net/manaserv/attributes.h" + +#include "resources/attributes.h" /** * Max. distance in tiles we are willing to scroll after a teleport; diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index ce193821..cc242951 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -38,6 +38,7 @@ #include "net/tmwa/network.h" #include "net/tmwa/protocol.h" +#include "resources/attributes.h" #include "resources/hairdb.h" #include "utils/dtor.h" @@ -278,7 +279,10 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window) const Token &token = static_cast(Net::getLoginHandler())->getToken(); - mCharCreateDialog->setAttributes(attributes, 30, 1, 9); + mCharCreateDialog->setAttributes(attributes, + Attributes::getCreationPoints(), + Attributes::getAttributeMinimum(), + Attributes::getAttributeMaximum()); mCharCreateDialog->setFixedGender(true, token.sex); } diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp index 6c2bcddb..0ce16691 100644 --- a/src/net/tmwa/generalhandler.cpp +++ b/src/net/tmwa/generalhandler.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -57,11 +57,11 @@ #include "net/tmwa/gui/guildtab.h" #include "net/tmwa/gui/partytab.h" +#include "resources/attributes.h" #include "resources/itemdb.h" #include "utils/gettext.h" -#include #include extern Net::GeneralHandler *generalHandler; @@ -108,6 +108,7 @@ GeneralHandler::GeneralHandler(): setStatsList(stats); + listen(Event::ClientChannel); listen(Event::GameChannel); } @@ -185,12 +186,17 @@ void GeneralHandler::reload() static_cast(mLoginHandler.get())->clearWorlds(); static_cast(mCharHandler.get())->setCharCreateDialog(0); static_cast(mCharHandler.get())->setCharSelectDialog(0); + + Attributes::unload(); + Attributes::load(); } void GeneralHandler::unload() { if (mNetwork) mNetwork->clearHandlers(); + + Attributes::unload(); } void GeneralHandler::flushNetwork() @@ -220,7 +226,14 @@ void GeneralHandler::clearHandlers() void GeneralHandler::event(Event::Channel channel, const Event &event) { - if (channel == Event::GameChannel) + if (channel == Event::ClientChannel) + { + if (event.getType() == Event::LoadingDatabases) + { + Attributes::load(); + } + } + else if (channel == Event::GameChannel) { if (event.getType() == Event::GuiWindowsLoaded) { diff --git a/src/resources/attributes.cpp b/src/resources/attributes.cpp new file mode 100644 index 00000000..c4c67fba --- /dev/null +++ b/src/resources/attributes.cpp @@ -0,0 +1,405 @@ +/* + * The Mana Client + * Copyright (C) 2010-2013 The Mana Developers + * + * This file is part of The Mana 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/attributes.h" + +#include "log.h" +#include "playerinfo.h" + +#include "gui/statuswindow.h" + +#include "resources/itemdb.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" +#include "utils/xml.h" + +#include +#include + +#define DEFAULT_ATTRIBUTESDB_FILE "attributes.xml" +#define DEFAULT_POINTS 30 +#define DEFAULT_MIN_PTS 1 +#define DEFAULT_MAX_PTS 9 + +namespace Attributes { + + typedef struct + { + unsigned int id; + std::string name; + std::string description; + /** Whether the attribute value can be modified by the player */ + bool modifiable; + /**< Attribute scope. */ + std::string scope; + /** The playerInfo core Id the attribute is linked with or -1 if not */ + int playerInfoId; + } Attribute; + + /** Map for attributes. */ + typedef std::map AttributeMap; + static AttributeMap attributes; + + /** tags = effects on attributes. */ + typedef std::map< std::string, std::string > TagMap; + static TagMap tags; + + /** List of modifiable attribute names used at character's creation. */ + static std::vector attributeLabels; + + /** Characters creation points. */ + static unsigned int creationPoints = DEFAULT_POINTS; + static unsigned int attributeMinimum = DEFAULT_MIN_PTS; + static unsigned int attributeMaximum = DEFAULT_MAX_PTS; + + unsigned int getCreationPoints() + { + return creationPoints; + } + + unsigned int getAttributeMinimum() + { + return attributeMinimum; + } + + unsigned int getAttributeMaximum() + { + return attributeMaximum; + } + + std::vector& getLabels() + { + return attributeLabels; + } + + /** + * Fills the list of base attribute labels. + */ + static void fillLabels() + { + // Fill up the modifiable attribute label list. + attributeLabels.clear(); + AttributeMap::const_iterator it, it_end; + for (it = attributes.begin(), it_end = attributes.end(); it != it_end; + it++) + { + if (it->second.modifiable && + (it->second.scope == "character" || it->second.scope == "being")) + attributeLabels.push_back(it->second.name + ":"); + } + } + + /** + * Fills the list of base attribute labels. + */ + static int getPlayerInfoIdFromAttrType(std::string attrType) + { + toLower(attrType); + if (attrType == "level") + return ::LEVEL; + else if (attrType == "hp") + return ::HP; + else if (attrType == "max-hp") + return ::MAX_HP; + else if (attrType == "mp") + return ::MP; + else if (attrType == "max-mp") + return ::MAX_MP; + else if (attrType == "exp") + return ::EXP; + else if (attrType == "exp-needed") + return ::EXP_NEEDED; + else if (attrType == "money") + return ::MONEY; + else if (attrType == "total-weight") + return ::TOTAL_WEIGHT; + else if (attrType == "max-weight") + return ::MAX_WEIGHT; + else if (attrType == "skill-points") + return ::SKILL_POINTS; + else if (attrType == "char-points") + return ::CHAR_POINTS; + else if (attrType == "corr-points") + return ::CORR_POINTS; + else if (attrType == "none") + return -2; // Used to hide the attribute display. + + return -1; // Not linked to a playerinfo stat. + } + + int getPlayerInfoIdFromAttrId(int attrId) + { + AttributeMap::const_iterator it = attributes.find(attrId); + + if (it != attributes.end()) + { + return it->second.playerInfoId; + } + + return -1; + } + + static void loadBuiltins() + { + { + Attribute a; + a.id = 16; + a.name = _("Strength"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("str", _("Strength %+.1f"))); + } + + { + Attribute a; + a.id = 17; + a.name = _("Agility"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("agi", _("Agility %+.1f"))); + } + + { + Attribute a; + a.id = 18; + a.name = _("Dexterity"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("dex", _("Dexterity %+.1f"))); + } + + { + Attribute a; + a.id = 19; + a.name = _("Vitality"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("vit", _("Vitality %+.1f"))); + } + + { + Attribute a; + a.id = 20; + a.name = _("Intelligence"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("int", _("Intelligence %+.1f"))); + } + + { + Attribute a; + a.id = 21; + a.name = _("Willpower"); + a.description = ""; + a.modifiable = true; + a.scope = "character"; + a.playerInfoId = -1; + + attributes[a.id] = a; + tags.insert(std::make_pair("wil", _("Willpower %+.1f"))); + } + } + + void load() + { + logger->log("Initializing attributes database..."); + + XML::Document doc(DEFAULT_ATTRIBUTESDB_FILE); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "attributes")) + { + logger->log("Attributes: Error while loading " + DEFAULT_ATTRIBUTESDB_FILE ". Using Built-ins."); + loadBuiltins(); + fillLabels(); + return; + } + + for_each_xml_child_node(node, rootNode) + { + if (xmlStrEqual(node->name, BAD_CAST "attribute")) + { + int id = XML::getProperty(node, "id", 0); + + if (!id) + { + logger->log("Attributes: Invalid or missing stat ID in " + DEFAULT_ATTRIBUTESDB_FILE "!"); + continue; + } + else if (attributes.find(id) != attributes.end()) + { + logger->log("Attributes: Redefinition of stat ID %d", id); + } + + std::string name = XML::getProperty(node, "name", ""); + + if (name.empty()) + { + logger->log("Attributes: Invalid or missing stat name in " + DEFAULT_ATTRIBUTESDB_FILE "!"); + continue; + } + + // Create the attribute. + Attribute a; + a.id = id; + a.name = name; + a.description = XML::getProperty(node, "desc", ""); + a.modifiable = XML::getBoolProperty(node, "modifiable", false); + a.scope = XML::getProperty(node, "scope", "none"); + a.playerInfoId = getPlayerInfoIdFromAttrType( + XML::getProperty(node, "player-info", "")); + + attributes[id] = a; + + unsigned int count = 0; + for_each_xml_child_node(effectNode, node) + { + if (!xmlStrEqual(effectNode->name, BAD_CAST "modifier")) + continue; + ++count; + std::string tag = XML::getProperty(effectNode, "tag", ""); + if (tag.empty()) + { + if (name.empty()) + { + logger->log("Attribute modifier in attribute %u:%s: " + "Empty name definition " + "on empty tag definition, skipping.", + a.id, a.name.c_str()); + --count; + continue; + } + tag = name.substr(0, name.size() > 3 ? 3 : name.size()); + tag = toLower(tag) + toString(count); + } + + std::string effect = XML::getProperty(effectNode, "effect", ""); + if (effect.empty()) + { + if (name.empty()) + { + logger->log("Attribute modifier in attribute %u:%s: " + "Empty name definition " + "on empty effect definition, skipping.", + a.id, a.name.c_str()); + --count; + continue; + } + else + effect = name + " %+f"; + } + tags.insert(std::make_pair(tag, effect)); + } + logger->log("Found %d tags for attribute %d.", count, id); + + }// End attribute + else if (xmlStrEqual(node->name, BAD_CAST "points")) + { + creationPoints = XML::getProperty(node, "start",DEFAULT_POINTS); + attributeMinimum = XML::getProperty(node, "minimum", + DEFAULT_MIN_PTS); + attributeMaximum = XML::getProperty(node, "maximum", + DEFAULT_MAX_PTS); + logger->log("Loaded points: start: %i, min: %i, max: %i.", + creationPoints, attributeMinimum, attributeMaximum); + } + else + { + continue; + } + } + logger->log("Found %d tags for %d attributes.", int(tags.size()), + int(attributes.size())); + + fillLabels(); + + // Sanity checks on starting points + float modifiableAttributeCount = (float) attributeLabels.size(); + float averageValue = ((float) creationPoints) / modifiableAttributeCount; + if (averageValue > attributeMaximum || averageValue < attributeMinimum + || creationPoints < 1) + { + logger->log("Attributes: Character's point values make " + "the character's creation impossible. " + "Switch back to defaults."); + creationPoints = DEFAULT_POINTS; + attributeMinimum = DEFAULT_MIN_PTS; + attributeMaximum = DEFAULT_MAX_PTS; + } + } + + void unload() + { + attributes.clear(); + } + + void informItemDB() + { + std::list dbStats; + + TagMap::const_iterator it, it_end; + for (it = tags.begin(), it_end = tags.end(); it != it_end; ++it) + dbStats.push_back(ItemStat(it->first, it->second)); + + setStatsList(dbStats); + } + + void informStatusWindow() + { + AttributeMap::const_iterator it, it_end; + for (it = attributes.begin(), it_end = attributes.end(); it != it_end; + it++) + { + if (it->second.playerInfoId == -1 && + (it->second.scope == "character" || it->second.scope == "being")) + { + statusWindow->addAttribute(it->second.id, + it->second.name, + it->second.modifiable, + it->second.description); + } + } + } + +} // namespace Attributes diff --git a/src/resources/attributes.h b/src/resources/attributes.h new file mode 100644 index 00000000..7124ba94 --- /dev/null +++ b/src/resources/attributes.h @@ -0,0 +1,68 @@ +/* + * The Mana Client + * Copyright (C) 2010-2013 The Mana Developers + * + * This file is part of The Mana 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_ATTRIBUTES_H +#define RESOURCES_ATTRIBUTES_H + +#include +#include + +namespace Attributes { + + void load(); + + void unload(); + + void informItemDB(); + + void informStatusWindow(); + + /** + * Returns the list of base attribute labels. + */ + std::vector& getLabels(); + + /** + * Give back the corresponding playerinfo Id from the attribute id + * defined in the xml file. + */ + int getPlayerInfoIdFromAttrId(int attrId); + + /** + * Give the attribute points given to a character + * at its creation. + */ + unsigned int getCreationPoints(); + + /** + * Give the minimum attribute point possible + * at character's creation. + */ + unsigned int getAttributeMinimum(); + + /** + * Give the maximum attribute point possible + * at character's creation. + */ + unsigned int getAttributeMaximum(); + +} // namespace Attributes + +#endif // RESOURCES_ATTRIBUTES_H -- cgit v1.2.3-70-g09d2 From 4b0da49b28bb64d2da293ca90fec63079c2c5849 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 27 Apr 2013 21:43:32 +0200 Subject: Added support for charcreation.xml settings This file was introduced by ManaPlus as a way of configuring the character creation process. It defines the number of hair styles and colors, how stat points should be divided and what the starting equipment of the player is. The minimum and maximum hair color/style IDs are not supported at the moment. This is mostly a backport of ManaPlus commits 10cf52b5 and dcc18eba, with some style changes. Mantis-issue: 501 Reviewed-by: Ablu --- src/CMakeLists.txt | 2 + src/client.cpp | 3 + src/gui/charcreatedialog.cpp | 7 ++ src/net/tmwa/charserverhandler.cpp | 28 ++++++-- src/net/tmwa/charserverhandler.h | 11 +--- src/resources/chardb.cpp | 132 +++++++++++++++++++++++++++++++++++++ src/resources/chardb.h | 48 ++++++++++++++ 7 files changed, 218 insertions(+), 13 deletions(-) create mode 100644 src/resources/chardb.cpp create mode 100644 src/resources/chardb.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32ac5426..946f4ba6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -369,6 +369,8 @@ SET(SRCS resources/attributes.h resources/beinginfo.cpp resources/beinginfo.h + resources/chardb.cpp + resources/chardb.h resources/dye.cpp resources/dye.h resources/emotedb.cpp diff --git a/src/client.cpp b/src/client.cpp index 1b413a7f..e6ab9191 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -64,6 +64,7 @@ #include "net/net.h" #include "net/worldinfo.h" +#include "resources/chardb.h" #include "resources/hairdb.h" #include "resources/emotedb.h" #include "resources/image.h" @@ -451,6 +452,7 @@ Client::~Client() SDL_RemoveTimer(mSecondsCounterId); // Unload XML databases + CharDB::unload(); hairDB.unload(); EmoteDB::unload(); delete itemDb; @@ -762,6 +764,7 @@ int Client::exec() Event::trigger(Event::ClientChannel, Event::LoadingDatabases); // Load XML databases + CharDB::load(); hairDB.load(); switch (Net::getNetworkType()) { diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index 8fee148b..a3c03a31 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -41,6 +41,7 @@ #include "net/charhandler.h" #include "net/net.h" +#include "resources/chardb.h" #include "resources/hairdb.h" #include "utils/gettext.h" @@ -56,6 +57,10 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): mPlayer = new Being(0, ActorSprite::PLAYER, 0, NULL); mPlayer->setGender(GENDER_MALE); + const std::vector &items = CharDB::getDefaultItems(); + for (size_t i = 0; i < items.size(); ++i) + mPlayer->setSprite(i + 1, items.at(i)); + mHairStylesIds = hairDB.getHairStyleIds( Net::getCharHandler()->getCharCreateMaxHairStyleId()); mHairStyleId = rand() * mHairStylesIds.size() / RAND_MAX; @@ -196,7 +201,9 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) } } else if (event.getId() == "cancel") + { scheduleDelete(); + } else if (event.getId() == "nextcolor") { ++mHairColorId; diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index cc242951..7c5f5c88 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -39,6 +39,7 @@ #include "net/tmwa/protocol.h" #include "resources/attributes.h" +#include "resources/chardb.h" #include "resources/hairdb.h" #include "utils/dtor.h" @@ -279,10 +280,17 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window) const Token &token = static_cast(Net::getLoginHandler())->getToken(); - mCharCreateDialog->setAttributes(attributes, - Attributes::getCreationPoints(), - Attributes::getAttributeMinimum(), - Attributes::getAttributeMaximum()); + unsigned minStat = CharDB::getMinStat(); + if (minStat == 0) + minStat = Attributes::getAttributeMinimum(); + unsigned maxStat = CharDB::getMaxStat(); + if (maxStat == 0) + maxStat = Attributes::getAttributeMaximum(); + unsigned sumStat = CharDB::getSumStat(); + if (sumStat == 0) + sumStat = Attributes::getCreationPoints(); + + mCharCreateDialog->setAttributes(attributes, sumStat, minStat, maxStat); mCharCreateDialog->setFixedGender(true, token.sex); } @@ -346,6 +354,18 @@ unsigned int CharServerHandler::maxSprite() const return SPRITE_VECTOREND; } +int CharServerHandler::getCharCreateMaxHairColorId() const +{ + const int max = CharDB::getMaxHairColor(); + return max ? max : 11; // default maximum +} + +int CharServerHandler::getCharCreateMaxHairStyleId() const +{ + const int max = CharDB::getMaxHairStyle(); + return max ? max : 19; // default maximum +} + void CharServerHandler::connect() { const Token &token = diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h index c9f44e0f..7e4fc2d9 100644 --- a/src/net/tmwa/charserverhandler.h +++ b/src/net/tmwa/charserverhandler.h @@ -69,15 +69,8 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler unsigned int maxSprite() const; - // Must be < 12 at character creation time, but can be higher - // after that. - int getCharCreateMaxHairColorId() const - { return 11; } - - // Must be < 20 at character creation time, but can be higher - // after that. - int getCharCreateMaxHairStyleId() const - { return 19; } + int getCharCreateMaxHairColorId() const; + int getCharCreateMaxHairStyleId() const; void connect(); diff --git a/src/resources/chardb.cpp b/src/resources/chardb.cpp new file mode 100644 index 00000000..40ecd999 --- /dev/null +++ b/src/resources/chardb.cpp @@ -0,0 +1,132 @@ +/* + * Character creation settings + * Copyright (C) 2011-2013 The ManaPlus Developers + * Copyright (C) 2013 The Mana 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/chardb.h" + +#include "log.h" + +#include "utils/xml.h" + +namespace +{ + bool mLoaded = false; + unsigned mMinHairColor = 0; + unsigned mMaxHairColor = 0; + unsigned mMinHairStyle = 0; + unsigned mMaxHairStyle = 0; + unsigned mMinStat = 0; + unsigned mMaxStat = 0; + unsigned mSumStat = 0; + std::vector mDefaultItems; +} + +static void loadMinMax(xmlNodePtr node, unsigned *min, unsigned *max) +{ + *min = XML::getProperty(node, "min", 1); + *max = XML::getProperty(node, "max", 10); +} + +void CharDB::load() +{ + if (mLoaded) + unload(); + + XML::Document doc("charcreation.xml"); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "chars")) + { + logger->log("CharDB: Failed to parse charcreation.xml."); + return; + } + + for_each_xml_child_node(node, root) + { + if (xmlStrEqual(node->name, BAD_CAST "haircolor")) + { + loadMinMax(node, &mMinHairColor, &mMaxHairColor); + } + else if (xmlStrEqual(node->name, BAD_CAST "hairstyle")) + { + loadMinMax(node, &mMinHairStyle, &mMaxHairStyle); + } + else if (xmlStrEqual(node->name, BAD_CAST "stat")) + { + loadMinMax(node, &mMinStat, &mMaxStat); + mSumStat = XML::getProperty(node, "sum", 0); + } + else if (xmlStrEqual(node->name, BAD_CAST "item")) + { + const int id = XML::getProperty(node, "id", 0); + if (id > 0) + mDefaultItems.push_back(id); + } + } + + mLoaded = true; +} + +void CharDB::unload() +{ + logger->log("Unloading chars database..."); + + mLoaded = false; +} + +unsigned CharDB::getMinHairColor() +{ + return mMinHairColor; +} + +unsigned CharDB::getMaxHairColor() +{ + return mMaxHairColor; +} + +unsigned CharDB::getMinHairStyle() +{ + return mMinHairStyle; +} + +unsigned CharDB::getMaxHairStyle() +{ + return mMaxHairStyle; +} + +unsigned CharDB::getMinStat() +{ + return mMinStat; +} + +unsigned CharDB::getMaxStat() +{ + return mMaxStat; +} + +unsigned CharDB::getSumStat() +{ + return mSumStat; +} + +const std::vector &CharDB::getDefaultItems() +{ + return mDefaultItems; +} diff --git a/src/resources/chardb.h b/src/resources/chardb.h new file mode 100644 index 00000000..10530b26 --- /dev/null +++ b/src/resources/chardb.h @@ -0,0 +1,48 @@ +/* + * Character creation settings + * Copyright (C) 2011-2013 The ManaPlus Developers + * Copyright (C) 2013 The Mana 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_CHARDB_H +#define RESOURCES_CHARDB_H + +#include + +/** + * Character creation settings. + */ +namespace CharDB +{ + void load(); + void unload(); + + unsigned getMinHairColor(); + unsigned getMaxHairColor(); + + unsigned getMinHairStyle(); + unsigned getMaxHairStyle(); + + unsigned getMinStat(); + unsigned getMaxStat(); + unsigned getSumStat(); + + const std::vector &getDefaultItems(); +} + +#endif // RESOURCES_CHARDB_H -- cgit v1.2.3-70-g09d2 From 4b0f15a3767a2309c433aa77bdeea04c56824322 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 27 Apr 2013 21:43:53 +0200 Subject: Small cleanup --- src/resources/theme.cpp | 2 +- src/utils/xml.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/resources/theme.cpp b/src/resources/theme.cpp index e95a1fa9..96927ac8 100644 --- a/src/resources/theme.cpp +++ b/src/resources/theme.cpp @@ -536,7 +536,7 @@ void Theme::loadColors(std::string file) if (file == "") file = defaultThemePath; - file += "/" COLORS_XML_FILE; + file += "/colors.xml"; XML::Document doc(file); xmlNodePtr root = doc.rootNode(); diff --git a/src/utils/xml.h b/src/utils/xml.h index 1e007cfd..60355aa6 100644 --- a/src/utils/xml.h +++ b/src/utils/xml.h @@ -26,10 +26,6 @@ #include -// Define commonly used xml file -#define HAIR_XML_FILE "hair.xml" -#define COLORS_XML_FILE "colors.xml" - /** * XML helper functions. */ -- cgit v1.2.3-70-g09d2 From 8f67f2179dd1038f44d4ad3506ff33e9cf2dddbf Mon Sep 17 00:00:00 2001 From: Przemysław Grzywacz Date: Mon, 29 Apr 2013 22:32:30 +0200 Subject: Single xml solution - compatibility with skill-set and special-set Mana-mantis: #506. --- src/gui/skilldialog.cpp | 3 ++- src/resources/specialdb.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 8c8abd19..a0c3e46b 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -368,7 +368,8 @@ void SkillDialog::loadSkills() for_each_xml_child_node(set, root) { - if (xmlStrEqual(set->name, BAD_CAST "set")) + if (xmlStrEqual(set->name, BAD_CAST "set") || + xmlStrEqual(set->name, BAD_CAST "skill-set")) { setCount++; setName = XML::getProperty(set, "name", strprintf(_("Skill Set %d"), setCount)); diff --git a/src/resources/specialdb.cpp b/src/resources/specialdb.cpp index 426a1143..c75f4b1b 100644 --- a/src/resources/specialdb.cpp +++ b/src/resources/specialdb.cpp @@ -61,7 +61,8 @@ void SpecialDB::load() for_each_xml_child_node(set, root) { - if (xmlStrEqual(set->name, BAD_CAST "set")) + if (xmlStrEqual(set->name, BAD_CAST "set") || + xmlStrEqual(set->name, BAD_CAST "special-set")) { setName = XML::getProperty(set, "name", "Actions"); -- cgit v1.2.3-70-g09d2 From 286eb6552fa059d8e4561fb4bb13cb5266dff71d Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Tue, 30 Apr 2013 21:20:36 +0200 Subject: Bumped protocol version to 3 This is so that master and lpc2012 use the same protocol again, where starting attributes are sent on character creation. --- src/net/manaserv/manaserv_protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index 319d7070..760fe655 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -25,7 +25,7 @@ namespace ManaServ { enum { - PROTOCOL_VERSION = 1, + PROTOCOL_VERSION = 3, SUPPORTED_DB_VERSION = 21 }; -- cgit v1.2.3-70-g09d2 From a6b11834f227b8edbfb39633380806480fd2a2c5 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sun, 28 Apr 2013 22:10:37 +0200 Subject: Hide attribute sliders on character creation when appropriate When the minimum and maximum values of the attributes are equal, then there is nothing for the player to customize and the sliders are not shown. At the same time the dialog has been fixed to resize properly to any number of modifiable attributes. --- src/gui/charcreatedialog.cpp | 112 +++++++++++++++++++++++++------------------ src/gui/charcreatedialog.h | 10 ++-- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index a3c03a31..26383d48 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -173,12 +173,6 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) // Attempt to create the character mCreateButton->setEnabled(false); - std::vector atts; - for (unsigned i = 0; i < mAttributeSlider.size(); i++) - { - atts.push_back((int) mAttributeSlider[i]->getValue()); - } - int characterSlot = mSlot; // On Manaserv, the slots start at 1, so we offset them. if (Net::getNetworkType() == ServerInfo::MANASERV) @@ -191,7 +185,8 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) 0 : mHairColorsIds.at(mHairColorId); Net::getCharHandler()->newCharacter(getName(), characterSlot, mFemale->isSelected(), - hairStyle, hairColor, atts); + hairStyle, hairColor, + mAttributes); } else { @@ -246,16 +241,24 @@ std::string CharCreateDialog::getName() const void CharCreateDialog::updateSliders() { + int distributedPoints = 0; + + // Update captions and synchronize values for (unsigned i = 0; i < mAttributeSlider.size(); i++) { - // Update captions - mAttributeValue[i]->setCaption( - toString((int) (mAttributeSlider[i]->getValue()))); - mAttributeValue[i]->adjustSize(); + gcn::Slider *slider = mAttributeSlider[i]; + gcn::Label *valueLabel = mAttributeValue[i]; + int value = static_cast(slider->getValue()); + + valueLabel->setCaption(toString(value)); + valueLabel->adjustSize(); + + mAttributes[i] = value; + distributedPoints += value; } // Update distributed points - int pointsLeft = mMaxPoints - getDistributedPoints(); + int pointsLeft = mMaxPoints - distributedPoints; if (pointsLeft == 0) { mAttributesLeft->setCaption(_("Character stats OK")); @@ -284,20 +287,9 @@ void CharCreateDialog::unlock() mCreateButton->setEnabled(true); } -int CharCreateDialog::getDistributedPoints() const -{ - int points = 0; - - for (unsigned i = 0; i < mAttributeSlider.size(); i++) - { - points += (int) mAttributeSlider[i]->getValue(); - } - return points; -} - void CharCreateDialog::setAttributes(const std::vector &labels, - unsigned int available, unsigned int min, - unsigned int max) + unsigned available, unsigned min, + unsigned max) { mMaxPoints = available; @@ -311,34 +303,57 @@ void CharCreateDialog::setAttributes(const std::vector &labels, delete mAttributeValue[i]; } - mAttributeLabel.resize(labels.size()); - mAttributeSlider.resize(labels.size()); - mAttributeValue.resize(labels.size()); + mAttributeLabel.clear(); + mAttributeSlider.clear(); + mAttributeValue.clear(); + + mAttributes.resize(labels.size(), min); int w = 200; - int h = 330; + int h = 190; - for (unsigned i = 0; i < labels.size(); i++) + // No attribute sliders when they can not be adapted by the user + if (min == max) { - mAttributeLabel[i] = new Label(labels[i]); - mAttributeLabel[i]->setWidth(70); - mAttributeLabel[i]->setPosition(5, 140 + i*20); - add(mAttributeLabel[i]); - - mAttributeSlider[i] = new Slider(min, max); - mAttributeSlider[i]->setDimension(gcn::Rectangle(75, 140 + i * 20, - 100, 10)); - mAttributeSlider[i]->setActionEventId("statslider"); - mAttributeSlider[i]->addActionListener(this); - add(mAttributeSlider[i]); - - mAttributeValue[i] = new Label(toString(min)); - mAttributeValue[i]->setPosition(180, 140 + i*20); - add(mAttributeValue[i]); + mAttributesLeft->setVisible(false); + mCreateButton->setEnabled(true); } + else + { + h += 20 * labels.size() + 20; - mAttributesLeft->setPosition(15, 280); - updateSliders(); + mAttributeLabel.resize(labels.size()); + mAttributeSlider.resize(labels.size()); + mAttributeValue.resize(labels.size()); + + for (unsigned i = 0; i < labels.size(); i++) + { + const int y = 140 + i * 20; + + Label *attributeLabel = new Label(labels[i]); + attributeLabel->setWidth(70); + attributeLabel->setPosition(5, y); + add(attributeLabel); + + Slider *attributeSlider = new Slider(min, max); + attributeSlider->setDimension(gcn::Rectangle(75, y, 100, 10)); + attributeSlider->setActionEventId("statslider"); + attributeSlider->addActionListener(this); + add(attributeSlider); + + Label *attributeValue = new Label(toString(min)); + attributeValue->setPosition(180, y); + add(attributeValue); + + mAttributeLabel[i] = attributeLabel; + mAttributeSlider[i] = attributeSlider; + mAttributeValue[i] = attributeValue; + } + + mAttributesLeft->setVisible(true); + mAttributesLeft->setPosition(15, h - 50); + updateSliders(); + } mCancelButton->setPosition( w - 5 - mCancelButton->getWidth(), @@ -346,6 +361,9 @@ void CharCreateDialog::setAttributes(const std::vector &labels, mCreateButton->setPosition( mCancelButton->getX() - 5 - mCreateButton->getWidth(), h - 5 - mCancelButton->getHeight()); + + setContentSize(w, h); + center(); } void CharCreateDialog::setFixedGender(bool fixed, Gender gender) diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h index 7548bbff..9f49f6c5 100644 --- a/src/gui/charcreatedialog.h +++ b/src/gui/charcreatedialog.h @@ -58,14 +58,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener void unlock(); void setAttributes(const std::vector &labels, - unsigned int available, - unsigned int min, unsigned int max); + unsigned available, + unsigned min, unsigned max); void setFixedGender(bool fixed, Gender gender = GENDER_FEMALE); private: - int getDistributedPoints() const; - void updateSliders(); /** @@ -94,13 +92,13 @@ class CharCreateDialog : public Window, public gcn::ActionListener gcn::RadioButton *mMale; gcn::RadioButton *mFemale; + std::vector mAttributes; std::vector mAttributeSlider; std::vector mAttributeLabel; std::vector mAttributeValue; gcn::Label *mAttributesLeft; - int mMaxPoints; - int mUsedPoints; + unsigned mMaxPoints; gcn::Button *mCreateButton; gcn::Button *mCancelButton; -- cgit v1.2.3-70-g09d2