/* * Copyright (C) 2010 - 2014 Eluna Lua Engine * This program is free software licensed under GPL version 3 * Please see the included DOCS/LICENSE.md for more information */ #ifndef GLOBALMETHODS_H #define GLOBALMETHODS_H namespace LuaGlobalFunctions { /** * Returns lua engine name. Currently `ElunaEngine` * * @return string engineName */ int GetLuaEngine(Eluna* /*E*/, lua_State* L) { Eluna::Push(L, "ElunaEngine"); return 1; } /** * Returns emulator / core name. * For example `MaNGOS`, `cMaNGOS` or `TrinityCore` * * @return string coreName */ int GetCoreName(Eluna* /*E*/, lua_State* L) { Eluna::Push(L, CORE_NAME); return 1; } /** * Returns emulator version * * * For TrinityCore returns for example `2014-08-13 17:27:22 +0300` * * For cMaNGOS returns for example `12708` * * For MaNGOS returns for example `20002` * * @return string version */ int GetCoreVersion(Eluna* /*E*/, lua_State* L) { Eluna::Push(L, CORE_VERSION); return 1; } /** * Returns emulator expansion. Expansion is 0 for classic, 1 for TBC, 2 for WOTLK and 3 for cataclysm * * @return int32 version : emulator expansion ID */ int GetCoreExpansion(Eluna* /*E*/, lua_State* L) { #ifdef CLASSIC Eluna::Push(L, 0); #elif defined(TBC) Eluna::Push(L, 1); #elif defined(WOTLK) Eluna::Push(L, 2); #elif defined(CATA) Eluna::Push(L, 3); #endif return 1; } /** * Returns [Quest] template * * @param uint32 questId : [Quest] entry ID * @return [Quest] quest */ int GetQuest(Eluna* /*E*/, lua_State* L) { uint32 questId = Eluna::CHECKVAL(L, 1); Eluna::Push(L, eObjectMgr->GetQuestTemplate(questId)); return 1; } /** * Finds and Returns [Player] by guid if found * * @param uint64 guid : guid of the [Player] * @return [Player] player */ int GetPlayerByGUID(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, eObjectAccessor->FindPlayer(ObjectGuid(guid))); return 1; } /** * Finds and Returns [Player] by name if found * * @param string name : name of the [Player] * @return [Player] player */ int GetPlayerByName(Eluna* /*E*/, lua_State* L) { const char* name = Eluna::CHECKVAL(L, 1); Eluna::Push(L, eObjectAccessor->FindPlayerByName(name)); return 1; } /** * Returns game time in seconds * * @return uint32 time */ int GetGameTime(Eluna* /*E*/, lua_State* L) { time_t time = eWorld->GetGameTime(); if (time < 0) Eluna::Push(L, int32(time)); else Eluna::Push(L, uint32(time)); return 1; } /** * Returns a table with all the current [Player]s in the world * *
     * enum TeamId
     * {
     *     TEAM_ALLIANCE = 0,
     *     TEAM_HORDE = 1,
     *     TEAM_NEUTRAL = 2
     * };
     * 
