diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-03-21 19:44:11 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2013-03-25 20:32:37 +0100 |
commit | 4e9e0ac87b4dc16f19ac4f930d52c4cc0a2c6f64 (patch) | |
tree | 1b77436b4623c8c1fc4419758e623753899fd818 /src/game-server | |
parent | 7aeb3b4a6c34a8f679719c207e51394d7e48828b (diff) | |
download | manaserv-4e9e0ac87b4dc16f19ac4f930d52c4cc0a2c6f64.tar.gz manaserv-4e9e0ac87b4dc16f19ac4f930d52c4cc0a2c6f64.tar.xz manaserv-4e9e0ac87b4dc16f19ac4f930d52c4cc0a2c6f64.zip |
Changed NPC to an NpcComponent added to a Being
Diffstat (limited to 'src/game-server')
-rw-r--r-- | src/game-server/actor.h | 18 | ||||
-rw-r--r-- | src/game-server/being.cpp | 2 | ||||
-rw-r--r-- | src/game-server/character.cpp | 4 | ||||
-rw-r--r-- | src/game-server/character.h | 7 | ||||
-rw-r--r-- | src/game-server/component.h | 5 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 13 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 1 | ||||
-rw-r--r-- | src/game-server/monster.h | 7 | ||||
-rw-r--r-- | src/game-server/npc.cpp | 123 | ||||
-rw-r--r-- | src/game-server/npc.h | 83 | ||||
-rw-r--r-- | src/game-server/state.cpp | 10 |
11 files changed, 135 insertions, 138 deletions
diff --git a/src/game-server/actor.h b/src/game-server/actor.h index 13d4af5..83b2c0f 100644 --- a/src/game-server/actor.h +++ b/src/game-server/actor.h @@ -54,7 +54,8 @@ class Actor : public Entity mUpdateFlags(0), mPublicID(65535), mSize(0), - mWalkMask(0) + mWalkMask(0), + mBlockType(BLOCKTYPE_NONE) {} ~Actor(); @@ -126,16 +127,20 @@ class Actor : public Entity { return mWalkMask; } /** + * Gets the way the actor blocks pathfinding for other actors. + */ + BlockType getBlockType() const + { return mBlockType; } + + void setBlockType(BlockType blockType) + { mBlockType = blockType; } + + /** * Overridden in order to update the walkmap. */ virtual void setMap(MapComposite *map); protected: - /** - * Gets the way the actor blocks pathfinding for other actors. - */ - virtual BlockType getBlockType() const - { return BLOCKTYPE_NONE; } /** Delay until move to next tile in miliseconds. */ unsigned short mMoveTime; @@ -150,6 +155,7 @@ class Actor : public Entity unsigned char mSize; /**< Radius of bounding circle. */ unsigned char mWalkMask; + BlockType mBlockType; }; #endif // ACTOR_H diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 66545ff..9112a1b 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -743,6 +743,8 @@ void Being::update() died(); processAttacks(); + + Actor::update(); } void Being::inserted(Entity *) diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index b139f12..8cc0e65 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -97,6 +97,7 @@ Character::Character(MessageIn &msg): mAttributes.insert(std::make_pair(it1->first, Attribute(*it1->second))); setWalkMask(Map::BLOCKMASK_WALL); + setBlockType(BLOCKTYPE_CHARACTER); // Get character data. mDatabaseID = msg.readInt32(); @@ -677,6 +678,9 @@ AttribmodResponseCode Character::useCorrectionPoint(size_t attribute) void Character::startNpcThread(Script::Thread *thread, int npcId) { + if (mNpcThread) + delete mNpcThread; + mNpcThread = thread; mTalkNpcId = npcId; diff --git a/src/game-server/character.h b/src/game-server/character.h index 2b755bd..dc703c8 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -431,13 +431,6 @@ class Character : public Being sigc::signal<void, Character *> signal_disconnected; - protected: - /** - * Gets the way the actor blocks pathfinding for other objects - */ - virtual BlockType getBlockType() const - { return BLOCKTYPE_CHARACTER; } - private: bool specialUseCheck(SpecialMap::iterator it); diff --git a/src/game-server/component.h b/src/game-server/component.h index 90dda5a..740668a 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -26,9 +26,10 @@ class Entity; enum ComponentType { CT_Effect, - CT_TriggerArea, - CT_SpawnArea, CT_Item, + CT_Npc, + CT_SpawnArea, + CT_TriggerArea, ComponentTypeCount }; diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index eeccdcc..51b64a2 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -453,22 +453,25 @@ void GameHandler::handleNpc(GameClient &client, MessageIn &message) return; } - NPC *npc = static_cast<NPC *>(actor); + Being *npc = static_cast<Being*>(actor); + switch (message.getId()) { case PGMSG_NPC_SELECT: - npc->select(client.character, message.readInt8()); + Npc::integerReceived(client.character, message.readInt8()); break; case PGMSG_NPC_NUMBER: - npc->integerReceived(client.character, message.readInt32()); + Npc::integerReceived(client.character, message.readInt32()); break; case PGMSG_NPC_STRING: - npc->stringReceived(client.character, message.readString()); + Npc::stringReceived(client.character, message.readString()); break; case PGMSG_NPC_TALK: + Npc::start(npc, client.character); + break; case PGMSG_NPC_TALK_NEXT: default: - npc->prompt(client.character, message.getId() == PGMSG_NPC_TALK); + Npc::resume(client.character); break; } } diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index edc89ec..ceae82c 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -60,6 +60,7 @@ Monster::Monster(MonsterClass *specy): LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ")."); setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); + setBlockType(BLOCKTYPE_MONSTER); /* * Initialise the attribute structures. diff --git a/src/game-server/monster.h b/src/game-server/monster.h index 8e927f9..e87180d 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -318,13 +318,6 @@ class Monster : public Being */ void forgetTarget(Entity *entity); - protected: - /** - * Returns the way the actor blocks pathfinding for other objects. - */ - virtual BlockType getBlockType() const - { return BLOCKTYPE_MONSTER; } - private: static const int DECAY_TIME = 50; diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp index 2eb7303..788f0c9 100644 --- a/src/game-server/npc.cpp +++ b/src/game-server/npc.cpp @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2007-2010 The Mana World Development Team + * Copyright (C) 2012 The Mana Developers * * This file is part of The Mana Server. * @@ -18,127 +19,109 @@ * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. */ +#include "game-server/npc.h" + #include "game-server/character.h" #include "game-server/gamehandler.h" #include "game-server/map.h" -#include "game-server/npc.h" #include "net/messageout.h" #include "scripting/script.h" #include "scripting/scriptmanager.h" -NPC::NPC(const std::string &name, int id): - Being(OBJECT_NPC), - mID(id), +const ComponentType NpcComponent::type; + +NpcComponent::NpcComponent(int npcId): + mNpcId(npcId), mEnabled(true) { - setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_MONSTER | - Map::BLOCKMASK_CHARACTER); - setName(name); } -NPC::~NPC() +NpcComponent::~NpcComponent() { Script *script = ScriptManager::currentState(); script->unref(mTalkCallback); script->unref(mUpdateCallback); } -void NPC::setEnabled(bool enabled) +void NpcComponent::setEnabled(bool enabled) { mEnabled = enabled; } -void NPC::update() +void NpcComponent::update(Entity &entity) { if (!mEnabled || !mUpdateCallback.isValid()) return; Script *script = ScriptManager::currentState(); script->prepare(mUpdateCallback); - script->push(this); - script->execute(getMap()); + script->push(&entity); + script->execute(entity.getMap()); } -void NPC::prompt(Character *ch, bool restart) +void NpcComponent::setTalkCallback(Script::Ref function) { - if (!mEnabled || !mTalkCallback.isValid()) - return; + ScriptManager::currentState()->unref(mTalkCallback); + mTalkCallback = function; +} - Script *script = ScriptManager::currentState(); +void NpcComponent::setUpdateCallback(Script::Ref function) +{ + ScriptManager::currentState()->unref(mUpdateCallback); + mUpdateCallback = function; +} - if (restart) - { - Script::Thread *thread = script->newThread(); - thread->getContext().map = getMap(); - script->prepare(mTalkCallback); - script->push(this); - script->push(ch); - ch->startNpcThread(thread, getPublicID()); - } - else - { - Script::Thread *thread = ch->getNpcThread(); - if (!thread || thread->mState != Script::ThreadPaused) - return; - script->prepareResume(thread); - ch->resumeNpcThread(); - } -} -void NPC::select(Character *ch, int index) +static Script *prepareResume(Character *ch, Script::ThreadState expectedState) { - if (!mEnabled) - return; - Script::Thread *thread = ch->getNpcThread(); - if (!thread || thread->mState != Script::ThreadExpectingNumber) - return; + if (!thread || thread->mState != expectedState) + return 0; Script *script = ScriptManager::currentState(); script->prepareResume(thread); - script->push(index); - ch->resumeNpcThread(); + return script; } -void NPC::integerReceived(Character *ch, int value) +void Npc::start(Being *npc, Character *ch) { - if (!mEnabled) - return; - - Script::Thread *thread = ch->getNpcThread(); - if (!thread || thread->mState != Script::ThreadExpectingNumber) - return; + NpcComponent *npcComponent = npc->getComponent<NpcComponent>(); Script *script = ScriptManager::currentState(); - script->prepareResume(thread); - script->push(value); - ch->resumeNpcThread(); + Script::Ref talkCallback = npcComponent->getTalkCallback(); + + if (npcComponent->isEnabled() && talkCallback.isValid()) + { + Script::Thread *thread = script->newThread(); + thread->getContext().map = npc->getMap(); + script->prepare(talkCallback); + script->push(npc); + script->push(ch); + ch->startNpcThread(thread, npc->getPublicID()); + } } -void NPC::stringReceived(Character *ch, const std::string &value) +void Npc::resume(Character *ch) { - if (!mEnabled) - return; - - Script::Thread *thread = ch->getNpcThread(); - if (!thread || thread->mState != Script::ThreadExpectingString) - return; - - Script *script = ScriptManager::currentState(); - script->prepareResume(thread); - script->push(value); - ch->resumeNpcThread(); + if (prepareResume(ch, Script::ThreadPaused)) + ch->resumeNpcThread(); } -void NPC::setTalkCallback(Script::Ref function) +void Npc::integerReceived(Character *ch, int value) { - ScriptManager::currentState()->unref(mTalkCallback); - mTalkCallback = function; + if (Script *script = prepareResume(ch, Script::ThreadExpectingNumber)) + { + script->push(value); + ch->resumeNpcThread(); + } } -void NPC::setUpdateCallback(Script::Ref function) +void Npc::stringReceived(Character *ch, const std::string &value) { - ScriptManager::currentState()->unref(mUpdateCallback); - mUpdateCallback = function; + if (Script *script = prepareResume(ch, Script::ThreadExpectingString)) + { + script->push(value); + ch->resumeNpcThread(); + } } diff --git a/src/game-server/npc.h b/src/game-server/npc.h index 49dd4bf..1a0b4e8 100644 --- a/src/game-server/npc.h +++ b/src/game-server/npc.h @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2007-2010 The Mana World Development Team + * Copyright (C) 2012 The Mana Developers * * This file is part of The Mana Server. * @@ -21,26 +22,31 @@ #ifndef GAMESERVER_NPC_H #define GAMESERVER_NPC_H -#include "game-server/being.h" +#include "game-server/component.h" #include "scripting/script.h" class Character; /** - * Class describing a non-player character. + * Component describing a non-player character. */ -class NPC : public Being +class NpcComponent : public Component { public: - NPC(const std::string &name, int id); + static const ComponentType type = CT_Npc; - ~NPC(); + NpcComponent(int npcId); + + ~NpcComponent(); /** * Sets the function that should be called when this NPC is talked to. */ void setTalkCallback(Script::Ref function); + Script::Ref getTalkCallback() const + { return mTalkCallback; } + /** * Sets the function that should be called each update. */ @@ -49,52 +55,57 @@ class NPC : public Being /** * Calls the update callback, if any. */ - void update(); + void update(Entity &entity); /** * Sets whether the NPC is enabled. + * + * When disabling an NPC, it does currently not cancel already started + * conversations with this NPC! */ void setEnabled(bool enabled); - /** - * Prompts NPC. - */ - void prompt(Character *, bool restart); - - /** - * Selects an NPC proposition. - */ - void select(Character *, int index); - - /** - * The player has choosen an integer. - */ - void integerReceived(Character *ch, int value); - - /** - * The player has entered an string. - */ - void stringReceived(Character *ch, const std::string &value); + bool isEnabled() const + { return mEnabled; } /** * Gets NPC ID. */ - int getNPC() const - { return mID; } - - protected: - /** - * Gets the way a monster blocks pathfinding for other objects - */ - virtual BlockType getBlockType() const - { return BLOCKTYPE_CHARACTER; } // blocks like a player character + int getNpcId() const + { return mNpcId; } private: - unsigned short mID; /**< ID of the NPC. */ - bool mEnabled; /**< Whether NPC is enabled */ + int mNpcId; + bool mEnabled; Script::Ref mTalkCallback; Script::Ref mUpdateCallback; }; + +namespace Npc { + +/** + * Starts a conversation with the NPC. + */ +void start(Being *npc, Character *ch); + +/** + * Resumes an NPC conversation. + */ +void resume(Character *ch); + +/** + * The player has made a choice or entered an integer. + */ +void integerReceived(Character *ch, int value); + +/** + * The player has entered an string. + */ +void stringReceived(Character *ch, const std::string &value); + +} // namespace Npc + + #endif // GAMESERVER_NPC_H diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index ab0dcd7..673d48f 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -274,9 +274,9 @@ static void informPlayer(MapComposite *map, Character *p) case OBJECT_NPC: { - NPC *q = static_cast< NPC * >(o); - enterMsg.writeInt16(q->getNPC()); - enterMsg.writeString(q->getName()); + NpcComponent *npcComponent = o->getComponent<NpcComponent>(); + enterMsg.writeInt16(npcComponent->getNpcId()); + enterMsg.writeString(o->getName()); } break; default: @@ -550,7 +550,7 @@ bool GameState::insert(Entity *ptr) break; case OBJECT_NPC: - LOG_DEBUG("NPC inserted: " << static_cast<NPC*>(obj)->getNPC()); + LOG_DEBUG("NPC inserted: " << obj->getComponent<NpcComponent>()->getNpcId()); break; case OBJECT_CHARACTER: @@ -624,7 +624,7 @@ void GameState::remove(Entity *ptr) break; case OBJECT_NPC: - LOG_DEBUG("NPC removed: " << static_cast<NPC*>(ptr)->getNPC()); + LOG_DEBUG("NPC removed: " << ptr->getComponent<NpcComponent>()->getNpcId()); break; case OBJECT_CHARACTER: |