From 6da6afe8ad3ffc3d690af9b60975c5f183f2aba8 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sat, 7 Jul 2012 23:11:28 +0200 Subject: Added script bind for getting specy id of a monster handle Reviewed-by: bjorn. --- src/scripting/lua.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/scripting/lua.cpp') diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 00a108c5..7ec7e053 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1307,6 +1307,17 @@ static int monster_get_name(lua_State *s) return 1; } +/** + * monster_get_id(handle monster): int monsterid + * Returns the id of the monster handle + */ +static int monster_get_id(lua_State *s) +{ + Monster *monster = checkMonster(s, 1); + lua_pushinteger(s, monster->getSpecy()->getId()); + return 1; +} + /** * monster_change_anger(Monster*, Being*, int anger) * Makes a monster angry at a being @@ -2411,6 +2422,7 @@ LuaScript::LuaScript(): { "exp_for_level", &exp_for_level }, { "monster_create", &monster_create }, { "monster_get_name", &monster_get_name }, + { "monster_get_id", &monster_get_id }, { "monster_change_anger", &monster_change_anger }, { "monster_remove", &monster_remove }, { "being_apply_status", &being_apply_status }, -- cgit v1.2.3-70-g09d2 From 4d88724f011090de417284668d2264931f1bfcc3 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sun, 8 Jul 2012 17:20:34 +0200 Subject: Added bind for setting login callback Reviewed-by: bjorn. --- src/game-server/character.cpp | 6 ++++++ src/game-server/character.h | 6 ++++++ src/game-server/gamehandler.cpp | 2 ++ src/scripting/lua.cpp | 8 ++++++++ 4 files changed, 22 insertions(+) (limited to 'src/scripting/lua.cpp') diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 4816f3c1..71427342 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -55,6 +55,7 @@ const float Character::EXP_LEVEL_FLEXIBILITY = 1.0f; Script::Ref Character::mDeathCallback; Script::Ref Character::mDeathAcceptedCallback; +Script::Ref Character::mLoginCallback; static bool executeCallback(Script::Ref function, Character *character) { @@ -830,3 +831,8 @@ void Character::clearSpecials() { mSpecials.clear(); } + +void Character::triggerLoginCallback() +{ + executeCallback(mLoginCallback, this); +} diff --git a/src/game-server/character.h b/src/game-server/character.h index b465a90e..b5ef578a 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -419,6 +419,11 @@ class Character : public Being static void setDeathAcceptedCallback(Script *script) { script->assignCallback(mDeathAcceptedCallback); } + static void setLoginCallback(Script *script) + { script->assignCallback(mLoginCallback); } + + void triggerLoginCallback(); + protected: /** * Gets the way the actor blocks pathfinding for other objects @@ -524,6 +529,7 @@ class Character : public Being static Script::Ref mDeathCallback; static Script::Ref mDeathAcceptedCallback; + static Script::Ref mLoginCallback; // Set as a friend, but still a lot of redundant accessors. FIXME. template< class T > diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index f7ee6af4..8b8c67a3 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -371,6 +371,8 @@ void GameHandler::tokenMatched(GameClient *computer, Character *character) computer->disconnect(result); return; } + // Trigger login script bind + character->triggerLoginCallback(); result.writeInt8(ERRMSG_OK); computer->send(result); diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 7ec7e053..51ebaa5e 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -92,6 +92,13 @@ static int on_character_death_accept(lua_State *s) return 0; } +static int on_character_login(lua_State *s) +{ + luaL_checktype(s, 1, LUA_TFUNCTION); + Character::setLoginCallback(getScript(s)); + return 0; +} + static int on_being_death(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); @@ -2367,6 +2374,7 @@ LuaScript::LuaScript(): static luaL_Reg const callbacks[] = { { "on_character_death", &on_character_death }, { "on_character_death_accept", &on_character_death_accept }, + { "on_character_login", &on_character_login }, { "on_being_death", &on_being_death }, { "on_being_remove", &on_being_remove }, { "on_update", &on_update }, -- cgit v1.2.3-70-g09d2 From 52bc6c29358ccfd241b99c8ff7a423f962c5493b Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Mon, 9 Jul 2012 21:23:34 +0200 Subject: Made kill count script bind capable of taking the monster name as argument Reviewed-by: bjorn. --- src/scripting/lua.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/scripting/lua.cpp') diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 51ebaa5e..b29ae74d 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1793,9 +1793,9 @@ static int chr_get_hair_color(lua_State *s) static int chr_get_kill_count(lua_State *s) { Character *c = checkCharacter(s, 1); - const int id = luaL_checkint(s, 2); + MonsterClass *monster = checkMonsterClass(s, 2); - lua_pushinteger(s, c->getKillCount(id)); + lua_pushinteger(s, c->getKillCount(monster->getId())); return 1; } -- cgit v1.2.3-70-g09d2 From 66f1696f101c39f7e3f01641e562c0c5c8eac77f Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sat, 14 Jul 2012 14:45:23 +0200 Subject: Fixed the get_beings_in_rectangle function. Previously it only used the rectangle iterator which in fact iterated over the beings in the map zones and returned often way higher number of beings compared to the actual rectangle. Change is tested. Reviewed-by: Bjorn. --- src/scripting/lua.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/scripting/lua.cpp') diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index b29ae74d..ad4806c9 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1585,7 +1585,8 @@ static int get_beings_in_rectangle(lua_State *s) { Being *b = *i; char t = b->getType(); - if (t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) + if ((t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) && + rect.contains(b->getPosition())) { lua_pushlightuserdata(s, b); lua_rawseti(s, tableStackPosition, tableIndex); -- cgit v1.2.3-70-g09d2 From 55e227f90e86a960e111a286bd70d49578eb838b Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Tue, 17 Jul 2012 12:07:54 +0200 Subject: Made chr_get_level capable of retrieving skill levels Reviewed-by: bjorn. --- src/scripting/lua.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/scripting/lua.cpp') diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index ad4806c9..a6b26e92 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -714,13 +714,22 @@ static int chr_unequip_item(lua_State *s) } /** - * chr_get_level(Character*): int level - * Tells the character current level. + * chr_get_level(Character* [, skill]): int level + * Tells the character current level. If a skill is passed as 2nd argument it + * will return the skill level. */ static int chr_get_level(lua_State *s) { Character *ch = checkCharacter(s, 1); - lua_pushinteger(s, ch->getLevel()); + if (lua_gettop(s) > 1) + { + int skillId = checkSkill(s, 2); + lua_pushinteger(s, ch->levelForExp(ch->getExperience(skillId))); + } + else + { + lua_pushinteger(s, ch->getLevel()); + } return 1; } -- cgit v1.2.3-70-g09d2 From fc8e16e33bc34bda74559d021f5c1855a789a2b2 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Mon, 16 Jul 2012 19:54:43 +0200 Subject: Added lua bind to send text effect particle to clients Change is tested. Reviewed-by: bjorn. --- src/common/manaserv_protocol.h | 1 + src/scripting/lua.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'src/scripting/lua.cpp') 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/scripting/lua.cpp b/src/scripting/lua.cpp index a6b26e92..05845a36 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1703,6 +1703,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 @@ -2478,6 +2490,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 }, -- cgit v1.2.3-70-g09d2 From f126afd524133f207c07d5eb52e3e774ab41604e Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Mon, 16 Jul 2012 17:45:52 +0200 Subject: Added script binds to get full monster anger list + drop anger of monsters Reviewed-by: bjorn. --- src/game-server/monster.h | 3 +++ src/scripting/lua.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src/scripting/lua.cpp') diff --git a/src/game-server/monster.h b/src/game-server/monster.h index 75ea1e83..5da975e9 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -325,6 +325,9 @@ class Monster : public Being */ void changeAnger(Actor *target, int amount); + const std::map &getAngerList() const + { return mAnger; } + /** * Calls the damage function in Being and updates the aggro list */ diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 05845a36..b7e61065 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1347,6 +1347,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. @@ -2454,6 +2469,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 }, -- cgit v1.2.3-70-g09d2 From 7a72ec38d336ed56d2759795d4b9db59b76868b8 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sun, 15 Jul 2012 22:01:41 +0200 Subject: 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. --- src/game-server/character.cpp | 1 - src/game-server/quest.cpp | 22 ++++++++++++-- src/game-server/quest.h | 55 +++++++++++++++++++++++++++++----- src/scripting/lua.cpp | 69 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 134 insertions(+), 13 deletions(-) (limited to 'src/scripting/lua.cpp') 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 +#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,13 +1399,76 @@ 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; return lua_yield(s, 0); } +/** + * 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 }, -- cgit v1.2.3-70-g09d2