Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added lua binds for issuing request of quest variable + bind for tryi…

…ng 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.
  • Loading branch information...
commit 7a72ec38d336ed56d2759795d4b9db59b76868b8 1 parent f126afd
Erik Schilling Ablu authored
1  src/game-server/character.cpp
@@ -67,7 +67,6 @@ static bool executeCallback(Script::Ref function, Character *character)
67 67 script->prepare(function);
68 68 script->push(character);
69 69 script->execute();
70   - script->setMap(0);
71 70 return true;
72 71 }
73 72
22 src/game-server/quest.cpp
@@ -30,7 +30,7 @@
30 30 #include "game-server/eventlistener.h"
31 31 #include "utils/logger.h"
32 32
33   -typedef std::list< QuestCallback > QuestCallbacks;
  33 +typedef std::list< QuestCallback * > QuestCallbacks;
34 34 typedef std::map< std::string, QuestCallbacks > PendingVariables;
35 35
36 36 struct PendingQuest
@@ -88,6 +88,21 @@ struct QuestDeathListener: EventDispatch
88 88 }
89 89 };
90 90
  91 +void QuestRefCallback::triggerCallback(Character *ch,
  92 + const std::string &value) const
  93 +{
  94 + if (!mRef.isValid())
  95 + return;
  96 +
  97 + Script *s = ScriptManager::currentState();
  98 + s->setMap(ch->getMap());
  99 + s->prepare(mRef);
  100 + s->push(ch);
  101 + s->push(mQuestName);
  102 + s->push(value);
  103 + s->execute();
  104 +}
  105 +
91 106 static QuestDeathListener questDeathDummy;
92 107 static EventListener questDeathListener(&questDeathDummy);
93 108
@@ -112,7 +127,7 @@ void QuestDeathListener::fullRemove(const EventListener *, Character *ch)
112 127 }
113 128
114 129 void recoverQuestVar(Character *ch, const std::string &name,
115   - const QuestCallback &f)
  130 + QuestCallback *f)
