diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/being.cpp | 26 | ||||
-rw-r--r-- | src/being.h | 4 | ||||
-rw-r--r-- | src/gui/emotecontainer.cpp | 29 | ||||
-rw-r--r-- | src/gui/emotecontainer.h | 6 | ||||
-rw-r--r-- | src/gui/emoteshortcutcontainer.cpp | 42 | ||||
-rw-r--r-- | src/gui/emoteshortcutcontainer.h | 7 | ||||
-rw-r--r-- | src/gui/emotewindow.cpp | 10 | ||||
-rw-r--r-- | src/gui/emotewindow.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 7 | ||||
-rw-r--r-- | src/npc.cpp | 3 | ||||
-rw-r--r-- | src/npc.h | 3 | ||||
-rw-r--r-- | src/resources/emotedb.cpp | 148 | ||||
-rw-r--r-- | src/resources/emotedb.h | 62 | ||||
-rw-r--r-- | src/resources/npcdb.cpp | 2 |
16 files changed, 300 insertions, 56 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 657d8e6b..dbdd64b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -233,6 +233,8 @@ SET(SRCS resources/colordb.h resources/dye.cpp resources/dye.h + resources/emotedb.cpp + resources/emotedb.h resources/image.cpp resources/image.h resources/imageloader.cpp diff --git a/src/Makefile.am b/src/Makefile.am index a54bb5c8..5c519832 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -131,7 +131,6 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \ gui/speechbubble.h \ gui/status.cpp \ gui/status.h \ - gui/table.h \ gui/table.cpp \ gui/table.h \ gui/table_model.cpp \ @@ -200,6 +199,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \ resources/colordb.h \ resources/dye.cpp \ resources/dye.h \ + resources/emotedb.cpp \ + resources/emotedb.h \ resources/image.cpp \ resources/image.h \ resources/imageloader.cpp \ diff --git a/src/being.cpp b/src/being.cpp index 69da1182..883344d8 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -35,6 +35,7 @@ #include "sound.h" #include "text.h" +#include "resources/emotedb.h" #include "resources/imageset.h" #include "resources/itemdb.h" #include "resources/iteminfo.h" @@ -50,7 +51,7 @@ int Being::instances = 0; int Being::mNumberOfHairstyles = 1; -ImageSet *Being::emotionSet = NULL; +std::vector<AnimatedSprite*> Being::emotionSet; static const int X_SPEECH_OFFSET = 18; static const int Y_SPEECH_OFFSET = 60; @@ -87,10 +88,18 @@ Being::Being(int id, int job, Map *map): if (instances == 0) { - // Load the emotion set - ResourceManager *rm = ResourceManager::getInstance(); - emotionSet = rm->getImageSet("graphics/sprites/emotions.png", 30, 32); - if (!emotionSet) logger->error(_("Unable to load emotions")); + // Setup emote sprites + for (int i = 0; i <= EmoteDB::getLast(); i++) + { + EmoteInfo info = EmoteDB::get(i); + + if (info.sprites != EmoteDB::getUnknown().sprites) + { + std::string file = "graphics/sprites/" + info.sprites.front()->sprite; + int variant = info.sprites.front()->variant; + emotionSet.push_back(AnimatedSprite::load(file, variant)); + } + } // Hairstyles are encoded as negative numbers. Count how far negative we can go. int hairstyles = 1; @@ -117,8 +126,7 @@ Being::~Being() if (instances == 0) { - emotionSet->decRef(); - emotionSet = NULL; + delete_all(emotionSet); } delete mSpeechBubble; @@ -448,8 +456,8 @@ void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY) const int py = mPy + offsetY - 60; const int emotionIndex = mEmotion - 1; - if (emotionIndex >= 0 && emotionIndex < (int) emotionSet->size()) - graphics->drawImage(emotionSet->get(emotionIndex), px, py); + if (emotionIndex >= 0 && emotionIndex < EmoteDB::getLast()) + emotionSet[emotionIndex]->draw(graphics, px, py); } void Being::drawSpeech(Graphics *graphics, int offsetX, int offsetY) diff --git a/src/being.h b/src/being.h index 54c9d717..4534b1ea 100644 --- a/src/being.h +++ b/src/being.h @@ -431,8 +431,8 @@ class Being : public Sprite // Speech Bubble components SpeechBubble *mSpeechBubble; - static int instances; /**< Number of Being instances */ - static ImageSet *emotionSet; /**< Emoticons used by beings */ + static int instances; /**< Number of Being instances */ + static std::vector<AnimatedSprite*> emotionSet; /**< Emoticons used by beings */ }; #endif diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp index c3e20c41..691211ca 100644 --- a/src/gui/emotecontainer.cpp +++ b/src/gui/emotecontainer.cpp @@ -25,14 +25,17 @@ #include "emotecontainer.h" #include "emoteshortcut.h" +#include "../animatedsprite.h" #include "../configuration.h" #include "../graphics.h" #include "../log.h" +#include "../resources/emotedb.h" #include "../resources/image.h" #include "../resources/iteminfo.h" #include "../resources/resourcemanager.h" +#include "../utils/dtor.h" #include "../utils/gettext.h" #include "../utils/tostring.h" @@ -46,15 +49,25 @@ EmoteContainer::EmoteContainer(): { ResourceManager *resman = ResourceManager::getInstance(); - mEmoteImg = resman->getImageSet("graphics/sprites/emotions.png", 30, 32); - if (!mEmoteImg) logger->error(_("Unable to load emotions")); + // Setup emote sprites + for (int i = 0; i <= EmoteDB::getLast(); i++) + { + EmoteInfo info = EmoteDB::get(i); + + if (info.sprites != EmoteDB::getUnknown().sprites) + { + std::string file = "graphics/sprites/" + info.sprites.front()->sprite; + int variant = info.sprites.front()->variant; + mEmoteImg.push_back(AnimatedSprite::load(file, variant)); + } + } mSelImg = resman->getImage("graphics/gui/selection.png"); if (!mSelImg) logger->error(_("Unable to load selection.png")); mSelImg->setAlpha(config.getValue("guialpha", 0.8)); - mMaxEmote = mEmoteImg->size(); + mMaxEmote = EmoteDB::getLast() + 1; addMouseListener(this); addWidgetListener(this); @@ -62,11 +75,8 @@ EmoteContainer::EmoteContainer(): EmoteContainer::~EmoteContainer() { - if (mEmoteImg) - { - mEmoteImg->decRef(); - mEmoteImg = NULL; - } + delete_all(mEmoteImg); + if (!mSelImg) { mSelImg->decRef(); @@ -90,8 +100,7 @@ void EmoteContainer::draw(gcn::Graphics *graphics) int emoteY = ((i) / columns) * gridHeight; // Draw emote icon - static_cast<Graphics*>(graphics)->drawImage( - mEmoteImg->get(i), emoteX, emoteY); + mEmoteImg[i]->draw(static_cast<Graphics*>(graphics), emoteX, emoteY); // Draw selection image below selected item if (mSelectedEmoteIndex == i) diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h index 2a115f0b..2231e01a 100644 --- a/src/gui/emotecontainer.h +++ b/src/gui/emotecontainer.h @@ -23,6 +23,7 @@ #define _AETHYRA_EMOTECONTAINER_H__ #include <list> +#include <vector> #include <guichan/mouselistener.hpp> #include <guichan/widget.hpp> @@ -30,8 +31,7 @@ #include "../guichanfwd.h" -#include "../resources/imageset.h" - +class AnimatedSprite; class Image; namespace gcn { @@ -123,7 +123,7 @@ class EmoteContainer : public gcn::Widget, */ void distributeValueChangedEvent(void); - ImageSet *mEmoteImg; + std::vector<AnimatedSprite*> mEmoteImg; Image *mSelImg; int mSelectedEmoteIndex; diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp index de9f8bab..edaa8602 100644 --- a/src/gui/emoteshortcutcontainer.cpp +++ b/src/gui/emoteshortcutcontainer.cpp @@ -21,6 +21,7 @@ #include "emoteshortcutcontainer.h" +#include "../animatedsprite.h" #include "../emoteshortcut.h" #include "../graphics.h" #include "../inventory.h" @@ -30,12 +31,16 @@ #include "../localplayer.h" #include "../log.h" +#include "../resources/emotedb.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" +#include "../utils/dtor.h" #include "../utils/gettext.h" #include "../utils/tostring.h" +static const int MAX_ITEMS = 12; + EmoteShortcutContainer::EmoteShortcutContainer(): mEmoteClicked(false), mEmoteMoved(0) @@ -48,10 +53,21 @@ EmoteShortcutContainer::EmoteShortcutContainer(): ResourceManager *resman = ResourceManager::getInstance(); mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); - mEmoteImg = resman->getImageSet("graphics/sprites/emotions.png", 30, 32); - if (!mEmoteImg) logger->error(_("Unable to load emotions")); - mMaxItems = emoteShortcut->getEmoteCount(); + // Setup emote sprites + for (int i = 0; i <= EmoteDB::getLast(); i++) + { + EmoteInfo info = EmoteDB::get(i); + + if (info.sprites != EmoteDB::getUnknown().sprites) + { + std::string file = "graphics/sprites/" + info.sprites.front()->sprite; + int variant = info.sprites.front()->variant; + mEmoteImg.push_back(AnimatedSprite::load(file, variant)); + } + } + + mMaxItems = MAX_ITEMS; mBoxHeight = mBackgroundImg->getHeight(); mBoxWidth = mBackgroundImg->getWidth(); @@ -60,11 +76,8 @@ EmoteShortcutContainer::EmoteShortcutContainer(): EmoteShortcutContainer::~EmoteShortcutContainer() { mBackgroundImg->decRef(); - if (mEmoteImg) - { - mEmoteImg->decRef(); - mEmoteImg=NULL; - } + + delete_all(mEmoteImg); } void EmoteShortcutContainer::draw(gcn::Graphics *graphics) @@ -88,21 +101,20 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics) if (emoteShortcut->getEmote(i)) { - static_cast<Graphics*>(graphics)->drawImage( - mEmoteImg->get(emoteShortcut->getEmote(i) - 1), emoteX + 2, emoteY + 10); + mEmoteImg[emoteShortcut->getEmote(i) - 1]->draw(g, emoteX + 2, emoteY + 10); } } if (mEmoteMoved) { // Draw the emote image being dragged by the cursor. - Image* image = mEmoteImg->get(mEmoteMoved-1); - if (image) + AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1]; + if (sprite) { - const int tPosX = mCursorPosX - (image->getWidth() / 2); - const int tPosY = mCursorPosY - (image->getHeight() / 2); + const int tPosX = mCursorPosX - (sprite->getWidth() / 2); + const int tPosY = mCursorPosY - (sprite->getHeight() / 2); - g->drawImage(image, tPosX, tPosY); + sprite->draw(g, tPosX, tPosY); } } } diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h index 5b3f61cd..f8a07dcc 100644 --- a/src/gui/emoteshortcutcontainer.h +++ b/src/gui/emoteshortcutcontainer.h @@ -22,6 +22,8 @@ #ifndef _AETHYRA_EMOTESHORTCUTCONTAINER_H__ #define _AETHYRA_EMOTESHORTCUTCONTAINER_H__ +#include <vector> + #include <guichan/mouselistener.hpp> #include <guichan/widget.hpp> #include <guichan/widgetlistener.hpp> @@ -30,8 +32,7 @@ #include "../guichanfwd.h" -#include "../resources/imageset.h" - +class AnimatedSprite; class Image; /** @@ -73,7 +74,7 @@ class EmoteShortcutContainer : public ShortcutContainer void mouseReleased(gcn::MouseEvent &event); private: - ImageSet *mEmoteImg; + std::vector<AnimatedSprite*> mEmoteImg; bool mEmoteClicked; int mEmoteMoved; diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp index af9648ef..9639d9b6 100644 --- a/src/gui/emotewindow.cpp +++ b/src/gui/emotewindow.cpp @@ -48,13 +48,13 @@ EmoteWindow::EmoteWindow(): mEmotes = new EmoteContainer(); mEmotes->addSelectionListener(this); - mInvenScroll = new ScrollArea(mEmotes); - mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mEmoteScroll = new ScrollArea(mEmotes); + mEmoteScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); draw(); add(mUseButton); - add(mInvenScroll); + add(mEmoteScroll); mUseButton->setSize(60, mUseButton->getHeight()); @@ -80,8 +80,8 @@ void EmoteWindow::draw() mUseButton->setPosition(8, height - 8 - mUseButton->getHeight()); - mInvenScroll->setSize(width - 16, mUseButton->getY() - 18); - mInvenScroll->setPosition(8, 10); + mEmoteScroll->setSize(width - 16, mUseButton->getY() - 18); + mEmoteScroll->setPosition(8, 10); setMinHeight(130); } diff --git a/src/gui/emotewindow.h b/src/gui/emotewindow.h index dbe4efd7..a996db99 100644 --- a/src/gui/emotewindow.h +++ b/src/gui/emotewindow.h @@ -70,7 +70,7 @@ class EmoteWindow : public Window, gcn::ActionListener, EmoteContainer *mEmotes; gcn::Button *mUseButton; - gcn::ScrollArea *mInvenScroll; + gcn::ScrollArea *mEmoteScroll; }; extern EmoteWindow *emoteWindow; diff --git a/src/main.cpp b/src/main.cpp index 61b90b12..a1109092 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,7 @@ #include "net/network.h" #include "resources/colordb.h" +#include "resources/emotedb.h" #include "resources/image.h" #include "resources/itemdb.h" #include "resources/monsterdb.h" @@ -402,7 +403,7 @@ void init_engine(const Options &options) // Initialize the item shortcuts. itemShortcut = new ItemShortcut(); - + // Initialize the emote shortcuts. emoteShortcut = new EmoteShortcut(); @@ -437,7 +438,6 @@ void exit_engine() { // Before config.write() since it writes the shortcuts to the config delete itemShortcut; - delete emoteShortcut; config.write(); @@ -453,6 +453,7 @@ void exit_engine() // Unload XML databases ColorDB::unload(); + EmoteDB::unload(); ItemDB::unload(); MonsterDB::unload(); NPCDB::unload(); @@ -903,6 +904,8 @@ int main(int argc, char *argv[]) ItemDB::load(); MonsterDB::load(); NPCDB::load(); + EmoteDB::load(); + state = CHAR_CONNECT_STATE; break; diff --git a/src/npc.cpp b/src/npc.cpp index a2fb7d38..a9aa216c 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -105,8 +105,7 @@ void NPC::setSprite(int slot, int id, std::string color) Being::setSprite(slot, id, color); } -Being::Type -NPC::getType() const +Being::Type NPC::getType() const { return Being::NPC; } @@ -39,8 +39,7 @@ class NPC : public Player void setGender(Gender gender); void setSprite(int slot, int id, std::string color); - virtual Type - getType() const; + virtual Type getType() const; void talk(); void nextDialog(); diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp new file mode 100644 index 00000000..03096eff --- /dev/null +++ b/src/resources/emotedb.cpp @@ -0,0 +1,148 @@ +/* + * Aethyra + * Copyright 2009 Aethyra Development Team + * + * This file is part of Aethyra. + * + * Aethyra 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. + * + * Aethyra 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 Aethyra; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "emotedb.h" +#include "resourcemanager.h" + +#include "../log.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" +#include "../utils/xml.h" + +namespace +{ + EmoteInfos mEmoteInfos; + EmoteInfo mUnknown; + bool mLoaded = false; + int mLastEmote = 0; +} + +void EmoteDB::load() +{ + if (mLoaded) + return; + + mLastEmote = 0; + + EmoteSprite *unknownSprite = new EmoteSprite; + unknownSprite->sprite = "error.xml"; + unknownSprite->name = "unknown"; + unknownSprite->variant = 0; + mUnknown.sprites.push_back(unknownSprite); + + logger->log(_("Initializing emote database...")); + + XML::Document doc("emotes.xml"); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "emotes")) + { + logger->log(_("Emote Database: Error while loading emotes.xml!")); + return; + } + + //iterate <emote>s + for_each_xml_child_node(emoteNode, rootNode) + { + if (!xmlStrEqual(emoteNode->name, BAD_CAST "emote")) + continue; + + int id = XML::getProperty(emoteNode, "id", -1); + if (id == -1) + { + logger->log(_("Emote Database: Emote with missing ID in emotes.xml!")); + continue; + } + + EmoteInfo *currentInfo = new EmoteInfo; + + for_each_xml_child_node(spriteNode, emoteNode) + { + if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) + { + EmoteSprite *currentSprite = new EmoteSprite; + currentSprite->sprite = (const char*) spriteNode->xmlChildrenNode->content; + currentSprite->variant = XML::getProperty(spriteNode, "variant", 0); + currentInfo->sprites.push_back(currentSprite); + } + else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) + { + std::string particlefx = (const char*) spriteNode->xmlChildrenNode->content; + currentInfo->particles.push_back(particlefx); + } + } + mEmoteInfos[id] = currentInfo; + if (id > mLastEmote) mLastEmote = id; + } + + mLoaded = true; +} + +void EmoteDB::unload() +{ + for ( EmoteInfosIterator i = mEmoteInfos.begin(); + i != mEmoteInfos.end(); + i++) + { + while (!i->second->sprites.empty()) + { + delete i->second->sprites.front(); + i->second->sprites.pop_front(); + } + delete i->second; + } + + mEmoteInfos.clear(); + + while (!mUnknown.sprites.empty()) + { + delete mUnknown.sprites.front(); + mUnknown.sprites.pop_front(); + } + + mLoaded = false; +} + +const EmoteInfo& EmoteDB::get(int id) +{ + EmoteInfosIterator i = mEmoteInfos.find(id); + + if (i == mEmoteInfos.end()) + { + logger->log(_("EmoteDB: Warning, unknown emote ID %d requested"), id); + return mUnknown; + } + else + { + return *(i->second); + } +} + +const EmoteInfo& EmoteDB::getUnknown() +{ + return mUnknown; +} + +const int& EmoteDB::getLast() +{ + return mLastEmote; +} diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h new file mode 100644 index 00000000..9e904cc1 --- /dev/null +++ b/src/resources/emotedb.h @@ -0,0 +1,62 @@ +/* + * Aethyra + * Copyright 2009 Aethyra Development Team + * + * This file is part of Aethyra. + * + * Aethyra 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. + * + * Aethyra 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 Aethyra; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _AETHYRA_EMOTE_DB_H +#define _AETHYRA_EMOTE_DB_H + +#include <list> +#include <map> +#include <string> + +struct EmoteSprite +{ + std::string sprite; + std::string name; + int variant; +}; + +struct EmoteInfo +{ + std::list<EmoteSprite*> sprites; + std::list<std::string> particles; +}; + +typedef std::map<int, EmoteInfo*> EmoteInfos; + +/** + * Emote information database. + */ +namespace EmoteDB +{ + void load(); + + void unload(); + + const EmoteInfo& get(int id); + + const EmoteInfo& getUnknown(); + + const int& getLast(); + + typedef EmoteInfos::iterator EmoteInfosIterator; +} + +#endif diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp index bfa22214..0908d67d 100644 --- a/src/resources/npcdb.cpp +++ b/src/resources/npcdb.cpp @@ -55,7 +55,7 @@ void NPCDB::load() logger->error(_("NPC Database: Error while loading npcs.xml!")); } - //iterate <monster>s + //iterate <npc>s for_each_xml_child_node(npcNode, rootNode) { if (!xmlStrEqual(npcNode->name, BAD_CAST "npc")) |