diff options
author | Jared Adams <jaxad0127@gmail.com> | 2010-08-15 21:28:10 -0600 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2010-08-16 13:19:09 -0600 |
commit | d8d9232a67a03548b827bdb0515fe7a620a488f8 (patch) | |
tree | d6e0644f99e0ff89f9b320c0b479ba5a4e398125 /src | |
parent | a6c2b90c2dabac18ad8052d948bc540406b3a613 (diff) | |
download | mana-d8d9232a67a03548b827bdb0515fe7a620a488f8.tar.gz mana-d8d9232a67a03548b827bdb0515fe7a620a488f8.tar.bz2 mana-d8d9232a67a03548b827bdb0515fe7a620a488f8.tar.xz mana-d8d9232a67a03548b827bdb0515fe7a620a488f8.zip |
Move more to the event system
Most of Net::InventoryHandler is now done through events. The
ActorSpriteManager was also replaced by events. A few odds and
ends were taken care of too.
Reviewed-by: Bertram
Diffstat (limited to 'src')
30 files changed, 472 insertions, 359 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6963663d..bc44a05c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -415,7 +415,6 @@ SET(SRCS actor.h actorsprite.cpp actorsprite.h - actorspritelistener.h actorspritemanager.cpp actorspritemanager.h animatedsprite.cpp diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp index cdc23dc6..ff12822c 100644 --- a/src/actorsprite.cpp +++ b/src/actorsprite.cpp @@ -19,7 +19,6 @@ */ #include "actorsprite.h" -#include "actorspritelistener.h" #include "client.h" #include "effectmanager.h" @@ -61,13 +60,10 @@ ActorSprite::~ActorSprite() mUsedTargetCursor = NULL; - if (player_node && player_node->getTarget() == this) - player_node->setTarget(NULL); - // Notify listeners of the destruction. - for (ActorSpriteListenerIterator iter = mActorSpriteListeners.begin(), - end = mActorSpriteListeners.end(); iter != end; ++iter) - (*iter)->actorSpriteDestroyed(*this); + Mana::Event event("Destroyed"); + event.setActor("source", this); + event.trigger("ActorSprite"); } bool ActorSprite::draw(Graphics *graphics, int offsetX, int offsetY) const @@ -378,16 +374,6 @@ void ActorSprite::unload() loaded = false; } -void ActorSprite::addActorSpriteListener(ActorSpriteListener *listener) -{ - mActorSpriteListeners.push_front(listener); -} - -void ActorSprite::removeActorSpriteListener(ActorSpriteListener *listener) -{ - mActorSpriteListeners.remove(listener); -} - static const char *cursorType(int type) { switch (type) diff --git a/src/actorsprite.h b/src/actorsprite.h index 7cc91c53..ab945d2f 100644 --- a/src/actorsprite.h +++ b/src/actorsprite.h @@ -33,7 +33,6 @@ class SimpleAnimation; class StatusEffect; -class ActorSpriteListener; class ActorSprite : public CompoundSprite, public Actor { @@ -162,16 +161,6 @@ public: static void unload(); - /** - * Add an ActorSprite listener. - */ - void addActorSpriteListener(ActorSpriteListener *listener); - - /** - * Remove an ActorSprite listener. - */ - void removeActorSpriteListener(ActorSpriteListener *listener); - protected: /** * Trigger visual effect, with components @@ -239,10 +228,6 @@ private: /** Target cursor being used */ SimpleAnimation *mUsedTargetCursor; - - typedef std::list<ActorSpriteListener*> ActorSpriteListeners; - typedef ActorSpriteListeners::iterator ActorSpriteListenerIterator; - ActorSpriteListeners mActorSpriteListeners; }; #endif // ACTORSPRITE_H diff --git a/src/actorspritelistener.h b/src/actorspritelistener.h deleted file mode 100644 index 994494f4..00000000 --- a/src/actorspritelistener.h +++ /dev/null @@ -1,42 +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/>. - */ - -#ifndef ACTORSPRITELISTENER_H -#define ACTORSPRITELISTENER_H - -class ActorSprite; - -class ActorSpriteListener -{ - public: - /** - * Destructor. - */ - virtual ~ActorSpriteListener() {} - - /** - * Called when the ActorSprite has been destroyed. The listener will - * have to be registered first. - * @param actorSprite the ActorSprite being destroyed. - */ - virtual void actorSpriteDestroyed(const ActorSprite &actorSprite) = 0; -}; - -#endif // ACTORSPRITELISTENER_H diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp index dd979c63..88618ccd 100644 --- a/src/actorspritemanager.cpp +++ b/src/actorspritemanager.cpp @@ -215,10 +215,7 @@ void ActorSpriteManager::logic() void ActorSpriteManager::clear() { if (player_node) - { - player_node->setTarget(0); mActors.erase(player_node); - } for_actors delete *it; diff --git a/src/event.cpp b/src/event.cpp index 38213cd2..3ca4c5e2 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -38,6 +38,8 @@ Event::~Event() } } +// Integers + void Event::setInt(const std::string &key, int value) throw (BadEvent) { if (mData.find(key) != mData.end()) @@ -65,6 +67,8 @@ bool Event::hasInt(const std::string &key) const || it->second->getType() != VariableData::DATA_INT); } +// Strings + void Event::setString(const std::string &key, const std::string &value) throw (BadEvent) { if (mData.find(key) != mData.end()) @@ -93,6 +97,8 @@ bool Event::hasString(const std::string &key) const || it->second->getType() != VariableData::DATA_STRING); } +// Floats + void Event::setFloat(const std::string &key, double value) throw (BadEvent) { if (mData.find(key) != mData.end()) @@ -120,6 +126,8 @@ bool Event::hasFloat(const std::string &key) const || it->second->getType() != VariableData::DATA_FLOAT); } +// Booleans + void Event::setBool(const std::string &key, bool value) throw (BadEvent) { if (mData.find(key) != mData.end()) @@ -147,6 +155,66 @@ bool Event::hasBool(const std::string &key) const || it->second->getType() != VariableData::DATA_BOOL); } +// Items + +void Event::setItem(const std::string &key, Item *value) throw (BadEvent) +{ + if (mData.find(key) != mData.end()) + throw KEY_ALREADY_EXISTS; + + mData[key] = new ItemData(value); +} + +Item *Event::getItem(const std::string &key) const throw (BadEvent) +{ + VariableMap::const_iterator it = mData.find(key); + if (it == mData.end()) + throw BAD_KEY; + + if (it->second->getType() != VariableData::DATA_ITEM) + throw BAD_VALUE; + + return static_cast<ItemData *>(it->second)->getData(); +} + +bool Event::hasItem(const std::string &key) const +{ + VariableMap::const_iterator it = mData.find(key); + return !(it == mData.end() + || it->second->getType() != VariableData::DATA_ITEM); +} + +// Actors + +void Event::setActor(const std::string &key, ActorSprite *value) throw (BadEvent) +{ + if (mData.find(key) != mData.end()) + throw KEY_ALREADY_EXISTS; + + mData[key] = new ActorData(value); +} + +ActorSprite *Event::getActor(const std::string &key) const throw (BadEvent) +{ + VariableMap::const_iterator it = mData.find(key); + if (it == mData.end()) + throw BAD_KEY; + + if (it->second->getType() != VariableData::DATA_ACTOR) + throw BAD_VALUE; + + return static_cast<ActorData *>(it->second)->getData(); +} + +bool Event::hasActor(const std::string &key) const +{ + VariableMap::const_iterator it = mData.find(key); + return !(it == mData.end() + || it->second->getType() != VariableData::DATA_ACTOR); +} + +// Triggers + void Event::trigger(const std::string &channel, const Event &event) { ListenMap::iterator it = mBindings.find(channel); diff --git a/src/event.h b/src/event.h index 68560dae..c7382fc1 100644 --- a/src/event.h +++ b/src/event.h @@ -21,9 +21,12 @@ #ifndef EVENT_H #define EVENT_H -#include <string> #include <map> #include <set> +#include <string> + +class ActorSprite; +class Item; namespace Mana { @@ -65,6 +68,8 @@ public: const std::string &getName() const { return mEventName; } +// Integers + /** * Sets the given variable to the given integer, if it isn't already set. */ @@ -87,6 +92,8 @@ public: */ bool hasInt(const std::string &key) const; +// Strings + /** * Sets the given variable to the given string, if it isn't already set. */ @@ -110,6 +117,8 @@ public: */ bool hasString(const std::string &key) const; +// Floats + /** * Sets the given variable to the given floating-point, if it isn't already * set. @@ -133,6 +142,8 @@ public: */ bool hasFloat(const std::string &key) const; +// Booleans + /** * Sets the given variable to the given boolean, if it isn't already set. */ @@ -155,6 +166,57 @@ public: */ bool hasBool(const std::string &key) const; +// Items + + /** + * Sets the given variable to the given Item, if it isn't already set. + */ + void setItem(const std::string &key, Item *value) throw (BadEvent); + + /** + * Returns the given variable if it is set and an Item. + */ + Item *getItem(const std::string &key) const throw (BadEvent); + + /** + * Returns the given variable if it is set and an Item, returning the + * given default otherwise. + */ + inline Item *getItem(const std::string &key, Item *defaultValue) const + { try { return getItem(key); } catch (BadEvent) { return defaultValue; }} + + /** + * Returns true if the given variable exists and is an Item. + */ + bool hasItem(const std::string &key) const; + +// ActorSprites + + /** + * Sets the given variable to the given actor, if it isn't already set. + */ + void setActor(const std::string &key, ActorSprite *value) throw (BadEvent); + + /** + * Returns the given variable if it is set and an actor. + */ + ActorSprite *getActor(const std::string &key) const throw (BadEvent); + + /** + * Returns the given variable if it is set and an actor, returning the + * given default otherwise. + */ + inline ActorSprite *getActor(const std::string &key, + ActorSprite *defaultValue) const + { try { return getActor(key); } catch (BadEvent) { return defaultValue; }} + + /** + * Returns true if the given variable exists and is an actor. + */ + bool hasActor(const std::string &key) const; + +// Triggers + /** * Sends this event to all classes listening to the given channel. */ diff --git a/src/game.cpp b/src/game.cpp index 8d6440b7..9035ba6a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -203,6 +203,8 @@ static void destroyGuiWindows() del_0(specialsWindow) del_0(socialWindow) + Mana::Event::trigger("NPC", "CloseAll"); // Cleanup remaining NPC dialogs + Mana::Event::trigger("Game", "GuiWindowsUnloaded"); } @@ -260,6 +262,8 @@ Game::Game(): Game::~Game() { + Mana::Event::trigger("Game", "Destructing"); + delete mWindowMenu; destroyGuiWindows(); diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index dcc372cd..474a9cb6 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -158,7 +158,7 @@ void EquipmentWindow::action(const gcn::ActionEvent &event) if (event.getId() == "unequip" && mSelected > -1) { Item *item = mEquipment->getEquipment(mSelected); - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); setSelected(-1); } } diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 41ac96b4..5df1d4ba 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -188,12 +188,12 @@ void InventoryWindow::action(const gcn::ActionEvent &event) if (item->isEquipment()) { if (item->isEquipped()) - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); else - Net::getInventoryHandler()->equipItem(item); + item->doEvent("doEquip"); } else - Net::getInventoryHandler()->useItem(item); + item->doEvent("doUse"); } else if (event.getId() == "drop") { @@ -249,13 +249,23 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) if(!item) return; if (mInventory->isMainInventory()) - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, - item->getInvIndex(), item->getQuantity(), - Inventory::STORAGE); + { + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("amount", item->getQuantity()); + event.setInt("source", Inventory::INVENTORY); + event.setInt("destination", Inventory::STORAGE); + event.trigger("Item"); + } else - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, - item->getInvIndex(), item->getQuantity(), - Inventory::INVENTORY); + { + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("amount", item->getQuantity()); + event.setInt("source", Inventory::STORAGE); + event.setInt("destination", Inventory::INVENTORY); + event.trigger("Item"); + } } } } @@ -344,7 +354,9 @@ void InventoryWindow::close() } else { - Net::getInventoryHandler()->closeStorage(Inventory::STORAGE); + Mana::Event event("doCloseInventory"); + event.setInt("type", mInventory->getType()); + event.trigger("Item"); scheduleDelete(); } } diff --git a/src/gui/itemamount.cpp b/src/gui/itemamount.cpp index a98a67ab..aed8d11d 100644 --- a/src/gui/itemamount.cpp +++ b/src/gui/itemamount.cpp @@ -47,20 +47,30 @@ void ItemAmountWindow::finish(Item *item, int amount, Usage usage) tradeWindow->tradeItem(item, amount); break; case ItemDrop: - Net::getInventoryHandler()->dropItem(item, amount); + item->doEvent("doDrop", amount); break; case ItemSplit: - Net::getInventoryHandler()->splitItem(item, amount); + item->doEvent("doSplit", amount); break; case StoreAdd: - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, - item->getInvIndex(), amount, - Inventory::STORAGE); + { + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("amount", amount); + event.setInt("source", Inventory::INVENTORY); + event.setInt("destination", Inventory::STORAGE); + event.trigger("Item"); + } break; case StoreRemove: - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, - item->getInvIndex(), amount, - Inventory::INVENTORY); + { + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("amount", amount); + event.setInt("source", Inventory::STORAGE); + event.setInt("destination", Inventory::INVENTORY); + event.trigger("Item"); + } break; default: break; diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp index ad3342ee..f16ebd39 100644 --- a/src/gui/outfitwindow.cpp +++ b/src/gui/outfitwindow.cpp @@ -171,7 +171,7 @@ void OutfitWindow::wearOutfit(int outfit) if (item && !item->isEquipped() && item->getQuantity()) { if (item->isEquipment()) - Net::getInventoryHandler()->equipItem(item); + item->doEvent("doEquip"); } } } @@ -337,7 +337,10 @@ void OutfitWindow::unequipNotInOutfit(int outfit) } if (!found) { - Net::getInventoryHandler()->unequipItem(inventory->getItem(i)); + Item *item = inventory->getItem(i); + + if (item) + item->doEvent("doUnequip"); } } } diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 7bf1d4fb..41ecafc9 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -277,14 +277,12 @@ void PopupMenu::handleLink(const std::string &link) if (mItem->isEquipment()) { if (mItem->isEquipped()) - Net::getInventoryHandler()->unequipItem(mItem); + mItem->doEvent("doUnequip"); else - Net::getInventoryHandler()->equipItem(mItem); + mItem->doEvent("doEquip"); } else - { - Net::getInventoryHandler()->useItem(mItem); - } + mItem->doEvent("doUse"); } else if (link == "chat") diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index f63fe5c6..972920a5 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -71,6 +71,8 @@ Viewport::Viewport(): mBeingPopup = new BeingPopup; setFocusable(true); + + listen("ActorSprite"); } Viewport::~Viewport() @@ -495,19 +497,14 @@ void Viewport::mouseMoved(gcn::MouseEvent &event) const int x = (event.getX() + (int) mPixelViewX); const int y = (event.getY() + (int) mPixelViewY); - if (mHoverBeing) - mHoverBeing->removeActorSpriteListener(this); mHoverBeing = actorSpriteManager->findBeingByPixel(x, y); mBeingPopup->show(getMouseX(), getMouseY(), mHoverBeing); - if (mHoverItem) - mHoverItem->removeActorSpriteListener(this); mHoverItem = actorSpriteManager->findItem(x / mMap->getTileWidth(), y / mMap->getTileHeight()); if (mHoverBeing) { - mHoverBeing->addActorSpriteListener(this); switch (mHoverBeing->getType()) { // NPCs @@ -527,7 +524,6 @@ void Viewport::mouseMoved(gcn::MouseEvent &event) } else if (mHoverItem) { - mHoverItem->addActorSpriteListener(this); gui->setCursorType(Gui::CURSOR_PICKUP); } else @@ -552,11 +548,16 @@ void Viewport::hideBeingPopup() mBeingPopup->setVisible(false); } -void Viewport::actorSpriteDestroyed(const ActorSprite &actorSprite) +void Viewport::event(const std::string &channel, const Mana::Event &event) { - if (&actorSprite == mHoverBeing) - mHoverBeing = 0; + if (channel == "ActorSprite" && event.getName() == "Destroyed") + { + ActorSprite *actor = event.getActor("source"); - if (&actorSprite == mHoverItem) - mHoverItem = 0; + if (mHoverBeing == actor) + mHoverBeing = 0; + + if (mHoverItem == actor) + mHoverItem = 0; + } } diff --git a/src/gui/viewport.h b/src/gui/viewport.h index eaf23085..c54b9860 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -22,9 +22,9 @@ #ifndef VIEWPORT_H #define VIEWPORT_H -#include "actorspritelistener.h" #include "actorspritemanager.h" #include "configlistener.h" +#include "listener.h" #include "position.h" #include "gui/widgets/windowcontainer.h" @@ -54,7 +54,7 @@ const int walkingMouseDelay = 500; * coordinates. */ class Viewport : public WindowContainer, public gcn::MouseListener, - public ConfigListener, public ActorSpriteListener + public ConfigListener, public Mana::Listener { public: /** @@ -160,7 +160,7 @@ class Viewport : public WindowContainer, public gcn::MouseListener, */ void hideBeingPopup(); - void actorSpriteDestroyed(const ActorSprite &actorSprite); + void event(const std::string &channel, const Mana::Event &event); private: /** diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index b98cac66..a9df95a6 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -260,12 +260,12 @@ void ItemContainer::mousePressed(gcn::MouseEvent &event) if (item->isEquipment()) { if (item->isEquipped()) - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); else - Net::getInventoryHandler()->equipItem(item); + item->doEvent("doEquip"); } else - Net::getInventoryHandler()->useItem(item); + item->doEvent("doUse"); } else @@ -275,18 +275,17 @@ void ItemContainer::mousePressed(gcn::MouseEvent &event) } else if (item && item->getId()) { - if(event.getClickCount() == 2) + if(event.getClickCount() == 2) { if (item->isEquipment()) { if (item->isEquipped()) - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); else - Net::getInventoryHandler()->equipItem(item); + item->doEvent("doEquip"); } else - Net::getInventoryHandler()->useItem(item); - + item->doEvent("doUse"); } else { @@ -337,7 +336,14 @@ void ItemContainer::mouseReleased(gcn::MouseEvent &event) return; if (index == mSelectedIndex || mSelectedIndex == -1) return; - Net::getInventoryHandler()->moveItem(mSelectedIndex, index); + + Item *item = getSelectedItem(); + { + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("newIndex", index); + event.trigger("Item"); + } selectNone(); } @@ -404,8 +410,11 @@ void ItemContainer::keyAction() mSelectedIndex != -1 && mHighlightedIndex != -1) { - Net::getInventoryHandler()->moveItem( - mSelectedIndex, mHighlightedIndex); + Item *item = getSelectedItem(); + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("newIndex", mHighlightedIndex); + event.trigger("Item"); setSelectedIndex(mHighlightedIndex); } // If the highlight is on an item then select it. @@ -417,8 +426,11 @@ void ItemContainer::keyAction() // If the highlight is on a blank space then move it. else if (mSelectedIndex != -1) { - Net::getInventoryHandler()->moveItem( - mSelectedIndex, mHighlightedIndex); + Item *item = getSelectedItem(); + Mana::Event event("doMove"); + event.setItem("item", item); + event.setInt("newIndex", mHighlightedIndex); + event.trigger("Item"); selectNone(); } } diff --git a/src/inventory.cpp b/src/inventory.cpp index a6038c85..7684b54c 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -19,6 +19,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "event.h" #include "inventory.h" #include "item.h" #include "log.h" @@ -36,7 +37,7 @@ struct SlotUsed : public std::unary_function<Item*, bool> } }; -Inventory::Inventory(int type, int size): +Inventory::Inventory(Type type, int size): mType(type), mSize(size == -1 ? Net::getInventoryHandler()->getSize(type) : size), mUsed(0) diff --git a/src/inventory.h b/src/inventory.h index 0ee516d6..088dfb8f 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -43,7 +43,7 @@ class Inventory public: static const int NO_SLOT_INDEX = -1; /**< Slot has no index. */ - enum { + enum Type { INVENTORY, STORAGE, TRADE, @@ -56,7 +56,7 @@ class Inventory * * @param size the number of items that fit in the inventory */ - Inventory(int type, int size = -1); + Inventory(Type type, int size = -1); /** * Destructor. @@ -143,7 +143,7 @@ class Inventory void distributeSlotsChangedEvent(); - int mType; + Type mType; Item **mItems; /**< The holder of items */ int mSize; /**< The max number of inventory items */ int mUsed; /**< THe number of slots in use */ diff --git a/src/item.cpp b/src/item.cpp index 6b13dd1b..7a8ccf6d 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -22,6 +22,7 @@ #include "item.h" #include "configuration.h" +#include "event.h" #include "resources/image.h" #include "resources/iteminfo.h" @@ -73,3 +74,18 @@ void Item::setId(int id) paths.getValue("unknownItemFile", "unknown-item.png")); } + +void Item::doEvent(const std::string &eventName) +{ + Mana::Event event(eventName); + event.setItem("item", this); + event.trigger("Item"); +} + +void Item::doEvent(const std::string &eventName, int amount) +{ + Mana::Event event(eventName); + event.setItem("item", this); + event.setInt("amount", amount); + event.trigger("Item"); +} @@ -118,6 +118,10 @@ class Item */ int getInvIndex() const { return mInvIndex; } + void doEvent(const std::string &eventName); + + void doEvent(const std::string &eventName, int amount); + /** * Returns information about this item type. */ diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp index 064fdbc6..eaf16889 100644 --- a/src/itemshortcut.cpp +++ b/src/itemshortcut.cpp @@ -20,6 +20,7 @@ */ #include "configuration.h" +#include "event.h" #include "inventory.h" #include "item.h" #include "itemshortcut.h" @@ -72,14 +73,12 @@ void ItemShortcut::useItem(int index) if (item->isEquipment()) { if (item->isEquipped()) - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); else - Net::getInventoryHandler()->equipItem(item); + item->doEvent("doEquip"); } else - { - Net::getInventoryHandler()->useItem(item); - } + item->doEvent("doUse"); } } } diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 33a07373..4577fd16 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -98,6 +98,8 @@ LocalPlayer::LocalPlayer(int id, int subtype): config.addListener("showownname", this); setShowName(config.getValue("showownname", 1)); + + listen("ActorSprite"); } LocalPlayer::~LocalPlayer() @@ -656,24 +658,16 @@ void LocalPlayer::pickUp(FloorItem *item) { setDestination(item->getPixelX() + 16, item->getPixelY() + 16); mPickUpTarget = item; - mPickUpTarget->addActorSpriteListener(this); } else { setDestination(item->getTileX(), item->getTileY()); mPickUpTarget = item; - mPickUpTarget->addActorSpriteListener(this); stopAttack(); } } } -void LocalPlayer::actorSpriteDestroyed(const ActorSprite &actorSprite) -{ - if (mPickUpTarget == &actorSprite) - mPickUpTarget = 0; -} - Being *LocalPlayer::getTarget() const { return mTarget; @@ -1096,7 +1090,20 @@ void LocalPlayer::optionChanged(const std::string &value) void LocalPlayer::event(const std::string &channel, const Mana::Event &event) { - if (channel == "Attributes") + if (channel == "ActorSprite") + { + if (event.getName() == "Destroyed") + { + ActorSprite *actor = event.getActor("source"); + + if (mPickUpTarget == actor) + mPickUpTarget = 0; + + if (mTarget == actor) + mTarget = 0; + } + } + else if (channel == "Attributes") { if (event.getName() == "UpdateAttribute") { @@ -1109,8 +1116,8 @@ void LocalPlayer::event(const std::string &channel, const Mana::Event &event) } } } - else - Being::event(channel, event); + + Being::event(channel, event); } void LocalPlayer::changeAwayMode() diff --git a/src/localplayer.h b/src/localplayer.h index 2fb93e9b..6b50091a 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -22,9 +22,7 @@ #ifndef LOCALPLAYER_H #define LOCALPLAYER_H -#include "actorspritelistener.h" #include "being.h" -#include "listener.h" #include "resources/userpalette.h" @@ -49,7 +47,7 @@ class AwayListener : public gcn::ActionListener /** * The local player character. */ -class LocalPlayer : public Being, public ActorSpriteListener +class LocalPlayer : public Being { public: /** @@ -96,12 +94,6 @@ class LocalPlayer : public Being, public ActorSpriteListener void pickUp(FloorItem *item); /** - * Called when an ActorSprite has been destroyed. - * @param actorSprite the ActorSprite being destroyed. - */ - void actorSpriteDestroyed(const ActorSprite &actorSprite); - - /** * Sets the attack range. */ void setAttackRange(int range) { mAttackRange = range; } diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h index 91257d3b..93b56a40 100644 --- a/src/net/inventoryhandler.h +++ b/src/net/inventoryhandler.h @@ -34,29 +34,8 @@ class InventoryHandler public: virtual ~InventoryHandler() {} - virtual void equipItem(const Item *item) = 0; - - virtual void unequipItem(const Item *item) = 0; - - virtual void useItem(const Item *item) = 0; - - virtual void dropItem(const Item *item, int amount) = 0; - virtual bool canSplit(const Item *item) = 0; - virtual void splitItem(const Item *item, int amount) = 0; - - virtual void moveItem(int oldIndex, int newIndex) = 0; - - virtual void openStorage(int type) = 0; - - virtual void closeStorage(int type) = 0; - - //void changeCart() = 0; - - virtual void moveItem(int source, int slot, int amount, - int destination) = 0; - // TODO: fix/remove me virtual size_t getSize(int type) const = 0; }; diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index 8622627e..28de9c1e 100644 --- a/src/net/manaserv/inventoryhandler.cpp +++ b/src/net/manaserv/inventoryhandler.cpp @@ -50,6 +50,8 @@ InventoryHandler::InventoryHandler() }; handledMessages = _messages; inventoryHandler = this; + + listen("Item"); } void InventoryHandler::handleMessage(Net::MessageIn &msg) @@ -86,37 +88,87 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) } } -void InventoryHandler::equipItem(const Item *item) -{ - MessageOut msg(PGMSG_EQUIP); - msg.writeInt8(item->getInvIndex()); - gameServerConnection->send(msg); -} - -void InventoryHandler::unequipItem(const Item *item) -{ - MessageOut msg(PGMSG_UNEQUIP); - msg.writeInt8(item->getInvIndex()); - gameServerConnection->send(msg); - - // Tidy equipment directly to avoid weapon still shown bug, for instance - int equipSlot = item->getInvIndex(); - mEquips.setEquipment(equipSlot, 0); -} - -void InventoryHandler::useItem(const Item *item) +void InventoryHandler::event(const std::string &channel, + const Mana::Event &event) { - MessageOut msg(PGMSG_USE_ITEM); - msg.writeInt8(item->getInvIndex()); - gameServerConnection->send(msg); -} + if (channel == "Item") + { + Item *item = event.getItem("item"); + + if (!item) + return; + + int index = item->getInvIndex(); + + if (event.getName() == "doEquip") + { + MessageOut msg(PGMSG_EQUIP); + msg.writeInt8(index); + gameServerConnection->send(msg); + } + else if (event.getName() == "doUnequip") + { + MessageOut msg(PGMSG_UNEQUIP); + msg.writeInt8(index); + gameServerConnection->send(msg); + + // Tidy equipment directly to avoid weapon still shown bug, for instance + mEquips.setEquipment(index, 0); + } + else if (event.getName() == "doUse") + { + MessageOut msg(PGMSG_USE_ITEM); + msg.writeInt8(index); + gameServerConnection->send(msg); + } + else if (event.getName() == "doDrop") + { + int amount = event.getInt("amount", 1); + + MessageOut msg(PGMSG_DROP); + msg.writeInt8(index); + msg.writeInt8(amount); + gameServerConnection->send(msg); + } + else if (event.getName() == "doSplit") + { + int amount = event.getInt("amount", 1); + + int newIndex = PlayerInfo::getInventory()->getFreeSlot(); + if (newIndex > Inventory::NO_SLOT_INDEX) + { + MessageOut msg(PGMSG_MOVE_ITEM); + msg.writeInt8(index); + msg.writeInt8(newIndex); + msg.writeInt8(amount); + gameServerConnection->send(msg); + } + } + else if (event.getName() == "doMove") + { + int newIndex = event.getInt("newIndex", -1); + + if (newIndex >= 0) + { + if (index == newIndex) + return; + + MessageOut msg(PGMSG_MOVE_ITEM); + msg.writeInt8(index); + msg.writeInt8(newIndex); + msg.writeInt8(item->getQuantity()); + gameServerConnection->send(msg); + } + else + { + /*int source = event.getInt("source"); + int destination = event.getInt("destination"); + int amount = event.getInt("amount", 1);*/ -void InventoryHandler::dropItem(const Item *item, int amount) -{ - MessageOut msg(PGMSG_DROP); - msg.writeInt8(item->getInvIndex()); - msg.writeInt8(amount); - gameServerConnection->send(msg); + // TODO + } + } + } } bool InventoryHandler::canSplit(const Item *item) @@ -124,48 +176,6 @@ bool InventoryHandler::canSplit(const Item *item) return item && !item->isEquipment() && item->getQuantity() > 1; } -void InventoryHandler::splitItem(const Item *item, int amount) -{ - int newIndex = PlayerInfo::getInventory()->getFreeSlot(); - if (newIndex > Inventory::NO_SLOT_INDEX) - { - MessageOut msg(PGMSG_MOVE_ITEM); - msg.writeInt8(item->getInvIndex()); - msg.writeInt8(newIndex); - msg.writeInt8(amount); - gameServerConnection->send(msg); - } -} - -void InventoryHandler::moveItem(int oldIndex, int newIndex) -{ - if (oldIndex == newIndex) - return; - - MessageOut msg(PGMSG_MOVE_ITEM); - msg.writeInt8(oldIndex); - msg.writeInt8(newIndex); - msg.writeInt8(PlayerInfo::getInventory()->getItem(oldIndex) - ->getQuantity()); - gameServerConnection->send(msg); -} - -void InventoryHandler::openStorage(int type) -{ - // TODO -} - -void InventoryHandler::closeStorage(int type) -{ - // TODO -} - -void InventoryHandler::moveItem(int source, int slot, int amount, - int destination) -{ - // TODO -} - size_t InventoryHandler::getSize(int type) const { switch (type) diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h index fd08b95e..a1673e99 100644 --- a/src/net/manaserv/inventoryhandler.h +++ b/src/net/manaserv/inventoryhandler.h @@ -23,6 +23,7 @@ #define NET_MANASERV_INVENTORYHANDLER_H #include "equipment.h" +#include "listener.h" #include "net/inventoryhandler.h" @@ -67,34 +68,18 @@ class EquipBackend : public Equipment::Backend Item *mEquipment[EQUIPMENT_SIZE]; }; -class InventoryHandler : public MessageHandler, Net::InventoryHandler +class InventoryHandler : public MessageHandler, Net::InventoryHandler, + public Mana::Listener { public: InventoryHandler(); void handleMessage(Net::MessageIn &msg); - void equipItem(const Item *item); - - void unequipItem(const Item *item); - - void useItem(const Item *item); - - void dropItem(const Item *item, int amount); + void event(const std::string &channel, const Mana::Event &event); bool canSplit(const Item *item); - void splitItem(const Item *item, int amount); - - void moveItem(int oldIndex, int newIndex); - - void openStorage(int type); - - void closeStorage(int type); - - void moveItem(int source, int slot, int amount, - int destination); - size_t getSize(int type) const; private: diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index c1a96788..46eb6258 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -109,6 +109,8 @@ InventoryHandler::InventoryHandler() mStorage = 0; mStorageWindow = 0; + + listen("Item"); } InventoryHandler::~InventoryHandler() @@ -421,41 +423,85 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) } } -void InventoryHandler::equipItem(const Item *item) +void InventoryHandler::event(const std::string &channel, + const Mana::Event &event) { - if (!item) - return; - - MessageOut outMsg(CMSG_PLAYER_EQUIP); - outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET); - outMsg.writeInt16(0); -} + if (channel == "Item") + { + if (event.getName() == "doCloseInventory") + { + // No need to worry about type + MessageOut outMsg(CMSG_CLOSE_STORAGE); + } + else + { + Item *item = event.getItem("item"); -void InventoryHandler::unequipItem(const Item *item) -{ - if (!item) - return; + if (!item) + return; - MessageOut outMsg(CMSG_PLAYER_UNEQUIP); - outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET); -} + int index = item->getInvIndex() + INVENTORY_OFFSET; -void InventoryHandler::useItem(const Item *item) -{ - if (!item) - return; + if (event.getName() == "doEquip") + { + MessageOut outMsg(CMSG_PLAYER_EQUIP); + outMsg.writeInt16(index); + outMsg.writeInt16(0); + } + else if (event.getName() == "doUnequip") + { + MessageOut outMsg(CMSG_PLAYER_UNEQUIP); + outMsg.writeInt16(index); + } + else if (event.getName() == "doUse") + { + MessageOut outMsg(CMSG_PLAYER_INVENTORY_USE); + outMsg.writeInt16(index); + outMsg.writeInt32(item->getId()); // unused + } + else if (event.getName() == "doDrop") + { + int amount = event.getInt("amount", 1); - MessageOut outMsg(CMSG_PLAYER_INVENTORY_USE); - outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET); - outMsg.writeInt32(item->getId()); // unused -} + // TODO: Fix wrong coordinates of drops, serverside? + // (what's wrong here?) + MessageOut outMsg(CMSG_PLAYER_INVENTORY_DROP); + outMsg.writeInt16(index); + outMsg.writeInt16(amount); + } + else if (event.getName() == "doMove") + { + int newIndex = event.getInt("newIndex", -1); -void InventoryHandler::dropItem(const Item *item, int amount) -{ - // TODO: Fix wrong coordinates of drops, serverside? (what's wrong here?) - MessageOut outMsg(CMSG_PLAYER_INVENTORY_DROP); - outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET); - outMsg.writeInt16(amount); + if (newIndex >= 0) + { + // Not implemented for tmwAthena (possible?) + } + else + { + int source = event.getInt("source"); + int destination = event.getInt("destination"); + int amount = event.getInt("amount", 1); + + if (source == Inventory::INVENTORY + && destination == Inventory::STORAGE) + { + MessageOut outMsg(CMSG_MOVE_TO_STORAGE); + outMsg.writeInt16(index); + outMsg.writeInt32(amount); + } + else if (source == Inventory::STORAGE + && destination == Inventory::INVENTORY) + { + MessageOut outMsg(CSMG_MOVE_FROM_STORAGE); + outMsg.writeInt16(index - INVENTORY_OFFSET + + STORAGE_OFFSET); + outMsg.writeInt32(amount); + } + } + } + } + } } bool InventoryHandler::canSplit(const Item *item) @@ -463,43 +509,6 @@ bool InventoryHandler::canSplit(const Item *item) return false; } -void InventoryHandler::splitItem(const Item *item, int amount) -{ - // Not implemented for eAthena (possible?) -} - -void InventoryHandler::moveItem(int oldIndex, int newIndex) -{ - // Not implemented for eAthena (possible?) -} - -void InventoryHandler::openStorage(int type) -{ - // Doesn't apply to eAthena, since opening happens through NPCs? -} - -void InventoryHandler::closeStorage(int type) -{ - MessageOut outMsg(CMSG_CLOSE_STORAGE); -} - -void InventoryHandler::moveItem(int source, int slot, int amount, - int destination) -{ - if (source == Inventory::INVENTORY && destination == Inventory::STORAGE) - { - MessageOut outMsg(CMSG_MOVE_TO_STORAGE); - outMsg.writeInt16(slot + INVENTORY_OFFSET); - outMsg.writeInt32(amount); - } - else if (source == Inventory::STORAGE && destination == Inventory::INVENTORY) - { - MessageOut outMsg(CSMG_MOVE_FROM_STORAGE); - outMsg.writeInt16(slot + STORAGE_OFFSET); - outMsg.writeInt32(amount); - } -} - size_t InventoryHandler::getSize(int type) const { switch (type) diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h index 8e6e12ca..18d73517 100644 --- a/src/net/tmwa/inventoryhandler.h +++ b/src/net/tmwa/inventoryhandler.h @@ -24,6 +24,7 @@ #include "equipment.h" #include "inventory.h" +#include "listener.h" #include "playerinfo.h" #include "gui/inventorywindow.h" @@ -115,7 +116,8 @@ class InventoryItem typedef std::list<InventoryItem> InventoryItems; -class InventoryHandler : public MessageHandler, public Net::InventoryHandler +class InventoryHandler : public MessageHandler, public Net::InventoryHandler, + public Mana::Listener { public: enum { @@ -129,27 +131,10 @@ class InventoryHandler : public MessageHandler, public Net::InventoryHandler void handleMessage(Net::MessageIn &msg); - void equipItem(const Item *item); - - void unequipItem(const Item *item); - - void useItem(const Item *item); - - void dropItem(const Item *item, int amount); + void event(const std::string &channel, const Mana::Event &event); bool canSplit(const Item *item); - void splitItem(const Item *item, int amount); - - void moveItem(int oldIndex, int newIndex); - - void openStorage(int type); - - void closeStorage(int type); - - void moveItem(int source, int slot, int amount, - int destination); - size_t getSize(int type) const; private: diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp index ee7931bd..05ca3f87 100644 --- a/src/net/tmwa/tradehandler.cpp +++ b/src/net/tmwa/tradehandler.cpp @@ -189,7 +189,7 @@ void TradeHandler::handleMessage(Net::MessageIn &msg) // Successfully added item if (item->isEquipment() && item->isEquipped()) { - Net::getInventoryHandler()->unequipItem(item); + item->doEvent("doUnequip"); } tradeWindow->addItem(item->getId(), true, quantity, item->isEquipment()); diff --git a/src/variabledata.h b/src/variabledata.h index f73ebab2..19e09795 100644 --- a/src/variabledata.h +++ b/src/variabledata.h @@ -23,6 +23,9 @@ #include <string> +class ActorSprite; +class Item; + namespace Mana { @@ -35,7 +38,9 @@ class VariableData DATA_INT, DATA_STRING, DATA_FLOAT, - DATA_BOOL + DATA_BOOL, + DATA_ITEM, + DATA_ACTOR }; virtual ~VariableData() {}; @@ -95,6 +100,32 @@ private: bool mData; }; +class ItemData : public VariableData +{ +public: + ItemData(Item *value) { mData = value; } + + Item *getData() const { return mData; } + + int getType() const { return DATA_ITEM; } + +private: + Item *mData; +}; + +class ActorData : public VariableData +{ +public: + ActorData(ActorSprite *value) { mData = value; } + + ActorSprite *getData() const { return mData; } + + int getType() const { return DATA_ACTOR; } + +private: + ActorSprite *mData; +}; + } // namespace Mana #endif |