summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2012-07-17 22:01:54 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2012-07-17 22:01:54 +0200
commit538b81540c7e04c5b1793d50aaf9ac8958878524 (patch)
tree3e91d482f341fffc4addacd96112407af2db50e6 /src
parent9091c129381ae18831707a5005c8c7626408298b (diff)
parent7a72ec38d336ed56d2759795d4b9db59b76868b8 (diff)
downloadmanaserv-538b81540c7e04c5b1793d50aaf9ac8958878524.tar.gz
manaserv-538b81540c7e04c5b1793d50aaf9ac8958878524.tar.bz2
manaserv-538b81540c7e04c5b1793d50aaf9ac8958878524.tar.xz
manaserv-538b81540c7e04c5b1793d50aaf9ac8958878524.zip
Merge branch 'master' into lpc2012
Conflicts: src/game-server/character.h
Diffstat (limited to 'src')
-rw-r--r--src/common/manaserv_protocol.h1
-rw-r--r--src/game-server/character.cpp1
-rw-r--r--src/game-server/monster.h3
-rw-r--r--src/game-server/quest.cpp22
-rw-r--r--src/game-server/quest.h55
-rw-r--r--src/scripting/lua.cpp99
6 files changed, 168 insertions, 13 deletions
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h
index 9feedfd9..4bac0837 100644
--- a/src/common/manaserv_protocol.h
+++ b/src/common/manaserv_protocol.h
@@ -185,6 +185,7 @@ enum {
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
GPMSG_CREATE_EFFECT_POS = 0x0320, // W effect id, W*2 position
GPMSG_CREATE_EFFECT_BEING = 0x0321, // W effect id, W BeingID
+ GPMSG_CREATE_TEXT_PARTICLE = 0x0322, // S text
GPMSG_SHAKE = 0x0330, // W intensityX, W intensityY, [W decay_times_10000, [W duration]]
// Guild
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index b0993afa..edd8e681 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -67,7 +67,6 @@ static bool executeCallback(Script::Ref function, Character *character)
script->prepare(function);
script->push(character);
script->execute();
- script->setMap(0);
return true;
}
diff --git a/src/game-server/monster.h b/src/game-server/monster.h
index 8e87d758..a1a82eb5 100644
--- a/src/game-server/monster.h
+++ b/src/game-server/monster.h
@@ -315,6 +315,9 @@ class Monster : public Being
*/
void changeAnger(Actor *target, int amount);
+ const std::map<Being *, int> &getAngerList() const
+ { return mAnger; }
+
/**
* Calls the damage function in Being and updates the aggro list
*/
diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp
index c4cce8e4..4d659227 100644
--- a/src/game-server/quest.cpp
+++ b/src/game-server/quest.cpp
@@ -30,7 +30,7 @@
#include "game-server/eventlistener.h"
#include "utils/logger.h"
-typedef std::list< QuestCallback > QuestCallbacks;
+typedef std::list< QuestCallback * > QuestCallbacks;
typedef std::map< std::string, QuestCallbacks > PendingVariables;
struct PendingQuest
@@ -88,6 +88,21 @@ struct QuestDeathListener: EventDispatch
}
};
+void QuestRefCallback::triggerCallback(Character *ch,
+ const std::string &value) const
+{
+ if (!mRef.isValid())
+ return;
+
+ Script *s = ScriptManager::currentState();
+ s->setMap(ch->getMap());
+ s->prepare(mRef);
+ s->push(ch);
+ s->push(mQuestName);
+ s->push(value);
+ s->execute();
+}
+
static QuestDeathListener questDeathDummy;
static EventListener questDeathListener(&questDeathDummy);
@@ -112,7 +127,7 @@ void QuestDeathListener::fullRemove(const EventListener *, Character *ch)
}
void recoverQuestVar(Character *ch, const std::string &name,
- const QuestCallback &f)
+ QuestCallback *f)
{
assert(ch->questCache.find(name) == ch->questCache.end());
int id = ch->getDatabaseID();
@@ -153,7 +168,8 @@ void recoveredQuestVar(int id,
for (QuestCallbacks::const_iterator k = j->second.begin(),
k_end = j->second.end(); k != k_end; ++k)
{
- k->handler(ch, value, k->script);
+ (*k)->triggerCallback(ch, value);
+ delete (*k);
}
variables.erase(j);
diff --git a/src/game-server/quest.h b/src/game-server/quest.h
index 0125e84b..05caa6ab 100644
--- a/src/game-server/quest.h
+++ b/src/game-server/quest.h
@@ -23,16 +23,58 @@
#include <string>
+#include "scripting/scriptmanager.h"
+
class Character;
class Script;
-struct QuestCallback
+
+class QuestCallback
{
- void (*handler)(Character *,
- const std::string &value,
- Script *script);
+ public:
+ virtual ~QuestCallback()
+ { }
+
+ virtual void triggerCallback(Character *ch,
+ const std::string &value) const = 0;
+};
+
+class QuestThreadCallback : public QuestCallback
+{
+ public:
+ QuestThreadCallback(void (*handler)(Character *,
+ const std::string &value,
+ Script *mScript),
+ Script *script) :
+ mHandler(handler),
+ mScript(script)
+ { }
+
+ virtual void triggerCallback(Character *ch,
+ const std::string &value) const
+ { mHandler(ch, value, mScript); }
+
+ private:
+ void (*mHandler)(Character *,
+ const std::string &value,
+ Script *mScript);
+
+ Script *mScript;
+};
+
+class QuestRefCallback : public QuestCallback
+{
+ public:
+ QuestRefCallback(Script *script, const std::string &questName) :
+ mQuestName(questName)
+ { script->assignCallback(mRef); }
+
+ virtual void triggerCallback(Character *ch,
+ const std::string &value) const;
- Script *script;
+ private:
+ Script::Ref mRef;
+ std::string mQuestName;
};
/**
@@ -51,8 +93,7 @@ void setQuestVar(Character *, const std::string &name,
* Starts the recovery of a variable and returns immediatly. The callback will
* be called once the value has been recovered.
*/
-void recoverQuestVar(Character *, const std::string &name,
- const QuestCallback &);
+void recoverQuestVar(Character *, const std::string &name, QuestCallback *);
/**
* Called by the handler of the account server when a value is received.
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 9e904cc9..5e64961a 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -1345,6 +1345,21 @@ static int monster_change_anger(lua_State *s)
return 0;
}
+static int monster_drop_anger(lua_State *s)
+{
+ Monster *monster = checkMonster(s, 1);
+ Being *being = checkBeing(s, 2);
+ monster->forgetTarget(being);
+ return 0;
+}
+
+static int monster_get_angerlist(lua_State *s)
+{
+ Monster *monster = checkMonster(s, 1);
+ pushSTLContainer(s, monster->getAngerList());
+ return 1;
+}
+
/**
* monster_remove(Monster*): bool success
* Remove a monster object without kill event.
@@ -1363,7 +1378,7 @@ static int monster_remove(lua_State *s)
}
/**
- * chr_get_quest(Character*, string): nil or string
+ * chr_get_quest(Character*, string): string
* Callback for getting a quest variable. Starts a recovery and returns
* immediatly, if the variable is not known yet.
*/
@@ -1382,7 +1397,8 @@ static int chr_get_quest(lua_State *s)
lua_pushstring(s, value.c_str());
return 1;
}
- QuestCallback f = { &LuaScript::getQuestCallback, getScript(s) };
+ QuestCallback *f = new QuestThreadCallback(&LuaScript::getQuestCallback,
+ getScript(s));
recoverQuestVar(q, name, f);
thread->mState = Script::ThreadExpectingString;
@@ -1390,6 +1406,68 @@ static int chr_get_quest(lua_State *s)
}
/**
+ * chr_request_quest(Character*, string, Ref function)
+ * Requests the questvar from the account server. This will make it available in
+ * the quest cache after some time. The passwed function will be called back as
+ * soon the quest var is available.
+ */
+static int chr_request_quest(lua_State *s)
+{
+ Character *ch = checkCharacter(s, 1);
+ const char *name = luaL_checkstring(s, 2);
+ luaL_argcheck(s, name[0] != 0, 2, "empty variable name");
+ luaL_checktype(s, 3, LUA_TFUNCTION);
+
+ std::string value;
+ bool res = getQuestVar(ch, name, value);
+ if (res)
+ {
+ // Already cached, call passed callback immediately
+ Script *script = getScript(s);
+ Script::Ref callback;
+ script->assignCallback(callback);
+
+ // Backup the map since execute will reset it
+ MapComposite *map = script->getMap();
+
+ script->prepare(callback);
+ script->push(ch);
+ script->push(name);
+ script->push(value);
+ script->execute();
+
+ // Restore map
+ script->setMap(map);
+ return 0;
+ }
+
+ QuestCallback *f = new QuestRefCallback(getScript(s), name);
+ recoverQuestVar(ch, name, f);
+
+ return 0;
+}
+
+/**
+ * chr_try_get_quest(Character*, string): nil or string
+ * Callback for checking if a quest variable is available in cache. It will
+ * return the variable if it is or nil if it is not in cache.
+ */
+static int chr_try_get_quest(lua_State *s)
+{
+ Character *q = checkCharacter(s, 1);
+ const char *name = luaL_checkstring(s, 2);
+ luaL_argcheck(s, name[0] != 0, 2, "empty variable name");
+
+ std::string value;
+ bool res = getQuestVar(q, name, value);
+ if (res)
+ lua_pushstring(s, value.c_str());
+ else
+ lua_pushnil(s);
+ return 1;
+}
+
+/**
* getvar_map(string): string
* Gets the value of a persistent map variable.
*/
@@ -1701,6 +1779,18 @@ static int chr_shake_screen(lua_State *s)
return 0;
}
+static int chr_create_text_particle(lua_State *s)
+{
+ Character *c = checkCharacter(s, 1);
+ const char *text = luaL_checkstring(s, 2);
+
+ MessageOut msg(GPMSG_CREATE_TEXT_PARTICLE);
+ msg.writeString(text);
+ c->getClient()->send(msg);
+
+ return 0;
+}
+
/**
* chr_get_exp(Character*, int skill): int
@@ -2529,6 +2619,8 @@ LuaScript::LuaScript():
{ "chr_get_level", &chr_get_level },
{ "chr_get_quest", &chr_get_quest },
{ "chr_set_quest", &chr_set_quest },
+ { "chr_request_quest", &chr_request_quest },
+ { "chr_try_get_quest", &chr_try_get_quest },
{ "getvar_map", &getvar_map },
{ "setvar_map", &setvar_map },
{ "getvar_world", &getvar_world },
@@ -2555,6 +2647,8 @@ LuaScript::LuaScript():
{ "monster_get_name", &monster_get_name },
{ "monster_get_id", &monster_get_id },
{ "monster_change_anger", &monster_change_anger },
+ { "monster_drop_anger", &monster_drop_anger },
+ { "monster_get_angerlist", &monster_get_angerlist },
{ "monster_remove", &monster_remove },
{ "being_apply_status", &being_apply_status },
{ "being_remove_status", &being_remove_status },
@@ -2591,6 +2685,7 @@ LuaScript::LuaScript():
{ "being_register", &being_register },
{ "effect_create", &effect_create },
{ "chr_shake_screen", &chr_shake_screen },
+ { "chr_create_text_particle", &chr_create_text_particle },
{ "test_tableget", &test_tableget },
{ "get_map_id", &get_map_id },
{ "get_map_property", &get_map_property },