From 02602a6a7bb92fbe19b7a015f5c6764ab658c469 Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Fri, 18 May 2012 13:32:34 +0200 Subject: Added emote support. --- example/effects.xml | 2 +- example/emotes.xml | 37 +++++++++++---------- gameserver.cbp | 2 ++ src/CMakeLists.txt | 2 ++ src/common/manaserv_protocol.h | 2 ++ src/game-server/actor.h | 3 +- src/game-server/being.cpp | 11 ++++++- src/game-server/being.h | 14 ++++++++ src/game-server/emotemanager.cpp | 70 ++++++++++++++++++++++++++++++++++++++++ src/game-server/emotemanager.h | 64 ++++++++++++++++++++++++++++++++++++ src/game-server/gamehandler.cpp | 12 +++++++ src/game-server/gamehandler.h | 2 ++ src/game-server/main-game.cpp | 5 +++ src/game-server/state.cpp | 13 ++++++++ 14 files changed, 217 insertions(+), 22 deletions(-) create mode 100644 src/game-server/emotemanager.cpp create mode 100644 src/game-server/emotemanager.h diff --git a/example/effects.xml b/example/effects.xml index 90de57e2..57e1c755 100644 --- a/example/effects.xml +++ b/example/effects.xml @@ -12,7 +12,6 @@ - @@ -26,4 +25,5 @@ + diff --git a/example/emotes.xml b/example/emotes.xml index 0136b13c..7b8ae739 100644 --- a/example/emotes.xml +++ b/example/emotes.xml @@ -1,101 +1,100 @@ - - - - - - - - - - - - - - - + + diff --git a/gameserver.cbp b/gameserver.cbp index ef0fc325..14d1dc14 100644 --- a/gameserver.cbp +++ b/gameserver.cbp @@ -132,6 +132,8 @@ + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 73f969f7..1d06c5d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -215,6 +215,8 @@ SET(SRCS_MANASERVGAME game-server/commandhandler.h game-server/effect.h game-server/effect.cpp + game-server/emotemanager.h + game-server/emotemanager.cpp game-server/entity.h game-server/entity.cpp game-server/gamehandler.h diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h index 913a1268..1fc85ba6 100644 --- a/src/common/manaserv_protocol.h +++ b/src/common/manaserv_protocol.h @@ -133,6 +133,8 @@ enum { GPMSG_BEING_LEAVE = 0x0201, // W being id GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B sprite layers changed, { B slot type, W item id }* + GPMSG_BEING_EMOTE = 0x0211, // W being id, W emote id + PGMSG_BEING_EMOTE = 0x0212, // W emoticon id PGMSG_WALK = 0x0260, // W*2 destination PGMSG_ACTION_CHANGE = 0x0270, // B Action GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action diff --git a/src/game-server/actor.h b/src/game-server/actor.h index 324393df..13d4af55 100644 --- a/src/game-server/actor.h +++ b/src/game-server/actor.h @@ -37,7 +37,8 @@ enum UPDATEFLAG_ACTIONCHANGE = 8, UPDATEFLAG_LOOKSCHANGE = 16, UPDATEFLAG_DIRCHANGE = 32, - UPDATEFLAG_HEALTHCHANGE = 64 + UPDATEFLAG_HEALTHCHANGE = 64, + UPDATEFLAG_EMOTE = 128 }; /** diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 0e240870..d7df2df9 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -41,7 +41,8 @@ Being::Being(EntityType type): mTarget(NULL), mGender(GENDER_UNSPECIFIED), mCurrentAttack(0), - mDirection(DOWN) + mDirection(DOWN), + mEmoteId(0) { const AttributeManager::AttributeScope &attr = attributeManager->getAttributeScope(BeingScope); LOG_DEBUG("Being creation: initialisation of " << attr.size() << " attributes."); @@ -73,6 +74,14 @@ Being::Being(EntityType type): #endif } +void Being::triggerEmote(int id) +{ + mEmoteId = id; + + if (id > -1) + raiseUpdateFlags(UPDATEFLAG_EMOTE); +} + int Being::damage(Actor * /* source */, const Damage &damage) { if (mAction == DEAD) diff --git a/src/game-server/being.h b/src/game-server/being.h index a08df018..d5a73588 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -299,6 +299,17 @@ class Being : public Actor sigc::signal signal_died; + /** + * Activate an emote flag on the being. + */ + void triggerEmote(int id); + + /** + * Tells the last emote used. + */ + int getLastEmote() const + { return mEmoteId; } + protected: /** * Performs an attack @@ -342,6 +353,9 @@ class Being : public Actor /** Time until hp is regenerated again */ Timeout mHealthRegenerationTimeout; + + /** The last being emote Id. Used when triggering a being emoticon. */ + int mEmoteId; }; #endif // BEING_H diff --git a/src/game-server/emotemanager.cpp b/src/game-server/emotemanager.cpp new file mode 100644 index 00000000..35f0aa47 --- /dev/null +++ b/src/game-server/emotemanager.cpp @@ -0,0 +1,70 @@ +/* + * The Mana Server + * Copyright (C) 2012 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server 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. + * + * The Mana Server 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 The Mana Server. If not, see . + */ + +#include "emotemanager.h" + +#include "utils/xml.h" +#include "utils/logger.h" + +void EmoteManager::initialize() +{ + clear(); + + XML::Document doc(mEmoteFile); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "emotes")) + { + LOG_ERROR("Emote Manager: " << mEmoteFile + << " is not a valid emote file!"); + return; + } + + LOG_INFO("Loading emote reference: " << mEmoteFile); + + for_each_xml_child_node(emoteNode, rootNode) + { + if (!xmlStrEqual(emoteNode->name, BAD_CAST "emote")) + continue; + + int id = XML::getProperty(emoteNode, "id", -1); + if (id < 0) + { + LOG_WARN("The " << mEmoteFile << " file is containing an invalid id" + "(" << id << ") and will be ignored."); + continue; + } + + mEmoteIds.push_back(id); + } + LOG_INFO(mEmoteIds.size() << " emotes available."); +} + +bool EmoteManager::isIdAvailable(int id) const +{ + std::vector::const_iterator it = mEmoteIds.begin(); + std::vector::const_iterator it_end = mEmoteIds.end(); + for (; it != it_end; ++it) + { + if ((*it) == id) + return true; + } + return false; +} diff --git a/src/game-server/emotemanager.h b/src/game-server/emotemanager.h new file mode 100644 index 00000000..42c71680 --- /dev/null +++ b/src/game-server/emotemanager.h @@ -0,0 +1,64 @@ +/* + * The Mana Server + * Copyright (C) 2011-2012 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server 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. + * + * The Mana Server 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 The Mana Server. If not, see . + */ + + +#ifndef EMOTEMANAGER_H +#define EMOTEMANAGER_H + +#include "utils/string.h" +#include "utils/xml.h" + +#include + +class EmoteManager +{ +public: + + EmoteManager(const std::string &emoteFile): + mEmoteFile(emoteFile) + { } + + ~EmoteManager() + { clear(); } + + /** + * Loads emote reference file. + */ + void initialize(); + + /** + * Tells whether the given id is a valid emote one. + */ + bool isIdAvailable(int id) const; + +private: + /** + * Clears up the emote list. + */ + void clear() + { mEmoteIds.clear(); } + + std::string mEmoteFile; + std::vector mEmoteIds; +}; + +extern EmoteManager *emoteManager; + +#endif // EMOTEMANAGER_H diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 18059d6e..3b356a5c 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -28,6 +28,7 @@ #include "game-server/accountconnection.h" #include "game-server/buysell.h" #include "game-server/commandhandler.h" +#include "game-server/emotemanager.h" #include "game-server/inventory.h" #include "game-server/item.h" #include "game-server/itemmanager.h" @@ -302,6 +303,10 @@ void GameHandler::processMessage(NetComputer *computer, MessageIn &message) handlePartyInvite(client, message); break; + case PGMSG_BEING_EMOTE: + handleTriggerEmoticon(client, message); + break; + default: LOG_WARN("Invalid message type"); client.send(MessageOut(XXMSG_INVALID)); @@ -919,6 +924,13 @@ void GameHandler::handlePartyInvite(GameClient &client, MessageIn &message) client.send(out); } +void GameHandler::handleTriggerEmoticon(GameClient &client, MessageIn &message) +{ + const int id = message.readInt16(); + if (emoteManager->isIdAvailable(id)) + client.character->triggerEmote(id); +} + void GameHandler::sendNpcError(GameClient &client, int id, const std::string &errorMsg) { diff --git a/src/game-server/gamehandler.h b/src/game-server/gamehandler.h index c0d843e9..c05e0087 100644 --- a/src/game-server/gamehandler.h +++ b/src/game-server/gamehandler.h @@ -152,6 +152,8 @@ class GameHandler: public ConnectionHandler void handlePartyInvite(GameClient &client, MessageIn &message); + void handleTriggerEmoticon(GameClient &client, MessageIn &message); + void sendNpcError(GameClient &client, int id, const std::string &errorMsg); diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index 406e7c5b..5814f0bc 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -25,6 +25,7 @@ #include "game-server/accountconnection.h" #include "game-server/attributemanager.h" #include "game-server/gamehandler.h" +#include "game-server/emotemanager.h" #include "game-server/itemmanager.h" #include "game-server/mapmanager.h" #include "game-server/monstermanager.h" @@ -74,6 +75,7 @@ using utils::Logger; #define DEFAULT_PERMISSION_FILE "permissions.xml" #define DEFAULT_MAIN_SCRIPT_FILE "scripts/main.lua" #define DEFAULT_SPECIALSDB_FILE "specials.xml" +#define DEFAULT_EMOTESDB_FILE "emotes.xml" static int const WORLD_TICK_SKIP = 2; /** tolerance for lagging behind in world calculation) **/ @@ -89,6 +91,7 @@ ItemManager *itemManager = new ItemManager(DEFAULT_ITEMSDB_FILE, DEFAULT_EQUIPDB MonsterManager *monsterManager = new MonsterManager(DEFAULT_MONSTERSDB_FILE); SkillManager *skillManager = new SkillManager(DEFAULT_SKILLSDB_FILE); SpecialManager *specialManager = new SpecialManager(DEFAULT_SPECIALSDB_FILE); +EmoteManager *emoteManager = new EmoteManager(DEFAULT_EMOTESDB_FILE); /** Core game message handler */ GameHandler *gameHandler; @@ -141,6 +144,7 @@ static void initializeServer() specialManager->initialize(); itemManager->initialize(); monsterManager->initialize(); + emoteManager->initialize(); StatusManager::initialize(DEFAULT_STATUSDB_FILE); PermissionManager::initialize(DEFAULT_PERMISSION_FILE); @@ -196,6 +200,7 @@ static void deinitializeServer() delete monsterManager; monsterManager = 0; delete skillManager; skillManager = 0; delete itemManager; itemManager = 0; + delete emoteManager; emoteManager = 0; MapManager::deinitialize(); StatusManager::deinitialize(); ScriptManager::deinitialize(); diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 006075b4..6fdfb6f5 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -193,6 +193,19 @@ static void informPlayer(MapComposite *map, Character *p) gameHandler->sendTo(p, LooksMsg); } + // Send emote messages. + if (oflags & UPDATEFLAG_EMOTE) + { + int emoteId = o->getLastEmote(); + if (emoteId > -1) + { + MessageOut EmoteMsg(GPMSG_BEING_EMOTE); + EmoteMsg.writeInt16(oid); + EmoteMsg.writeInt16(emoteId); + gameHandler->sendTo(p, EmoteMsg); + } + } + // Send direction change messages. if (oflags & UPDATEFLAG_DIRCHANGE) { -- cgit v1.2.3-60-g2f50