* * @param [TeamId] team = TEAM_NEUTRAL : optional check team of the [Player], Alliance, Horde or Neutral (All) * @param bool onlyGM = false : optional check if GM only * @return table worldPlayers */ int GetPlayersInWorld(Eluna* /*E*/, lua_State* L) { uint32 team = Eluna::CHECKVAL(L, 1, TEAM_NEUTRAL); bool onlyGM = Eluna::CHECKVAL(L, 2, false); lua_newtable(L); int tbl = lua_gettop(L); uint32 i = 0; SessionMap const& sessions = eWorld->GetAllSessions(); for (SessionMap::const_iterator it = sessions.begin(); it != sessions.end(); ++it) { if (Player* player = it->second->GetPlayer()) { #ifndef TRINITY if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->isGameMaster())) #else if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->IsGameMaster())) #endif { ++i; Eluna::Push(L, i); Eluna::Push(L, player); lua_settable(L, tbl); } } } lua_settop(L, tbl); // push table to top of stack return 1; } /** * Returns a table with all the current [Player]s in a map * *
     * enum TeamId
     * {
     *     TEAM_ALLIANCE = 0,
     *     TEAM_HORDE = 1,
     *     TEAM_NEUTRAL = 2
     * };
     * 
* * @param uint32 mapId : the [Map] entry ID * @param uint32 instanceId : the instance ID to search in the map * @param [TeamId] team : optional check team of the [Player], Alliance, Horde or Neutral (All) * @return table mapPlayers */ int GetPlayersInMap(Eluna* /*E*/, lua_State* L) { uint32 mapID = Eluna::CHECKVAL(L, 1); uint32 instanceID = Eluna::CHECKVAL(L, 2, 0); uint32 team = Eluna::CHECKVAL(L, 3, TEAM_NEUTRAL); lua_newtable(L); Map* map = eMapMgr->FindMap(mapID, instanceID); if (!map) return 1; int tbl = lua_gettop(L); uint32 i = 0; Map::PlayerList const& players = map->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { #ifndef TRINITY Player* player = itr->getSource(); #else Player* player = itr->GetSource(); #endif if (!player) continue; if (player->GetSession() && (team >= TEAM_NEUTRAL || player->GetTeamId() == team)) { ++i; Eluna::Push(L, i); Eluna::Push(L, player); lua_settable(L, tbl); } } lua_settop(L, tbl); return 1; } /** * Returns [Guild] by name * * @param string name : the name of a guild * @return [Guild] guild */ int GetGuildByName(Eluna* /*E*/, lua_State* L) { const char* name = Eluna::CHECKVAL(L, 1); Eluna::Push(L, eGuildMgr->GetGuildByName(name)); return 1; } /** * Returns [Map] by ID * * @param uint32 mapId : the [Map] ID * @param uint32 instanceId : instance ID to search, use 0 if not instance * @return [Map] map */ int GetMapById(Eluna* /*E*/, lua_State* L) { uint32 mapid = Eluna::CHECKVAL(L, 1); uint32 instance = Eluna::CHECKVAL(L, 2); Eluna::Push(L, eMapMgr->FindMap(mapid, instance)); return 1; } /** * Returns [Guild] by the leader's GUID * * @param uint64 guid : the guid of a [Guild] leader * @return [Guild] guild */ int GetGuildByLeaderGUID(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, eGuildMgr->GetGuildByLeader(ObjectGuid(guid))); return 1; } /** * Returns the amount of [Player]s in the world * * @return uint32 count */ int GetPlayerCount(Eluna* /*E*/, lua_State* L) { Eluna::Push(L, eWorld->GetActiveSessionCount()); return 1; } /** * Returns a [Player]'s GUID * [Player] GUID consist of low GUID and type ID * [Player] and [Creature] for example can have the same low GUID but not GUID. * * @param uint32 lowguid : low GUID of the [Player] * @return uint64 guid */ int GetPlayerGUID(Eluna* /*E*/, lua_State* L) { uint32 lowguid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER)); return 1; } /** * Returns an [Item]'s GUID * [Item] GUID consist of low GUID and type ID * [Player] and [Item] for example can have the same low GUID but not GUID. * * @param uint32 lowguid : low GUID of the [Item] * @return uint64 guid */ int GetItemGUID(Eluna* /*E*/, lua_State* L) { uint32 lowguid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_ITEM)); return 1; } /** * Returns a [GameObject]'s GUID * [GameObject] GUID consist of entry ID, low GUID and type ID * [Player] and [GameObject] for example can have the same low GUID but not GUID. * * @param uint32 lowguid : low GUID of the [GameObject] * @param uint32 entry : entry ID of the [GameObject] * @return uint64 guid */ int GetObjectGUID(Eluna* /*E*/, lua_State* L) { uint32 lowguid = Eluna::CHECKVAL(L, 1); uint32 entry = Eluna::CHECKVAL(L, 2); Eluna::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); return 1; } /** * Returns a [Creature]'s GUID. * [Creature] GUID consist of entry ID, low GUID and type ID * [Player] and [Creature] for example can have the same low GUID but not GUID. * * @param uint32 lowguid : low GUID of the [Creature] * @param uint32 entry : entry ID of the [Creature] * @return uint64 guid */ int GetUnitGUID(Eluna* /*E*/, lua_State* L) { uint32 lowguid = Eluna::CHECKVAL(L, 1); uint32 entry = Eluna::CHECKVAL(L, 2); Eluna::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_UNIT)); return 1; } /** * Returns the low GUID from a GUID. * Low GUID is an ID to distinct the objects of the same type. * [Player] and [Creature] for example can have the same low GUID but not GUID. * GUID consist of entry ID, low GUID and type ID * * @param uint64 guid : GUID of an [Object] * @return uint32 lowguid : low GUID of the [Object] */ int GetGUIDLow(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, GUID_LOPART(guid)); return 1; } /** * Returns an item chat link for given entry * *
     * enum LocaleConstant
     * {
     *     LOCALE_enUS = 0,
     *     LOCALE_koKR = 1,
     *     LOCALE_frFR = 2,
     *     LOCALE_deDE = 3,
     *     LOCALE_zhCN = 4,
     *     LOCALE_zhTW = 5,
     *     LOCALE_esES = 6,
     *     LOCALE_esMX = 7,
     *     LOCALE_ruRU = 8
     * };
     * 
* * @param uint32 entry : entry ID of an [Item] * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Item] name in * @return string itemLink */ int GetItemLink(Eluna* /*E*/, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint8 locale = Eluna::CHECKVAL(L, 2, DEFAULT_LOCALE); if (locale >= TOTAL_LOCALES) return luaL_argerror(L, 2, "valid LocaleConstant expected"); const ItemTemplate* temp = eObjectMgr->GetItemTemplate(entry); if (!temp) return luaL_argerror(L, 1, "valid ItemEntry expected"); std::string name = temp->Name1; if (ItemLocale const* il = eObjectMgr->GetItemLocale(entry)) ObjectMgr::GetLocaleString(il->Name, locale, name); std::ostringstream oss; oss << "|c" << std::hex << ItemQualityColors[temp->Quality] << std::dec << "|Hitem:" << entry << ":0:" << #ifndef CLASSIC "0:0:0:0:" << #endif "0:0:0:0|h[" << name << "]|h|r"; Eluna::Push(L, oss.str()); return 1; } /** * Returns the type ID from a GUID. * Type ID is different for each type ([Player], [Creature], [GameObject]...) * GUID consist of entry ID, low GUID and type ID * * @param uint64 guid : GUID of an [Object] * @return uint32 typeId : type ID of the [Object] */ int GetGUIDType(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, GUID_HIPART(guid)); return 1; } /** * Returns the entry ID from a GUID. * Entry ID is different for each [Creature] and [GameObject]. * [Item] GUIDs dont include the entry * GUID consist of entry ID, low GUID and type ID * * @param uint64 guid : GUID of an [Creature] or [GameObject], otherwise returns 0 * @return uint32 entry : entry ID of the [Creature] or [GameObject] */ int GetGUIDEntry(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); Eluna::Push(L, GUID_ENPART(guid)); return 1; } /** * Returns the area's or zone's name * *
     * enum LocaleConstant
     * {
     *     LOCALE_enUS = 0,
     *     LOCALE_koKR = 1,
     *     LOCALE_frFR = 2,
     *     LOCALE_deDE = 3,
     *     LOCALE_zhCN = 4,
     *     LOCALE_zhTW = 5,
     *     LOCALE_esES = 6,
     *     LOCALE_esMX = 7,
     *     LOCALE_ruRU = 8
     * };
     * 
* * @param uint32 areaOrZoneId : area ID or zone ID * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the name in * @return string areaOrZoneName */ int GetAreaName(Eluna* /*E*/, lua_State* L) { uint32 areaOrZoneId = Eluna::CHECKVAL(L, 1); uint8 locale = Eluna::CHECKVAL(L, 2, DEFAULT_LOCALE); if (locale >= TOTAL_LOCALES) return luaL_argerror(L, 2, "valid LocaleConstant expected"); AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaOrZoneId); if (!areaEntry) return luaL_argerror(L, 1, "valid Area or Zone ID expected"); Eluna::Push(L, areaEntry->area_name[locale]); return 1; } /** * Registers a packet event * *
     * enum PacketEvents
     * {
     *     PACKET_EVENT_ON_PACKET_RECEIVE          =     5,
     *     PACKET_EVENT_ON_PACKET_RECEIVE_UNKNOWN  =     6,
     *     PACKET_EVENT_ON_PACKET_SEND             =     7,
     *
     *     PACKET_EVENT_COUNT
     * };
     * 
* * @param uint32 entry : opcode * @param uint32 event : packet event Id, refer to PacketEvents above * @param function function : function to register */ int RegisterPacketEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_PACKET, entry, ev, functionRef); return 0; } /** * Registers a server event * *
     * enum ServerEvents
     * {
     *     // Server
     *     SERVER_EVENT_ON_NETWORK_START           =     1,       // Not Implemented
     *     SERVER_EVENT_ON_NETWORK_STOP            =     2,       // Not Implemented
     *     SERVER_EVENT_ON_SOCKET_OPEN             =     3,       // Not Implemented
     *     SERVER_EVENT_ON_SOCKET_CLOSE            =     4,       // Not Implemented
     *     SERVER_EVENT_ON_PACKET_RECEIVE          =     5,       // (event, packet, player) - Player only if accessible. Can return false or a new packet
     *     SERVER_EVENT_ON_PACKET_RECEIVE_UNKNOWN  =     6,       // Not Implemented
     *     SERVER_EVENT_ON_PACKET_SEND             =     7,       // (event, packet, player) - Player only if accessible. Can return false or a new packet
     *
     *     // World
     *     WORLD_EVENT_ON_OPEN_STATE_CHANGE        =     8,        // (event, open) - Needs core support on Mangos
     *     WORLD_EVENT_ON_CONFIG_LOAD              =     9,        // (event, reload)
     *     // UNUSED                               =     10,
     *     WORLD_EVENT_ON_SHUTDOWN_INIT            =     11,       // (event, code, mask)
     *     WORLD_EVENT_ON_SHUTDOWN_CANCEL          =     12,       // (event)
     *     WORLD_EVENT_ON_UPDATE                   =     13,       // (event, diff)
     *     WORLD_EVENT_ON_STARTUP                  =     14,       // (event)
     *     WORLD_EVENT_ON_SHUTDOWN                 =     15,       // (event)
     *
     *     // Eluna
     *     ELUNA_EVENT_ON_LUA_STATE_CLOSE          =     16,       // (event) - triggers just before shutting down eluna (on shutdown and restart)
     *     ELUNA_EVENT_ON_LUA_STATE_OPEN           =     33,       // (event) - triggers after all scripts are loaded
     *
     *     // Map
     *     MAP_EVENT_ON_CREATE                     =     17,       // (event, map)
     *     MAP_EVENT_ON_DESTROY                    =     18,       // (event, map)
     *     MAP_EVENT_ON_GRID_LOAD                  =     19,       // Not Implemented
     *     MAP_EVENT_ON_GRID_UNLOAD                =     20,       // Not Implemented
     *     MAP_EVENT_ON_PLAYER_ENTER               =     21,       // (event, map, player)
     *     MAP_EVENT_ON_PLAYER_LEAVE               =     22,       // (event, map, player)
     *     MAP_EVENT_ON_UPDATE                     =     23,       // (event, map, diff)
     *
     *     // Area trigger
     *     TRIGGER_EVENT_ON_TRIGGER                =     24,       // (event, player, triggerId)
     *
     *     // Weather
     *     WEATHER_EVENT_ON_CHANGE                 =     25,       // (event, weather, state, grade)
     *
     *     // Auction house
     *     AUCTION_EVENT_ON_ADD                    =     26,       // (event, AHObject)
     *     AUCTION_EVENT_ON_REMOVE                 =     27,       // (event, AHObject)
     *     AUCTION_EVENT_ON_SUCCESSFUL             =     28,       // (event, AHObject) // Not Implemented
     *     AUCTION_EVENT_ON_EXPIRE                 =     29,       // (event, AHObject) // Not Implemented
     *
     *     // AddOns
     *     ADDON_EVENT_ON_MESSAGE                  =     30,       // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guild/group/channel
     *
     *     WORLD_EVENT_ON_DELETE_CREATURE          =     31,       // (event, creature)
     *     WORLD_EVENT_ON_DELETE_GAMEOBJECT        =     32,       // (event, gameobject)
     *
     *     SERVER_EVENT_COUNT
     * };
     * 
* * @param uint32 event : server event Id, refer to ServerEvents above * @param function function : function to register */ int RegisterServerEvent(Eluna* E, lua_State* L) { uint32 ev = Eluna::CHECKVAL(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushvalue(L, 2); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_SERVER, 0, ev, functionRef); return 0; } /** * Registers a [Player] event * *
     * enum PlayerEvents
     * {
     *     PLAYER_EVENT_ON_CHARACTER_CREATE        =     1,        // (event, player)
     *     PLAYER_EVENT_ON_CHARACTER_DELETE        =     2,        // (event, guid)
     *     PLAYER_EVENT_ON_LOGIN                   =     3,        // (event, player)
     *     PLAYER_EVENT_ON_LOGOUT                  =     4,        // (event, player)
     *     PLAYER_EVENT_ON_SPELL_CAST              =     5,        // (event, player, spell, skipCheck)
     *     PLAYER_EVENT_ON_KILL_PLAYER             =     6,        // (event, killer, killed)
     *     PLAYER_EVENT_ON_KILL_CREATURE           =     7,        // (event, killer, killed)
     *     PLAYER_EVENT_ON_KILLED_BY_CREATURE      =     8,        // (event, killer, killed)
     *     PLAYER_EVENT_ON_DUEL_REQUEST            =     9,        // (event, target, challenger)
     *     PLAYER_EVENT_ON_DUEL_START              =     10,       // (event, player1, player2)
     *     PLAYER_EVENT_ON_DUEL_END                =     11,       // (event, winner, loser, type)
     *     PLAYER_EVENT_ON_GIVE_XP                 =     12,       // (event, player, amount, victim) - Can return new XP amount
     *     PLAYER_EVENT_ON_LEVEL_CHANGE            =     13,       // (event, player, oldLevel)
     *     PLAYER_EVENT_ON_MONEY_CHANGE            =     14,       // (event, player, amount)
     *     PLAYER_EVENT_ON_REPUTATION_CHANGE       =     15,       // (event, player, factionId, standing, incremental) - Can return new standing
     *     PLAYER_EVENT_ON_TALENTS_CHANGE          =     16,       // (event, player, points)
     *     PLAYER_EVENT_ON_TALENTS_RESET           =     17,       // (event, player, noCost)
     *     PLAYER_EVENT_ON_CHAT                    =     18,       // (event, player, msg, Type, lang) - Can return false or new msg
     *     PLAYER_EVENT_ON_WHISPER                 =     19,       // (event, player, msg, Type, lang, receiver) - Can return false or new msg
     *     PLAYER_EVENT_ON_GROUP_CHAT              =     20,       // (event, player, msg, Type, lang, group) - Can return false or new msg
     *     PLAYER_EVENT_ON_GUILD_CHAT              =     21,       // (event, player, msg, Type, lang, guild) - Can return false or new msg
     *     PLAYER_EVENT_ON_CHANNEL_CHAT            =     22,       // (event, player, msg, Type, lang, channel) - Can return false or new msg
     *     PLAYER_EVENT_ON_EMOTE                   =     23,       // (event, player, emote) - Not triggered on any known emote
     *     PLAYER_EVENT_ON_TEXT_EMOTE              =     24,       // (event, player, textEmote, emoteNum, guid)
     *     PLAYER_EVENT_ON_SAVE                    =     25,       // (event, player)
     *     PLAYER_EVENT_ON_BIND_TO_INSTANCE        =     26,       // (event, player, difficulty, mapid, permanent)
     *     PLAYER_EVENT_ON_UPDATE_ZONE             =     27,       // (event, player, newZone, newArea)
     *     PLAYER_EVENT_ON_MAP_CHANGE              =     28,       // (event, player)
     *
     *     // Custom
     *     PLAYER_EVENT_ON_EQUIP                   =     29,       // (event, player, item, bag, slot)
     *     PLAYER_EVENT_ON_FIRST_LOGIN             =     30,       // (event, player)
     *     PLAYER_EVENT_ON_CAN_USE_ITEM            =     31,       // (event, player, itemEntry)
     *     PLAYER_EVENT_ON_LOOT_ITEM               =     32,       // (event, player, item, count)
     *     PLAYER_EVENT_ON_ENTER_COMBAT            =     33,       // (event, player, enemy)
     *     PLAYER_EVENT_ON_LEAVE_COMBAT            =     34,       // (event, player)
     *     PLAYER_EVENT_ON_REPOP                   =     35,       // (event, player)
     *     PLAYER_EVENT_ON_RESURRECT               =     36,       // (event, player)
     *     PLAYER_EVENT_ON_LOOT_MONEY              =     37,       // (event, player, amount)
     *     PLAYER_EVENT_ON_QUEST_ABANDON           =     38,       // (event, player, questId)
     *     // UNUSED                               =     39,       // (event, player)
     *     // UNUSED                               =     40,       // (event, player)
     *     // UNUSED                               =     41,       // (event, player)
     *     PLAYER_EVENT_ON_COMMAND                 =     42,       // (event, player, command) - player is nil if command used from console. Can return false
     *
     *     PLAYER_EVENT_COUNT
     * };
     * 
* * @param uint32 event : [Player] event Id, refer to PlayerEvents above * @param function function : function to register */ int RegisterPlayerEvent(Eluna* E, lua_State* L) { uint32 ev = Eluna::CHECKVAL(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushvalue(L, 2); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_PLAYER, 0, ev, functionRef); return 0; } /** * Registers a [Guild] event * *
     * enum GuildEvents
     * {
     *     // Guild
     *     GUILD_EVENT_ON_ADD_MEMBER               =     1,       // (event, guild, player, rank)
     *     GUILD_EVENT_ON_REMOVE_MEMBER            =     2,       // (event, guild, isDisbanding)
     *     GUILD_EVENT_ON_MOTD_CHANGE              =     3,       // (event, guild, newMotd)
     *     GUILD_EVENT_ON_INFO_CHANGE              =     4,       // (event, guild, newInfo)
     *     GUILD_EVENT_ON_CREATE                   =     5,       // (event, guild, leader, name)  // Not on TC
     *     GUILD_EVENT_ON_DISBAND                  =     6,       // (event, guild)
     *     GUILD_EVENT_ON_MONEY_WITHDRAW           =     7,       // (event, guild, player, amount, isRepair)
     *     GUILD_EVENT_ON_MONEY_DEPOSIT            =     8,       // (event, guild, player, amount)
     *     GUILD_EVENT_ON_ITEM_MOVE                =     9,       // (event, guild, player, item, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId)   // TODO
     *     GUILD_EVENT_ON_EVENT                    =     10,      // (event, guild, eventType, plrGUIDLow1, plrGUIDLow2, newRank)  // TODO
     *     GUILD_EVENT_ON_BANK_EVENT               =     11,      // (event, guild, eventType, tabId, playerGUIDLow, itemOrMoney, itemStackCount, destTabId)
     *
     *     GUILD_EVENT_COUNT
     * };
     * 
* * @param uint32 event : [Guild] event Id, refer to GuildEvents above * @param function function : function to register */ int RegisterGuildEvent(Eluna* E, lua_State* L) { uint32 ev = Eluna::CHECKVAL(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushvalue(L, 2); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_GUILD, 0, ev, functionRef); return 0; } /** * Registers a [Group] event * *
     * enum GroupEvents
     * {
     *     // Group
     *     GROUP_EVENT_ON_MEMBER_ADD               =     1,       // (event, group, guid)
     *     GROUP_EVENT_ON_MEMBER_INVITE            =     2,       // (event, group, guid)
     *     GROUP_EVENT_ON_MEMBER_REMOVE            =     3,       // (event, group, guid, method, kicker, reason)
     *     GROUP_EVENT_ON_LEADER_CHANGE            =     4,       // (event, group, newLeaderGuid, oldLeaderGuid)
     *     GROUP_EVENT_ON_DISBAND                  =     5,       // (event, group)
     *     GROUP_EVENT_ON_CREATE                   =     6,       // (event, group, leaderGuid, groupType)
     *
     *     GROUP_EVENT_COUNT
     * };
     * 
* * @param uint32 event : [Group] event Id, refer to GroupEvents above * @param function function : function to register */ int RegisterGroupEvent(Eluna* E, lua_State* L) { uint32 ev = Eluna::CHECKVAL(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushvalue(L, 2); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_GROUP, 0, ev, functionRef); return 0; } /** * Registers a [Creature] gossip event * *
     * enum GossipEvents
     * {
     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. For item gossip can return false to stop spell *casting.
     *     GOSSIP_EVENT_ON_SELECT                          = 2,    // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is *only for player gossip
     *     GOSSIP_EVENT_COUNT
     * };
     * 
* * @param uint32 menu_id : [Creature] entry Id * @param uint32 event : [Creature] gossip event Id, refer to GossipEvents above * @param function function : function to register */ int RegisterCreatureGossipEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_CREATURE_GOSSIP, entry, ev, functionRef); return 0; } /** * Registers a [GameObject] gossip event * *
     * enum GossipEvents
     * {
     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. For item gossip can return false to stop spell *casting.
     *     GOSSIP_EVENT_ON_SELECT                          = 2,    // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is *only for player gossip
     *     GOSSIP_EVENT_COUNT
     * };
     * 
* * @param uint32 menu_id : [GameObject] entry Id * @param uint32 event : [GameObject] gossip event Id, refer to GossipEvents above * @param function function : function to register */ int RegisterGameObjectGossipEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_GAMEOBJECT_GOSSIP, entry, ev, functionRef); return 0; } /** * Registers an [Item] event * *
     * enum ItemEvents
     * {
     *     ITEM_EVENT_ON_DUMMY_EFFECT                      = 1,    // (event, caster, spellid, effindex, item)
     *     ITEM_EVENT_ON_USE                               = 2,    // (event, player, item, target) - Can return false to stop the spell casting
     *     ITEM_EVENT_ON_QUEST_ACCEPT                      = 3,    // (event, player, item, quest)
     *     ITEM_EVENT_ON_EXPIRE                            = 4,    // (event, player, itemid)
     *     ITEM_EVENT_ON_REMOVE                            = 5,    // (event, player, item)
     *     ITEM_EVENT_COUNT
     * };
     * 
* * @param uint32 entry : [Item] entry Id * @param uint32 event : [Item] event Id, refer to ItemEvents above * @param function function : function to register */ int RegisterItemEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_ITEM, entry, ev, functionRef); return 0; } /** * Registers an [Item] gossip event * *
     * enum GossipEvents
     * {
     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. For item gossip can return false to stop spell *casting.
     *     GOSSIP_EVENT_ON_SELECT                          = 2,    // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is *only for player gossip
     *     GOSSIP_EVENT_COUNT
     * };
     * 
* * @param uint32 entry : [Item] entry Id * @param uint32 event : [Item] gossip event Id, refer to GossipEvents above * @param function function : function to register */ int RegisterItemGossipEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_ITEM_GOSSIP, entry, ev, functionRef); return 0; } /** * Registers a [Player] gossip event * *
     * enum GossipEvents
     * {
     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. For item gossip can return false to stop spell *casting.
     *     GOSSIP_EVENT_ON_SELECT                          = 2,    // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is *only for player gossip
     *     GOSSIP_EVENT_COUNT
     * };
     * 
* * @param uint32 menu_id : [Player] gossip menu Id * @param uint32 event : [Player] gossip event Id, refer to GossipEvents above * @param function function : function to register */ int RegisterPlayerGossipEvent(Eluna* E, lua_State* L) { uint32 menu_id = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_PLAYER_GOSSIP, menu_id, ev, functionRef); return 0; } /** * Registers a [Creature] event * *
     * enum CreatureEvents
     * {
     *     CREATURE_EVENT_ON_ENTER_COMBAT                    = 1,  // (event, creature, target)
     *     CREATURE_EVENT_ON_LEAVE_COMBAT                    = 2,  // (event, creature)
     *     CREATURE_EVENT_ON_TARGET_DIED                     = 3,  // (event, creature, victim)
     *     CREATURE_EVENT_ON_DIED                            = 4,  // (event, creature, killer)
     *     CREATURE_EVENT_ON_SPAWN                           = 5,  // (event, creature)
     *     CREATURE_EVENT_ON_REACH_WP                        = 6,  // (event, creature, type, id)
     *     CREATURE_EVENT_ON_AIUPDATE                        = 7,  // (event, creature, diff)
     *     CREATURE_EVENT_ON_RECEIVE_EMOTE                   = 8,  // (event, creature, player, emoteid)
     *     CREATURE_EVENT_ON_DAMAGE_TAKEN                    = 9,  // (event, creature, attacker, damage) - Can return new damage
     *     CREATURE_EVENT_ON_PRE_COMBAT                      = 10, // (event, creature, target)
     *     CREATURE_EVENT_ON_ATTACKED_AT                     = 11, // (event, creature, attacker)
     *     CREATURE_EVENT_ON_OWNER_ATTACKED                  = 12, // (event, creature, target)    // Not on mangos
     *     CREATURE_EVENT_ON_OWNER_ATTACKED_AT               = 13, // (event, creature, attacker)  // Not on mangos
     *     CREATURE_EVENT_ON_HIT_BY_SPELL                    = 14, // (event, creature, caster, spellid)
     *     CREATURE_EVENT_ON_SPELL_HIT_TARGET                = 15, // (event, creature, target, spellid)
     *     // UNUSED                                         = 16, // (event, creature)
     *     // UNUSED                                         = 17, // (event, creature)
     *     // UNUSED                                         = 18, // (event, creature)
     *     CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE          = 19, // (event, creature, summon)
     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN       = 20, // (event, creature, summon)
     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED          = 21, // (event, creature, summon, killer)    // Not on mangos
     *     CREATURE_EVENT_ON_SUMMONED                        = 22, // (event, creature, summoner)
     *     CREATURE_EVENT_ON_RESET                           = 23, // (event, creature)
     *     CREATURE_EVENT_ON_REACH_HOME                      = 24, // (event, creature)
     *     // UNUSED                                         = 25, // (event, creature)
     *     CREATURE_EVENT_ON_CORPSE_REMOVED                  = 26, // (event, creature, respawndelay) - Can return new respawndelay
     *     CREATURE_EVENT_ON_MOVE_IN_LOS                     = 27, // (event, creature, unit) - Does not actually check LOS. Just uses the sight range
     *     // UNUSED                                         = 28, // (event, creature)
     *     // UNUSED                                         = 29, // (event, creature)
     *     CREATURE_EVENT_ON_DUMMY_EFFECT                    = 30, // (event, caster, spellid, effindex, creature)
     *     CREATURE_EVENT_ON_QUEST_ACCEPT                    = 31, // (event, player, creature, quest)
     *     // UNUSED                                         = 32, // (event, creature)
     *     // UNUSED                                         = 33, // (event, creature)
     *     CREATURE_EVENT_ON_QUEST_REWARD                    = 34, // (event, player, creature, quest, opt)
     *     CREATURE_EVENT_ON_DIALOG_STATUS                   = 35, // (event, player, creature)
     *     CREATURE_EVENT_ON_ADD                             = 36, // (event, creature)
     *     CREATURE_EVENT_ON_REMOVE                          = 37, // (event, creature)
     *     CREATURE_EVENT_COUNT
     * };
     * 
* * @param uint32 entry : [Creature] entry Id * @param uint32 event : [Creature] event Id, refer to CreatureEvents above * @param function function : function to register */ int RegisterCreatureEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_CREATURE, entry, ev, functionRef); return 0; } /** * Registers a [GameObject] event * *
     * enum GameObjectEvents
     * {
     *     GAMEOBJECT_EVENT_ON_AIUPDATE                    = 1,    // (event, go, diff)
     *     GAMEOBJECT_EVENT_ON_SPAWN                       = 2,    // (event, go)
     *     GAMEOBJECT_EVENT_ON_DUMMY_EFFECT                = 3,    // (event, caster, spellid, effindex, go)
     *     GAMEOBJECT_EVENT_ON_QUEST_ACCEPT                = 4,    // (event, player, go, quest)
     *     GAMEOBJECT_EVENT_ON_QUEST_REWARD                = 5,    // (event, player, go, quest, opt)
     *     GAMEOBJECT_EVENT_ON_DIALOG_STATUS               = 6,    // (event, player, go)
     *     GAMEOBJECT_EVENT_ON_DESTROYED                   = 7,    // (event, go, player)
     *     GAMEOBJECT_EVENT_ON_DAMAGED                     = 8,    // (event, go, player)
     *     GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE           = 9,    // (event, go, state)
     *     GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED            = 10,   // (event, go, state)
     *     // UNUSED                                       = 11,   // (event, gameobject)
     *     GAMEOBJECT_EVENT_ON_ADD                         = 12,   // (event, gameobject)
     *     GAMEOBJECT_EVENT_ON_REMOVE                      = 13,   // (event, gameobject)
     *     GAMEOBJECT_EVENT_COUNT
     * };
     * 
* * @param uint32 entry : [GameObject] entry Id * @param uint32 event : [GameObject] event Id, refer to GameObjectEvents above * @param function function : function to register */ int RegisterGameObjectEvent(Eluna* E, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 ev = Eluna::CHECKVAL(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); lua_pushvalue(L, 3); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_GAMEOBJECT, entry, ev, functionRef); return 0; } /** * Registers a [Battleground] event * *
     * enum BGEvents
     * {
     *     BG_EVENT_ON_START                               = 1,    // (event, bg, bgId, instanceId) - Needs to be added to TC
     *     BG_EVENT_ON_END                                 = 2,    // (event, bg, bgId, instanceId, winner) - Needs to be added to TC
     *     BG_EVENT_ON_CREATE                              = 3,    // (event, bg, bgId, instanceId) - Needs to be added to TC
     *     BG_EVENT_ON_PRE_DESTROY                         = 4,    // (event, bg, bgId, instanceId) - Needs to be added to TC
     *     BG_EVENT_COUNT
     * };
     * 
* * @param uint32 event : [Battleground] event Id, refer to BGEvents above * @param function function : function to register */ int RegisterBGEvent(Eluna* E, lua_State* L) { uint32 ev = Eluna::CHECKVAL(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushvalue(L, 2); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef > 0) E->Register(HookMgr::REGTYPE_BG, 0, ev, functionRef); return 0; } /** * Reloads the Lua Engine * */ int ReloadEluna(Eluna* /*E*/, lua_State* /*L*/) { Eluna::reload = true; return 0; } /** * Sends a message to the world * * @param string message : message to send */ int SendWorldMessage(Eluna* /*E*/, lua_State* L) { const char* message = Eluna::CHECKVAL(L, 1); eWorld->SendServerMessage(SERVER_MSG_STRING, message); return 0; } /** * Executes world database sql [Query] instantly and returns QueryResult object * * @param string query : sql [Query] to run * @return QueryResult result */ int WorldDBQuery(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); #ifdef TRINITY ElunaQuery result = WorldDatabase.Query(query); if (result) Eluna::Push(L, new ElunaQuery(result)); else Eluna::Push(L); #else ElunaQuery* result = WorldDatabase.QueryNamed(query); if (result) Eluna::Push(L, result); else Eluna::Push(L); #endif return 1; } /** * Executes a sql [Query] (not instantly) to your world database * * @param string query : sql [Query] to execute */ int WorldDBExecute(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); WorldDatabase.Execute(query); return 0; } /** * Executes character database sql [Query] instantly and returns QueryResult object * * @param string query : sql [Query] to run * @return [Query] result */ int CharDBQuery(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); #ifdef TRINITY QueryResult result = CharacterDatabase.Query(query); if (result) Eluna::Push(L, new QueryResult(result)); else Eluna::Push(L); #else QueryNamedResult* result = CharacterDatabase.QueryNamed(query); if (result) Eluna::Push(L, result); else Eluna::Push(L); #endif return 1; } /** * Executes a [Query] (not instantly) to your character database * * @param string query : sql [Query] to execute */ int CharDBExecute(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); CharacterDatabase.Execute(query); return 0; } /** * Executes auth database sql [Query] instantly and returns QueryResult object * * @param string query : sql [Query] to run * @return [Query] result */ int AuthDBQuery(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); #ifdef TRINITY QueryResult result = LoginDatabase.Query(query); if (result) Eluna::Push(L, new QueryResult(result)); else Eluna::Push(L); #else QueryNamedResult* result = LoginDatabase.QueryNamed(query); if (result) Eluna::Push(L, result); else Eluna::Push(L); #endif return 1; } /** * Executes a [Query] (not instantly ) to your auth database * * @param string query : sql [Query] to execute */ int AuthDBExecute(Eluna* /*E*/, lua_State* L) { const char* query = Eluna::CHECKVAL(L, 1); LoginDatabase.Execute(query); return 0; } /** * Registers a global timed event * When the passed function is called, the parameters `(eventId, delay, repeats)` are passed to it. * Repeats will decrease on each call if the event does not repeat indefinitely * * @param function function : function to trigger when the time has passed * @param uint32 delay : set time in milliseconds for the event to trigger * @param uint32 repeats : how many times for the event to repeat, 0 is infinite * @return int eventId : unique ID for the timed event used to cancel it or nil */ int CreateLuaEvent(Eluna* E, lua_State* L) { luaL_checktype(L, 1, LUA_TFUNCTION); uint32 delay = Eluna::CHECKVAL(L, 2); uint32 repeats = Eluna::CHECKVAL(L, 3); lua_pushvalue(L, 1); int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); if (functionRef != LUA_REFNIL && functionRef != LUA_NOREF) { E->eventMgr->globalProcessor->AddEvent(functionRef, delay, repeats); Eluna::Push(L, functionRef); } return 1; } /** * Removes a global timed event specified by the event ID * * @param int eventId : event Id to remove * @param bool all_Events = false : remove from all events, not just global */ int RemoveEventById(Eluna* E, lua_State* L) { int eventId = Eluna::CHECKVAL(L, 1); bool all_Events = Eluna::CHECKVAL(L, 1, false); // not thread safe if (all_Events) E->eventMgr->RemoveEvent(eventId); else E->eventMgr->globalProcessor->RemoveEvent(eventId); return 0; } /** * Removes all global timed events * * @param bool all_Events = false : remove all events, not just global */ int RemoveEvents(Eluna* E, lua_State* L) { bool all_Events = Eluna::CHECKVAL(L, 1, false); // not thread safe if (all_Events) E->eventMgr->RemoveEvents(); else E->eventMgr->globalProcessor->RemoveEvents(); return 0; } /** * Performs an ingame spawn and returns [Creature] or [GameObject] dependent on spawnType * * @param int32 spawnType : type of object to spawn, 1 = [Creature], 2 = [GameObject] * @param uint32 entry : entry ID of the [Creature] or [GameObject] * @param uint32 mapId : map ID to spawn the [Creature] or [GameObject] in * @param uint32 instanceId : instance ID to put the [Creature] or [GameObject] in. Non instance is 0 * @param float x : x coordinate of the [Creature] or [GameObject] * @param float y : y coordinate of the [Creature] or [GameObject] * @param float z : z coordinate of the [Creature] or [GameObject] * @param float o : o facing/orientation of the [Creature] or [GameObject] * @param bool save = false : optional to save the [Creature] or [GameObject] to the database * @param uint32 durorresptime = 0 : despawn time of the [Creature] if it's not saved or respawn time of [GameObject] * @param uint32 phase = 1 : phase to put the [Creature] or [GameObject] in * @return [WorldObject] worldObject : returns [Creature] or [GameObject] */ int PerformIngameSpawn(Eluna* /*E*/, lua_State* L) { int spawntype = Eluna::CHECKVAL(L, 1); uint32 entry = Eluna::CHECKVAL(L, 2); uint32 mapID = Eluna::CHECKVAL(L, 3); uint32 instanceID = Eluna::CHECKVAL(L, 4); float x = Eluna::CHECKVAL(L, 5); float y = Eluna::CHECKVAL(L, 6); float z = Eluna::CHECKVAL(L, 7); float o = Eluna::CHECKVAL(L, 8); bool save = Eluna::CHECKVAL(L, 9, false); uint32 durorresptime = Eluna::CHECKVAL(L, 10, 0); #if (!defined(TBC) && !defined(CLASSIC)) uint32 phase = Eluna::CHECKVAL(L, 11, PHASEMASK_NORMAL); if (!phase) { Eluna::Push(L); return 1; } #endif #ifndef TRINITY Map* map = eMapMgr->FindMap(mapID, instanceID); if (!map) { Eluna::Push(L); return 1; } if (spawntype == 1) // spawn creature { if (save) { CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(entry); if (!cinfo) { Eluna::Push(L); return 1; } #if (defined(TBC) || defined(CLASSIC)) CreatureCreatePos pos(map, x, y, z, o); #else CreatureCreatePos pos(map, x, y, z, o, phase); #endif Creature* pCreature = new Creature; // used guids from specially reserved range (can be 0 if no free values) uint32 lowguid = eObjectMgr->GenerateStaticCreatureLowGuid(); if (!lowguid) { Eluna::Push(L); return 1; } if (!pCreature->Create(lowguid, pos, cinfo)) { delete pCreature; Eluna::Push(L); return 1; } #ifdef TBC pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); #elif defined(CLASSIC) pCreature->SaveToDB(map->GetId()); #else pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); #endif uint32 db_guid = pCreature->GetGUIDLow(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); pCreature->LoadFromDB(db_guid, map); map->Add(pCreature); eObjectMgr->AddCreatureToGrid(db_guid, eObjectMgr->GetCreatureData(db_guid)); if (durorresptime) pCreature->ForcedDespawn(durorresptime); Eluna::Push(L, pCreature); } else { CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(entry); if (!cinfo) { Eluna::Push(L); return 1; } TemporarySummon* pCreature = new TemporarySummon(ObjectGuid(uint64(0))); #if (defined(TBC) || defined(CLASSIC)) CreatureCreatePos pos(map, x, y, z, o); #else CreatureCreatePos pos(map, x, y, z, o, phase); #endif if (!pCreature->Create(map->GenerateLocalLowGuid(cinfo->GetHighGuid()), pos, cinfo, TEAM_NONE)) { delete pCreature; { Eluna::Push(L); return 1; } } pCreature->SetRespawnCoord(pos); // Active state set before added to map pCreature->SetActiveObjectState(false); // Also initializes the AI and MMGen pCreature->Summon(durorresptime ? TEMPSUMMON_TIMED_OR_DEAD_DESPAWN : TEMPSUMMON_MANUAL_DESPAWN, durorresptime); // Creature Linking, Initial load is handled like respawn if (pCreature->IsLinkingEventTrigger()) map->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_RESPAWN, pCreature); Eluna::Push(L, pCreature); } return 1; } if (spawntype == 2) // Spawn object { if (save) { const GameObjectInfo* gInfo = ObjectMgr::GetGameObjectInfo(entry); if (!gInfo) { Eluna::Push(L); return 1; } // used guids from specially reserved range (can be 0 if no free values) uint32 db_lowGUID = eObjectMgr->GenerateStaticGameObjectLowGuid(); if (!db_lowGUID) { Eluna::Push(L); return 1; } GameObject* pGameObj = new GameObject; #if (defined(TBC) || defined(CLASSIC)) if (!pGameObj->Create(db_lowGUID, gInfo->id, map, x, y, z, o)) #else if (!pGameObj->Create(db_lowGUID, gInfo->id, map, phase, x, y, z, o)) #endif { delete pGameObj; Eluna::Push(L); return 1; } if (durorresptime) pGameObj->SetRespawnTime(durorresptime); // fill the gameobject data and save to the db #ifdef TBC pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); #elif defined(CLASSIC) pGameObj->SaveToDB(map->GetId()); #else pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); #endif // this will generate a new guid if the object is in an instance if (!pGameObj->LoadFromDB(db_lowGUID, map)) { delete pGameObj; Eluna::Push(L); return 1; } // DEBUG_LOG(GetMangosString(LANG_GAMEOBJECT_CURRENT), gInfo->name, db_lowGUID, x, y, z, o); map->Add(pGameObj); eObjectMgr->AddGameobjectToGrid(db_lowGUID, eObjectMgr->GetGOData(db_lowGUID)); Eluna::Push(L, pGameObj); } else { GameObject* pGameObj = new GameObject; #if (defined(TBC) || defined(CLASSIC)) if (!pGameObj->Create(map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT), entry, map, x, y, z, o)) #else if (!pGameObj->Create(map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT), entry, map, phase, x, y, z, o)) #endif { delete pGameObj; Eluna::Push(L); return 1; } pGameObj->SetRespawnTime(durorresptime / IN_MILLISECONDS); map->Add(pGameObj); Eluna::Push(L, pGameObj); } return 1; } #else Map* map = eMapMgr->FindMap(mapID, instanceID); if (!map) { Eluna::Push(L); return 1; } Position pos = { x, y, z, o }; if (spawntype == 1) // spawn creature { if (save) { Creature* creature = new Creature(); if (!creature->Create(eObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, x, y, z, o)) { delete creature; Eluna::Push(L); return 1; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); uint32 db_lowguid = creature->GetDBTableGUIDLow(); if (!creature->LoadCreatureFromDB(db_lowguid, map)) { delete creature; Eluna::Push(L); return 1; } eObjectMgr->AddCreatureToGrid(db_lowguid, eObjectMgr->GetCreatureData(db_lowguid)); Eluna::Push(L, creature); } else { TempSummon* creature = map->SummonCreature(entry, pos, NULL, durorresptime); if (!creature) { Eluna::Push(L); return 1; } if (durorresptime) creature->SetTempSummonType(TEMPSUMMON_TIMED_OR_DEAD_DESPAWN); else creature->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN); Eluna::Push(L, creature); } return 1; } if (spawntype == 2) // Spawn object { const GameObjectTemplate* objectInfo = eObjectMgr->GetGameObjectTemplate(entry); if (!objectInfo) { Eluna::Push(L); return 1; } if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) { Eluna::Push(L); return 1; } GameObject* object = new GameObject; uint32 lowguid = eObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); if (!object->Create(lowguid, objectInfo->entry, map, phase, x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; Eluna::Push(L); return 1; } if (durorresptime) object->SetRespawnTime(durorresptime); if (save) { // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); // this will generate a new lowguid if the object is in an instance if (!object->LoadGameObjectFromDB(lowguid, map)) { delete object; Eluna::Push(L); return 1; } eObjectMgr->AddGameobjectToGrid(lowguid, eObjectMgr->GetGOData(lowguid)); } else map->AddToMap(object); Eluna::Push(L, object); return 1; } #endif Eluna::Push(L); return 1; } /** * Creates a [WorldPacket] * * @param uint32 opcode : opcode to create * @param uint32 size : size of opcode * @return [WorldPacket] packet */ int CreatePacket(Eluna* /*E*/, lua_State* L) { uint32 opcode = Eluna::CHECKVAL(L, 1); uint32 size = Eluna::CHECKVAL(L, 2); if (opcode >= NUM_MSG_TYPES) return luaL_argerror(L, 1, "valid opcode expected"); Eluna::Push(L, new WorldPacket((OpcodesList)opcode, size)); return 1; } /** * Adds an [Item] to a vendor * * @param uint32 entry : [Creature] entry Id * @param uint32 item : [Item] entry Id * @param int32 maxcount : max [Item] stack count * @param uint32 incrtime : combined with maxcount, incrtime tells how often (in seconds) the vendor list is refreshed and the limited [Item] copies are restocked * @param uint32 extendedcost : unique cost of an [Item], such as conquest points for example */ int AddVendorItem(Eluna* /*E*/, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 item = Eluna::CHECKVAL(L, 2); int maxcount = Eluna::CHECKVAL(L, 3); uint32 incrtime = Eluna::CHECKVAL(L, 4); uint32 extendedcost = Eluna::CHECKVAL(L, 5); #ifndef TRINITY if (!eObjectMgr->IsVendorItemValid(false, "npc_vendor", entry, item, maxcount, incrtime, extendedcost, 0)) return 0; #ifndef CLASSIC eObjectMgr->AddVendorItem(entry, item, maxcount, incrtime, extendedcost); #else eObjectMgr->AddVendorItem(entry, item, maxcount, incrtime); #endif #else #ifdef CATA if (!eObjectMgr->IsVendorItemValid(entry, item, maxcount, incrtime, extendedcost, 1)) return 0; eObjectMgr->AddVendorItem(entry, item, maxcount, incrtime, extendedcost, 1); #else if (!eObjectMgr->IsVendorItemValid(entry, item, maxcount, incrtime, extendedcost)) return 0; eObjectMgr->AddVendorItem(entry, item, maxcount, incrtime, extendedcost); #endif #endif return 0; } /** * Removes an [Item] from a vendor * * @param uint32 entry : [Creature] entry Id * @param uint32 item : [Item] entry Id */ int VendorRemoveItem(Eluna* /*E*/, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); uint32 item = Eluna::CHECKVAL(L, 2); if (!eObjectMgr->GetCreatureTemplate(entry)) return luaL_argerror(L, 1, "valid CreatureEntry expected"); #ifdef CATA eObjectMgr->RemoveVendorItem(entry, item, 1); #else eObjectMgr->RemoveVendorItem(entry, item); #endif return 0; } /** * Removes all [Item]s from a vendor * * @param uint32 entry : [Creature] entry Id */ int VendorRemoveAllItems(Eluna* /*E*/, lua_State* L) { uint32 entry = Eluna::CHECKVAL(L, 1); VendorItemData const* items = eObjectMgr->GetNpcVendorItemList(entry); if (!items || items->Empty()) return 0; VendorItemList const itemlist = items->m_items; for (VendorItemList::const_iterator itr = itemlist.begin(); itr != itemlist.end(); ++itr) #ifdef CATA eObjectMgr->RemoveVendorItem(entry, (*itr)->item, 1); #else eObjectMgr->RemoveVendorItem(entry, (*itr)->item); #endif return 0; } /** * Kicks a [Player] from the server * * @param [Player] player : [Player] to kick */ int Kick(Eluna* /*E*/, lua_State* L) { Player* player = Eluna::CHECKOBJ(L, 1); player->GetSession()->KickPlayer(); return 0; } /** * Ban's a [Player]'s account, character or IP * *
     * enum BanMode
     * {
     *     BAN_ACCOUNT,
     *     BAN_CHARACTER,
     *     BAN_IP
     * };
     * 
