diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-07-15 22:01:41 +0200 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-07-17 21:58:40 +0200 |
commit | 7a72ec38d336ed56d2759795d4b9db59b76868b8 (patch) | |
tree | 0bf377084dd44faaaae53b05a4b97af0829b6347 | |
parent | f126afd524133f207c07d5eb52e3e774ab41604e (diff) | |
download | manaserv-7a72ec38d336ed56d2759795d4b9db59b76868b8.tar.gz manaserv-7a72ec38d336ed56d2759795d4b9db59b76868b8.tar.bz2 manaserv-7a72ec38d336ed56d2759795d4b9db59b76868b8.tar.xz manaserv-7a72ec38d336ed56d2759795d4b9db59b76868b8.zip |
Added lua binds for issuing request of quest variable + bind for trying to read them
The difference to the old chr_get_quest bind is that this allows querying quest
vars from non npc functions as well.
Change is tested.
Reviewed-by: bjorn.
-rw-r--r-- | src/game-server/character.cpp | 1 | ||||
-rw-r--r-- | src/game-server/quest.cpp | 22 | ||||
-rw-r--r-- | src/game-server/quest.h | 55 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 69 |
4 files changed, 134 insertions, 13 deletions
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 71427342..a053cd83 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/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 b7e61065..56f60f81 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1380,7 +1380,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. */ @@ -1399,7 +1399,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; @@ -1407,6 +1408,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. */ @@ -2443,6 +2506,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 }, |