summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-03-09 21:30:42 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-03-10 18:07:29 +0100
commit78c912fb4007c3e5f0b43de02646772acb21ecf2 (patch)
treee45409ff061de75b0e4273763a87f5a25de6a65b /src/game-server
parent2fa7d1f39b24714ee6dc72b6b9e61ec5a1997724 (diff)
downloadmanaserv-78c912fb4007c3e5f0b43de02646772acb21ecf2.tar.gz
manaserv-78c912fb4007c3e5f0b43de02646772acb21ecf2.tar.bz2
manaserv-78c912fb4007c3e5f0b43de02646772acb21ecf2.tar.xz
manaserv-78c912fb4007c3e5f0b43de02646772acb21ecf2.zip
Moved the managing of NPC script coroutines into C++
Rather than wrapping NPC functions up in coroutines in the Lua side, they are now managed on the C++ side as "script threads", which are essentially the same thing. The main purpose is that the server can now know whether any of these long running script interactions are still active, which will probably be useful when adding the ability to reload scripts. Reviewed-by: Erik Schilling
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/autoattack.h2
-rw-r--r--src/game-server/character.cpp8
-rw-r--r--src/game-server/character.h9
-rw-r--r--src/game-server/npc.cpp106
-rw-r--r--src/game-server/npc.h27
-rw-r--r--src/game-server/postman.h7
-rw-r--r--src/game-server/quest.cpp5
-rw-r--r--src/game-server/quest.h6
8 files changed, 102 insertions, 68 deletions
diff --git a/src/game-server/autoattack.h b/src/game-server/autoattack.h
index e7b853d3..a1e22aee 100644
--- a/src/game-server/autoattack.h
+++ b/src/game-server/autoattack.h
@@ -26,8 +26,6 @@
#include "common/defines.h"
-#include "game-server/skillmanager.h"
-
/**
* Structure that describes the severity and nature of an attack a being can
* be hit by.
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index 14b49bca..bf16e268 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -85,7 +85,8 @@ Character::Character(MessageIn &msg):
mUpdateLevelProgress(false),
mRecalculateLevel(true),
mParty(0),
- mTransaction(TRANS_NONE)
+ mTransaction(TRANS_NONE),
+ mNpcThread(0)
{
const AttributeManager::AttributeScope &attr =
attributeManager->getAttributeScope(CharacterScope);
@@ -111,6 +112,11 @@ Character::Character(MessageIn &msg):
giveSpecial(3);
}
+Character::~Character()
+{
+ delete mNpcThread;
+}
+
void Character::update()
{
// First, deal with being generic updates
diff --git a/src/game-server/character.h b/src/game-server/character.h
index 76498421..1b31c611 100644
--- a/src/game-server/character.h
+++ b/src/game-server/character.h
@@ -62,6 +62,8 @@ class Character : public Being
*/
Character(MessageIn &msg);
+ ~Character();
+
/**
* recalculates the level when necessary and calls Being::update
*/
@@ -346,6 +348,12 @@ class Character : public Being
void setCorrectionPoints(int points) { mCorrectionPoints = points; }
int getCorrectionPoints() const { return mCorrectionPoints; }
+ void setNpcThread(Script::Thread *thread)
+ { mNpcThread = thread; }
+
+ Script::Thread *getNpcThread() const
+ { return mNpcThread; }
+
/**
* Gets the way the actor is blocked by other things on the map
*/
@@ -464,6 +472,7 @@ class Character : public Being
int mParty; /**< Party id of the character */
TransactionType mTransaction; /**< Trade/buy/sell action the character is involved in. */
std::map<int, int> mKillCount; /**< How many monsters the character has slain of each type */
+ Script::Thread *mNpcThread; /**< Script thread executing NPC interaction, if any */
static Script::Ref mDeathCallback;
static Script::Ref mDeathAcceptedCallback;
diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp
index 052b296e..aa032c98 100644
--- a/src/game-server/npc.cpp
+++ b/src/game-server/npc.cpp
@@ -21,17 +21,13 @@
#include "game-server/character.h"
#include "game-server/npc.h"
#include "scripting/script.h"
+#include "scripting/scriptmanager.h"
Script::Ref NPC::mStartCallback;
-Script::Ref NPC::mNextCallback;
-Script::Ref NPC::mChooseCallback;
-Script::Ref NPC::mIntegerCallback;
-Script::Ref NPC::mStringCallback;
Script::Ref NPC::mUpdateCallback;
-NPC::NPC(const std::string &name, int id, Script *s):
+NPC::NPC(const std::string &name, int id):
Being(OBJECT_NPC),
- mScript(s),
mID(id),
mEnabled(true)
{
@@ -45,53 +41,89 @@ void NPC::enable(bool enabled)
void NPC::update()
{
- if (!mScript || !mEnabled || !mUpdateCallback.isValid())
+ if (!mEnabled || !mUpdateCallback.isValid())
return;
- mScript->prepare(mUpdateCallback);
- mScript->push(this);
- mScript->execute();
+
+ Script *script = ScriptManager::currentState();
+ script->prepare(mUpdateCallback);
+ script->push(this);
+ script->execute();
}
void NPC::prompt(Character *ch, bool restart)
{
- if (!mScript || !mEnabled || !mStartCallback.isValid()
- || !mNextCallback.isValid())
+ if (!mEnabled || !mStartCallback.isValid())
return;
- mScript->prepare(restart ? mStartCallback : mNextCallback);
- mScript->push(this);
- mScript->push(ch);
- mScript->execute();
+
+ Script *script = ScriptManager::currentState();
+
+ if (restart)
+ {
+ Script::Thread *thread = script->newThread();
+ thread->mMap = getMap();
+ script->prepare(mStartCallback);
+ script->push(this);
+ script->push(ch);
+
+ if (!script->resume())
+ ch->setNpcThread(thread);
+ }
+ else
+ {
+ Script::Thread *thread = ch->getNpcThread();
+ if (!thread || thread->mState != Script::ThreadPaused)
+ return;
+
+ script->prepareResume(thread);
+ if (script->resume())
+ ch->setNpcThread(0);
+ }
}
-void NPC::select(Character *ch, int v)
+void NPC::select(Character *ch, int index)
{
- if (!mScript || !mEnabled || !mChooseCallback.isValid())
+ if (!mEnabled)
+ return;
+
+ Script::Thread *thread = ch->getNpcThread();
+ if (!thread || thread->mState != Script::ThreadExpectingNumber)
return;
- mScript->prepare(mChooseCallback);
- mScript->push(this);
- mScript->push(ch);
- mScript->push(v);
- mScript->execute();
+
+ Script *script = ScriptManager::currentState();
+ script->prepareResume(thread);
+ script->push(index);
+ if (script->resume())
+ ch->setNpcThread(0);
}
-void NPC::integerReceived(Character *ch, int v)
+void NPC::integerReceived(Character *ch, int value)
{
- if (!mScript || !mEnabled || !mIntegerCallback.isValid())
+ if (!mEnabled)
+ return;
+
+ Script::Thread *thread = ch->getNpcThread();
+ if (!thread || thread->mState != Script::ThreadExpectingNumber)
return;
- mScript->prepare(mIntegerCallback);
- mScript->push(this);
- mScript->push(ch);
- mScript->push(v);
- mScript->execute();
+
+ Script *script = ScriptManager::currentState();
+ script->prepareResume(thread);
+ script->push(value);
+ if (script->resume())
+ ch->setNpcThread(0);
}
-void NPC::stringReceived(Character *ch, const std::string &v)
+void NPC::stringReceived(Character *ch, const std::string &value)
{
- if (!mScript || !mEnabled || !mStringCallback.isValid())
+ if (!mEnabled)
return;
- mScript->prepare(mStringCallback);
- mScript->push(this);
- mScript->push(ch);
- mScript->push(v);
- mScript->execute();
+
+ Script::Thread *thread = ch->getNpcThread();
+ if (!thread || thread->mState != Script::ThreadExpectingString)
+ return;
+
+ Script *script = ScriptManager::currentState();
+ script->prepareResume(thread);
+ script->push(value);
+ if (script->resume())
+ ch->setNpcThread(0);
}
diff --git a/src/game-server/npc.h b/src/game-server/npc.h
index 1ca6b1bb..4bff9af0 100644
--- a/src/game-server/npc.h
+++ b/src/game-server/npc.h
@@ -32,7 +32,7 @@ class Character;
class NPC : public Being
{
public:
- NPC(const std::string &name, int id, Script *);
+ NPC(const std::string &name, int id);
void update();
@@ -49,17 +49,17 @@ class NPC : public Being
/**
* Selects an NPC proposition.
*/
- void select(Character *, int);
+ void select(Character *, int index);
/**
* The player has choosen an integer.
*/
- void integerReceived(Character *ch, int v);
+ void integerReceived(Character *ch, int value);
/**
* The player has entered an string.
*/
- void stringReceived(Character *ch, const std::string &v);
+ void stringReceived(Character *ch, const std::string &value);
/**
* Gets NPC ID.
@@ -76,18 +76,6 @@ class NPC : public Being
static void setStartCallback(Script *script)
{ script->assignCallback(mStartCallback); }
- static void setNextCallback(Script *script)
- { script->assignCallback(mNextCallback); }
-
- static void setChooseCallback(Script *script)
- { script->assignCallback(mChooseCallback); }
-
- static void setIntegerCallback(Script *script)
- { script->assignCallback(mIntegerCallback); }
-
- static void setStringCallback(Script *script)
- { script->assignCallback(mStringCallback); }
-
static void setUpdateCallback(Script *script)
{ script->assignCallback(mUpdateCallback); }
@@ -99,16 +87,11 @@ class NPC : public Being
{ return BLOCKTYPE_CHARACTER; } // blocks like a player character
private:
- Script *mScript; /**< Script describing NPC behavior. */
unsigned short mID; /**< ID of the NPC. */
bool mEnabled; /**< Whether NPC is enabled */
static Script::Ref mStartCallback;
- static Script::Ref mNextCallback;
- static Script::Ref mChooseCallback;
- static Script::Ref mIntegerCallback;
- static Script::Ref mStringCallback;
static Script::Ref mUpdateCallback;
};
-#endif
+#endif // GAMESERVER_NPC_H
diff --git a/src/game-server/postman.h b/src/game-server/postman.h
index 5669ebef..b9cf7bb2 100644
--- a/src/game-server/postman.h
+++ b/src/game-server/postman.h
@@ -29,8 +29,11 @@ class Script;
struct PostCallback
{
- void (*handler)(Character *, const std::string &sender,
- const std::string &letter, Script *script);
+ void (*handler)(Character *,
+ const std::string &sender,
+ const std::string &letter,
+ Script *);
+
Script *script;
};
diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp
index 974fc4ce..3b415fe0 100644
--- a/src/game-server/quest.cpp
+++ b/src/game-server/quest.cpp
@@ -129,7 +129,8 @@ void recoverQuestVar(Character *ch, const std::string &name,
accountHandler->requestCharacterVar(ch, name);
}
-void recoveredQuestVar(int id, const std::string &name,
+void recoveredQuestVar(int id,
+ const std::string &name,
const std::string &value)
{
PendingQuests::iterator i = pendingQuests.find(id);
@@ -152,7 +153,7 @@ void recoveredQuestVar(int id, const std::string &name,
for (QuestCallbacks::const_iterator k = j->second.begin(),
k_end = j->second.end(); k != k_end; ++k)
{
- k->handler(ch, name, value, k->script);
+ k->handler(ch, value, k->script);
}
variables.erase(j);
diff --git a/src/game-server/quest.h b/src/game-server/quest.h
index 86d2be46..0125e84b 100644
--- a/src/game-server/quest.h
+++ b/src/game-server/quest.h
@@ -28,8 +28,10 @@ class Script;
struct QuestCallback
{
- void (*handler)(Character *, const std::string &name,
- const std::string &value, Script *script);
+ void (*handler)(Character *,
+ const std::string &value,
+ Script *script);
+
Script *script;
};