summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
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;
};