diff --git a/data/libs/functions/player.lua b/data/libs/functions/player.lua index ac1706a364f..5b20c93f07f 100644 --- a/data/libs/functions/player.lua +++ b/data/libs/functions/player.lua @@ -679,3 +679,19 @@ function Player:canFightBoss(bossNameOrId) local cooldown = self:getBossCooldown(bossNameOrId) return cooldown > os.time() and false or true end + +function Player.addAddonToAllOutfits(self, addon) + for sex = 0, 1 do + local outfits = Game.getOutfits(sex) + for outfit = 1, #outfits do + self:addOutfitAddon(outfits[outfit].lookType, addon) + end + end +end + +function Player.addAllMounts(self) + local mounts = Game.getMounts() + for mount = 1, #mounts do + self:addMount(mounts[mount].id) + end +end diff --git a/data/scripts/talkactions/god/add_addons.lua b/data/scripts/talkactions/god/add_addons.lua index 5498ae1e11b..acb578c7c08 100644 --- a/data/scripts/talkactions/god/add_addons.lua +++ b/data/scripts/talkactions/god/add_addons.lua @@ -1,242 +1,6 @@ -- /addaddons playername local addons = TalkAction("/addaddons") -local looktypes = { - - -- Female Outfits - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 147, - 148, - 149, - 150, - 155, - 156, - 157, - 158, - 252, - 269, - 270, - 279, - 288, - 324, - 329, - 336, - 366, - 431, - 433, - 464, - 466, - 471, - 513, - 514, - 542, - 575, - 578, - 618, - 620, - 632, - 635, - 636, - 664, - 666, - 683, - 694, - 696, - 698, - 724, - 732, - 745, - 749, - 759, - 845, - 852, - 874, - 885, - 900, - 909, - 929, - 956, - 958, - 963, - 965, - 967, - 969, - 971, - 973, - 975, - 1020, - 1024, - 1043, - 1050, - 1057, - 1070, - 1095, - 1103, - 1128, - 1147, - 1162, - 1174, - 1187, - 1203, - 1205, - 1207, - 1211, - 1244, - 1246, - 1252, - 1271, - 1280, - 1283, - 1289, - 1293, - 1323, - 1332, - 1339, - 1372, - 1383, - 1385, - 1387, - 1416, - 1437, - 1445, - 1450, - 1456, - 1461, - 1490, - 1501, - 1569, - 1576, - 1582, - 1598, - 1613, - 1619, - 1663, - 1676, - 1681, - - -- Male Outfits - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 143, - 144, - 145, - 146, - 151, - 152, - 153, - 154, - 251, - 268, - 273, - 278, - 289, - 325, - 328, - 335, - 367, - 430, - 432, - 463, - 465, - 472, - 512, - 516, - 541, - 574, - 577, - 610, - 619, - 633, - 634, - 637, - 665, - 667, - 684, - 695, - 697, - 699, - 725, - 733, - 746, - 750, - 760, - 846, - 853, - 873, - 884, - 899, - 908, - 931, - 955, - 957, - 962, - 964, - 966, - 968, - 970, - 972, - 974, - 1021, - 1023, - 1042, - 1051, - 1056, - 1069, - 1094, - 1102, - 1127, - 1146, - 1161, - 1173, - 1186, - 1202, - 1204, - 1206, - 1210, - 1243, - 1245, - 1251, - 1270, - 1279, - 1282, - 1288, - 1292, - 1322, - 1331, - 1338, - 1371, - 1382, - 1384, - 1386, - 1415, - 1436, - 1444, - 1449, - 1457, - 1460, - 1489, - 1500, - 1568, - 1575, - 1581, - 1597, - 1612, - 1618, - 1662, - 1675, - 1680, -} function addons.onSay(player, words, param) -- create log @@ -263,9 +27,7 @@ function addons.onSay(player, words, param) return true end - for i = 1, #looktypes do - target:addOutfitAddon(looktypes[i], 3) - end + target:addAddonToAllOutfits(3) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All addons unlocked for " .. target:getName() .. ".") target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All of your addons have been unlocked!") diff --git a/data/scripts/talkactions/god/add_mounts.lua b/data/scripts/talkactions/god/add_mounts.lua index 6a589327039..dc3380a0f2d 100644 --- a/data/scripts/talkactions/god/add_mounts.lua +++ b/data/scripts/talkactions/god/add_mounts.lua @@ -18,9 +18,7 @@ function mounts.onSay(player, words, param) return true end - for i = 1, 217 do - target:addMount(i) - end + target:addAllMounts() player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All mounts unlocked for: " .. target:getName()) target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All of your mounts have been unlocked!") diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp index 8510502b226..ec938e4e277 100644 --- a/src/lua/callbacks/event_callback.cpp +++ b/src/lua/callbacks/event_callback.cpp @@ -64,7 +64,7 @@ bool EventCallback::creatureOnChangeOutfit(std::shared_ptr creature, c LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); - LuaScriptInterface::pushOutfit(L, outfit); + LuaScriptInterface::pushOutfitType(L, outfit); return getScriptInterface()->callFunction(2); } diff --git a/src/lua/creature/events.cpp b/src/lua/creature/events.cpp index 176044d666e..caa5b83c55c 100644 --- a/src/lua/creature/events.cpp +++ b/src/lua/creature/events.cpp @@ -240,7 +240,7 @@ bool Events::eventCreatureOnChangeOutfit(std::shared_ptr creature, con LuaScriptInterface::pushUserdata(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); - LuaScriptInterface::pushOutfit(L, outfit); + LuaScriptInterface::pushOutfitType(L, outfit); return scriptInterface.callFunction(2); } diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index cab8c599a21..fc570513687 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -782,3 +782,42 @@ int GameFunctions::luaGameGetEventCallbacks(lua_State* L) { lua_pop(L, 1); return 1; } + +int GameFunctions::luaGameGetOutfits(lua_State* L) { + // Game.getOutfits(playerSex) + if (!isNumber(L, 1)) { + lua_pushnil(L); + return 1; + } + + PlayerSex_t playerSex = getNumber(L, 1); + if (playerSex > PLAYERSEX_LAST) { + lua_pushnil(L); + return 1; + } + + const auto outfits = Outfits::getInstance().getOutfits(playerSex); + lua_createtable(L, outfits.size(), 0); + + int index = 0; + for (const auto outfit : outfits) { + pushOutfit(L, outfit); + lua_rawseti(L, -2, ++index); + } + + return 1; +} + +int GameFunctions::luaGameGetMounts(lua_State* L) { + // Game.getMounts() + const auto mounts = g_game().mounts.getMounts(); + lua_createtable(L, mounts.size(), 0); + + int index = 0; + for (const auto mount : mounts) { + pushMount(L, mount); + lua_rawseti(L, -2, ++index); + } + + return 1; +} diff --git a/src/lua/functions/core/game/game_functions.hpp b/src/lua/functions/core/game/game_functions.hpp index 95febd76e0d..86eabd4aaa4 100644 --- a/src/lua/functions/core/game/game_functions.hpp +++ b/src/lua/functions/core/game/game_functions.hpp @@ -81,6 +81,9 @@ class GameFunctions final : LuaScriptInterface { registerMethod(L, "Game", "getTalkActions", GameFunctions::luaGameGetTalkActions); registerMethod(L, "Game", "getEventCallbacks", GameFunctions::luaGameGetEventCallbacks); + + registerMethod(L, "Game", "getOutfits", GameFunctions::luaGameGetOutfits); + registerMethod(L, "Game", "getMounts", GameFunctions::luaGameGetMounts); } private: @@ -150,4 +153,7 @@ class GameFunctions final : LuaScriptInterface { static int luaGameGetTalkActions(lua_State* L); static int luaGameGetEventCallbacks(lua_State* L); + + static int luaGameGetOutfits(lua_State* L); + static int luaGameGetMounts(lua_State* L); }; diff --git a/src/lua/functions/creatures/creature_functions.cpp b/src/lua/functions/creatures/creature_functions.cpp index c5221a9c3ad..162718bcd64 100644 --- a/src/lua/functions/creatures/creature_functions.cpp +++ b/src/lua/functions/creatures/creature_functions.cpp @@ -608,7 +608,7 @@ int CreatureFunctions::luaCreatureGetOutfit(lua_State* L) { // creature:getOutfit() std::shared_ptr creature = getUserdataShared(L, 1); if (creature) { - pushOutfit(L, creature->getCurrentOutfit()); + pushOutfitType(L, creature->getCurrentOutfit()); } else { lua_pushnil(L); } diff --git a/src/lua/functions/creatures/monster/monster_type_functions.cpp b/src/lua/functions/creatures/monster/monster_type_functions.cpp index 0db51998ea7..34b5bf9a31e 100644 --- a/src/lua/functions/creatures/monster/monster_type_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_type_functions.cpp @@ -1156,7 +1156,7 @@ int MonsterTypeFunctions::luaMonsterTypeOutfit(lua_State* L) { const auto monsterType = getUserdataShared(L, 1); if (monsterType) { if (lua_gettop(L) == 1) { - pushOutfit(L, monsterType->info.outfit); + pushOutfitType(L, monsterType->info.outfit); } else { Outfit_t outfit = getOutfit(L, 2); if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS) && outfit.lookType != 0 && !g_game().isLookTypeRegistered(outfit.lookType)) { diff --git a/src/lua/functions/creatures/npc/npc_type_functions.cpp b/src/lua/functions/creatures/npc/npc_type_functions.cpp index f38032e4a4d..b2f6d15e9be 100644 --- a/src/lua/functions/creatures/npc/npc_type_functions.cpp +++ b/src/lua/functions/creatures/npc/npc_type_functions.cpp @@ -305,7 +305,7 @@ int NpcTypeFunctions::luaNpcTypeOutfit(lua_State* L) { const auto &npcType = getUserdataShared(L, 1); if (npcType) { if (lua_gettop(L) == 1) { - pushOutfit(L, npcType->info.outfit); + pushOutfitType(L, npcType->info.outfit); } else { Outfit_t outfit = getOutfit(L, 2); if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS) && outfit.lookType != 0 && !g_game().isLookTypeRegistered(outfit.lookType)) { diff --git a/src/lua/functions/lua_functions_loader.cpp b/src/lua/functions/lua_functions_loader.cpp index 0973876c294..34804f54747 100644 --- a/src/lua/functions/lua_functions_loader.cpp +++ b/src/lua/functions/lua_functions_loader.cpp @@ -584,7 +584,7 @@ void LuaFunctionsLoader::pushPosition(lua_State* L, const Position &position, in setMetatable(L, -1, "Position"); } -void LuaFunctionsLoader::pushOutfit(lua_State* L, const Outfit_t &outfit) { +void LuaFunctionsLoader::pushOutfitType(lua_State* L, const Outfit_t &outfit) { if (validateDispatcherContext(__FUNCTION__)) { return; } @@ -605,6 +605,28 @@ void LuaFunctionsLoader::pushOutfit(lua_State* L, const Outfit_t &outfit) { setField(L, "lookFamiliarsType", outfit.lookFamiliarsType); } +void LuaFunctionsLoader::pushOutfit(lua_State* L, const std::shared_ptr outfit) { + if (validateDispatcherContext(__FUNCTION__)) { + return; + } + + lua_createtable(L, 0, 5); + setField(L, "name", outfit->name); + setField(L, "looktype", outfit->lookType); + setField(L, "premium", outfit->premium); + setField(L, "unlocked", outfit->unlocked); + setField(L, "from", outfit->from); +} + +void LuaFunctionsLoader::pushMount(lua_State* L, const std::shared_ptr mount) { + lua_createtable(L, 0, 5); + setField(L, "name", mount->name); + setField(L, "speed", mount->speed); + setField(L, "clientId", mount->clientId); + setField(L, "id", mount->id); + setField(L, "premium", mount->premium); +} + void LuaFunctionsLoader::registerClass(lua_State* L, const std::string &className, const std::string &baseClass, lua_CFunction newFunction /* = nullptr*/) { // className = {} lua_newtable(L); diff --git a/src/lua/functions/lua_functions_loader.hpp b/src/lua/functions/lua_functions_loader.hpp index 89baf958e18..d608dbe827a 100644 --- a/src/lua/functions/lua_functions_loader.hpp +++ b/src/lua/functions/lua_functions_loader.hpp @@ -18,13 +18,15 @@ class Combat; class Creature; class Cylinder; class Game; +class Guild; class InstantSpell; class Item; +class KV; +class Mount; +class Outfit; class Player; class Thing; -class Guild; class Zone; -class KV; #define reportErrorFunc(a) reportError(__FUNCTION__, a, true) @@ -156,7 +158,9 @@ class LuaFunctionsLoader { static void pushCombatDamage(lua_State* L, const CombatDamage &damage); static void pushInstantSpell(lua_State* L, const InstantSpell &spell); static void pushPosition(lua_State* L, const Position &position, int32_t stackpos = 0); - static void pushOutfit(lua_State* L, const Outfit_t &outfit); + static void pushOutfitType(lua_State* L, const Outfit_t &outfit); + static void pushOutfit(lua_State* L, const std::shared_ptr outfit); + static void pushMount(lua_State* L, const std::shared_ptr mount); static void setField(lua_State* L, const char* index, lua_Number value) { lua_pushnumber(L, value);