- Awards
- 10
Ayuda convertir este NPC para usarlo en canary, consta de comprar items, addons, mounts, exp boost x tournament coins, por favor, ygracias de antemano
Código Lua:
local OFFER_TYPE = {
ITEM = 1,
STACK_ITEM = 2,
ADDON = 3,
MOUNT = 4,
EXP_BOOST = 5,
}
local function createReturnValue(status, internal, msg)
internal = internal or ""
msg = msg or "no error"
local ret = {
status = status,
internal = internal,
msg = msg,
}
return ret
end
local OFFER_TYPE_FUNC = {
[OFFER_TYPE.ITEM] = function(cid, offer)
local player = Player(cid)
if not player then
return createReturnValue(false, "player is null", "Please, contact a admin.")
end
if not offer then
return createReturnValue(false, "offer is null", "Please, contact a admin.")
end
if player:getFreeCapacity() < ItemType(offer.itemId):getWeight(offer.count) then
return createReturnValue(true, "", "Please make sure you have free capacity to hold this item.")
end
local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
if inbox and inbox:getEmptySlots() > offer.count then
if not inbox:addItem(offer.itemId, offer.count) then
return createReturnValue(false, "Cannot create item", "Please, contact a admin.")
end
else
return createReturnValue(true, "", "Please make sure you have free slots in your store inbox.")
end
return createReturnValue(true)
end,
[OFFER_TYPE.STACK_ITEM] = function(player, offer)
local player = Player(cid)
if not player then
return createReturnValue(false, "player is null", "Please, contact a admin.")
end
if not offer then
return createReturnValue(false, "offer is null", "Please, contact a admin.")
end
if player:getFreeCapacity() < ItemType(offer.itemId):getWeight(offer.count) then
return createReturnValue(true, "", "Please make sure you have free capacity to hold this item.")
end
local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
if inbox and inbox:getEmptySlots() > offer.count then
if not inbox:addItem(offer.itemId, offer.count) then
return createReturnValue(false, "Cannot create item", "Please, contact a admin.")
end
else
return createReturnValue(true, "", "Please make sure you have free slots in your store inbox.")
end
return createReturnValue(true)
end,
[OFFER_TYPE.ADDON] = function(cid, offer)
local player = Player(cid)
if not player then
return createReturnValue(false, "player is null", "Please, contact a admin.")
end
if not offer then
return createReturnValue(false, "offer is null", "Please, contact a admin.")
end
local hasOutfit = false
for _, sexId in pairs(offer.lookType) do
if player:hasOutfit(sexId, 3) then
return createReturnValue(true, "", "You already have this outfit and addon.")
else
player:addOutfitAddon(sexId, 3)
end
end
return createReturnValue(true)
end,
[OFFER_TYPE.MOUNT] = function(cid, offer)
local player = Player(cid)
if not player then
return createReturnValue(false, "player is null", "Please, contact a admin.")
end
if not offer then
return createReturnValue(false, "offer is null", "Please, contact a admin.")
end
if player:hasMount(offer.mountId) then
return createReturnValue(true, "", "You already have this outfit and addon.")
end
player:addMount(offer.mountId)
return createReturnValue(true)
end,
[OFFER_TYPE.EXP_BOOST] = function(cid, offer)
local player = Player(cid)
if not player then
return createReturnValue(false, "player is null", "Please, contact a admin.")
end
if not offer then
return createReturnValue(false, "offer is null", "Please, contact a admin.")
end
local lastPurchase = player:getStorageValue(98336)
if lastPurchase > os.time() then
return createReturnValue(true, "", "You can only buy XP Boost once a day.")
end
player:setStorageValue(98336, os.time() + 24 * 60 * 60)
player:setStoreXpBoost(50)
local currentExpBoostTime = player:getExpBoostStamina()
player:setExpBoostStamina(currentExpBoostTime + offer.count * 60 * 60)
return createReturnValue(true)
end,
}
local TournamentShop = {
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
{
categoryName = "Items",
categoryId = 1,
offers = {
{
offerName = "Swan Feather Cloak",
itemId = 29079,
count = 1,
price = 200,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Shining Sun Catcher",
itemId = 29213,
count = 1,
price = 120,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Moon Mirror",
itemId = 29211,
count = 1,
price = 140,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Butterfly Ring",
itemId = 29003,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Blossom Bag",
itemId = 29080,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Gill Coat",
itemId = 18399,
count = 1,
price = 150,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Gill Gugel",
itemId = 18398,
count = 1,
price = 150,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Gill Legs",
itemId = 18400,
count = 1,
price = 150,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Glacial Rod",
itemId = 18412,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Muck Rod",
itemId = 18411,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Wand Of Everblazing",
itemId = 18409,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Wand Of Defiance",
itemId = 18390,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Spellbook Of Vigilance",
itemId = 18401,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Prismatic Shield",
itemId = 18410,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Prismatic Legs",
itemId = 18405,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Prismatic Helmet",
itemId = 18403,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Prismatic Boots",
itemId = 18406,
count = 1,
price = 80,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Prismatic Armor",
itemId = 18404,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Mycological Mace",
itemId = 18452,
count = 1,
price = 150,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Mycological Bow",
itemId = 18454,
count = 1,
price = 150,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Shiny Blade",
itemId = 18465,
count = 1,
price = 200,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Crystalline Axe",
itemId = 18451,
count = 1,
price = 200,
type = OFFER_TYPE.ITEM,
},
{
offerName = "Crystal Crossbow",
itemId = 18453,
count = 1,
price = 100,
type = OFFER_TYPE.ITEM,
},
{
offerName = "earthheart cuirass",
itemId = 25177,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "earthheart hauberk",
itemId = 25178,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "earthheart platemail",
itemId = 25179,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "earthmind raiment",
itemId = 25191,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "earthsoul tabard",
itemId = 25187,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "fireheart cuirass",
itemId = 25174,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "fireheart hauberk",
itemId = 25175,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "fireheart platemail",
itemId = 25176,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "firemind raiment",
itemId = 25190,
count = 1,
price = 200,
type = OFFER_TYPE.ITEM,
},
{
offerName = "firesoul tabard",
itemId = 25186,
count = 1,
price = 200,
type = OFFER_TYPE.ITEM,
},
{
offerName = "frostheart cuirass",
itemId = 25183,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "frostheart hauberk",
itemId = 25184,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "frostheart platemail",
itemId = 25185,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "frostmind raiment",
itemId = 25193,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "frostsoul tabard",
itemId = 25189,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "magic shield potion",
itemId = 40398,
count = 1,
price = 50,
type = OFFER_TYPE.ITEM,
},
{
offerName = "thunderheart cuirass",
itemId = 25180,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "thunderheart hauberk",
itemId = 25181,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "thunderheart platemail",
itemId = 25182,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "thundermind raiment",
itemId = 25192,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
{
offerName = "thundersoul tabard",
itemId = 25188,
count = 1,
price = 250,
type = OFFER_TYPE.ITEM,
},
},
},
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
{
categoryName = "Addons",
categoryId = 2,
offers = {
{
offerName = "Puppeteer full",
lookType = {[0] = 696, [1] = 697}, -- 0 = female, 1 = male.
price = 1200,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Arena Champion full",
lookType = {[0] = 885, [1] = 884}, -- 0 = female, 1 = male.
price = 1200,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Grove Keeper full",
lookType = {[0] = 909, [1] = 908}, -- 0 = female, 1 = male.
price = 1000,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Pumpkin Mummy full",
lookType = {[0] = 1128, [1] = 1127}, -- 0 = female, 1 = male.
price = 1800,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Dream Warrior full",
lookType = {[0] = 1147, [1] = 1146}, -- 0 = female, 1 = male.
price = 1600,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Formal Dress full",
lookType = {[0] = 1461, [1] = 1460}, -- 0 = female, 1 = male.
price = 2500,
type = OFFER_TYPE.ADDON,
},
},
},
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
{
categoryName = "Mounts",
categoryId = 3,
offers = {
{
offerName = "Tin Lizzard",
mountId = 8,
price = 800,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Draptor",
mountId = 6,
price = 690,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Uniwheel",
mountId = 15,
price = 700,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Crystal Wolf",
mountId = 16,
price = 850,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Phant",
mountId = 182,
price = 1200,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Water Buffalo",
mountId = 35,
price = 600,
type = OFFER_TYPE.MOUNT,
},
},
},
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
{
categoryName = "Userful Things",
categoryId = 4,
offers = {
{
offerName = "Boost Exp 2h",
count = 2,
price = 1000,
type = OFFER_TYPE.EXP_BOOST,
},
{
offerName = "Boost Exp 4h",
count = 4,
price = 2000,
type = OFFER_TYPE.EXP_BOOST,
},
},
},
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
{
categoryName = "Especial Offers",
categoryId = 5,
offers = {
{
offerName = "Blazing Unicorn",
mountId = 113,
price = 2600,
type = OFFER_TYPE.MOUNT,
},
{
offerName = "Golden addon full",
lookType = {[0] = 1211, [1] = 1210}, -- 0 = female, 1 = male.
price = 15000,
type = OFFER_TYPE.ADDON,
},
{
offerName = "Mage Addon Full",
lookType = {[0] = 138, [1] = 130}, -- 0 = female, 1 = male.
price = 45000,
type = OFFER_TYPE.ADDON,
},
{
offerName = "soul stone",
itemId = 5809,
count = 1,
price = 1000,
type = OFFER_TYPE.ITEM,
},
{
offerName = "golden helmet",
itemId = 2471,
count = 1,
price = 30000,
type = OFFER_TYPE.ITEM,
},
},
},
----------------------------------------------------------------------------------------------
-------------==== category====----------------------------------------------------------------
}
local function getShopCategory(param)
if not param then
return nil
end
for index, category in pairs(TournamentShop) do
if type(param) == "string" then
if param == category.categoryName then
return category
end
elseif type(param) == "number" then
if param == category.categoryId then
return category
end
end
end
return nil
end
local function getShopOffer(categoryParam, param)
if not categoryParam or not param then
return nil
end
local category
if type(categoryParam) == "table" and categoryParam.offers then
category = categoryParam
elseif type(categoryParam) == "string" or type(categoryParam) == "number" then
category = getShopCategory(categoryParam)
end
if not category then
return nil
end
for index=1, #category.offers do
local offer = category.offers[index]
if offer then
if index == param then
return offer
end
end
end
return nil
end
local function processShopPurchase(cid, offer)
local player = Player(cid)
if not player or not offer or type(offer) ~= "table" then
return false
end
if player:getTournamentCoinsBalance() < offer.price then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have enough tournament.")
return false
end
local retValue = OFFER_TYPE_FUNC[offer.type](player, offer)
if not retValue.status then
Spdlog.warn(string.format("[TournamentShop] Error: %s, Player: %s, Message: %s", retValue.internal, player:getName(), retValue.msg))
end
if retValue.msg ~= "no error" then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, retValue.msg)
return false
end
player:removeTournamentCoinsBalance(offer.price)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You bought %sx %s for %s Tournament Coins.", offer.count, offer.offerName, offer.price))
return true
end
function sendShopCategoryModal(cid, id)
local player = Player(cid)
if not player or not id then
return false
end
local category = getShopCategory(id)
if not category then
return false
end
local window = ModalWindow {
title = 'Tournament Shop',
message = string.format("You have %s Coins\nSelect offer.", player:getTournamentCoinsBalance())
}
for index=1, #category.offers do
local offer = category.offers[index]
if offer then
local offerCountStr = offer.count or ""
if offer.type == OFFER_TYPE.ITEM then
offerCountStr = offer.count.."x"
elseif offer.type == OFFER_TYPE.EXP_BOOST then
offerCountStr = ""
elseif offer.type == OFFER_TYPE.ADDON then
offerCountStr = ""
elseif offer.type == OFFER_TYPE.MOUNT then
offerCountStr = ""
end
local choice = window:addChoice(string.format("%s %s | Price: %s", offerCountStr, offer.offerName, offer.price))
choice.id = index
end
end
window:addButton('Buy',
function(button, choice)
local offer = getShopOffer(category, choice.id)
if not offer then
Spdlog.warn(string.format("Failed to find offer: %s category: %s, player: %s", choice.id, category.categoryName, player:getName()));
return false
end
processShopPurchase(cid, offer)
end
)
window:addButton('Back',
function(button, choice)
sendTournamentShopModal(cid)
end
)
window:addButton('Close')
window:setDefaultEnterButton('Buy')
window:setDefaultEscapeButton('Back')
window:sendToPlayer(player)
return true
end
function sendTournamentShopModal(cid)
local player = Player(cid)
if not player then
return false
end
local window = ModalWindow {
title = 'Tournament Shop',
message = string.format("You have %s Tourn. Coins\nSelect category.", player:getTournamentCoinsBalance())
}
for _, category in pairs(TournamentShop) do
local choice = window:addChoice(category.categoryName)
choice.id = category.categoryId
end
window:addButton('Select',
function(button, choice)
sendShopCategoryModal(cid, choice.id)
end
)
window:addButton('Close')
window:setDefaultEnterButton('Select')
window:setDefaultEscapeButton('Close')
window:sendToPlayer(player)
return true
end
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
function onCreatureAppear(cid)
npcHandler:onCreatureAppear(cid)
end
function onCreatureDisappear(cid)
npcHandler:onCreatureDisappear(cid)
end
function onCreatureSay(cid, type, msg)
npcHandler:onCreatureSay(cid, type, msg)
end
function onThink()
npcHandler:onThink()
end
local function greetCallback(cid)
npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|, looking for {tournament}, {shop} or {offers}?")
local player = Player(cid)
if not player then
return true
end
npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|, looking for {tournament}, {shop} or {offers}?. You have "..player:getTournamentCoinsBalance().." Tournament Coins.")
return true
end
local function creatureSayCallback(cid, type, msg)
local player = Player(cid)
if not player or not npcHandler:isFocused(cid) then
return false
end
if msgcontains(msg, "tournament") or msgcontains(msg, "shop") or msgcontains(msg, "offers") then
if player:getTournamentCoinsBalance() <= 0 then
npcHandler:say("You don't have Tournament Coins to access the Shop.", cid)
return true
end
sendTournamentShopModal(player)
return true
end
-- player:getTournamentCoinsBalance()
return true
end
npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Tournament NPC" walkinterval="2000" floorchange="0" script="tournament_shop.lua">
<health now="100" max="100"/>
<look type="54"/>
<parameters>
<parameter key="message_greet" value="Hello |PLAYERNAME|, looking for {tournament} - {shop} - {offers}?"/>
<parameter key="message_farewell" value="Bye."/>
</parameters>
</npc>