diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/game-server/being.cpp | 27 | ||||
-rw-r--r-- | src/game-server/being.h | 10 | ||||
-rw-r--r-- | src/game-server/character.cpp | 10 | ||||
-rw-r--r-- | src/game-server/character.h | 2 | ||||
-rw-r--r-- | src/game-server/entity.cpp | 47 | ||||
-rw-r--r-- | src/game-server/entity.h | 37 | ||||
-rw-r--r-- | src/game-server/eventlistener.h | 102 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 83 | ||||
-rw-r--r-- | src/game-server/monster.h | 23 | ||||
-rw-r--r-- | src/game-server/quest.cpp | 78 | ||||
-rw-r--r-- | src/game-server/spawnarea.cpp | 20 | ||||
-rw-r--r-- | src/game-server/spawnarea.h | 2 | ||||
-rw-r--r-- | src/game-server/state.cpp | 6 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 6 | ||||
-rw-r--r-- | src/scripting/luascript.cpp | 2 | ||||
-rw-r--r-- | src/scripting/luascript.h | 2 | ||||
-rw-r--r-- | src/scripting/script.cpp | 3 | ||||
-rw-r--r-- | src/scripting/script.h | 22 |
19 files changed, 150 insertions, 337 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a4b38fc..73f969f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ FIND_PACKAGE(LibXml2 REQUIRED) FIND_PACKAGE(PhysFS REQUIRED) FIND_PACKAGE(ZLIB REQUIRED) +FIND_PACKAGE(SigC++ REQUIRED) IF (CMAKE_COMPILER_IS_GNUCXX) # Help getting compilation warnings @@ -93,6 +94,8 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${PHYSFS_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} + ${SigC++_INCLUDE_DIR} + ${SigC++Config_INCLUDE_DIR} ) # Fix some stuff that gets not hidden by mainline modules @@ -214,7 +217,6 @@ SET(SRCS_MANASERVGAME game-server/effect.cpp game-server/entity.h game-server/entity.cpp - game-server/eventlistener.h game-server/gamehandler.h game-server/gamehandler.cpp game-server/inventory.h @@ -315,6 +317,7 @@ FOREACH(program ${PROGRAMS}) ${PHYSFS_LIBRARY} ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES} + ${SigC++_LIBRARIES} ${OPTIONAL_LIBRARIES} ${EXTRA_LIBRARIES}) INSTALL(TARGETS ${program} RUNTIME DESTINATION ${PKG_BINDIR}) diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index ea7540ca..9ce19d76 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -27,7 +27,6 @@ #include "game-server/attributemanager.h" #include "game-server/character.h" #include "game-server/collisiondetection.h" -#include "game-server/eventlistener.h" #include "game-server/mapcomposite.h" #include "game-server/effect.h" #include "game-server/skillmanager.h" @@ -58,6 +57,9 @@ Being::Being(EntityType type): Attribute(*it1->second))); } + + signal_inserted.connect(sigc::mem_fun(this, &Being::inserted)); + // TODO: Way to define default base values? // Should this be handled by the virtual modifiedAttribute? // URGENT either way @@ -177,14 +179,7 @@ void Being::died() // reset target mTarget = NULL; - for (Listeners::iterator i = mListeners.begin(), - i_end = mListeners.end(); i != i_end;) - { - const EventListener &l = **i; - ++i; // In case the listener removes itself from the list on the fly. - if (l.dispatch->died) - l.dispatch->died(&l, this); - } + signal_died.emit(this); } void Being::processAttacks() @@ -512,6 +507,11 @@ bool Being::removeModifier(unsigned attr, double value, unsigned layer, return ret; } +void Being::setGender(BeingGender gender) +{ + mGender = gender; +} + void Being::setAttribute(unsigned id, double value) { AttributeMap::iterator ret = mAttributes.find(id); @@ -743,20 +743,13 @@ void Being::update() processAttacks(); } -void Being::inserted() +void Being::inserted(Entity *) { - Actor::inserted(); - // Reset the old position, since after insertion it is important that it is // in sync with the zone that we're currently present in. mOld = getPosition(); } -void Being::setGender(BeingGender gender) -{ - mGender = gender; -} - void Being::processAttack(Attack &attack) { performAttack(mTarget, attack.getAttackInfo()->getDamage()); diff --git a/src/game-server/being.h b/src/game-server/being.h index 0083be1f..a08df018 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -297,10 +297,7 @@ class Being : public Actor void setTarget(Being *target) { mTarget = target; } - /** - * Overridden in order to reset the old position upon insertion. - */ - virtual void inserted(); + sigc::signal<void, Being *> signal_died; protected: /** @@ -332,6 +329,11 @@ class Being : public Actor Being(const Being &rhs); Being &operator=(const Being &rhs); + /** + * Connected to signal_inserted to reset the old position. + */ + void inserted(Entity *); + Path mPath; BeingDirection mDirection; /**< Facing direction. */ diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 15ba940a..a9777991 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -24,7 +24,6 @@ #include "game-server/accountconnection.h" #include "game-server/attributemanager.h" #include "game-server/buysell.h" -#include "game-server/eventlistener.h" #include "game-server/inventory.h" #include "game-server/item.h" #include "game-server/itemmanager.h" @@ -792,14 +791,7 @@ void Character::disconnected() else GameState::remove(this); - for (Listeners::iterator i = mListeners.begin(), - i_end = mListeners.end(); i != i_end;) - { - const EventListener &l = **i; - ++i; // In case the listener removes itself from the list on the fly. - if (l.dispatch->disconnected) - l.dispatch->disconnected(&l, this); - } + signal_disconnected.emit(this); } bool Character::takeSpecial(int id) diff --git a/src/game-server/character.h b/src/game-server/character.h index 5f3d3a64..d225081b 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -428,6 +428,8 @@ class Character : public Being virtual void removeAttack(AttackInfo *attackInfo); + sigc::signal<void, Character *> signal_disconnected; + protected: /** * Gets the way the actor blocks pathfinding for other objects diff --git a/src/game-server/entity.cpp b/src/game-server/entity.cpp index 671ef5e6..6cb61e58 100644 --- a/src/game-server/entity.cpp +++ b/src/game-server/entity.cpp @@ -18,51 +18,4 @@ * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. */ -#include <cassert> - #include "game-server/entity.h" - -#include "game-server/eventlistener.h" - -Entity::~Entity() -{ - /* As another object will stop listening and call removeListener when it is - deleted, the following assertion ensures that all the calls to - removeListener have been performed will this object was still alive. It - is not strictly necessary, as there are cases where no removal is - performed (e.g. ~SpawnArea). But this is rather exceptional, so keep the - assertion to catch all the other forgotten calls to removeListener. */ - assert(mListeners.empty()); -} - -void Entity::addListener(const EventListener *l) -{ - mListeners.insert(l); -} - -void Entity::removeListener(const EventListener *l) -{ - mListeners.erase(l); -} - -void Entity::inserted() -{ - for (Listeners::iterator i = mListeners.begin(), - i_end = mListeners.end(); i != i_end;) - { - const EventListener &l = **i; - ++i; // In case the listener removes itself from the list on the fly. - if (l.dispatch->inserted) l.dispatch->inserted(&l, this); - } -} - -void Entity::removed() -{ - for (Listeners::iterator i = mListeners.begin(), - i_end = mListeners.end(); i != i_end;) - { - const EventListener &l = **i; - ++i; // In case the listener removes itself from the list on the fly. - if (l.dispatch->removed) l.dispatch->removed(&l, this); - } -} diff --git a/src/game-server/entity.h b/src/game-server/entity.h index 652db7c7..91f13699 100644 --- a/src/game-server/entity.h +++ b/src/game-server/entity.h @@ -23,18 +23,20 @@ #include "common/manaserv_protocol.h" -using namespace ManaServ; - #include <set> -class EventListener; +#include <sigc++/signal.h> +#include <sigc++/trackable.h> + +using namespace ManaServ; + class MapComposite; /** * Base class for in-game objects. Knows only its type and the map it resides * on. Provides listeners. */ -class Entity +class Entity : public sigc::trackable { public: Entity(EntityType type, MapComposite *map = 0) @@ -42,7 +44,7 @@ class Entity mType(type) {} - virtual ~Entity(); + virtual ~Entity() {} /** * Gets type of this entity. @@ -88,29 +90,8 @@ class Entity virtual void setMap(MapComposite *map) { mMap = map; } - /** - * Adds a new listener. - */ - void addListener(const EventListener *); - - /** - * Removes an existing listener. - */ - void removeListener(const EventListener *); - - /** - * Calls all the "inserted" listeners. - */ - virtual void inserted(); - - /** - * Calls all the "removed" listeners. - */ - virtual void removed(); - - protected: - typedef std::set< const EventListener * > Listeners; - Listeners mListeners; /**< List of event listeners. */ + sigc::signal<void, Entity *> signal_inserted; + sigc::signal<void, Entity *> signal_removed; private: MapComposite *mMap; /**< Map the entity is on */ diff --git a/src/game-server/eventlistener.h b/src/game-server/eventlistener.h deleted file mode 100644 index 53d92077..00000000 --- a/src/game-server/eventlistener.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * The Mana Server - * Copyright (C) 2007-2010 The Mana World Development Team - * - * 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 <http://www.gnu.org/licenses/>. - */ - -#ifndef GAMESERVER_EVENTLISTENER_H -#define GAMESERVER_EVENTLISTENER_H - -class Entity; -class Being; -class Character; - -struct EventDispatch; - -/** - * Pointer to a dispatch table. - */ -struct EventListener -{ - const EventDispatch *dispatch; - EventListener(const EventDispatch *d): dispatch(d) {} -}; - -/** - * Dispatch table for event notification. - */ -struct EventDispatch -{ - /** - * Called just after something is inserted in a map. - */ - void (*inserted)(const EventListener *, Entity *); - - /** - * Called just before something is removed from a map. - */ - void (*removed)(const EventListener *, Entity *); - - /** - * Called just after a being has died. - */ - void (*died)(const EventListener *, Being *); - - /** - * Called just before a character is deleted. - */ - void (*disconnected)(const EventListener *, Character *); - - /** - * Initializes dispatch methods as missing. - */ - EventDispatch(): - inserted(0), removed(0), died(0), disconnected(0) - {} -}; - -/** - * Helper for using member functions as dispatch methods. The 3-level structure - * is due to default template parameter not being allowed on functions yet. - * Conceptually, this helper takes two parameters: the name of the member - * variable pointing to the dispatch table and the name of the member function - * to call on dispatch. With these two parameters, it creates a dispatch - * method. When called, this free function forwards the call to the member - * function. - * Pseudo-syntax for getting a dispatch method: - * <code>&EventListenerFactory< _, DispatchPointerName >::create< _, MemberFunctionName >::function</code> - * See the start of the spawnarea.cpp file for a complete example. - */ -template< class T, EventListener T::*D > -struct EventListenerFactory -{ - template< class U, void (T::*F)(U *), class V = U > - struct create - { - static void function(const EventListener *d, V *u) - { - /* Get the address of the T object by substracting the offset of D - from the pointer d. */ - T *t = (T *)((char *)d - - ((char *)&(((T *)42)->*D) - (char *)&(*(T *)42))); - // Then call the method F of this T object. - (t->*F)(u); - } - }; -}; - -#endif diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index cdfe063a..330e3f4f 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -35,18 +35,6 @@ #include <cmath> -struct MonsterTargetEventDispatch: EventDispatch -{ - MonsterTargetEventDispatch() - { - typedef EventListenerFactory<Monster, &Monster::mTargetListener> Factory; - removed = &Factory::create< Entity, &Monster::forgetTarget >::function; - died = &Factory::create<Entity, &Monster::forgetTarget, Being>::function; - } -}; - -static MonsterTargetEventDispatch monsterTargetEventDispatch; - MonsterClass::~MonsterClass() { for (std::vector<AttackInfo *>::iterator it = mAttacks.begin(), @@ -67,7 +55,6 @@ double MonsterClass::getVulnerability(Element element) const Monster::Monster(MonsterClass *specy): Being(OBJECT_MONSTER), mSpecy(specy), - mTargetListener(&monsterTargetEventDispatch), mOwner(NULL) { LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ")."); @@ -137,12 +124,6 @@ Monster::Monster(MonsterClass *specy): Monster::~Monster() { - // Remove death listeners. - for (std::map<Being *, int>::iterator i = mAnger.begin(), - i_end = mAnger.end(); i != i_end; ++i) - { - i->first->removeListener(&mTargetListener); - } } void Monster::update() @@ -229,11 +210,11 @@ void Monster::refreshTarget() // Determine how much we hate the target int targetPriority = 0; - std::map<Being *, int, std::greater<Being *> >::iterator angerIterator; - angerIterator = mAnger.find(target); + std::map<Being *, AggressionInfo>::iterator angerIterator = mAnger.find(target); if (angerIterator != mAnger.end()) { - targetPriority = angerIterator->second; + const AggressionInfo &aggressionInfo = angerIterator->second; + targetPriority = aggressionInfo.anger; } else if (mSpecy->isAggressive()) { @@ -359,11 +340,15 @@ int Monster::calculatePositionPriority(Point position, int targetPriority) } } -void Monster::forgetTarget(Entity *t) +void Monster::forgetTarget(Entity *entity) { - Being *b = static_cast< Being * >(t); + Being *b = static_cast< Being * >(entity); + { + AggressionInfo &aggressionInfo = mAnger[b]; + aggressionInfo.removedConnection.disconnect(); + aggressionInfo.diedConnection.disconnect(); + } mAnger.erase(b); - b->removeListener(&mTargetListener); if (b->getType() == OBJECT_CHARACTER) { @@ -375,20 +360,42 @@ void Monster::forgetTarget(Entity *t) void Monster::changeAnger(Actor *target, int amount) { - if (target && (target->getType() == OBJECT_MONSTER - || target->getType() == OBJECT_CHARACTER)) + const EntityType type = target->getType(); + if (type != OBJECT_MONSTER && type != OBJECT_CHARACTER) + return; + + Being *being = static_cast< Being * >(target); + + if (mAnger.find(being) != mAnger.end()) { - Being *t = static_cast< Being * >(target); - if (mAnger.find(t) != mAnger.end()) - { - mAnger[t] += amount; - } - else - { - mAnger[t] = amount; - t->addListener(&mTargetListener); - } + mAnger[being].anger += amount; + } + else + { + AggressionInfo &aggressionInfo = mAnger[being]; + aggressionInfo.anger = amount; + + // Forget target either when it's removed or died, whichever + // happens first. + aggressionInfo.removedConnection = + being->signal_removed.connect(sigc::mem_fun(this, &Monster::forgetTarget)); + aggressionInfo.diedConnection = + being->signal_died.connect(sigc::mem_fun(this, &Monster::forgetTarget)); + } +} + +std::map<Being *, int> Monster::getAngerList() const +{ + std::map<Being *, int> result; + std::map<Being *, AggressionInfo>::const_iterator i, i_end; + + for (i = mAnger.begin(), i_end = mAnger.end(); i != i_end; ++i) + { + const AggressionInfo &aggressionInfo = i->second; + result.insert(std::make_pair(i->first, aggressionInfo.anger)); } + + return result; } int Monster::damage(Actor *source, const Damage &damage) @@ -399,9 +406,7 @@ int Monster::damage(Actor *source, const Damage &damage) newDamage.delta = newDamage.delta * factor; int HPLoss = Being::damage(source, newDamage); if (source) - { changeAnger(source, HPLoss); - } if (HPLoss && source && source->getType() == OBJECT_CHARACTER) { diff --git a/src/game-server/monster.h b/src/game-server/monster.h index 73fec6aa..3313345c 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -22,7 +22,6 @@ #define MONSTER_H #include "game-server/being.h" -#include "game-server/eventlistener.h" #include "common/defines.h" #include "scripting/script.h" #include "utils/string.h" @@ -31,6 +30,9 @@ #include <vector> #include <string> +#include <sigc++/connection.h> + +class Character; class ItemClass; class Script; @@ -315,8 +317,7 @@ class Monster : public Being */ void changeAnger(Actor *target, int amount); - const std::map<Being *, int> &getAngerList() const - { return mAnger; } + std::map<Being *, int> getAngerList() const; /** * Calls the damage function in Being and updates the aggro list @@ -326,7 +327,7 @@ class Monster : public Being /** * Removes a being from the anger list. */ - void forgetTarget(Entity *being); + void forgetTarget(Entity *entity); /** * Called when an attribute modifier is changed. @@ -351,10 +352,16 @@ class Monster : public Being MonsterClass *mSpecy; /** Aggression towards other beings. */ - std::map<Being *, int> mAnger; - - /** Listener for updating the anger list. */ - EventListener mTargetListener; + struct AggressionInfo { + AggressionInfo() + : anger(0) + {} + + int anger; + sigc::connection removedConnection; + sigc::connection diedConnection; + }; + std::map<Being *, AggressionInfo> mAnger; /** * Character who currently owns this monster (killsteal protection). diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp index 4d659227..c28a4213 100644 --- a/src/game-server/quest.cpp +++ b/src/game-server/quest.cpp @@ -18,24 +18,27 @@ * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. */ -#include <cassert> -#include <list> -#include <map> -#include <string> - #include "game-server/quest.h" #include "game-server/accountconnection.h" #include "game-server/character.h" -#include "game-server/eventlistener.h" #include "utils/logger.h" +#include <cassert> +#include <list> +#include <map> +#include <string> + +#include <sigc++/connection.h> + typedef std::list< QuestCallback * > QuestCallbacks; typedef std::map< std::string, QuestCallbacks > PendingVariables; struct PendingQuest { Character *character; + sigc::connection removedConnection; + sigc::connection disconnectedConnection; PendingVariables variables; }; @@ -72,22 +75,6 @@ void setQuestVar(Character *ch, const std::string &name, accountHandler->updateCharacterVar(ch, name, value); } -/** - * Listener for deleting related quests when a character disappears. - */ -struct QuestDeathListener: EventDispatch -{ - static void partialRemove(const EventListener *, Entity *); - - static void fullRemove(const EventListener *, Character *); - - QuestDeathListener() - { - removed = &partialRemove; - disconnected = &fullRemove; - } -}; - void QuestRefCallback::triggerCallback(Character *ch, const std::string &value) const { @@ -103,10 +90,7 @@ void QuestRefCallback::triggerCallback(Character *ch, s->execute(); } -static QuestDeathListener questDeathDummy; -static EventListener questDeathListener(&questDeathDummy); - -void QuestDeathListener::partialRemove(const EventListener *, Entity *t) +static void partialRemove(Entity *t) { int id = static_cast< Character * >(t)->getDatabaseID(); PendingVariables &variables = pendingQuests[id].variables; @@ -119,11 +103,18 @@ void QuestDeathListener::partialRemove(const EventListener *, Entity *t) // The listener is kept in case a fullRemove is needed later. } -void QuestDeathListener::fullRemove(const EventListener *, Character *ch) +static void fullRemove(Character *ch) { - ch->removeListener(&questDeathListener); + int id = ch->getDatabaseID(); + + { + PendingQuest &pendingQuest = pendingQuests[id]; + pendingQuest.removedConnection.disconnect(); + pendingQuest.disconnectedConnection.disconnect(); + } + // Remove anything related to this character. - pendingQuests.erase(ch->getDatabaseID()); + pendingQuests.erase(id); } void recoverQuestVar(Character *ch, const std::string &name, @@ -134,11 +125,19 @@ void recoverQuestVar(Character *ch, const std::string &name, PendingQuests::iterator i = pendingQuests.lower_bound(id); if (i == pendingQuests.end() || i->first != id) { - i = pendingQuests.insert(i, std::make_pair(id, PendingQuest())); - i->second.character = ch; - /* Register a listener, because we cannot afford to get invalid - pointers, when we finally recover the variable. */ - ch->addListener(&questDeathListener); + PendingQuest pendingQuest; + pendingQuest.character = ch; + + /* Connect to removed and disconnected signals, because we cannot + * afford to get invalid pointers, when we finally recover the + * variable. + */ + pendingQuest.removedConnection = + ch->signal_removed.connect(sigc::ptr_fun(partialRemove)); + pendingQuest.disconnectedConnection = + ch->signal_disconnected.connect(sigc::ptr_fun(fullRemove)); + + i = pendingQuests.insert(i, std::make_pair(id, pendingQuest)); } i->second.variables[name].push_back(f); accountHandler->requestCharacterVar(ch, name); @@ -149,12 +148,14 @@ void recoveredQuestVar(int id, const std::string &value) { PendingQuests::iterator i = pendingQuests.find(id); - if (i == pendingQuests.end()) return; + if (i == pendingQuests.end()) + return; - Character *ch = i->second.character; - ch->removeListener(&questDeathListener); + PendingQuest &pendingQuest = i->second; + pendingQuest.removedConnection.disconnect(); + pendingQuest.disconnectedConnection.disconnect(); - PendingVariables &variables = i->second.variables; + PendingVariables &variables = pendingQuest.variables; PendingVariables::iterator j = variables.find(name); if (j == variables.end()) { @@ -162,6 +163,7 @@ void recoveredQuestVar(int id, return; } + Character *ch = pendingQuest.character; ch->questCache[name] = value; // Call the registered callbacks. diff --git a/src/game-server/spawnarea.cpp b/src/game-server/spawnarea.cpp index 155d4c0d..73dca6b2 100644 --- a/src/game-server/spawnarea.cpp +++ b/src/game-server/spawnarea.cpp @@ -25,18 +25,6 @@ #include "game-server/state.h" #include "utils/logger.h" -struct SpawnAreaEventDispatch : EventDispatch -{ - SpawnAreaEventDispatch() - { - typedef EventListenerFactory< SpawnArea, &SpawnArea::mSpawnedListener > - Factory; - removed = &Factory::create< Entity, &SpawnArea::decrease >::function; - } -}; - -static SpawnAreaEventDispatch spawnAreaEventDispatch; - SpawnArea::SpawnArea(MapComposite *map, MonsterClass *specy, const Rectangle &zone, @@ -44,7 +32,6 @@ SpawnArea::SpawnArea(MapComposite *map, int spawnRate): Entity(OBJECT_OTHER, map), mSpecy(specy), - mSpawnedListener(&spawnAreaEventDispatch), mZone(zone), mMaxBeings(maxBeings), mSpawnRate(spawnRate), @@ -102,7 +89,9 @@ void SpawnArea::update() if (c) { - being->addListener(&mSpawnedListener); + being->signal_removed.connect( + sigc::mem_fun(this, &SpawnArea::decrease)); + being->setMap(map); being->setPosition(position); being->clearDestination(); @@ -125,8 +114,7 @@ void SpawnArea::update() } } -void SpawnArea::decrease(Entity *t) +void SpawnArea::decrease(Entity *) { --mNumBeings; - t->removeListener(&mSpawnedListener); } diff --git a/src/game-server/spawnarea.h b/src/game-server/spawnarea.h index cc0642f1..628c072e 100644 --- a/src/game-server/spawnarea.h +++ b/src/game-server/spawnarea.h @@ -21,7 +21,6 @@ #ifndef SPAWNAREA_H #define SPAWNAREA_H -#include "game-server/eventlistener.h" #include "game-server/entity.h" #include "utils/point.h" @@ -47,7 +46,6 @@ class SpawnArea : public Entity private: MonsterClass *mSpecy; /**< Specy of monster that spawns in this area. */ - EventListener mSpawnedListener; /**< Tracking of spawned monsters. */ Rectangle mZone; int mMaxBeings; /**< Maximum population of this area. */ int mSpawnRate; /**< Number of beings spawning per minute. */ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index ede94f86..a688caca 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -498,7 +498,7 @@ bool GameState::insert(Entity *ptr) if (!ptr->isVisible()) { map->insert(ptr); - ptr->inserted(); + ptr->signal_inserted.emit(ptr); return true; } @@ -523,7 +523,7 @@ bool GameState::insert(Entity *ptr) return false; } - obj->inserted(); + obj->signal_inserted.emit(obj); // DEBUG INFO switch (obj->getType()) @@ -596,7 +596,7 @@ void GameState::remove(Entity *ptr) MapComposite *map = ptr->getMap(); int visualRange = Configuration::getValue("game_visualRange", 448); - ptr->removed(); + ptr->signal_removed.emit(ptr); // DEBUG INFO switch (ptr->getType()) diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 545e365e..880216d2 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1709,7 +1709,11 @@ static int chr_get_post(lua_State *s) static int being_register(lua_State *s) { Being *being = checkBeing(s, 1); - being->addListener(getScript(s)->getScriptListener()); + Script *script = getScript(s); + + being->signal_died.connect(sigc::mem_fun(script, &Script::processDeathEvent)); + being->signal_removed.connect(sigc::mem_fun(script, &Script::processRemoveEvent)); + return 0; } diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index 4104bc89..f4ea39ac 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -265,8 +265,6 @@ void LuaScript::processRemoveEvent(Entity *entity) // being. This might be very interesting for scripting quests. execute(); } - - entity->removeListener(getScriptListener()); } /** diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h index 7631d982..9515bf0e 100644 --- a/src/scripting/luascript.h +++ b/src/scripting/luascript.h @@ -28,6 +28,8 @@ extern "C" { #include "scripting/script.h" +class Character; + /** * Implementation of the Script class for Lua. */ diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp index 3e299461..63ab7ff4 100644 --- a/src/scripting/script.cpp +++ b/src/scripting/script.cpp @@ -40,8 +40,7 @@ Script::Ref Script::mUpdateCallback; Script::Script(): mCurrentThread(0), - mMap(0), - mEventListener(&scriptEventDispatch) + mMap(0) {} Script::~Script() diff --git a/src/scripting/script.h b/src/scripting/script.h index 238bc34c..8dee23a9 100644 --- a/src/scripting/script.h +++ b/src/scripting/script.h @@ -23,19 +23,21 @@ #include "common/inventorydata.h" #include "common/manaserv_protocol.h" -#include "game-server/eventlistener.h" #include <list> #include <string> #include <vector> +#include <sigc++/trackable.h> + +class Being; class MapComposite; class Entity; /** * Abstract interface for calling functions written in an external language. */ -class Script +class Script : public sigc::trackable { public: /** @@ -216,9 +218,6 @@ class Script MapComposite *getMap() const { return mMap; } - EventListener *getScriptListener() - { return &mEventListener; } - virtual void processDeathEvent(Being *entity) = 0; virtual void processRemoveEvent(Entity *entity) = 0; @@ -235,7 +234,6 @@ class Script private: MapComposite *mMap; - EventListener mEventListener; /**< Tracking of being deaths. */ std::vector<Thread*> mThreads; static Ref mCreateNpcDelayedCallback; @@ -245,16 +243,4 @@ class Script friend class Thread; }; -struct ScriptEventDispatch: EventDispatch -{ - ScriptEventDispatch() - { - typedef EventListenerFactory< Script, &Script::mEventListener > Factory; - died = &Factory::create< Being, &Script::processDeathEvent >::function; - removed = &Factory::create< Entity, &Script::processRemoveEvent >::function; - } -}; - -static ScriptEventDispatch scriptEventDispatch; - #endif // SCRIPTING_SCRIPT_H |