From 5dafc242bdc8f9fd3cf0d4f8b7cb7f436de310ca Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Fri, 24 Nov 2023 14:56:20 -0300 Subject: [PATCH 1/5] Created tournament market custom, to buy items, outfits, mounts with tournament coins (item used as tournament coins: gold of bar). --- config.lua.dist | 1 + data-otservbr-global/npc/jeronimo.lua | 232 +++++++++++++++--- .../actions/custom/tournament_tokens.lua | 17 ++ .../scripts/globalevents/vip/online_coins.lua | 6 +- .../globalevents/vip/online_tokens.lua | 7 +- src/config/config_enums.hpp | 1 + src/config/configmanager.cpp | 1 + .../creatures/player/player_functions.cpp | 55 ++++- .../creatures/player/player_functions.hpp | 6 + 9 files changed, 289 insertions(+), 37 deletions(-) create mode 100644 data-otservbr-global/scripts/actions/custom/tournament_tokens.lua diff --git a/config.lua.dist b/config.lua.dist index 9d1ed2fa681..1e3425ac1c7 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -6,6 +6,7 @@ useAnyDatapackFolder = false dataPackDirectory = "data-otservbr-global" -- Don't change this unless you know what you're doing coreDirectory = "data" +tournamentCoinsName = "Tournament Coins" -- Set log level -- It can be trace, debug, info, warning, error, critical, off (default: info). diff --git a/data-otservbr-global/npc/jeronimo.lua b/data-otservbr-global/npc/jeronimo.lua index 5f9fdc122e3..c1801ddf46b 100644 --- a/data-otservbr-global/npc/jeronimo.lua +++ b/data-otservbr-global/npc/jeronimo.lua @@ -23,10 +23,13 @@ npcConfig.flags = { floorchange = false, } +local tournamentCoinName = configManager.getString(configKeys.TOURNAMENT_COINS_NAME) + npcConfig.voices = { interval = 15000, chance = 50, - { text = "Change your Bar of Gold's for Items here!" }, + { text = "Change your " .. tournamentCoinName .. " for Items here!" }, + { text = "Visit our Game Store -> Tournament Shopp to check the offers" }, } local keywordHandler = KeywordHandler:new() @@ -56,15 +59,58 @@ npcType.onCloseChannel = function(npc, creature) npcHandler:onCloseChannel(npc, creature) end --- ID, Count, Price +-- ID, Count, Price, Wrappable, Charges local eventShopItems = { - ["small stamina refill"] = { 22473, 1, 100 }, - ["zaoan chess box"] = { 18339, 1, 100 }, - ["pannier backpack"] = { 19159, 1, 70 }, - ["green light"] = { 21217, 1, 70 }, - ["blood herb"] = { 3734, 3, 10 }, - ["draken doll"] = { 12044, 1, 70 }, - ["bear doll"] = { 3001, 1, 70 }, + ["exercise sword"] = { 28552, 1, 25, false, 500 }, + ["exercise axe"] = { 28553, 1, 25, false, 500 }, + ["exercise club"] = { 28554, 1, 25, false, 500 }, + ["exercise bow"] = { 28555, 1, 25, false, 500 }, + ["exercise rod"] = { 28556, 1, 25, false, 500 }, + ["exercise wand"] = { 28557, 1, 25, false, 500 }, + + ["baby brain squid"] = { 32909, 1, 800, true }, + ["baby vulcongra"] = { 32908, 1, 800, true }, + ["cerberus champion puppy"] = { 31464, 1, 800, true }, + ["guzzlemaw grub"] = { 32907, 1, 800, true }, + ["jousting eagle baby"] = { 31462, 1, 800, true }, + ["demon doll"] = { 32918, 1, 400, true }, + ["ogre rowdy doll"] = { 32944, 1, 400, true }, + ["retching horror doll"] = { 32945, 1, 400, true }, + ["vexclaw doll"] = { 32943, 1, 400, true }, + + ["gilded blessed shield"] = { 37165, 1, 1500, true }, + ["gilded crown"] = { 34332, 1, 1500, true }, + ["gilded horned helmet"] = { 38640, 1, 1500, true }, + ["gilded magic longsword"] = { 36995, 1, 1500, true }, + ["gilded warlord sword"] = { 39767, 1, 1500, true }, + + ["sublime tournament accolade"] = { 31472, 1, 500, true }, + ["tournament accolade"] = { 31470, 1, 500, true }, + + ["sublime tournament carpet"] = { 31467, 1, 100, true }, + ["tournament carpet"] = { 31466, 1, 100, true }, + + ["carved table"] = { 32972, 1, 100, true }, + ["carved table centre"] = { 32974, 1, 100, true }, + ["carved table corner"] = { 32969, 1, 100, true }, + + ["cozy couch"] = { 32948, 1, 100, true }, + ["cozy couch left end"] = { 32948, 1, 100, true }, + ["cozy couch right end"] = { 32956, 1, 100, true }, + ["cozy couch corner"] = { 32964, 1, 100, true }, + + ["zaoan chess box"] = { 18339, 1, 200, false }, + ["pannier backpack"] = { 19159, 1, 150, false }, + ["green light"] = { 21217, 1, 80, false }, + ["blood herb"] = { 3734, 3, 30, false }, + + ["cerberus champion"] = { 146, 1, 1250, false, 9999999 }, + ["jousting eagle"] = { 145, 1, 1250, false, 9999999 }, + + ["full dragon slayer"] = { 1289, 1288, 5000, false, 8888888 }, + ["full lion of war"] = { 1207, 1206, 1750, false, 8888888 }, + ["full veteran paladin"] = { 1205, 1204, 750, false, 8888888 }, + ["full void master"] = { 1203, 1202, 750, false, 8888888 }, } local function creatureSayCallback(npc, creature, type, message) @@ -75,43 +121,169 @@ local function creatureSayCallback(npc, creature, type, message) return false end + local amountTournamentCoins = player:getTournamentCoins() message = string.lower(message) - if message == "event shop" then - npcHandler:say("In our website enter in {Events} => {Events Shop}.", npc, creature) + if message == "help" or message == tournamentCoinName:lower() then + npcHandler:say("In our game store -> Tournament Shop", npc, creature) + return true + elseif message == "balance" then + npcHandler:say(string.format("Your balance is %i %s%s!", amountTournamentCoins, tournamentCoinName:lower(), amountTournamentCoins > 1 and "s" or ""), npc, creature) + return true + elseif MsgContains(message, "categor") then + npcHandler:say("You can see items by category: {Exercise Weapons}, {Dolls}, {House Decorations}, {Utils}, {Outfits} or {Mounts}.", npc, creature) + npcHandler:setTopic(playerId, 1) + return true end - if eventShopItems[message] then + if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and eventShopItems[message] == nil then npcHandler:setTopic(playerId, 0) - local itemId, itemCount, itemPrice = eventShopItems[message][1], eventShopItems[message][2], eventShopItems[message][3] - if player:getItemCount(14112) > 0 then - npcHandler:say("You want buy {" .. message .. "} for " .. itemPrice .. "x?", npc, creature) - npcHandler:setTopic(message) + npcHandler:say("We can't find the item that you want, try again or access https://thorfinn.com.br/?thorfinncoins", npc, creature) + return true + end + + if npcHandler:getTopic(playerId) == 1 then + npcHandler:setTopic(playerId, 2) + local text = "We can't find the {category} that you want, try again or access https://thorfinn.com.br/?thorfinncoins" + if message == "exercise weapons" then + text = "{exercise sword} (25), {exercise axe} (25), {exercise club} (25), {exercise bow} (25), {exercise rod} (25), {exercise wand} (25). Each one with 500 charges" + elseif message == "dolls" then + text = "{baby brain squid} (800), {baby vulcongra} (800), {cerberus champion puppy} (800), {guzzlemaw grub} (800), {jousting eagle baby} (800), {demon doll} (400), {ogre rowdy doll} (400), {retching horror doll} (400), {vexclaw doll} (400)." + elseif message == "house decorations" then + text = "\nGilded: {gilded blessed shield} (1500), {gilded crown} (1500), {gilded horned helmet} (1500), {gilded magic longsword} (1500), {gilded warlord sword} (1500).\n" + .. "Accolade: {sublime tournament accolade} (500), {tournament accolade} (500).\n" + .. "Carpet: {sublime tournament carpet} (100), {tournament carpet} (100).\n" + .. "Table: {carved table} (100), {carved table centre} (100), {carved table corner} (100).\n" + .. "Cozy: {cozy couch} (100), {cozy couch left end} (100), {cozy couch right end} (100), {cozy couch corner} (100)." + elseif message == "utils" then + text = "{stamina extension} (300), {zaoan chess box} (200), {pannier backpack} (150), {green light} (80), {blood herb} (30)." + elseif message == "mounts" then + text = "{jousting eagle} (1500), {foxmouse} (2500), {doom skull} (4000), {corpsefire skull} (4000), {cerberus champion} (4000), {spirit of purity} (4000)." + elseif message == "outfits" then + text = "{full lion of war} (2000), {full veteran paladin} (2000), {full void master} (2000), {full dragon slayer} (5000)." + end + npcHandler:say(text, npc, creature) + return true + end + + if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and eventShopItems[message] ~= nil then + local selected = eventShopItems[message] + local itemCount, itemPrice, itemCharge = selected[2], selected[3], selected[5] or 0 + local descCharge = "" + if itemCharge > 0 and (itemCharge ~= 9999999 and itemCharge ~= 8888888) then + descCharge = " with " .. itemCharge .. " charges" + end + + if amountTournamentCoins > 0 and amountTournamentCoins >= itemPrice then + if itemCharge == 9999999 then + npcHandler:say(string.format("You want buy %s mount for %i %s? {yes} or {no}", message, itemPrice, tournamentCoinName:lower()), npc, creature) + npcHandler:setTopic("mount", message) + elseif itemCharge == 8888888 then + npcHandler:say(string.format("You want buy %s outfit for %i %s? {yes} or {no}", message, itemPrice, tournamentCoinName:lower()), npc, creature) + npcHandler:setTopic("outfit", message) + else + npcHandler:say(string.format("You want buy %ix %s%s for %i %s? {yes} or {no}", itemCount, message, descCharge, itemPrice, tournamentCoinName:lower()), npc, creature) + end + npcHandler:setTopic(playerId, 3) + npcHandler:setTopic("selected", selected) else - npcHandler:say("You don't have " .. itemPrice .. " {Bar of Gold(s)}!", npc, creature) - return true + npcHandler:say(string.format("You don't have %i {%s}!", itemPrice, tournamentCoinName), npc, creature) + npcHandler:setTopic(playerId, 0) + npcHandler:setTopic("selected", {}) + npcHandler:setTopic("outfit", {}) + npcHandler:setTopic("mount", {}) end + return true end - if eventShopItems[npcHandler:getTopic(playerId)] then - local itemId, itemCount, itemPrice = eventShopItems[npcHandler:getTopic(playerId)][1], eventShopItems[npcHandler:getTopic(playerId)][2], eventShopItems[npcHandler:getTopic(playerId)][3] - if message == "no" then + if npcHandler:getTopic(playerId) == 3 then + if message ~= "yes" then npcHandler:say("So... what you want?", npc, creature) npcHandler:setTopic(playerId, 0) - elseif message == "yes" then - if player:getItemCount(14112) >= itemPrice then - npcHandler:say("You bought {" .. npcHandler:getTopic(playerId) .. "} " .. itemCount .. "x for " .. itemPrice .. " {Bar of Gold(s)}!", npc, creature) - player:removeItem(14112, itemPrice) - player:addItem(itemId, itemCount) - else - npcHandler:say("You don't have enough bar's.", npc, creature) + npcHandler:setTopic("selected", {}) + return true + else + local selected = npcHandler:getTopic("selected") + if not selected or selected == nil then + npcHandler:setTopic(playerId, 0) + npcHandler:setTopic("selected", {}) + logger.error("[jeronimo]: item not selected") return true end + + local itemId, itemCount, itemPrice, isWrappable, itemCharge = selected[1], selected[2], selected[3], selected[4] or false, selected[5] or 0 + + if itemCharge == 9999999 then + if player:hasMount(itemId) then + npcHandler:say("You already own this mount.", npc, creature) + return true + end + player:updateTournamentCoins(itemPrice, "remove") + player:addMount(itemId) + local mountName = npcHandler:getTopic("mount") + local msg = string.format("You bought %s mount for %i {%s}!", mountName, itemPrice, tournamentCoinName) + player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) + npcHandler:say(msg, npc, creature) + npcHandler:setTopic(playerId, 0) + npcHandler:setTopic("selected", {}) + npcHandler:setTopic("mount", {}) + elseif itemCharge == 8888888 then + local female, male = itemCount, itemId + if player:hasOutfit(female) or player:hasOutfit(male) then + npcHandler:say("You already own this outfit.", npc, creature) + return true + end + player:updateTournamentCoins(itemPrice, "remove") + player:addOutfitAddon(female, 3) + player:addOutfitAddon(male, 3) + local outfitName = npcHandler:getTopic("outfit") + local msg = string.format("You bought %s outfit for %i {%s}!", outfitName, itemPrice, tournamentCoinName) + player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) + npcHandler:say(msg, npc, creature) + npcHandler:setTopic(playerId, 0) + npcHandler:setTopic("selected", {}) + npcHandler:setTopic("outfit", {}) + else + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + local itemT = ItemType(itemId) + if amountTournamentCoins >= itemPrice then + if inbox and inbox:getEmptySlots() > 0 and player:getFreeCapacity() >= itemT:getCapacity() then + player:updateTournamentCoins(itemPrice, "remove") + + if itemCharge > 0 then + local addedItem = player:addItem(itemId, itemCount, true) + addedItem:setAttribute("charges", itemCharge) + else + if isWrappable then + local decoKit = inbox:addItem(ITEM_DECORATION_KIT, 1) + if decoKit then + decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "Unwrap it in your own house to create a <" .. itemT:getName() .. ">.") + decoKit:setCustomAttribute("unWrapId", itemId) + decoKit:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime()) + player:sendUpdateContainer(inbox) + end + else + player:addItem(itemId, itemCount) + end + end + local descCharge = itemCharge > 0 and " with " .. itemCharge .. " charges" or "" + local msg = string.format("You bought %ix %s%s for %i {%s} and received in your store inbox!", itemCount, itemT:getName(), descCharge, itemPrice, tournamentCoinName) + player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) + npcHandler:say(msg, npc, creature) + npcHandler:setTopic(playerId, 0) + npcHandler:setTopic("selected", {}) + else + npcHandler:say("You need to have capacity and empty slots to receive.", npc, creature) + end + else + npcHandler:say(string.format("You don't have enough {%s}.", tournamentCoinName), npc, creature) + end + end end end + return true end +npcHandler:setMessage(MESSAGE_GREET, "Welcome |PLAYERNAME|! You can see my offers by {categories} or if you want to change your " .. tournamentCoinName:lower() .. " to items, just say the item name! If you want help, say {help}! Or do you want know your {balance}?") npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true) - --- npcType registering the npcConfig table npcType:register(npcConfig) diff --git a/data-otservbr-global/scripts/actions/custom/tournament_tokens.lua b/data-otservbr-global/scripts/actions/custom/tournament_tokens.lua new file mode 100644 index 00000000000..5aef9deaf67 --- /dev/null +++ b/data-otservbr-global/scripts/actions/custom/tournament_tokens.lua @@ -0,0 +1,17 @@ +local token = Action() + +local tokenId = 14112 -- bar of gold (if you don't use custom item, you need to verify all drops in monsters) + +function token.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getItemCount(tokenId) > 0 then + local tournamentCoins = player:getItemCount(tokenId) + db.query("UPDATE `accounts` SET `tournament_coins` = `tournament_coins` + '" .. tournamentCoins .. "' WHERE `id` = '" .. player:getAccountId() .. "';") + player:sendTextMessage(MESSAGE_INFO_DESCR, string.format("You added %d %s to your account.", tournamentCoins, configManager.getString(configKeys.TOURNAMENT_COINS_NAME):lower())) + player:removeItem(tokenId, tournamentCoins) + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + return true +end + +token:id(tokenId) +token:register() diff --git a/data-otservbr-global/scripts/globalevents/vip/online_coins.lua b/data-otservbr-global/scripts/globalevents/vip/online_coins.lua index f249752397d..e75f23bde7a 100644 --- a/data-otservbr-global/scripts/globalevents/vip/online_coins.lua +++ b/data-otservbr-global/scripts/globalevents/vip/online_coins.lua @@ -8,7 +8,7 @@ local config = { -- per hour | system will calculate how many coins will be given and when -- put 0 in coinsPerHour.free to disable free from receiving coins coinsPerHour = { - free = 1, + free = 0, vip = 5, }, @@ -43,8 +43,8 @@ function onlineCoinsEvent.onThink(interval) player:setStorageValue(config.storage, coins * 10000000) if coins >= config.awardOn then local coinsMath = math.floor(coins) - player:addTibiaCoins(coinsMath, true) - player:sendTextMessage(MESSAGE_FAILURE, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), coinsMath, "tibia coins")) + player:addTibiaCoins(coinsMath, false) + player:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), coinsMath, "tibia coins")) player:setStorageValue(config.storage, (coins - coinsMath) * 10000000) end end diff --git a/data-otservbr-global/scripts/globalevents/vip/online_tokens.lua b/data-otservbr-global/scripts/globalevents/vip/online_tokens.lua index 656039dfe66..4a0a86ca58d 100644 --- a/data-otservbr-global/scripts/globalevents/vip/online_tokens.lua +++ b/data-otservbr-global/scripts/globalevents/vip/online_tokens.lua @@ -3,9 +3,9 @@ local config = { storage = Storage.VipSystem.OnlineTokensGain, checkDuplicateIps = false, - tokenItemId = 14112, -- bar of gold + tokenItemId = 14112, -- bar of gold (if you don't use custom item, you need to verify all drops in monsters) - interval = 60 * 1000, + interval = 60 * 1000, -- 1 hora -- per hour | system will calculate how many tokens will be given and when -- put 0 in tokensPerHour.free to disable free from receiving tokens @@ -30,6 +30,7 @@ function onlineTokensEvent.onThink(interval) return true end + local tournamentCoinName = configManager.getString(configKeys.TOURNAMENT_COINS_NAME) local checkIp = {} for _, player in pairs(players) do if player:getGroup():getId() > GROUP_TYPE_SENIORTUTOR then @@ -46,7 +47,7 @@ function onlineTokensEvent.onThink(interval) local tokensMath = math.floor(tokens) local item = player:addItem(config.tokenItemId, tokensMath) if item then - player:sendTextMessage(MESSAGE_FAILURE, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), tokensMath, "tokens")) + player:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), tokensMath, tournamentCoinName)) end player:setStorageValue(config.storage, (tokens - tokensMath) * 10000000) end diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp index 0e53c97546e..f93ed9c8238 100644 --- a/src/config/config_enums.hpp +++ b/src/config/config_enums.hpp @@ -304,6 +304,7 @@ enum ConfigKey_t : uint16_t { TOGGLE_SERVER_IS_RETRO, TOGGLE_TRAVELS_FREE, TOGGLE_WHEELSYSTEM, + TOURNAMENT_COINS_NAME, TRANSCENDANCE_AVATAR_DURATION, TRANSCENDANCE_CHANCE_FORMULA_A, TRANSCENDANCE_CHANCE_FORMULA_B, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 35d2cf3b1be..3166226e15a 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -367,6 +367,7 @@ bool ConfigManager::load() { loadStringConfig(L, SERVER_NAME, "serverName", ""); loadStringConfig(L, STORE_IMAGES_URL, "coinImagesURL", ""); loadStringConfig(L, TIBIADROME_CONCOCTION_TICK_TYPE, "tibiadromeConcoctionTickType", "online"); + loadStringConfig(L, TOURNAMENT_COINS_NAME, "tournamentCoinsName", "Tournament Coins"); loadStringConfig(L, URL, "url", ""); loadStringConfig(L, WORLD_TYPE, "worldType", "pvp"); diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index 5f14db6ea99..22e9a8e83a2 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -2569,7 +2569,7 @@ int PlayerFunctions::luaPlayerAddTibiaCoins(lua_State* L) { return 1; } - if (player->account->addCoins(enumToValue(CoinType::Normal), getNumber(L, 2)) != enumToValue(AccountErrors_t::Ok)) { + if (player->account->addCoins(enumToValue(CoinType::Normal), getNumber(L, 2), "") != enumToValue(AccountErrors_t::Ok)) { reportErrorFunc("Failed to add coins"); lua_pushnil(L); return 1; @@ -2681,6 +2681,59 @@ int PlayerFunctions::luaPlayerRemoveTransferableCoins(lua_State* L) { return 1; } +int PlayerFunctions::luaPlayerGetTournamentCoins(lua_State* L) { + // player:getTournamentCoins() + std::shared_ptr player = getUserdataShared(L, 1); + if (!player || !player->getAccount()) { + reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); + lua_pushnil(L); + return 1; + } + + auto [coins, result] = player->getAccount()->getCoins(account::CoinType::TOURNAMENT); + + if (result == account::ERROR_NO) { + lua_pushnumber(L, coins); + } + + return 1; +} + +int PlayerFunctions::luaPlayerUpdateTournamentCoins(lua_State* L) { + // player:updateTournamentCoins(coins, action: 'add' | 'remove') + std::shared_ptr player = getUserdataShared(L, 1); + if (!player || !player->getAccount()) { + reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); + lua_pushnil(L); + return 1; + } + + std::string tournamentCoinName = asLowerCaseString(g_configManager().getString(TOURNAMENT_COINS_NAME, __FUNCTION__)); + const std::string &action = getString(L, 3); + uint32_t amount = getNumber(L, 2); + if (action == "add" && player->account->addCoins(account::CoinType::TOURNAMENT, amount, "", false) != account::ERROR_NO) { + reportErrorFunc(fmt::format("Failed to update (add) {}", tournamentCoinName)); + lua_pushnil(L); + return 1; + } else if (action == "remove" && player->account->removeCoins(account::CoinType::TOURNAMENT, amount) != account::ERROR_NO) { + if (player->account->removeCoins(account::CoinType::COIN, getNumber(L, 2)) != account::ERROR_NO) { + reportErrorFunc(fmt::format("Failed to update (remove) {}", tournamentCoinName)); + lua_pushnil(L); + return 1; + } + } + + if (player->getAccount()->save() != account::ERROR_NO) { + reportErrorFunc("Failed to save account"); + lua_pushnil(L); + return 1; + } + + pushBoolean(L, true); + + return 1; +} + int PlayerFunctions::luaPlayerHasBlessing(lua_State* L) { // player:hasBlessing(blessing) uint8_t blessing = getNumber(L, 2); diff --git a/src/lua/functions/creatures/player/player_functions.hpp b/src/lua/functions/creatures/player/player_functions.hpp index 4d89a86d27f..9a9c77927b9 100644 --- a/src/lua/functions/creatures/player/player_functions.hpp +++ b/src/lua/functions/creatures/player/player_functions.hpp @@ -227,6 +227,9 @@ class PlayerFunctions final : LuaScriptInterface { registerMethod(L, "Player", "addTransferableCoins", PlayerFunctions::luaPlayerAddTransferableCoins); registerMethod(L, "Player", "removeTransferableCoins", PlayerFunctions::luaPlayerRemoveTransferableCoins); + registerMethod(L, "Player", "getTournamentCoins", PlayerFunctions::luaPlayerGetTournamentCoins); + registerMethod(L, "Player", "updateTournamentCoins", PlayerFunctions::luaPlayerUpdateTournamentCoins); + registerMethod(L, "Player", "hasBlessing", PlayerFunctions::luaPlayerHasBlessing); registerMethod(L, "Player", "addBlessing", PlayerFunctions::luaPlayerAddBlessing); registerMethod(L, "Player", "removeBlessing", PlayerFunctions::luaPlayerRemoveBlessing); @@ -587,6 +590,9 @@ class PlayerFunctions final : LuaScriptInterface { static int luaPlayerAddTransferableCoins(lua_State* L); static int luaPlayerRemoveTransferableCoins(lua_State* L); + static int luaPlayerGetTournamentCoins(lua_State* L); + static int luaPlayerUpdateTournamentCoins(lua_State* L); + static int luaPlayerHasBlessing(lua_State* L); static int luaPlayerAddBlessing(lua_State* L); static int luaPlayerRemoveBlessing(lua_State* L); From 705d6895e16f13bbbce3cca0a64aae1fd0df621f Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Sat, 25 Nov 2023 08:55:54 -0300 Subject: [PATCH 2/5] Adjusted prices and npc jeronimo. (offers will only be shown in game store, but isn't purchasable, ONLY IN NPC) --- data-otservbr-global/npc/jeronimo.lua | 246 +++++----- data/modules/scripts/gamestore/gamestore.lua | 460 +++++++++++++------ data/modules/scripts/gamestore/init.lua | 1 + 3 files changed, 462 insertions(+), 245 deletions(-) diff --git a/data-otservbr-global/npc/jeronimo.lua b/data-otservbr-global/npc/jeronimo.lua index c1801ddf46b..8a76261496c 100644 --- a/data-otservbr-global/npc/jeronimo.lua +++ b/data-otservbr-global/npc/jeronimo.lua @@ -29,7 +29,7 @@ npcConfig.voices = { interval = 15000, chance = 50, { text = "Change your " .. tournamentCoinName .. " for Items here!" }, - { text = "Visit our Game Store -> Tournament Shopp to check the offers" }, + { text = "Visit our Game Store -> Tournament Shop to check the offers" }, } local keywordHandler = KeywordHandler:new() @@ -59,58 +59,84 @@ npcType.onCloseChannel = function(npc, creature) npcHandler:onCloseChannel(npc, creature) end --- ID, Count, Price, Wrappable, Charges -local eventShopItems = { - ["exercise sword"] = { 28552, 1, 25, false, 500 }, - ["exercise axe"] = { 28553, 1, 25, false, 500 }, - ["exercise club"] = { 28554, 1, 25, false, 500 }, - ["exercise bow"] = { 28555, 1, 25, false, 500 }, - ["exercise rod"] = { 28556, 1, 25, false, 500 }, - ["exercise wand"] = { 28557, 1, 25, false, 500 }, - - ["baby brain squid"] = { 32909, 1, 800, true }, - ["baby vulcongra"] = { 32908, 1, 800, true }, - ["cerberus champion puppy"] = { 31464, 1, 800, true }, - ["guzzlemaw grub"] = { 32907, 1, 800, true }, - ["jousting eagle baby"] = { 31462, 1, 800, true }, - ["demon doll"] = { 32918, 1, 400, true }, - ["ogre rowdy doll"] = { 32944, 1, 400, true }, - ["retching horror doll"] = { 32945, 1, 400, true }, - ["vexclaw doll"] = { 32943, 1, 400, true }, - - ["gilded blessed shield"] = { 37165, 1, 1500, true }, - ["gilded crown"] = { 34332, 1, 1500, true }, - ["gilded horned helmet"] = { 38640, 1, 1500, true }, - ["gilded magic longsword"] = { 36995, 1, 1500, true }, - ["gilded warlord sword"] = { 39767, 1, 1500, true }, - - ["sublime tournament accolade"] = { 31472, 1, 500, true }, - ["tournament accolade"] = { 31470, 1, 500, true }, - - ["sublime tournament carpet"] = { 31467, 1, 100, true }, - ["tournament carpet"] = { 31466, 1, 100, true }, - - ["carved table"] = { 32972, 1, 100, true }, - ["carved table centre"] = { 32974, 1, 100, true }, - ["carved table corner"] = { 32969, 1, 100, true }, - - ["cozy couch"] = { 32948, 1, 100, true }, - ["cozy couch left end"] = { 32948, 1, 100, true }, - ["cozy couch right end"] = { 32956, 1, 100, true }, - ["cozy couch corner"] = { 32964, 1, 100, true }, - - ["zaoan chess box"] = { 18339, 1, 200, false }, - ["pannier backpack"] = { 19159, 1, 150, false }, - ["green light"] = { 21217, 1, 80, false }, - ["blood herb"] = { 3734, 3, 30, false }, - - ["cerberus champion"] = { 146, 1, 1250, false, 9999999 }, - ["jousting eagle"] = { 145, 1, 1250, false, 9999999 }, - - ["full dragon slayer"] = { 1289, 1288, 5000, false, 8888888 }, - ["full lion of war"] = { 1207, 1206, 1750, false, 8888888 }, - ["full veteran paladin"] = { 1205, 1204, 750, false, 8888888 }, - ["full void master"] = { 1203, 1202, 750, false, 8888888 }, +local OfferType = { + ExerciseWeapon = 1, + Doll = 2, + House = 3, + Utils = 4, + Outfit = 5, + Mount = 6, +} + +--local listShopItems = { +-- ["name"] = { id = x, count = 1, value = x, charges = x, type = OfferType.x }, +--} +local listShopItems = { + ["exercise sword"] = { id = 28552, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + ["exercise axe"] = { id = 28553, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + ["exercise club"] = { id = 28554, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + ["exercise bow"] = { id = 28555, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + ["exercise rod"] = { id = 28556, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + ["exercise wand"] = { id = 28557, count = 1, value = 700, charges = 1500, type = OfferType.ExerciseWeapon }, + + ["baby brain squid"] = { id = 32909, count = 1, value = 800, wrap = true, type = OfferType.House }, + ["baby vulcongra"] = { id = 32908, count = 1, value = 800, wrap = true, type = OfferType.House }, + ["cerberus champion puppy"] = { id = 31464, count = 1, value = 800, wrap = true, type = OfferType.House }, + ["guzzlemaw grub"] = { id = 32907, count = 1, value = 800, wrap = true, type = OfferType.House }, + ["jousting eagle baby"] = { id = 31462, count = 1, value = 800, wrap = true, type = OfferType.House }, + ["demon doll"] = { id = 32918, count = 1, value = 400, wrap = true, type = OfferType.House }, + ["ogre rowdy doll"] = { id = 32944, count = 1, value = 400, wrap = true, type = OfferType.House }, + ["retching horror doll"] = { id = 32945, count = 1, value = 400, wrap = true, type = OfferType.House }, + ["vexclaw doll"] = { id = 32943, count = 1, value = 400, wrap = true, type = OfferType.House }, + ["draken doll"] = { id = 12044, count = 1, value = 150, wrap = true, type = OfferType.House }, + ["bear doll"] = { id = 3001, count = 1, value = 150, wrap = true, type = OfferType.House }, + + ["gilded blessed shield"] = { id = 37165, count = 1, value = 1500, wrap = true, type = OfferType.House }, + ["gilded crown"] = { id = 34332, count = 1, value = 1500, wrap = true, type = OfferType.House }, + ["gilded horned helmet"] = { id = 38640, count = 1, value = 1500, wrap = true, type = OfferType.House }, + ["gilded magic longsword"] = { id = 36995, count = 1, value = 1500, wrap = true, type = OfferType.House }, + ["gilded warlord sword"] = { id = 39767, count = 1, value = 1500, wrap = true, type = OfferType.House }, + + ["sublime tournament accolade"] = { id = 31472, count = 1, value = 500, wrap = true, type = OfferType.House }, + ["tournament accolade"] = { id = 31470, count = 1, value = 500, wrap = true, type = OfferType.House }, + + ["sublime tournament carpet"] = { id = 31467, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["tournament carpet"] = { id = 31466, count = 1, value = 100, wrap = true, type = OfferType.House }, + + ["carved table"] = { id = 32972, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["carved table centre"] = { id = 32974, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["carved table corner"] = { id = 32969, count = 1, value = 100, wrap = true, type = OfferType.House }, + + ["cozy couch"] = { id = 32948, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["cozy couch left end"] = { id = 32948, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["cozy couch right end"] = { id = 32956, count = 1, value = 100, wrap = true, type = OfferType.House }, + ["cozy couch corner"] = { id = 32964, count = 1, value = 100, wrap = true, type = OfferType.House }, + + ["zaoan chess box"] = { id = 18339, count = 1, value = 200, type = OfferType.Utils }, + ["pannier backpack"] = { id = 19159, count = 1, value = 150, type = OfferType.Utils }, + ["green light"] = { id = 21217, count = 1, value = 80, type = OfferType.Utils }, + ["blood herb"] = { id = 3734, count = 3, value = 30, type = OfferType.Utils }, + + ["full dragon slayer"] = { id = { female = 1289, male = 1288 }, value = 5000, type = OfferType.Outfit }, + ["full lion of war"] = { id = { female = 1207, male = 1206 }, value = 2000, type = OfferType.Outfit }, + ["full veteran paladin"] = { id = { female = 1205, male = 1204 }, value = 2000, type = OfferType.Outfit }, + ["full void master"] = { id = { female = 1203, male = 1202 }, value = 2000, type = OfferType.Outfit }, + + ["cerberus champion"] = { id = 146, value = 4000, type = OfferType.Mount }, + ["jousting eagle"] = { id = 145, value = 1500, type = OfferType.Mount }, +} + +local offersByCategories = { + ["exercise weapons"] = "{exercise sword} (700), {exercise axe} (700), {exercise club} (700), {exercise bow} (700), {exercise rod} (700), {exercise wand} (700). Each one with 1500 charges.", + ["dolls"] = "{baby brain squid} (800), {baby vulcongra} (800), {cerberus champion puppy} (800), {guzzlemaw grub} (800), {jousting eagle baby} (800), {demon doll} (400), {ogre rowdy doll} (400), {retching horror doll} (400), {vexclaw doll} (400), {draken doll} (150), {bear doll} (150).", + ["house decorations"] = "\nGilded: {gilded blessed shield} (1500), {gilded crown} (1500), {gilded horned helmet} (1500), {gilded magic longsword} (1500), {gilded warlord sword} (1500).\n" + .. "Accolade: {sublime tournament accolade} (500), {tournament accolade} (500).\n" + .. "Carpet: {sublime tournament carpet} (100), {tournament carpet} (100).\n" + .. "Table: {carved table} (100), {carved table centre} (100), {carved table corner} (100).\n" + .. "Cozy: {cozy couch} (100), {cozy couch left end} (100), {cozy couch right end} (100), {cozy couch corner} (100).", + ["utils"] = "{zaoan chess box} (200), {pannier backpack} (150), {green light} (80), {blood herb} (30).", + ["outfits"] = "{full lion of war} (2000), {full veteran paladin} (2000), {full void master} (2000), {full dragon slayer} (5000).", + ["mounts"] = "{jousting eagle} (1500), {cerberus champion} (4000).", } local function creatureSayCallback(npc, creature, type, message) @@ -121,7 +147,7 @@ local function creatureSayCallback(npc, creature, type, message) return false end - local amountTournamentCoins = player:getTournamentCoins() + local amountTournamentCoins = player:getTournamentCoins() or 0 message = string.lower(message) if message == "help" or message == tournamentCoinName:lower() then npcHandler:say("In our game store -> Tournament Shop", npc, creature) @@ -135,63 +161,51 @@ local function creatureSayCallback(npc, creature, type, message) return true end - if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and eventShopItems[message] == nil then + if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and listShopItems[message] == nil then npcHandler:setTopic(playerId, 0) - npcHandler:say("We can't find the item that you want, try again or access https://thorfinn.com.br/?thorfinncoins", npc, creature) + npcHandler:say("We can't find the item that you want, try again or access our game store to see the offers!", npc, creature) return true end if npcHandler:getTopic(playerId) == 1 then npcHandler:setTopic(playerId, 2) - local text = "We can't find the {category} that you want, try again or access https://thorfinn.com.br/?thorfinncoins" - if message == "exercise weapons" then - text = "{exercise sword} (25), {exercise axe} (25), {exercise club} (25), {exercise bow} (25), {exercise rod} (25), {exercise wand} (25). Each one with 500 charges" - elseif message == "dolls" then - text = "{baby brain squid} (800), {baby vulcongra} (800), {cerberus champion puppy} (800), {guzzlemaw grub} (800), {jousting eagle baby} (800), {demon doll} (400), {ogre rowdy doll} (400), {retching horror doll} (400), {vexclaw doll} (400)." - elseif message == "house decorations" then - text = "\nGilded: {gilded blessed shield} (1500), {gilded crown} (1500), {gilded horned helmet} (1500), {gilded magic longsword} (1500), {gilded warlord sword} (1500).\n" - .. "Accolade: {sublime tournament accolade} (500), {tournament accolade} (500).\n" - .. "Carpet: {sublime tournament carpet} (100), {tournament carpet} (100).\n" - .. "Table: {carved table} (100), {carved table centre} (100), {carved table corner} (100).\n" - .. "Cozy: {cozy couch} (100), {cozy couch left end} (100), {cozy couch right end} (100), {cozy couch corner} (100)." - elseif message == "utils" then - text = "{stamina extension} (300), {zaoan chess box} (200), {pannier backpack} (150), {green light} (80), {blood herb} (30)." - elseif message == "mounts" then - text = "{jousting eagle} (1500), {foxmouse} (2500), {doom skull} (4000), {corpsefire skull} (4000), {cerberus champion} (4000), {spirit of purity} (4000)." - elseif message == "outfits" then - text = "{full lion of war} (2000), {full veteran paladin} (2000), {full void master} (2000), {full dragon slayer} (5000)." + local text = offersByCategories[message] + if text == nil then + text = "We can't find the {category} that you want, try again or access our game store to see the offers!" + npcHandler:setTopic(playerId, 0) end npcHandler:say(text, npc, creature) return true end - if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and eventShopItems[message] ~= nil then - local selected = eventShopItems[message] - local itemCount, itemPrice, itemCharge = selected[2], selected[3], selected[5] or 0 - local descCharge = "" - if itemCharge > 0 and (itemCharge ~= 9999999 and itemCharge ~= 8888888) then - descCharge = " with " .. itemCharge .. " charges" - end - - if amountTournamentCoins > 0 and amountTournamentCoins >= itemPrice then - if itemCharge == 9999999 then - npcHandler:say(string.format("You want buy %s mount for %i %s? {yes} or {no}", message, itemPrice, tournamentCoinName:lower()), npc, creature) - npcHandler:setTopic("mount", message) - elseif itemCharge == 8888888 then - npcHandler:say(string.format("You want buy %s outfit for %i %s? {yes} or {no}", message, itemPrice, tournamentCoinName:lower()), npc, creature) - npcHandler:setTopic("outfit", message) - else - npcHandler:say(string.format("You want buy %ix %s%s for %i %s? {yes} or {no}", itemCount, message, descCharge, itemPrice, tournamentCoinName:lower()), npc, creature) - end - npcHandler:setTopic(playerId, 3) - npcHandler:setTopic("selected", selected) - else - npcHandler:say(string.format("You don't have %i {%s}!", itemPrice, tournamentCoinName), npc, creature) + if (npcHandler:getTopic(playerId) == 2 or npcHandler:getTopic(playerId) == 0) and listShopItems[message] ~= nil then + local selected = listShopItems[message] + if amountTournamentCoins < selected.value then + npcHandler:say(string.format("You don't have %i {%s}!", selected.value, tournamentCoinName), npc, creature) npcHandler:setTopic(playerId, 0) npcHandler:setTopic("selected", {}) npcHandler:setTopic("outfit", {}) npcHandler:setTopic("mount", {}) end + + local descCharge = "" + if selected.type == OfferType.ExerciseWeapon and selected.charges ~= nil then + descCharge = " with " .. selected.charges .. " charges" + end + + if selected.type == OfferType.Outfit then + npcHandler:say(string.format("You want buy %s outfit for %i %s? {yes} or {no}", message, selected.value, tournamentCoinName:lower()), npc, creature) + npcHandler:setTopic("outfit", message) + elseif selected.type == OfferType.Mount then + npcHandler:say(string.format("You want buy %s mount for %i %s? {yes} or {no}", message, selected.value, tournamentCoinName:lower()), npc, creature) + npcHandler:setTopic("mount", message) + else + npcHandler:say(string.format("You want buy %ix %s%s for %i %s? {yes} or {no}", selected.count, message, descCharge, selected.value, tournamentCoinName:lower()), npc, creature) + end + + npcHandler:setTopic(playerId, 3) + npcHandler:setTopic("selected", selected) + return true end @@ -210,33 +224,31 @@ local function creatureSayCallback(npc, creature, type, message) return true end - local itemId, itemCount, itemPrice, isWrappable, itemCharge = selected[1], selected[2], selected[3], selected[4] or false, selected[5] or 0 - - if itemCharge == 9999999 then - if player:hasMount(itemId) then + if selected.type == OfferType.Mount then + if player:hasMount(selected.id) then npcHandler:say("You already own this mount.", npc, creature) return true end - player:updateTournamentCoins(itemPrice, "remove") - player:addMount(itemId) + player:updateTournamentCoins(selected.value, "remove") + player:addMount(selected.id) local mountName = npcHandler:getTopic("mount") - local msg = string.format("You bought %s mount for %i {%s}!", mountName, itemPrice, tournamentCoinName) + local msg = string.format("You bought %s mount for %i {%s}!", mountName, selected.value, tournamentCoinName) player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) npcHandler:say(msg, npc, creature) npcHandler:setTopic(playerId, 0) npcHandler:setTopic("selected", {}) npcHandler:setTopic("mount", {}) - elseif itemCharge == 8888888 then - local female, male = itemCount, itemId + elseif selected.type == OfferType.Outfit then + local female, male = selected.id.female, selected.id.male if player:hasOutfit(female) or player:hasOutfit(male) then npcHandler:say("You already own this outfit.", npc, creature) return true end - player:updateTournamentCoins(itemPrice, "remove") + player:updateTournamentCoins(selected.value, "remove") player:addOutfitAddon(female, 3) player:addOutfitAddon(male, 3) local outfitName = npcHandler:getTopic("outfit") - local msg = string.format("You bought %s outfit for %i {%s}!", outfitName, itemPrice, tournamentCoinName) + local msg = string.format("You bought %s outfit for %i %s!", outfitName, selected.value, tournamentCoinName:lower()) player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) npcHandler:say(msg, npc, creature) npcHandler:setTopic(playerId, 0) @@ -244,29 +256,29 @@ local function creatureSayCallback(npc, creature, type, message) npcHandler:setTopic("outfit", {}) else local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) - local itemT = ItemType(itemId) - if amountTournamentCoins >= itemPrice then + local itemT = ItemType(selected.id) + if amountTournamentCoins >= selected.value then if inbox and inbox:getEmptySlots() > 0 and player:getFreeCapacity() >= itemT:getCapacity() then - player:updateTournamentCoins(itemPrice, "remove") + player:updateTournamentCoins(selected.value, "remove") - if itemCharge > 0 then - local addedItem = player:addItem(itemId, itemCount, true) - addedItem:setAttribute("charges", itemCharge) + if selected.charges > 0 then + local addedItem = player:addItem(selected.id, selected.count, true) + addedItem:setAttribute("charges", selected.charges) else - if isWrappable then + if selected.wrap then local decoKit = inbox:addItem(ITEM_DECORATION_KIT, 1) if decoKit then decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "Unwrap it in your own house to create a <" .. itemT:getName() .. ">.") - decoKit:setCustomAttribute("unWrapId", itemId) + decoKit:setCustomAttribute("unWrapId", selected.id) decoKit:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime()) player:sendUpdateContainer(inbox) end else - player:addItem(itemId, itemCount) + player:addItem(selected.id, selected.count) end end - local descCharge = itemCharge > 0 and " with " .. itemCharge .. " charges" or "" - local msg = string.format("You bought %ix %s%s for %i {%s} and received in your store inbox!", itemCount, itemT:getName(), descCharge, itemPrice, tournamentCoinName) + local descCharge = selected.charges > 0 and " with " .. selected.charges .. " charges" or "" + local msg = string.format("You bought %ix %s%s for %i {%s} and received in your store inbox!", selected.count, itemT:getName(), descCharge, selected.value, tournamentCoinName) player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) npcHandler:say(msg, npc, creature) npcHandler:setTopic(playerId, 0) diff --git a/data/modules/scripts/gamestore/gamestore.lua b/data/modules/scripts/gamestore/gamestore.lua index f000c4079af..e05b5459774 100644 --- a/data/modules/scripts/gamestore/gamestore.lua +++ b/data/modules/scripts/gamestore/gamestore.lua @@ -2675,7 +2675,7 @@ GameStore.Categories = { { icons = { "Outfit_Veteran_Paladin_Male_Addon_3.png", "Outfit_Veteran_Paladin_Female_Addon_3.png" }, name = "Full Veteran Paladin Outfit", - price = 750, + price = 2000, sexId = { female = 1205, male = 1204 }, addon = 3, description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nA Veteran Paladin has mastered the art of distance fighting. No matter how far away his prey may be, a marksman like the Veteran Paladin will always hit with extraordinary precision. No one can escape his keen hawk-eyed vision and even small stones become deadly weapons in his hands.", @@ -2684,7 +2684,7 @@ GameStore.Categories = { { icons = { "Outfit_Void_Master_Male_Addon_3.png", "Outfit_Void_Master_Female_Addon_3.png" }, name = "Full Void Master Outfit", - price = 750, + price = 2000, sexId = { female = 1203, male = 1202 }, addon = 3, description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nAccording to ancient rumours, the pulsating orb that the Void Master balances skilfully on the tip of his staff consists of powerful cosmic spheres. If you gaze too long into the infinite emptiness inside the orb, its powers will absorb your mind.", @@ -6455,31 +6455,220 @@ GameStore.Categories = { -- Tournament { icons = { "Category_Tournament.png" }, - name = "Tournament", + name = "Tournament Shop", rookgaard = true, - subclasses = { "Tickets", "Exclusive Offers" }, + subclasses = { "TS-Exercise Weapons", "TS-Outfits", "TS-Mounts", "TS-Dolls", "TS-House Furniture" }, }, -- Tournament ~ Tickets + --{ + -- icons = { "Category_Tickets.png" }, + -- parent = "Tournament", + -- name = "Tickets", + -- rookgaard = true, + -- offers = { + -- { + -- icons = { "Tournament_Restricted.png" }, + -- name = "Restricted Tournament Ticket", + -- price = 500, + -- }, + -- }, + --}, { - icons = { "Category_Tickets.png" }, - parent = "Tournament", - name = "Tickets", + icons = { "Category_ExerciseWeapons.png" }, + name = "TS-Exercise Weapons", + parent = "Tournament Shop", rookgaard = true, offers = { { - icons = { "Tournament_Restricted.png" }, - name = "Restricted Tournament Ticket", - price = 500, + icons = { "Exercise_Sword.png" }, + name = "Exercise Sword", + price = 700, + itemtype = 28552, + charges = 1500, + description = "Use it to train your sword fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your sword fighting skill\n{info} usable 1500 times a piece\n{info} this item cannot be traded and cannot be moved", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Axe.png" }, + name = "Exercise Axe", + price = 700, + itemtype = 28553, + charges = 1500, + description = "Use it to train your axe fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your axe fighting skill\n{info} usable 1500 times a piece\n{info} this item cannot be traded and cannot be moved", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Club.png" }, + name = "Exercise Club", + price = 700, + itemtype = 28554, + charges = 1500, + description = "Use it to train your club fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your club fighting skill\n{info} usable 1500 times a piece\n{info} this item cannot be traded and cannot be moved", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Bow.png" }, + name = "Exercise Bow", + price = 700, + itemtype = 28555, + charges = 1500, + description = "Use it to train your distance fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your distance fighting skill\n{info} usable 1500 times a piece\n{info} this item cannot be traded and cannot be moved", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Rod.png" }, + name = "Exercise Rod", + price = 700, + itemtype = 28556, + charges = 1500, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 1500 times a piece\n{info} this item cannot be traded and cannot be moved", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Wand.png" }, + name = "Exercise Wand", + price = 700, + itemtype = 28557, + charges = 1500, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 1500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Exercise_Shield.png" }, + name = "Exercise Shield", + price = 700, + itemtype = 44065, + charges = 1500, + description = "Use it to train your shielding skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your shielding skill\n{info} usable 1500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + coinType = GameStore.CoinType.Tournament, }, }, }, - -- Tournament ~ Exclusive Offers + -- Tournament Shop ~ Outfits { - icons = { "Category_ExclusiveOffers.png" }, - name = "Exclusive Offers", - parent = "Tournament", + icons = { "Category_Outfits.png" }, + name = "TS-Outfits", + parent = "Tournament Shop", + rookgaard = true, + offers = { + { + icons = { "Outfit_Dragon_Slayer_Male_Addon_3.png", "Outfit_Dragon_Slayer_Female_Addon_3.png" }, + name = "Full Dragon Slayer Outfit", + price = 5000, + sexId = { female = 1289, male = 1288 }, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe souls of countless slain dragons have been fused over the years with this armour, wrought from the impervious scales of the ancestors of those very same beings, wicked and wise, winged and wild. The Dragon Slayer Outfit has seen an unfathomable amount of bloodshed, but it pales in comparison to the untold lives lost in the strife over the armour itself. Only the mightiest warriors can even begin to dream of ever owning this exceedingly rare token of power.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Outfit_Lion_of_War_Male_Addon_3.png", "Outfit_Lion_of_War_Female_Addon_3.png" }, + name = "Full Lion of War Outfit", + price = 2000, + sexId = { female = 1207, male = 1206 }, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Lion of War has fought on countless battlefields and never lost once. Enemies tremble with fear when he batters his sword against his almighty shield. Realising that a Lion of War knows no mercy, his opponents often surrender before the battle even begins.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Outfit_Veteran_Paladin_Male_Addon_3.png", "Outfit_Veteran_Paladin_Female_Addon_3.png" }, + name = "Full Veteran Paladin Outfit", + price = 2000, + sexId = { female = 1205, male = 1204 }, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nA Veteran Paladin has mastered the art of distance fighting. No matter how far away his prey may be, a marksman like the Veteran Paladin will always hit with extraordinary precision. No one can escape his keen hawk-eyed vision and even small stones become deadly weapons in his hands.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Outfit_Void_Master_Male_Addon_3.png", "Outfit_Void_Master_Female_Addon_3.png" }, + name = "Full Void Master Outfit", + price = 2000, + sexId = { female = 1203, male = 1202 }, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nAccording to ancient rumours, the pulsating orb that the Void Master balances skilfully on the tip of his staff consists of powerful cosmic spheres. If you gaze too long into the infinite emptiness inside the orb, its powers will absorb your mind.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CoinType.Tournament, + }, + }, + }, + -- Tournament Shop ~ Mounts + { + icons = { "Category_Mounts.png" }, + name = "TS-Mounts", + parent = "Tournament Shop", + rookgaard = true, + offers = { + { + icons = { "Cerberus_Champion.png" }, + name = "Cerberus Champion", + price = 4000, + id = 146, + description = "{info} usable by all characters of the account\n{speedboost}\n\nA fierce and grim guardian of the underworld has risen to fight side by side with the bravest warriors in order to send evil creatures into the realm of the dead. The three headed Cerberus Champion is constantly baying for blood and using its sharp fangs it easily rips apart even the strongest armour and shield.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Jousting_Eagle.png" }, + name = "Jousting Eagle", + price = 1500, + id = 145, + description = "{info} usable by all characters of the account\n{speedboost}\n\nHigh above the clouds far away from dry land, the training of giant eagles takes place. Only the cream of the crop is able to survive in such harsh environment long enough to call themselves Jousting Eagles while the weaklings find themselves at the bottom of the sea. The tough ones become noble and graceful mounts that are well known for their agility and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Doom_Skull.png" }, + name = "Doom Skull", + price = 4000, + id = 219, + description = "{character}\n{speedboost}\n\nSkulls are the infernal heralds of untamed power. Bodies are obsolete when sinister forces animate your being. Embrace their presence and command the devastating might that awaits on the back of a grim Doom Skull.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Foxmouse.png" }, + name = "Foxmouse", + price = 2500, + id = 218, + description = "{character}\n{speedboost}\n\nA wild, ancient creature, which had been hiding in the depths of the shadows for a very long time, has been spotted in Tibia again! The almighty Shadow Draptor has returned and only the bravest Tibians can control such a beast!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Corpsefire_Skull.png" }, + name = "Corpsefire Skull", + price = 4000, + id = 221, + description = "{character}\n{speedboost}\n\nSkulls are the infernal heralds of untamed power. Bodies are obsolete when sinister forces animate your being. Embrace their presence and command the devastating might that awaits on the back of an eerie Corpsefire Skull!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + { + icons = { "Spirit_of_Purity.png" }, + name = "Spirit of Purity", + price = 4000, + id = 217, + description = "{character}\n{speedboost}\n\nA wild, ancient creature, which had been hiding in the depths of the shadows for a very long time, has been spotted in Tibia again! The almighty Shadow Draptor has returned and only the bravest Tibians can control such a beast!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CoinType.Tournament, + }, + }, + }, + -- Tournament Shop ~ Dolls + { + icons = { "Category_HouseDecorations.png" }, + name = "TS-Dolls", + parent = "Tournament Shop", rookgaard = true, - state = GameStore.States.STATE_NONE, offers = { { icons = { "Baby_Brain_Squid.png" }, @@ -6489,6 +6678,7 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { icons = { "Baby_Vulcongra.png" }, @@ -6498,105 +6688,107 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Carved_Table.png" }, - name = "Carved Table", - price = 100, - itemtype = 32972, - count = 1, - description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", - type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - }, - { - icons = { "Carved_Table_Centre.png" }, - name = "Carved Table Centre", - price = 100, - itemtype = 32974, + icons = { "Cerberus_Champion_Puppy.png" }, + name = "Cerberus Champion Puppy", + price = 800, + itemtype = 31464, count = 1, - description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Carved_Table_Corner.png" }, - name = "Carved Table Corner", - price = 100, - itemtype = 32969, + icons = { "Guzzlemaw_Grub.png" }, + name = "Guzzlemaw Grub", + price = 800, + itemtype = 32907, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Cerberus_Champion.png" }, - name = "Cerberus Champion", - price = 1250, - id = 146, - description = "{info} usable by all characters of the account\n{speedboost}\n\nA fierce and grim guardian of the underworld has risen to fight side by side with the bravest warriors in order to send evil creatures into the realm of the dead. The three headed Cerberus Champion is constantly baying for blood and using its sharp fangs it easily rips apart even the strongest armour and shield.", - type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, - }, - { - icons = { "Cerberus_Champion_Puppy.png" }, - name = "Cerberus Champion Puppy", + icons = { "Jousting_Eagle_Baby.png" }, + name = "Jousting Eagle Baby", price = 800, - itemtype = 31464, + itemtype = 31462, count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Cozy_Couch.png" }, - name = "Cozy Couch", - price = 100, - itemtype = 32948, + icons = { "Demon_Doll.png" }, + name = "Demon Doll", + price = 400, + itemtype = 32918, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Cozy_Couch_Left_End.png" }, - name = "Cozy Couch Left End", - price = 100, - itemtype = 32952, + icons = { "Ogre_Rowdy_Doll.png" }, + name = "Ogre Rowdy Doll", + price = 400, + itemtype = 32944, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Cozy_Couch_Right_End.png" }, - name = "Cozy Couch Right End", - price = 100, - itemtype = 32956, + icons = { "Retching_Horror_Doll.png" }, + name = "Retching Horror Doll", + price = 400, + itemtype = 32945, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Cozy_Couch_Corner.png" }, - name = "Cozy Couch Corner", - price = 100, - itemtype = 32964, + icons = { "Vexclaw_Doll.png" }, + name = "Vexclaw Doll", + price = 400, + itemtype = 32943, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Demon_Doll.png" }, - name = "Demon Doll", - price = 400, - itemtype = 32918, + icons = { "Draken_Doll.png" }, + name = "Draken Doll", + price = 150, + itemtype = 12044, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Outfit_Dragon_Slayer_Male_Addon_3.png", "Outfit_Dragon_Slayer_Female_Addon_3.png" }, - name = "Full Dragon Slayer Outfit", - price = 5000, - sexId = { female = 1289, male = 1288 }, - addon = 3, - description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe souls of countless slain dragons have been fused over the years with this armour, wrought from the impervious scales of the ancestors of those very same beings, wicked and wise, winged and wild. The Dragon Slayer Outfit has seen an unfathomable amount of bloodshed, but it pales in comparison to the untold lives lost in the strife over the armour itself. Only the mightiest warriors can even begin to dream of ever owning this exceedingly rare token of power.", - type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + icons = { "Bear_Doll.png" }, + name = "Bear Doll", + price = 150, + itemtype = 3001, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, + }, + }, + -- Tournament Shop ~ House Furniture + { + icons = { "Category_HouseDecorations.png" }, + name = "TS-House Furniture", + parent = "Tournament Shop", + rookgaard = true, + offers = { { icons = { "Gilded_Blessed_Shield.png" }, name = "Gilded Blessed Shield", @@ -6605,7 +6797,7 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - home = true, + coinType = GameStore.CoinType.Tournament, }, { icons = { "Gilded_Crown.png" }, @@ -6615,7 +6807,7 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - home = true, + coinType = GameStore.CoinType.Tournament, }, { icons = { "Gilded_Horned_Helmet.png" }, @@ -6625,7 +6817,7 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - home = true, + coinType = GameStore.CoinType.Tournament, }, { icons = { "Gilded_Magic_Longsword.png" }, @@ -6635,7 +6827,7 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - home = true, + coinType = GameStore.CoinType.Tournament, }, { icons = { "Gilded_Warlord_Sword.png" }, @@ -6645,105 +6837,117 @@ GameStore.Categories = { count = 1, description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, - home = true, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Guzzlemaw_Grub.png" }, - name = "Guzzlemaw Grub", - price = 800, - itemtype = 32907, + icons = { "Sublime_Tournament_Accolade.png" }, + name = "Sublime Tournament Accolade", + price = 500, + itemtype = 31472, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Jousting_Eagle.png" }, - name = "Jousting Eagle", - price = 1250, - id = 145, - description = "{info} usable by all characters of the account\n{speedboost}\n\nHigh above the clouds far away from dry land, the training of giant eagles takes place. Only the cream of the crop is able to survive in such harsh environment long enough to call themselves Jousting Eagles while the weaklings find themselves at the bottom of the sea. The tough ones become noble and graceful mounts that are well known for their agility and endurance.", - type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + icons = { "Tournament_Accolade.png" }, + name = "Tournament Accolade", + price = 500, + itemtype = 31470, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Jousting_Eagle_Baby.png" }, - name = "Jousting Eagle Baby", - price = 800, - itemtype = 31462, + icons = { "Sublime_Tournament_Carpet.png" }, + name = "Sublime Tournament Carpet", + price = 100, + itemtype = 31467, count = 1, - description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Outfit_Lion_of_War_Male_Addon_3.png", "Outfit_Lion_of_War_Female_Addon_3.png" }, - name = "Full Lion of War Outfit", - price = 1750, - sexId = { female = 1207, male = 1206 }, - addon = 3, - description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Lion of War has fought on countless battlefields and never lost once. Enemies tremble with fear when he batters his sword against his almighty shield. Realising that a Lion of War knows no mercy, his opponents often surrender before the battle even begins.", - type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + icons = { "Tournament_Carpet.png" }, + name = "Tournament Carpet", + price = 100, + itemtype = 31466, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Ogre_Rowdy_Doll.png" }, - name = "Ogre Rowdy Doll", - price = 400, - itemtype = 32944, + icons = { "Carved_Table.png" }, + name = "Carved Table", + price = 100, + itemtype = 32972, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Retching_Horror_Doll.png" }, - name = "Retching Horror Doll", - price = 400, - itemtype = 32945, + icons = { "Carved_Table_Centre.png" }, + name = "Carved Table Centre", + price = 100, + itemtype = 32974, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Sublime_Tournament_Accolade.png" }, - name = "Sublime Tournament Accolade", - price = 500, - itemtype = 31472, + icons = { "Carved_Table_Corner.png" }, + name = "Carved Table Corner", + price = 100, + itemtype = 32969, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Sublime_Tournament_Carpet.png" }, - name = "Sublime Tournament Carpet", - price = 70, - itemtype = 31467, + icons = { "Cozy_Couch.png" }, + name = "Cozy Couch", + price = 100, + itemtype = 32948, count = 1, - description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Tournament_Accolade.png" }, - name = "Tournament Accolade", - price = 500, - itemtype = 31470, + icons = { "Cozy_Couch_Left_End.png" }, + name = "Cozy Couch Left End", + price = 100, + itemtype = 32952, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Tournament_Carpet.png" }, - name = "Tournament Carpet", - price = 70, - itemtype = 31466, + icons = { "Cozy_Couch_Right_End.png" }, + name = "Cozy Couch Right End", + price = 100, + itemtype = 32956, count = 1, - description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, { - icons = { "Vexclaw_Doll.png" }, - name = "Vexclaw Doll", - price = 400, - itemtype = 32943, + icons = { "Cozy_Couch_Corner.png" }, + name = "Cozy Couch Corner", + price = 100, + itemtype = 32964, count = 1, description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CoinType.Tournament, }, }, }, diff --git a/data/modules/scripts/gamestore/init.lua b/data/modules/scripts/gamestore/init.lua index 214aec77d43..d17fa6a4b83 100644 --- a/data/modules/scripts/gamestore/init.lua +++ b/data/modules/scripts/gamestore/init.lua @@ -68,6 +68,7 @@ GameStore.ActionType = { GameStore.CoinType = { Coin = 0, Transferable = 1, + Tournament = 2, } GameStore.Storages = { From c3f2050ef53df76b4da56f94b20bb712d4421bfa Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Sat, 25 Nov 2023 09:44:38 -0300 Subject: [PATCH 3/5] Fix check in charges. --- data-otservbr-global/npc/jeronimo.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data-otservbr-global/npc/jeronimo.lua b/data-otservbr-global/npc/jeronimo.lua index 8a76261496c..59952d3229c 100644 --- a/data-otservbr-global/npc/jeronimo.lua +++ b/data-otservbr-global/npc/jeronimo.lua @@ -261,10 +261,11 @@ local function creatureSayCallback(npc, creature, type, message) if inbox and inbox:getEmptySlots() > 0 and player:getFreeCapacity() >= itemT:getCapacity() then player:updateTournamentCoins(selected.value, "remove") - if selected.charges > 0 then + if selected.charges ~= nil and selected.charges > 0 then local addedItem = player:addItem(selected.id, selected.count, true) addedItem:setAttribute("charges", selected.charges) else + selected.charges = 0 if selected.wrap then local decoKit = inbox:addItem(ITEM_DECORATION_KIT, 1) if decoKit then From ef54336fafbfd85941660f45e8cebb2c33189f25 Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Sun, 17 Dec 2023 13:51:41 -0300 Subject: [PATCH 4/5] fixes. --- data-otservbr-global/npc/jeronimo.lua | 1 + src/lua/functions/creatures/player/player_functions.cpp | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/data-otservbr-global/npc/jeronimo.lua b/data-otservbr-global/npc/jeronimo.lua index 59952d3229c..86c6a69e6ab 100644 --- a/data-otservbr-global/npc/jeronimo.lua +++ b/data-otservbr-global/npc/jeronimo.lua @@ -186,6 +186,7 @@ local function creatureSayCallback(npc, creature, type, message) npcHandler:setTopic("selected", {}) npcHandler:setTopic("outfit", {}) npcHandler:setTopic("mount", {}) + return true end local descCharge = "" diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index 22e9a8e83a2..7b00370e4e9 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -2716,11 +2716,9 @@ int PlayerFunctions::luaPlayerUpdateTournamentCoins(lua_State* L) { lua_pushnil(L); return 1; } else if (action == "remove" && player->account->removeCoins(account::CoinType::TOURNAMENT, amount) != account::ERROR_NO) { - if (player->account->removeCoins(account::CoinType::COIN, getNumber(L, 2)) != account::ERROR_NO) { - reportErrorFunc(fmt::format("Failed to update (remove) {}", tournamentCoinName)); - lua_pushnil(L); - return 1; - } + reportErrorFunc(fmt::format("Failed to update (remove) {}", tournamentCoinName)); + lua_pushnil(L); + return 1; } if (player->getAccount()->save() != account::ERROR_NO) { From be4f911e252fd8825d26298ae97da18ed3136efb Mon Sep 17 00:00:00 2001 From: Elson Costa Date: Fri, 21 Jun 2024 14:49:15 -0300 Subject: [PATCH 5/5] fixes. --- .../scripts/globalevents/vip/online_coins.lua | 2 +- src/account/account.cpp | 4 +++- src/lua/functions/creatures/player/player_functions.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/data-otservbr-global/scripts/globalevents/vip/online_coins.lua b/data-otservbr-global/scripts/globalevents/vip/online_coins.lua index e75f23bde7a..af25471ee28 100644 --- a/data-otservbr-global/scripts/globalevents/vip/online_coins.lua +++ b/data-otservbr-global/scripts/globalevents/vip/online_coins.lua @@ -43,7 +43,7 @@ function onlineCoinsEvent.onThink(interval) player:setStorageValue(config.storage, coins * 10000000) if coins >= config.awardOn then local coinsMath = math.floor(coins) - player:addTibiaCoins(coinsMath, false) + player:addTibiaCoins(coinsMath) player:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), coinsMath, "tibia coins")) player:setStorageValue(config.storage, (coins - coinsMath) * 10000000) end diff --git a/src/account/account.cpp b/src/account/account.cpp index 2e5f58dd864..77f56189b92 100644 --- a/src/account/account.cpp +++ b/src/account/account.cpp @@ -110,7 +110,9 @@ uint8_t Account::addCoins(const uint8_t &type, const uint32_t &amount, const std return enumToValue(AccountErrors_t::Storage); } - registerCoinTransaction(enumToValue(CoinTransactionType::Add), type, amount, detail); + if (!detail.empty()) { + registerCoinTransaction(enumToValue(CoinTransactionType::Add), type, amount, detail); + } return enumToValue(AccountErrors_t::Ok); } diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index 7b00370e4e9..b65d7e66dd0 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -2561,7 +2561,7 @@ int PlayerFunctions::luaPlayerGetTibiaCoins(lua_State* L) { } int PlayerFunctions::luaPlayerAddTibiaCoins(lua_State* L) { - // player:addTibiaCoins(coins) + // player:addTibiaCoins(coins[, detail = ""]) std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); @@ -2569,7 +2569,7 @@ int PlayerFunctions::luaPlayerAddTibiaCoins(lua_State* L) { return 1; } - if (player->account->addCoins(enumToValue(CoinType::Normal), getNumber(L, 2), "") != enumToValue(AccountErrors_t::Ok)) { + if (player->account->addCoins(enumToValue(CoinType::Normal), getNumber(L, 2), getString(L, 3, "")) != enumToValue(AccountErrors_t::Ok)) { reportErrorFunc("Failed to add coins"); lua_pushnil(L); return 1; @@ -2630,7 +2630,7 @@ int PlayerFunctions::luaPlayerGetTransferableCoins(lua_State* L) { } int PlayerFunctions::luaPlayerAddTransferableCoins(lua_State* L) { - // player:addTransferableCoins(coins) + // player:addTransferableCoins(coins[, detail = ""]) std::shared_ptr player = getUserdataShared(L, 1); if (!player || !player->getAccount()) { reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND)); @@ -2638,7 +2638,7 @@ int PlayerFunctions::luaPlayerAddTransferableCoins(lua_State* L) { return 1; } - if (player->account->addCoins(enumToValue(CoinType::Transferable), getNumber(L, 2)) != enumToValue(AccountErrors_t::Ok)) { + if (player->account->addCoins(enumToValue(CoinType::Transferable), getNumber(L, 2), getString(L, 3, "")) != enumToValue(AccountErrors_t::Ok)) { reportErrorFunc("failed to add transferable coins"); lua_pushnil(L); return 1;