Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement tournament market custom #1901

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
248 changes: 217 additions & 31 deletions data-otservbr-global/npc/jeronimo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 Shop to check the offers" },
}

local keywordHandler = KeywordHandler:new()
Expand Down Expand Up @@ -56,15 +59,84 @@ npcType.onCloseChannel = function(npc, creature)
npcHandler:onCloseChannel(npc, creature)
end

-- ID, Count, Price
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 },
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)
Expand All @@ -75,43 +147,157 @@ local function creatureSayCallback(npc, creature, type, message)
return false
end

local amountTournamentCoins = player:getTournamentCoins() or 0
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 listShopItems[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)
else
npcHandler:say("You don't have " .. itemPrice .. " {Bar of Gold(s)}!", 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 = 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 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", {})
return true
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

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

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(selected.value, "remove")
player:addMount(selected.id)
local mountName = npcHandler:getTopic("mount")
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 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(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, selected.value, tournamentCoinName:lower())
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(selected.id)
if amountTournamentCoins >= selected.value then
if inbox and inbox:getEmptySlots() > 0 and player:getFreeCapacity() >= itemT:getCapacity() then
player:updateTournamentCoins(selected.value, "remove")

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
decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "Unwrap it in your own house to create a <" .. itemT:getName() .. ">.")
decoKit:setCustomAttribute("unWrapId", selected.id)
decoKit:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime())
player:sendUpdateContainer(inbox)
end
else
player:addItem(selected.id, selected.count)
end
end
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)
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)
17 changes: 17 additions & 0 deletions data-otservbr-global/scripts/actions/custom/tournament_tokens.lua
Original file line number Diff line number Diff line change
@@ -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()
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},

Expand Down Expand Up @@ -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)
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Loading
Loading