znoteshop_talkaction.lua

main 108 lines · 3.9 KB Raw
Alex Alex Commit Initial commit 01/10/2026 09:20
1-- Znote Shop for Znote AAC on Canary (opentibiabr) / otservbr-global.
2-- Players type !shop while standing in a protection zone to receive the orders
3-- they bought on the website.
4--
5-- Order types (znote_shop_orders.type):
6-- 1 item id itemid = item id, count = amount
7-- 2 premium handled by the website
8-- 3 gender change handled by the website
9-- 4 name change handled by the website
10-- 5 outfit + addons itemid = male*1000 + female (or a single look type),
11-- count = addon bitmask (1, 2 or 3)
12-- 6 mount itemid = mount id
13-- 7 instant house itemid = house id, count = buyer player id
14
15local znoteShopTalk = TalkAction("!shop")
16
17function znoteShopTalk.onSay(player, words, param)
18 local storage = 54073 -- unused storage, throttles !shop against SQL spam
19 local cooldown = 15 -- seconds
20
21 local remaining = player:getStorageValue(storage) - os.time()
22 if remaining > 0 then
23 player:sendTextMessage(MESSAGE_STATUS, ("You can use !shop again in %d seconds."):format(remaining))
24 return true
25 end
26 player:setStorageValue(storage, os.time() + cooldown)
27
28 local orders = db.storeQuery("SELECT `id`, `type`, `itemid`, `count` FROM `znote_shop_orders` WHERE `account_id` = " .. player:getAccountId() .. ";")
29 if orders == false then
30 player:sendTextMessage(MESSAGE_STATUS, "You have no orders.")
31 return true
32 end
33
34 local served = false
35 repeat
36 local oId = result.getNumber(orders, "id")
37 local oType = result.getNumber(orders, "type")
38 local oItemId = result.getNumber(orders, "itemid")
39 local oCount = result.getNumber(orders, "count")
40
41 if oType == 1 then
42 served = true
43 local itemType = ItemType(oItemId)
44 if player:getFreeCapacity() >= itemType:getWeight(oCount) then
45 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. oId .. ";")
46 player:addItem(oItemId, oCount)
47 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ("You received %dx %s."):format(oCount, itemType:getName()))
48 else
49 player:sendTextMessage(MESSAGE_FAILURE, "You need more capacity to carry this order.")
50 end
51
52 elseif oType == 5 then
53 served = true
54 local looks = {}
55 local packed = oItemId
56 if packed > 1000 then
57 local male = math.floor(packed / 1000)
58 table.insert(looks, male)
59 packed = packed - (male * 1000)
60 end
61 table.insert(looks, packed)
62 for _, lookType in ipairs(looks) do
63 if not player:hasOutfit(lookType, oCount) then
64 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. oId .. ";")
65 player:addOutfit(lookType)
66 player:addOutfitAddon(lookType, oCount)
67 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You received a new outfit.")
68 else
69 player:sendTextMessage(MESSAGE_FAILURE, "You already own this outfit and addon.")
70 end
71 end
72
73 elseif oType == 6 then
74 served = true
75 if not player:hasMount(oItemId) then
76 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. oId .. ";")
77 player:addMount(oItemId)
78 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You received a new mount.")
79 else
80 player:sendTextMessage(MESSAGE_FAILURE, "You already own this mount.")
81 end
82
83 elseif oType == 7 then
84 served = true
85 local house = House(oItemId)
86 local buyer = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = " .. oCount .. " LIMIT 1;")
87 if buyer ~= false then
88 local buyerName = result.getString(buyer, "name")
89 result.free(buyer)
90 if house then
91 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. oId .. ";")
92 house:setHouseOwner(oCount, true)
93 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ("House %s now belongs to %s. Keep the rent in the bank."):format(house:getName(), buyerName))
94 end
95 end
96 end
97 until not result.next(orders)
98 result.free(orders)
99
100 if not served then
101 player:sendTextMessage(MESSAGE_STATUS, "You have no in-game orders to process.")
102 end
103 return true
104end
105
106znoteShopTalk:separator(" ")
107znoteShopTalk:register()
108
Top