116 131 {
117 132 assert(ch->questCache.find(name) == ch->questCache.end());
118 133 int id = ch->getDatabaseID();
@@ -153,7 +168,8 @@ void recoveredQuestVar(int id,
153 168 for (QuestCallbacks::const_iterator k = j->second.begin(),
154 169 k_end = j->second.end(); k != k_end; ++k)
155 170 {
156   - k->handler(ch, value, k->script);
  171 + (*k)->triggerCallback(ch, value);
  172 + delete (*k);
157 173 }
158 174
159 175 variables.erase(j);
55 src/game-server/quest.h
@@ -23,16 +23,58 @@
23 23
24 24 #include <string>
25 25
  26 +#include "scripting/scriptmanager.h"
  27 +
26 28 class Character;
27 29 class Script;
28 30
29   -struct QuestCallback
  31 +
  32 +class QuestCallback
30 33 {
31   - void (*handler)(Character *,
32   - const std::string &value,
33   - Script *script);
  34 + public:
  35 + virtual ~QuestCallback()
  36 + { }
  37 +
  38 + virtual void triggerCallback(Character *ch,
  39 + const std::string &value) const = 0;
  40 +};
  41 +
  42 +class QuestThreadCallback : public QuestCallback
  43 +{
  44 + public:
  45 + QuestThreadCallback(void (*handler)(Character *,
  46 + const std::string &value,
  47 + Script *mScript),
  48 + Script *script) :
  49 + mHandler(handler),
  50 + mScript(script)
  51 + { }
  52 +
  53 + virtual void triggerCallback(Character *ch,
  54 + const std::string &value) const
  55 + { mHandler(ch, value, mScript); }
  56 +
  57 + private:
  58 + void (*mHandler)(Character *,
  59 + const std::string &value,
  60 + Script *mScript);
  61 +
  62 + Script *mScript;
  63 +};
  64 +
  65 +class QuestRefCallback : public QuestCallback
  66 +{
  67 + public:
  68 + QuestRefCallback(Script *script, const std::string &questName) :
  69 + mQuestName(questName)
  70 + { script->assignCallback(mRef); }
  71 +
  72 + virtual void triggerCallback(Character *ch,
  73 + const std::string &value) const;
34 74
35   - Script *script;
  75 + private:
  76 + Script::Ref mRef;
  77 + std::string mQuestName;
36 78 };
37 79
38 80 /**
@@ -51,8 +93,7 @@ void setQuestVar(Character *, const std::string &name,
51 93 * Starts the recovery of a variable and returns immediatly. The callback will
52 94 * be called once the value has been recovered.
53 95 */
54   -void recoverQuestVar(Character *, const std::string &name,
55   - const QuestCallback &);
  96 +void recoverQuestVar(Character *, const std::string &name, QuestCallback *);
56 97
57 98 /**
58 99 * Called by the handler of the account server when a value is received.
69 src/scripting/lua.cpp
@@ -1380,7 +1380,7 @@ static int monster_remove(lua_State *s)
1380 1380 }
1381 1381
1382 1382 /**
1383   - * chr_get_quest(Character*, string): nil or string
  1383 + * chr_get_quest(Character*, string): string
1384 1384 * Callback for getting a quest variable. Starts a recovery and returns
1385 1385 * immediatly, if the variable is not known yet.
1386 1386 */
@@ -1399,7 +1399,8 @@ static int chr_get_quest(lua_State *s)
1399 1399 lua_pushstring(s, value.c_str());
1400 1400 return 1;
1401 1401 }
1402   - QuestCallback f = { &LuaScript::getQuestCallback, getScript(s) };
  1402 + QuestCallback *f = new QuestThreadCallback(&LuaScript::getQuestCallback,
  1403 + getScript(s));
1403 1404 recoverQuestVar(q, name, f);
1404 1405
1405 1406 thread->mState = Script::ThreadExpectingString;
@@ -1407,6 +1408,68 @@ static int chr_get_quest(lua_State *s)
1407 1408 }
1408 1409
1409 1410 /**
  1411 + * chr_request_quest(Character*, string, Ref function)
  1412 + * Requests the questvar from the account server. This will make it available in
  1413 + * the quest cache after some time. The passwed function will be called back as
  1414 + * soon the quest var is available.
  1415 + */
  1416 +static int chr_request_quest(lua_State *s)
  1417 +{
  1418 + Character *ch = checkCharacter(s, 1);
  1419 + const char *name = luaL_checkstring(s, 2);
  1420 + luaL_argcheck(s, name[0] != 0, 2, "empty variable name");
  1421 + luaL_checktype(s, 3, LUA_TFUNCTION);
  1422 +
  1423 + std::string value;
  1424 + bool res = getQuestVar(ch, name, value);
  1425 + if (res)
  1426 + {
  1427 + // Already cached, call passed callback immediately
  1428 + Script *script = getScript(s);
  1429 + Script::Ref callback;
  1430 + script->assignCallback(callback);
  1431 +
  1432 + // Backup the map since execute will reset it
  1433 + MapComposite *map = script->getMap();
  1434 +
  1435 + script->prepare(callback);
  1436 + script->push(ch);
  1437 + script->push(name);
  1438 + script->push(value);
  1439 + script->execute();
  1440 +
  1441 + // Restore map
  1442 + script->setMap(map);
  1443 + return 0;
  1444 + }
  1445 +
  1446 + QuestCallback *f = new QuestRefCallback(getScript(s), name);
  1447 + recoverQuestVar(ch, name, f);
  1448 +
  1449 + return 0;
  1450 +}
  1451 +
  1452 +/**
  1453 + * chr_try_get_quest(Character*, string): nil or string
  1454 + * Callback for checking if a quest variable is available in cache. It will
  1455 + * return the variable if it is or nil if it is not in cache.
  1456 + */
  1457 +static int chr_try_get_quest(lua_State *s)
  1458 +{
  1459 + Character *q = checkCharacter(s, 1);
  1460 + const char *name = luaL_checkstring(s, 2);
  1461 + luaL_argcheck(s, name[0] != 0, 2, "empty variable name");
  1462 +
  1463 + std::string value;
  1464 + bool res = getQuestVar(q, name, value);
  1465 + if (res)
  1466 + lua_pushstring(s, value.c_str());
  1467 + else
  1468 + lua_pushnil(s);
  1469 + return 1;
  1470 +}
  1471 +
  1472 +/**
1410 1473 * getvar_map(string): string
1411 1474 * Gets the value of a persistent map variable.
1412 1475 */
@@ -2443,6 +2506,8 @@ LuaScript::LuaScript():
2443 2506 { "chr_get_level", &chr_get_level },
2444 2507 { "chr_get_quest", &chr_get_quest },
2445 2508 { "chr_set_quest", &chr_set_quest },
  2509 + { "chr_request_quest", &chr_request_quest },
  2510 + { "chr_try_get_quest", &chr_try_get_quest },
2446 2511 { "getvar_map", &getvar_map },
2447 2512 { "setvar_map", &setvar_map },
2448 2513 { "getvar_world", &getvar_world },

0 comments on commit 7a72ec3

Please sign in to comment.
Something went wrong with that request. Please try again.