* * @param int32 banMode : method of ban, refer to BanMode above * @param string nameOrIP : name of the [Player] or IP of the [Player] * @param uint32 duration : duration (in seconds) of the ban * @param string reason = "" : ban reason, this is optional * @param string whoBanned = "" : the [Player]'s name that banned the account, character or IP, this is optional */ int Ban(Eluna* /*E*/, lua_State* L) { int banMode = Eluna::CHECKVAL(L, 1); std::string nameOrIP = Eluna::CHECKVAL(L, 2); uint32 duration = Eluna::CHECKVAL(L, 3); const char* reason = Eluna::CHECKVAL(L, 4, ""); const char* whoBanned = Eluna::CHECKVAL(L, 5, ""); switch (banMode) { case BAN_ACCOUNT: #ifdef CATA if (!Utf8ToUpperOnlyLatin(nameOrIP)) return 0; #else if (!AccountMgr::normalizeString(nameOrIP)) return 0; #endif break; case BAN_CHARACTER: if (!normalizePlayerName(nameOrIP)) return 0; break; case BAN_IP: if (!IsIPAddress(nameOrIP.c_str())) return 0; break; default: return 0; } eWorld->BanAccount((BanMode)banMode, nameOrIP, duration, reason, whoBanned); return 0; } /** * Saves all [Player]s * */ int SaveAllPlayers(Eluna* /*E*/, lua_State* /*L*/) { eObjectAccessor->SaveAllPlayers(); return 0; } /** * Sends mail to a [Player] * There can be several item entry-amount pairs at the end of the function. There can be maximum of 12 different items. * *
     * enum MailStationery
     * {
     *     MAIL_STATIONERY_TEST = 1,
     *     MAIL_STATIONERY_DEFAULT = 41,
     *     MAIL_STATIONERY_GM = 61,
     *     MAIL_STATIONERY_AUCTION = 62,
     *     MAIL_STATIONERY_VAL = 64, // Valentine
     *     MAIL_STATIONERY_CHR = 65, // Christmas
     *     MAIL_STATIONERY_ORP = 67 // Orphan
     * };
     * 
