diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/manaserv_protocol.h | 59 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 121 | ||||
-rw-r--r-- | src/scripting/luautil.cpp | 10 | ||||
-rw-r--r-- | src/scripting/luautil.h | 2 |
4 files changed, 191 insertions, 1 deletions
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h index 86f6196c..2bfd8c70 100644 --- a/src/common/manaserv_protocol.h +++ b/src/common/manaserv_protocol.h @@ -254,6 +254,9 @@ enum { PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode PCMSG_KICK_USER = 0x0466, // W channel id, S name + // -- Questlog + GPMSG_QUESTLOG_STATUS = 0x0470, // W quest id, B flags, [B status], [S questname], [S questdescription] + // Inter-server GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value } @@ -415,6 +418,13 @@ enum { GUILD_EVENT_OFFLINE_PLAYER }; +enum { + QUESTLOG_UPDATE_STATE = 1, + QUESTLOG_UPDATE_TITLE = 2, + QUESTLOG_UPDATE_DESCRIPTION = 4, + QUESTLOG_SHOW_NOTIFICATION = 8, +}; + /** * Moves enum for beings and actors for others players vision. * WARNING: Has to be in sync with the same enum in the Being class @@ -483,6 +493,55 @@ inline ManaServ::BeingGender getGender(std::string gender) return ManaServ::GENDER_UNSPECIFIED; } +/** + * Quest states + */ +enum QuestStatus +{ + STATUS_OPEN = 0, + STATUS_STARTED, + STATUS_FINISHED, + STATUS_INVALID +}; + +/** + * Helper function for getting quest status by id + * @param status id of the status + * @return the status as enum value + */ +inline ManaServ::QuestStatus getQuestStatus(int status) +{ + switch (status) + { + case 0: + return ManaServ::STATUS_OPEN; + case 1: + return ManaServ::STATUS_STARTED; + case 2: + return ManaServ::STATUS_FINISHED; + default: + return ManaServ::STATUS_INVALID; + } +} + +/** + * Helper function for getting quest status by string + * @param status name of quest status (open, started or finished) + * @return the status as enum value + */ +inline ManaServ::QuestStatus getQuestStatus(std::string status) +{ + std::string lowercase = utils::toLower(status); + if (lowercase == "open") + return ManaServ::STATUS_OPEN; + else if (lowercase == "started") + return ManaServ::STATUS_STARTED; + else if (lowercase == "finished") + return ManaServ::STATUS_FINISHED; + else + return ManaServ::STATUS_INVALID; +} + } // namespace ManaServ #endif // MANASERV_PROTOCOL_H diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 0e58f52b..ad699187 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -2336,6 +2336,122 @@ static int entity_use_ability(lua_State *s) return 1; } +/** LUA set_questlog_status (being) + * entity:set_questlog_status(int id, int state, string name, + * string description[, bool notify = true]) + ** + * Sets the questlog status. + * + * Valid only for character entities. + * + * For state you can use one of the following: + * * `QUEST_OPEN` + * * `QUEST_FINISHED` + * * `QUEST_FAILED` + */ +static int set_questlog_status(lua_State *s) +{ + const Entity *character = checkCharacter(s, 1); + const int questId = luaL_checkinteger(s, 2); + const int questState = luaL_checkinteger(s, 3); + const char *questTitle = luaL_checkstring(s, 4); + const char *questDescription = luaL_checkstring(s, 5); + const bool questNotification = checkOptionalBool(s, 6, true); + + MessageOut out(GPMSG_QUESTLOG_STATUS); + out.writeInt16(questId); + int flags = QUESTLOG_UPDATE_STATE | + QUESTLOG_UPDATE_TITLE | + QUESTLOG_UPDATE_DESCRIPTION; + if (questNotification) + flags |= QUESTLOG_SHOW_NOTIFICATION; + out.writeInt8(flags); + out.writeInt8(questState); + out.writeString(questTitle); + out.writeString(questDescription); + + character->getComponent<CharacterComponent>()->getClient()->send(out); + return 0; +} + +/** LUA set_questlog_state (being) + * entity:set_questlog_state(int id, int state[, bool notify = true]) + ** + * Sets the questlog state. + * + * Valid only for character entities. + * + * For state you can use one of the following: + * * `QUEST_OPEN` + * * `QUEST_FINISHED` + * * `QUEST_FAILED` + */ +static int set_questlog_state(lua_State *s) +{ + const Entity *character = checkCharacter(s, 1); + const int questId = luaL_checkinteger(s, 2); + const int questState = luaL_checkinteger(s, 3); + const bool questNotification = checkOptionalBool(s, 4, true); + + MessageOut out(GPMSG_QUESTLOG_STATUS); + out.writeInt16(questId); + out.writeInt8(QUESTLOG_UPDATE_STATE | + questNotification ? QUESTLOG_SHOW_NOTIFICATION : 0); + out.writeInt8(questState); + + character->getComponent<CharacterComponent>()->getClient()->send(out); + return 0; +} + +/** LUA set_questlog_title (being) + * entity:set_questlog_title(int id, string title[, bool notify = true]) + ** + * Sets the questlog title. + * + * Valid only for character entities. + */ +static int set_questlog_title(lua_State *s) +{ + const Entity *character = checkCharacter(s, 1); + const int questId = luaL_checkinteger(s, 2); + const char *questTitle = luaL_checkstring(s, 3); + const bool questNotification = checkOptionalBool(s, 4, true); + + MessageOut out(GPMSG_QUESTLOG_STATUS); + out.writeInt16(questId); + out.writeInt8(QUESTLOG_UPDATE_TITLE | + questNotification ? QUESTLOG_SHOW_NOTIFICATION : 0); + out.writeString(questTitle); + + character->getComponent<CharacterComponent>()->getClient()->send(out); + return 0; +} + +/** LUA set_questlog_description (being) + * entity:set_questlog_description(int id, string description[, bool notify = true]) + ** + * Sets the questlog description. + * + * Valid only for character entities. + */ +static int set_questlog_description(lua_State *s) +{ + const Entity *character = checkCharacter(s, 1); + const int questId = luaL_checkinteger(s, 2); + luaL_argcheck(s, lua_isboolean(s, 3), 3, "boolean expected"); + const char *questDescription = luaL_checkstring(s, 3); + const bool questNotification = checkOptionalBool(s, 4, true); + + MessageOut out(GPMSG_QUESTLOG_STATUS); + out.writeInt16(questId); + out.writeInt8(QUESTLOG_UPDATE_DESCRIPTION | + questNotification ? QUESTLOG_SHOW_NOTIFICATION : 0); + out.writeString(questDescription); + + character->getComponent<CharacterComponent>()->getClient()->send(out); + return 0; +} + /** LUA_CATEGORY Monster (monster) */ @@ -3158,7 +3274,6 @@ static int map_object_get_type(lua_State *s) return 1; } - /** LUA_CATEGORY Item class (itemclass) */ @@ -3429,6 +3544,10 @@ LuaScript::LuaScript(): { "status_time", entity_get_status_time }, { "set_status_time", entity_set_status_time }, { "add_hit_taken", entity_add_hit_taken }, + { "set_questlog_status", set_questlog_status }, + { "set_questlog_state", set_questlog_state }, + { "set_questlog_title", set_questlog_title }, + { "set_questlog_description", set_questlog_description }, { nullptr, nullptr } }; diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index d3db13f2..4607c8dd 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -163,6 +163,16 @@ MonsterClass *getMonsterClass(lua_State *s, int p) } +bool checkOptionalBool(lua_State *s, int p, bool defaultValue) +{ + if (lua_gettop(s) >= p) + { + luaL_argcheck(s, lua_isboolean(s, p), p, "boolean expected"); + return lua_toboolean(s, p); + } + return defaultValue; +} + Entity *checkActor(lua_State *s, int p) { Entity *entity = LuaEntity::check(s, p); diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index 45e075f1..fb4793a0 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -172,6 +172,8 @@ Script * getScript(lua_State *s); ItemClass * getItemClass(lua_State *s, int p); MonsterClass * getMonsterClass(lua_State *s, int p); +bool checkOptionalBool(lua_State *s, int p, bool defaultValue); + Entity * checkActor(lua_State *s, int p); Entity * checkBeing(lua_State *s, int p); Entity * checkCharacter(lua_State *s, int p); |