diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/manaserv/attributes.cpp | 317 | ||||
-rw-r--r-- | src/net/manaserv/attributes.h (renamed from src/net/manaserv/stats.h) | 34 | ||||
-rw-r--r-- | src/net/manaserv/charhandler.cpp | 24 | ||||
-rw-r--r-- | src/net/manaserv/charhandler.h | 12 | ||||
-rw-r--r-- | src/net/manaserv/generalhandler.cpp | 16 | ||||
-rw-r--r-- | src/net/manaserv/inventoryhandler.cpp | 64 | ||||
-rw-r--r-- | src/net/manaserv/inventoryhandler.h | 24 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.cpp | 35 | ||||
-rw-r--r-- | src/net/manaserv/protocol.h | 31 | ||||
-rw-r--r-- | src/net/manaserv/stats.cpp | 217 | ||||
-rw-r--r-- | src/net/tmwa/generalhandler.cpp | 2 | ||||
-rw-r--r-- | src/net/tmwa/inventoryhandler.cpp | 24 | ||||
-rw-r--r-- | src/net/tmwa/tradehandler.cpp | 10 |
13 files changed, 477 insertions, 333 deletions
diff --git a/src/net/manaserv/attributes.cpp b/src/net/manaserv/attributes.cpp new file mode 100644 index 00000000..7a9a761a --- /dev/null +++ b/src/net/manaserv/attributes.cpp @@ -0,0 +1,317 @@ +/* + * The Mana Client + * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. + */ + +#include "net/manaserv/attributes.h" + +#include "log.h" + +#include "gui/statuswindow.h" + +#include "resources/itemdb.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" +#include "utils/xml.h" + +#include <list> +#include <map> + +#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; + bool modifiable; + } Attribute; + + // tag -> effect + typedef std::map< std::string, std::string > TagMap; + + typedef std::map<unsigned int, Attribute> AttributeMap; + AttributeMap attributes; + + TagMap tags; + + // List of modifiable attribute names used at character's creation. + static std::vector<std::string> attributeLabels; + + 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<std::string>& getLabels() + { + return attributeLabels; + } + + static void loadBuiltins() + { + { + Attribute a; + a.id = 16; + a.name = _("Strength"); + a.description = ""; + a.modifiable = true; + + 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; + + 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; + + 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; + + 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; + + 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; + + 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(); + 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; + } + + Attribute a; + a.id = id; + a.name = name; + a.description = XML::getProperty(node, "desc", ""); + a.modifiable = XML::getProperty(node, "modifiable", "false") + == "true"; + + 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())); + + // 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) + attributeLabels.push_back(it->second.name + ":"); + } + + // 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<ItemDB::Stat> dbStats; + + TagMap::const_iterator it, it_end; + for (it = tags.begin(), it_end = tags.end(); it != it_end; ++it) + dbStats.push_back(ItemDB::Stat(it->first, + it->second)); + + itemDb->setStatsList(dbStats); + } + + void informStatusWindow() + { + AttributeMap::const_iterator it, it_end; + for (it = attributes.begin(), it_end = attributes.end(); it != it_end; + it++) + statusWindow->addAttribute(it->second.id, it->second.name, + it->second.modifiable, + it->second.description); + } + +} // namespace Attributes +} // namespace ManaServ diff --git a/src/net/manaserv/stats.h b/src/net/manaserv/attributes.h index 63349095..9791d2cb 100644 --- a/src/net/manaserv/stats.h +++ b/src/net/manaserv/attributes.h @@ -18,14 +18,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef NET_MANASERV_STATS_H -#define NET_MANASERV_STATS_H +#ifndef NET_MANASERV_ATTRIBUTES_H +#define NET_MANASERV_ATTRIBUTES_H #include <string> #include <vector> namespace ManaServ { -namespace Stats { +namespace Attributes { void load(); void unload(); @@ -34,8 +34,30 @@ namespace Stats { void informStatusWindow(); - std::vector<std::string> getLabelVector(); -} // namespace Stats + /** + * Returns the list of base attribute labels. + */ + std::vector<std::string>& getLabels(); + + /** + * 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_STATS_H +#endif // NET_MANASERV_ATTRIBUTES_H diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index 7e401455..90909440 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -37,7 +37,7 @@ #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/protocol.h" -#include "net/manaserv/stats.h" +#include "net/manaserv/attributes.h" #include "resources/colordb.h" @@ -108,11 +108,15 @@ void CharHandler::handleCharacterInfo(Net::MessageIn &msg) info.level = msg.readInt16(); info.characterPoints = msg.readInt16(); info.correctionPoints = msg.readInt16(); - info.money = msg.readInt32(); - for (int i = 0; i < 7; i++) + while (msg.getUnreadLength() > 0) { - info.attribute[i] = msg.readInt8(); + int id = msg.readInt32(); + CachedAttrbiute attr; + attr.base = msg.readInt32() / 256.0; + attr.mod = msg.readInt32() / 256.0; + + info.attribute[id] = attr; } mCachedCharacterInfos.push_back(info); @@ -260,7 +264,10 @@ void CharHandler::setCharCreateDialog(CharCreateDialog *window) if (!mCharCreateDialog) return; - mCharCreateDialog->setAttributes(Stats::getLabelVector(), 60, 1, 20); + mCharCreateDialog->setAttributes(Attributes::getLabels(), + Attributes::getCreationPoints(), + Attributes::getAttributeMinimum(), + Attributes::getAttributeMaximum()); } void CharHandler::requestCharacters() @@ -359,11 +366,12 @@ void CharHandler::updateCharacters() character->data.mAttributes[LEVEL] = info.level; character->data.mAttributes[CHAR_POINTS] = info.characterPoints; character->data.mAttributes[CORR_POINTS] = info.correctionPoints; - character->data.mAttributes[MONEY] = info.money; - for (int i = 0; i < 7; i++) + for (CachedAttributes::const_iterator it = info.attribute.begin(), + it_end = info.attribute.end(); it != it_end; it++) { - character->data.mStats[i].base = info.attribute[i]; + character->data.mStats[i].base = it->second.base; + character->data.mStats[i].mod = it->second.mod; } mCharacters.push_back(character); diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h index dac4a29e..2f335688 100644 --- a/src/net/manaserv/charhandler.h +++ b/src/net/manaserv/charhandler.h @@ -28,6 +28,8 @@ #include "net/manaserv/messagehandler.h" +#include <map.h> + class LoginData; namespace ManaServ { @@ -79,6 +81,13 @@ class CharHandler : public MessageHandler, public Net::CharHandler * we have loaded the dynamic data, so we can't resolve load any * sprites yet. */ + struct CachedAttrbiute { + double base; + double mod; + }; + + typedef std::map<int, CachedAttrbiute> CachedAttributes; + struct CachedCharacterInfo { int slot; std::string name; @@ -88,8 +97,7 @@ class CharHandler : public MessageHandler, public Net::CharHandler int level; int characterPoints; int correctionPoints; - int money; - int attribute[7]; + CachedAttributes attribute; }; void handleCharacterInfo(Net::MessageIn &msg); diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp index 210e3043..f4982173 100644 --- a/src/net/manaserv/generalhandler.cpp +++ b/src/net/manaserv/generalhandler.cpp @@ -46,7 +46,7 @@ #include "net/manaserv/partyhandler.h" #include "net/manaserv/playerhandler.h" #include "net/manaserv/specialhandler.h" -#include "net/manaserv/stats.h" +#include "net/manaserv/attributes.h" #include "net/manaserv/tradehandler.h" #include "utils/gettext.h" @@ -130,9 +130,9 @@ void GeneralHandler::reload() gameServer.clear(); chatServer.clear(); - Stats::unload(); - Stats::load(); - Stats::informItemDB(); + Attributes::unload(); + Attributes::load(); + Attributes::informItemDB(); } void GeneralHandler::unload() @@ -150,7 +150,7 @@ void GeneralHandler::unload() delete gameServerConnection; delete chatServerConnection; - Stats::unload(); + Attributes::unload(); finalize(); } @@ -185,8 +185,8 @@ void GeneralHandler::event(const std::string &channel, } else if (newState == STATE_LOAD_DATA) { - Stats::load(); - Stats::informItemDB(); + Attributes::load(); + Attributes::informItemDB(); } } else if (channel == "Game") @@ -198,7 +198,7 @@ void GeneralHandler::event(const std::string &channel, PlayerInfo::setAttribute(EXP_NEEDED, 100); - Stats::informStatusWindow(); + Attributes::informStatusWindow(); } } } diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index 28de9c1e..da1abab5 100644 --- a/src/net/manaserv/inventoryhandler.cpp +++ b/src/net/manaserv/inventoryhandler.cpp @@ -46,6 +46,7 @@ InventoryHandler::InventoryHandler() static const Uint16 _messages[] = { GPMSG_INVENTORY_FULL, GPMSG_INVENTORY, + GPMSG_EQUIP, 0 }; handledMessages = _messages; @@ -59,31 +60,50 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) switch (msg.getId()) { case GPMSG_INVENTORY_FULL: - PlayerInfo::clearInventory(); - PlayerInfo::getEquipment()->setBackend(&mEquips); - // no break! - - case GPMSG_INVENTORY: - while (msg.getUnreadLength()) { - unsigned int slot = msg.readInt8(); - if (slot == 255) + PlayerInfo::clearInventory(); + PlayerInfo::getEquipment()->setBackend(&mEquips); + int count = msg.readInt16(); + while (count--) { - PlayerInfo::setAttribute(MONEY, msg.readInt32()); - continue; + unsigned int slot = msg.readInt16(); + int id = msg.readInt16(); + unsigned int amount = msg.readInt16(); + PlayerInfo::setInventoryItem(slot, id, amount); } - - int id = msg.readInt16(); - if (slot < EQUIPMENT_SIZE) + while (msg.getUnreadLength()) { - mEquips.setEquipment(slot, id); + unsigned int slot = msg.readInt8(); + unsigned int ref = msg.readInt16(); + + mEquips.addEquipment(slot, ref); } - else if (slot >= 32 && slot < 32 + getSize(Inventory::INVENTORY)) + } + break; + + case GPMSG_INVENTORY: + while (msg.getUnreadLength()) + { + unsigned int slot = msg.readInt16(); + int id = msg.readInt16(); + unsigned int amount = id ? msg.readInt16() : 0; + PlayerInfo::setInventoryItem(slot, id, amount); + } + break; + + case GPMSG_EQUIP: + while (msg.getUnreadLength()) + { + unsigned int ref = msg.readInt16(); + int count = msg.readInt8(); + while (count--) { - int amount = id ? msg.readInt8() : 0; - PlayerInfo::setInventoryItem(slot - 32, id, amount); + unsigned int slot = msg.readInt8(); + unsigned int used = msg.readInt8(); + + mEquips.setEquipment(slot, used, ref); } - }; + } break; } } @@ -112,8 +132,9 @@ void InventoryHandler::event(const std::string &channel, msg.writeInt8(index); gameServerConnection->send(msg); - // Tidy equipment directly to avoid weapon still shown bug, for instance - mEquips.setEquipment(index, 0); + // Tidy equipment directly to avoid weapon still shown bug, + // for instance. + mEquips.setEquipment(index, 0, 0); } else if (event.getName() == "doUse") { @@ -173,7 +194,8 @@ void InventoryHandler::event(const std::string &channel, bool InventoryHandler::canSplit(const Item *item) { - return item && !item->isEquipment() && item->getQuantity() > 1; + return item && !item->getInfo().getEquippable() + && item->getQuantity() > 1; } size_t InventoryHandler::getSize(int type) const diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h index a1673e99..aa44f2ee 100644 --- a/src/net/manaserv/inventoryhandler.h +++ b/src/net/manaserv/inventoryhandler.h @@ -38,30 +38,20 @@ class EquipBackend : public Equipment::Backend { memset(mEquipment, 0, sizeof(mEquipment)); } Item *getEquipment(int index) const - { return mEquipment[index]; } + { return 0; } void clear() { - for (int i = 0; i < EQUIPMENT_SIZE; ++i) - delete mEquipment[i]; + } - std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0); + void setEquipment(unsigned int slot, unsigned int used, int reference) + { + printf("Equip: %d at %dx%d\n", reference, slot, used); } - void setEquipment(int index, int id, int quantity = 0) + void addEquipment(unsigned int slot, int reference) { - if (mEquipment[index] && mEquipment[index]->getId() == id) - return; - - delete mEquipment[index]; - mEquipment[index] = (id > 0) ? new Item(id, quantity) : 0; - - if (mEquipment[index]) - { - mEquipment[index]->setInvIndex(index); - mEquipment[index]->setEquipped(true); - mEquipment[index]->setInEquipment(true); - } + printf("Equip: %d at %d\n", reference, slot); } private: diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index db2dcf7a..5bacce49 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -110,24 +110,20 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) case GPMSG_PLAYER_ATTRIBUTE_CHANGE: { - logger->log("ATTRIBUTE UPDATE:"); while (msg.getUnreadLength()) { - int stat = msg.readInt16(); - int base = msg.readInt16(); - int value = msg.readInt16(); - logger->log("%d set to %d %d", stat, base, value); + int attr = msg.readInt16(); + double base = msg.readInt32() / 256.0; + double value = msg.readInt32() / 256.0; - if (stat == BASE_ATTR_HP) - { - PlayerInfo::setAttribute(MAX_HP, base); + /* TODO handle HP + if (attr == ATTR_HP) PlayerInfo::setAttribute(HP, value); - } - else - { - PlayerInfo::setStatBase(stat, base); - PlayerInfo::setStatMod(stat, value - base); - } + else if (attr == ATTR_MAX_HP) + PlayerInfo::setAttribute(MAX_HP, value);*/ + + PlayerInfo::setStatBase(attr, base); + PlayerInfo::setStatMod(attr, value - base); } } break; @@ -166,7 +162,7 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) case GPMSG_RAISE_ATTRIBUTE_RESPONSE: { int errCode = msg.readInt8(); - int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN; + int attrNum = msg.readInt16(); switch (errCode) { case ATTRIBMOD_OK: @@ -203,7 +199,7 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) case GPMSG_LOWER_ATTRIBUTE_RESPONSE: { int errCode = msg.readInt8(); - int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN; + int attrNum = msg.readInt16(); switch (errCode) { case ATTRIBMOD_OK: @@ -221,9 +217,10 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) // undo attribute change and set points to 0 logger->log("Warning: Server denied reduction of attribute %d (no points left) ", attrNum); int attrValue = PlayerInfo::getStatBase(attrNum) + 1; + // TODO are these right? PlayerInfo::setAttribute(CHAR_POINTS, 0); + PlayerInfo::setAttribute(CORR_POINTS, 0); PlayerInfo::setStatBase(attrNum, attrValue); - break; } break; case ATTRIBMOD_DENIED: { @@ -326,14 +323,14 @@ void PlayerHandler::emote(int emoteId) void PlayerHandler::increaseAttribute(int attr) { MessageOut msg(PGMSG_RAISE_ATTRIBUTE); - msg.writeInt8(attr); + msg.writeInt16(attr); gameServerConnection->send(msg); } void PlayerHandler::decreaseAttribute(int attr) { MessageOut msg(PGMSG_LOWER_ATTRIBUTE); - msg.writeInt8(attr); + msg.writeInt16(attr); gameServerConnection->send(msg); } diff --git a/src/net/manaserv/protocol.h b/src/net/manaserv/protocol.h index 226a27a0..571879c5 100644 --- a/src/net/manaserv/protocol.h +++ b/src/net/manaserv/protocol.h @@ -57,7 +57,10 @@ enum { APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error PAMSG_CHAR_DELETE = 0x0022, // B index APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error - APMSG_CHAR_INFO = 0x0024, // B index, S name, B gender, B hair style, B hair color, W level, W character points, W correction points, D money, W*6 stats + // B index, S name, B gender, B hair style, B hair color, W level, + // W character points, W correction points, + // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }* + APMSG_CHAR_INFO = 0x0024, // ^ PAMSG_CHAR_SELECT = 0x0026, // B index APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port PAMSG_EMAIL_CHANGE = 0x0030, // S email @@ -86,16 +89,17 @@ enum { PGMSG_EQUIP = 0x0112, // B slot PGMSG_UNEQUIP = 0x0113, // B slot PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount - GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* - GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* - GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, W base value, W modified value }* + GPMSG_INVENTORY = 0x0120, // { W slot, W item id [, W amount] (if item id is nonzero) }* + GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount } { B equip slot, W invy slot}* + GPMSG_EQUIP = 0x0122, // { W Invy slot, B equip slot type count { B equip slot, B number used} }* + GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, D base value (in 1/256ths), D modified value (in 1/256ths)}* GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }* GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup - PGMSG_RAISE_ATTRIBUTE = 0x0160, // B attribute - GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, B attribute - PGMSG_LOWER_ATTRIBUTE = 0x0170, // B attribute - GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, B attribute + PGMSG_RAISE_ATTRIBUTE = 0x0160, // W attribute + GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, W attribute + PGMSG_LOWER_ATTRIBUTE = 0x0170, // W attribute + GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute PGMSG_RESPAWN = 0x0180, // - GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position // character: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }* @@ -109,7 +113,7 @@ enum { GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action PGMSG_DIRECTION_CHANGE = 0x0272, // B Direction GPMSG_BEING_DIR_CHANGE = 0x0273, // W being id, B direction - GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W health + GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W hp, W max hp GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, W*2 position, B speed] }* GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }* PGMSG_ATTACK = 0x0290, // W being id @@ -272,10 +276,11 @@ enum { // used to identify part of sync message enum { - SYNC_CHARACTER_POINTS = 0x01, // D charId, D charPoints, D corrPoints, B attribute id, D attribute value - SYNC_CHARACTER_SKILL = 0x02, // D charId, B skillId, D skill value - SYNC_ONLINE_STATUS = 0x03, // D charId, B 0x00 = offline, 0x01 = online - SYNC_END_OF_BUFFER = 0xFF // shows, that the buffer ends here. + SYNC_CHARACTER_POINTS = 0x01, // D charId, D charPoints, D corrPoints + SYNC_CHARACTER_ATTRIBUTE = 0x02, // D charId, D attrId, DF base, DF mod + SYNC_CHARACTER_SKILL = 0x03, // D charId, B skillId, D skill value + SYNC_ONLINE_STATUS = 0x04, // D charId, B 0x00 = offline, 0x01 = online + SYNC_END_OF_BUFFER = 0xFF // shows, that the buffer ends here. }; // Login specific return values diff --git a/src/net/manaserv/stats.cpp b/src/net/manaserv/stats.cpp deleted file mode 100644 index ece0e72a..00000000 --- a/src/net/manaserv/stats.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. - */ - -#include "net/manaserv/stats.h" - -#include "log.h" - -#include "gui/statuswindow.h" - -#include "resources/itemdb.h" - -#include "utils/gettext.h" -#include "utils/xml.h" - -#include <list> -#include <map> - -#define DEFAULT_ATTRIBUTESDB_FILE "attributes.xml" - -namespace ManaServ { -namespace Stats { - typedef struct { - unsigned int id; - std::string name; - std::string tag; - std::string effect; - std::string description; - bool modifiable; - } Stat; - - typedef std::map<unsigned int, Stat> StatMap; - StatMap stats; - - static void loadBuiltins() - { - { - Stat s; - s.id = 16; - s.name = _("Strength"); - s.tag = "str"; - s.effect = _("Strength %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - - { - Stat s; - s.id = 17; - s.name = _("Agility"); - s.tag = "agi"; - s.effect = _("Agility %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - - { - Stat s; - s.id = 18; - s.name = _("Dexterity"); - s.tag = "dex"; - s.effect = _("Dexterity %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - - { - Stat s; - s.id = 19; - s.name = _("Vitality"); - s.tag = "vit"; - s.effect = _("Vitality %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - - { - Stat s; - s.id = 20; - s.name = _("Intelligence"); - s.tag = "int"; - s.effect = _("Intelligence %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - - { - Stat s; - s.id = 21; - s.name = _("Willpower"); - s.tag = "will"; - s.effect = _("Willpower %+d"); - s.description = ""; - s.modifiable = true; - - stats[s.id] = s; - } - } - - void load() - { - XML::Document doc(DEFAULT_ATTRIBUTESDB_FILE); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "stats")) - { - logger->log("Stats: Error while loading " - DEFAULT_ATTRIBUTESDB_FILE ". Using Built-ins."); - loadBuiltins(); - return; - } - - for_each_xml_child_node(node, rootNode) - { - if (!xmlStrEqual(node->name, BAD_CAST "stat")) - continue; - - int id = XML::getProperty(node, "id", 0); - - if (id == 0) - { - logger->log("Stats: Invalid or missing stat ID in " - DEFAULT_ATTRIBUTESDB_FILE "!"); - continue; - } - else if (stats.find(id) != stats.end()) - { - logger->log("Stats: Redefinition of stat ID %d", id); - } - - std::string name = XML::getProperty(node, "name", ""); - - if (name.empty()) - { - logger->log("Stats: Invalid or missing stat name in " - DEFAULT_ATTRIBUTESDB_FILE "!"); - continue; - } - - Stat s; - s.id = id; - s.name = name; - s.tag = XML::getProperty(node, "tag", ""); - s.effect = XML::getProperty(node, "effect", ""); - s.description = XML::getProperty(node, "desc", ""); - s.modifiable = XML::getProperty(node, "modifiable", "false") - == "true"; - - stats[id] = s; - } - } - - void unload() - { - stats.clear(); - } - - void informItemDB() - { - std::list<ItemDB::Stat> dbStats; - - StatMap::const_iterator it, it_end; - for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) - if (!it->second.tag.empty()) - dbStats.push_back(ItemDB::Stat(it->second.tag, - it->second.effect)); - - ItemDB::setStatsList(dbStats); - } - - void informStatusWindow() - { - StatMap::const_iterator it, it_end; - for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) - statusWindow->addAttribute(it->second.id, it->second.name, - it->second.modifiable, - it->second.description); - } - - std::vector<std::string> getLabelVector() - { - std::vector<std::string> attributes; - StatMap::const_iterator it, it_end; - for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) - if (it->second.modifiable) - attributes.push_back(it->second.name + ":"); - - return attributes; - } -} // namespace Stats -} // namespace ManaServ diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp index 8d69767f..79362a6d 100644 --- a/src/net/tmwa/generalhandler.cpp +++ b/src/net/tmwa/generalhandler.cpp @@ -106,7 +106,7 @@ GeneralHandler::GeneralHandler(): stats.push_back(ItemDB::Stat("dex", _("Dexterity %+d"))); stats.push_back(ItemDB::Stat("luck", _("Luck %+d"))); - ItemDB::setStatsList(stats); + itemDb->setStatsList(stats); listen("Game"); } diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index 46eb6258..4a46e475 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -174,17 +174,10 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) } if (msg.getId() == SMSG_PLAYER_INVENTORY) - { - // Trick because arrows are not considered equipment - bool isEquipment = arrow & 0x8000; - - inventory->setItem(index, itemId, amount, isEquipment); - } + inventory->setItem(index, itemId, amount); else - { mInventoryItems.push_back(InventoryItem(index, itemId, amount, false)); - } } break; @@ -228,11 +221,11 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // refine for (int i = 0; i < 4; i++) cards[i] = msg.readInt16(); - equipType = msg.readInt16(); + msg.readInt16(); // EquipType itemType = msg.readInt8(); { - const ItemInfo &itemInfo = ItemDB::get(itemId); + const ItemInfo &itemInfo = itemDb->get(itemId); if (msg.readInt8() > 0) { @@ -247,7 +240,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) if (item && item->getId() == itemId) amount += inventory->getItem(index)->getQuantity(); - inventory->setItem(index, itemId, amount, equipType != 0); + inventory->setItem(index, itemId, amount); } } break; @@ -304,8 +297,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) InventoryItems::iterator it = mInventoryItems.begin(); InventoryItems::iterator it_end = mInventoryItems.end(); for (; it != it_end; it++) - mStorage->setItem((*it).slot, (*it).id, (*it).quantity, - (*it).equip); + mStorage->setItem((*it).slot, (*it).id, (*it).quantity); mInventoryItems.clear(); if (!mStorageWindow) @@ -330,9 +322,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) item->increaseQuantity(amount); } else - { - mStorage->setItem(index, itemId, amount, false); - } + mStorage->setItem(index, itemId, amount); break; case SMSG_PLAYER_STORAGE_REMOVE: @@ -374,7 +364,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // refine msg.skip(8); // card - inventory->setItem(index, itemId, 1, true); + inventory->setItem(index, itemId, 1); if (equipType) { diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp index 05ca3f87..c8615485 100644 --- a/src/net/tmwa/tradehandler.cpp +++ b/src/net/tmwa/tradehandler.cpp @@ -37,6 +37,8 @@ #include "net/tmwa/protocol.h" +#include "resources/iteminfo.h" + #include "utils/gettext.h" #include "utils/stringutils.h" @@ -167,7 +169,7 @@ void TradeHandler::handleMessage(Net::MessageIn &msg) if (type == 0) tradeWindow->setMoney(amount); else - tradeWindow->addItem(type, false, amount, false); + tradeWindow->addItem(type, false, amount); } break; @@ -187,12 +189,12 @@ void TradeHandler::handleMessage(Net::MessageIn &msg) { case 0: // Successfully added item - if (item->isEquipment() && item->isEquipped()) + if (item->isEquippable() && item->isEquipped()) { item->doEvent("doUnequip"); } - tradeWindow->addItem(item->getId(), true, quantity, - item->isEquipment()); + tradeWindow->addItem(item->getId(), true, quantity); + item->increaseQuantity(-quantity); break; case 1: |