* * @param string subject : title (subject) of the mail * @param string text : contents of the mail * @param uint32 receiverGUIDLow : low GUID of the receiver * @param uint32 senderGUIDLow = 0 : low GUID of the sender * @param uint32 stationary = MAIL_STATIONERY_DEFAULT : type of mail that is being sent as, refer to MailStationery above * @param uint32 delay = 0 : mail send delay in milliseconds * @param uint32 money = 0 : money to send * @param uint32 cod = 0 : cod money amount * @param uint32 entry = 0 : entry of an [Item] to send with mail * @param uint32 amount = 0 : amount of the [Item] to send with mail */ int SendMail(Eluna* /*E*/, lua_State* L) { int i = 0; std::string subject = Eluna::CHECKVAL(L, ++i); std::string text = Eluna::CHECKVAL(L, ++i); uint32 receiverGUIDLow = Eluna::CHECKVAL(L, ++i); uint32 senderGUIDLow = Eluna::CHECKVAL(L, ++i, 0); uint32 stationary = Eluna::CHECKVAL(L, ++i, MAIL_STATIONERY_DEFAULT); uint32 delay = Eluna::CHECKVAL(L, ++i, 0); uint32 money = Eluna::CHECKVAL(L, ++i, 0); uint32 cod = Eluna::CHECKVAL(L, ++i, 0); int argAmount = lua_gettop(L); MailSender sender(MAIL_NORMAL, senderGUIDLow, (MailStationery)stationary); MailDraft draft(subject, text); #ifdef TRINITY if (cod) draft.AddCOD(cod); if (money) draft.AddMoney(money); #else if (cod) draft.SetCOD(cod); if (money) draft.SetMoney(money); #endif #ifdef TRINITY SQLTransaction trans = CharacterDatabase.BeginTransaction(); #endif uint8 addedItems = 0; while (addedItems <= MAX_MAIL_ITEMS && i + 2 <= argAmount) { uint32 entry = Eluna::CHECKVAL(L, ++i); uint32 amount = Eluna::CHECKVAL(L, ++i); #ifndef TRINITY ItemTemplate const* item_proto = ObjectMgr::GetItemPrototype(entry); #else ItemTemplate const* item_proto = eObjectMgr->GetItemTemplate(entry); #endif if (!item_proto) { luaL_error(L, "Item entry %d does not exist", entry); continue; } if (amount < 1 || (item_proto->MaxCount > 0 && amount > uint32(item_proto->MaxCount))) { luaL_error(L, "Item entry %d has invalid amount %d", entry, amount); continue; } if (Item* item = Item::CreateItem(entry, amount)) { #ifndef TRINITY item->SaveToDB(); #else item->SaveToDB(trans); #endif draft.AddItem(item); ++addedItems; } } #ifndef TRINITY draft.SendMailTo(MailReceiver(MAKE_NEW_GUID(receiverGUIDLow, 0, HIGHGUID_PLAYER)), sender); #else draft.SendMailTo(trans, MailReceiver(receiverGUIDLow), sender, MAIL_CHECK_MASK_NONE, delay); CharacterDatabase.CommitTransaction(trans); #endif return 0; } /** * Returns the result of bitwise and: a & b * * @param uint32 a * @param uint32 b * @return uint32 result */ int bit_and(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); uint32 b = Eluna::CHECKVAL(L, 2); Eluna::Push(L, a & b); return 1; } /** * Returns the result of bitwise or: a | b * * @param uint32 a * @param uint32 b * @return uint32 result */ int bit_or(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); uint32 b = Eluna::CHECKVAL(L, 2); Eluna::Push(L, a | b); return 1; } /** * Returns the result of bitwise left shift: a << b * * @param uint32 a * @param uint32 b * @return uint32 result */ int bit_lshift(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); uint32 b = Eluna::CHECKVAL(L, 2); Eluna::Push(L, a << b); return 1; } /** * Returns the result of bitwise right shift: a >> b * * @param uint32 a * @param uint32 b * @return uint32 result */ int bit_rshift(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); uint32 b = Eluna::CHECKVAL(L, 2); Eluna::Push(L, a >> b); return 1; } /** * Returns the result of bitwise xor: a ^ b * * @param uint32 a * @param uint32 b * @return uint32 result */ int bit_xor(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); uint32 b = Eluna::CHECKVAL(L, 2); Eluna::Push(L, a ^ b); return 1; } /** * Returns the result of bitwise not: ~a * * @param uint32 a * @return uint32 result */ int bit_not(Eluna* /*E*/, lua_State* L) { uint32 a = Eluna::CHECKVAL(L, 1); Eluna::Push(L, ~a); return 1; } /** * Adds a taxi path to a specified map, returns the used pathId * Related function: [Player:StartTaxi] * *
     * -- Execute on startup
     * local pathTable = {{mapid, x, y, z}, {mapid, x, y, z}}
     * local path = AddTaxiPath(pathTable, 28135, 28135)
     * -- Execute when the player should fly
     * player:StartTaxi(path)
     * 
* * @param table waypoints : table containing waypoints: {map, x, y, z[, actionFlag, delay]} * @param uint32 mountA : alliance [Creature] entry * @param uint32 mountH : horde [Creature] entry * @param uint32 price = 0 : price of the taxi path * @param uint32 pathId = 0 : path Id of the taxi path * @return uint32 actualPathId */ int AddTaxiPath(Eluna* /*E*/, lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); uint32 mountA = Eluna::CHECKVAL(L, 2); uint32 mountH = Eluna::CHECKVAL(L, 3); uint32 price = Eluna::CHECKVAL(L, 4, 0); uint32 pathId = Eluna::CHECKVAL(L, 5, 0); lua_pushvalue(L, 1); std::list nodes; int start = lua_gettop(L); int end = start; Eluna::Push(L); while (lua_next(L, -2) != 0) { luaL_checktype(L, -1, LUA_TTABLE); Eluna::Push(L); while (lua_next(L, -2) != 0) { lua_insert(L, end++); } if (start == end) continue; if (end - start < 4) // no mandatory args, dont add { while (end != start) if (!lua_isnone(L, --end)) lua_remove(L, end); continue; } while (end - start < 8) // fill optional args with 0 { Eluna::Push(L, 0); lua_insert(L, end++); } TaxiPathNodeEntry* entry = new TaxiPathNodeEntry(); // mandatory entry->mapid = Eluna::CHECKVAL(L, start); entry->x = Eluna::CHECKVAL(L, start + 1); entry->y = Eluna::CHECKVAL(L, start + 2); entry->z = Eluna::CHECKVAL(L, start + 3); // optional entry->actionFlag = Eluna::CHECKVAL(L, start + 4, 0); entry->delay = Eluna::CHECKVAL(L, start + 5, 0); nodes.push_back(*entry); while (end != start) // remove args if (!lua_isnone(L, --end)) lua_remove(L, end); lua_pop(L, 1); } if (nodes.size() < 2) { Eluna::Push(L); return 1; } if (!pathId) pathId = sTaxiPathNodesByPath.size(); if (sTaxiPathNodesByPath.size() <= pathId) sTaxiPathNodesByPath.resize(pathId + 1); sTaxiPathNodesByPath[pathId].clear(); sTaxiPathNodesByPath[pathId].resize(nodes.size()); static uint32 nodeId = 500; uint32 startNode = nodeId; uint32 index = 0; for (std::list::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { TaxiPathNodeEntry entry = *it; entry.path = pathId; TaxiNodesEntry* nodeEntry = new TaxiNodesEntry(); nodeEntry->ID = index; nodeEntry->map_id = entry.mapid; nodeEntry->MountCreatureID[0] = mountH; nodeEntry->MountCreatureID[1] = mountA; nodeEntry->x = entry.x; nodeEntry->y = entry.y; nodeEntry->z = entry.z; sTaxiNodesStore.SetEntry(nodeId, nodeEntry); entry.index = nodeId++; sTaxiPathNodesByPath[pathId].set(index++, TaxiPathNodePtr(new TaxiPathNodeEntry(entry))); } if (startNode >= nodeId) { Eluna::Push(L); return 1; } sTaxiPathSetBySource[startNode][nodeId - 1] = TaxiPathBySourceAndDestination(pathId, price); Eluna::Push(L, pathId); return 1; } /** * Adds a [Corpse] to the world * * @param [Corpse] corpse : [Corpse] to add */ int AddCorpse(Eluna* /*E*/, lua_State* L) { Corpse* corpse = Eluna::CHECKOBJ(L, 1); eObjectAccessor->AddCorpse(corpse); return 0; } /** * Removes a [Corpse] from the world * * @param [Corpse] corpse : [Corpse] to remove */ int RemoveCorpse(Eluna* /*E*/, lua_State* L) { Corpse* corpse = Eluna::CHECKOBJ(L, 1); eObjectAccessor->RemoveCorpse(corpse); Eluna::CHECKOBJ(L, 1)->Invalidate(); return 1; } /** * Converts a [Corpse] by guid, also allows for insignia to be looted * * @param uint64 playerGUID : guid of the [Player] * @param bool insignia = false : if true, it allows insignia to be looted * @return [Corpse] corpse : returns converted [Corpse] */ int ConvertCorpseForPlayer(Eluna* /*E*/, lua_State* L) { uint64 guid = Eluna::CHECKVAL(L, 1); bool insignia = Eluna::CHECKVAL(L, 2, false); Eluna::Push(L, eObjectAccessor->ConvertCorpseForPlayer(ObjectGuid(guid), insignia)); return 0; } /** * Removes old [Corpse]s from the world * */ int RemoveOldCorpses(Eluna* /*E*/, lua_State* L) { eObjectAccessor->RemoveOldCorpses(); return 0; } /** * Finds [Weather] in a zone, also returns [Weather] * * @param uint32 zoneId : zone Id to check for [Weather] * @return [Weather] weather */ int FindWeather(Eluna* /*E*/, lua_State* L) { uint32 zoneId = Eluna::CHECKVAL(L, 1); #ifndef TRINITY Weather* weather = eWorld->FindWeather(zoneId); #else Weather* weather = WeatherMgr::FindWeather(zoneId); #endif Eluna::Push(L, weather); return 1; } /** * Adds [Weather] to a zone, also returns [Weather] * * @param uint32 zoneId : zone Id to add [Weather] * @return [Weather] weather */ int AddWeather(Eluna* /*E*/, lua_State* L) { uint32 zoneId = Eluna::CHECKVAL(L, 1); #ifndef TRINITY Weather* weather = eWorld->AddWeather(zoneId); #else Weather* weather = WeatherMgr::AddWeather(zoneId); #endif Eluna::Push(L, weather); return 1; } /** * Removes [Weather] from a zone * * @param uint32 zoneId : zone Id to remove [Weather] */ int RemoveWeather(Eluna* /*E*/, lua_State* L) { uint32 zoneId = Eluna::CHECKVAL(L, 1); #ifndef TRINITY eWorld->RemoveWeather(zoneId); #else WeatherMgr::RemoveWeather(zoneId); #endif return 0; } /** * Sends normal [Weather] to a [Player] * * @param [Player] player : [Player] to send the normal weather to */ int SendFineWeatherToPlayer(Eluna* /*E*/, lua_State* L) { Player* player = Eluna::CHECKOBJ(L, 1); #ifndef TRINITY Weather::SendFineWeatherUpdateToPlayer(player); #else WeatherMgr::SendFineWeatherUpdateToPlayer(player); #endif return 0; } /** * Returns true if the bag and slot is a valid inventory position, otherwise false * *
     * Possible and most commonly used combinations:
     *
     * bag = 255
     * slots 0-18 equipment
     * slots 19-22 equipped bag slots
     * slots 23-38 backpack
     * slots 39-66 bank main slots
     * slots 67-74 bank bag slots
     * slots 86-117 keyring
     *
     * bag = 19-22
     * slots 0-35 for equipped bags
     *
     * bag = 67-74
     * slots 0-35 for bank bags
     * 
* * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] * @return bool isInventoryPos */ int IsInventoryPos(Eluna* /*E*/, lua_State* L) { uint8 bag = Eluna::CHECKVAL(L, 1); uint8 slot = Eluna::CHECKVAL(L, 2); Eluna::Push(L, Player::IsInventoryPos(bag, slot)); return 1; } /** * Returns true if the bag and slot is a valid equipment position, otherwise false * *
     * Possible and most commonly used combinations:
     *
     * bag = 255
     * slots 0-18 equipment
     * slots 19-22 equipped bag slots
     * slots 23-38 backpack
     * slots 39-66 bank main slots
     * slots 67-74 bank bag slots
     * slots 86-117 keyring
     *
     * bag = 19-22
     * slots 0-35 for equipped bags
     *
     * bag = 67-74
     * slots 0-35 for bank bags
     * 
* * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] * @return bool isEquipmentPosition */ int IsEquipmentPos(Eluna* /*E*/, lua_State* L) { uint8 bag = Eluna::CHECKVAL(L, 1); uint8 slot = Eluna::CHECKVAL(L, 2); Eluna::Push(L, Player::IsEquipmentPos(bag, slot)); return 1; } /** * Returns true if the bag and slot is a valid bank position, otherwise false * *
     * Possible and most commonly used combinations:
     *
     * bag = 255
     * slots 0-18 equipment
     * slots 19-22 equipped bag slots
     * slots 23-38 backpack
     * slots 39-66 bank main slots
     * slots 67-74 bank bag slots
     * slots 86-117 keyring
     *
     * bag = 19-22
     * slots 0-35 for equipped bags
     *
     * bag = 67-74
     * slots 0-35 for bank bags
     * 
* * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] * @return bool isBankPosition */ int IsBankPos(Eluna* /*E*/, lua_State* L) { uint8 bag = Eluna::CHECKVAL(L, 1); uint8 slot = Eluna::CHECKVAL(L, 2); Eluna::Push(L, Player::IsBankPos(bag, slot)); return 1; } /** * Returns true if the bag and slot is a valid bag position, otherwise false * *
     * Possible and most commonly used combinations:
     *
     * bag = 255
     * slots 0-18 equipment
     * slots 19-22 equipped bag slots
     * slots 23-38 backpack
     * slots 39-66 bank main slots
     * slots 67-74 bank bag slots
     * slots 86-117 keyring
     *
     * bag = 19-22
     * slots 0-35 for equipped bags
     *
     * bag = 67-74
     * slots 0-35 for bank bags
     * 
* * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] * @return bool isBagPosition */ int IsBagPos(Eluna* /*E*/, lua_State* L) { uint8 bag = Eluna::CHECKVAL(L, 1); uint8 slot = Eluna::CHECKVAL(L, 2); Eluna::Push(L, Player::IsBagPos((bag << 8) + slot)); return 1; } /** * Returns current time in ms * * @return uint32 currTime */ int GetCurrTime(Eluna* /*E*/, lua_State* L) { Eluna::Push(L, ElunaUtil::GetCurrTime()); return 1; } /** * Returns difference from a [Global:GetCurrTime] time to now * * @param uint32 oldTime * @return uint32 timeDiff */ int GetTimeDiff(Eluna* /*E*/, lua_State* L) { uint32 oldtimems = Eluna::CHECKVAL(L, 1); Eluna::Push(L, ElunaUtil::GetTimeDiff(oldtimems)); return 1; } std::string GetStackAsString(lua_State* L) { std::ostringstream oss; for (int i = 1; i <= lua_gettop(L); ++i) oss << luaL_tolstring(L, i, NULL); return oss.str(); } /** * Prints given parameters to the info log * * @param ... variableArguments */ int PrintInfo(Eluna* /*E*/, lua_State* L) { ELUNA_LOG_INFO("%s", GetStackAsString(L).c_str()); return 0; } /** * Prints given parameters to the error log * * @param ... variableArguments */ int PrintError(Eluna* /*E*/, lua_State* L) { ELUNA_LOG_ERROR("%s", GetStackAsString(L).c_str()); return 0; } /** * Prints given parameters to the debug log * * @param ... variableArguments */ int PrintDebug(Eluna* /*E*/, lua_State* L) { ELUNA_LOG_DEBUG("%s", GetStackAsString(L).c_str()); return 0; } } #endif