shopsystem_talkaction.lua

main 136 lines · 5.1 KB Raw
Alex Alex Commit Initial commit 01/10/2026 09:20
1local talkaction = TalkAction("!shop")
2
3function talkaction.onSay(player)
4 local storage = 54073 -- Make sure to select non-used storage. This is used to prevent SQL load attacks.
5 local cooldown = 15 -- in seconds.
6
7 if player:getStorageValue(storage) <= os.time() then
8 player:setStorageValue(storage, os.time() + cooldown)
9
10 local type_desc = {
11 "itemids",
12 "pending premium (skip)",
13 "pending gender change (skip)",
14 "pending character name change (skip)",
15 "Outfit and addons",
16 "Mounts",
17 "Instant house purchase"
18 }
19 print("Player: " .. player:getName() .. " triggered !shop talkaction.")
20 -- Create the query
21 local orderQuery = db.storeQuery("SELECT `id`, `type`, `itemid`, `count` FROM `znote_shop_orders` WHERE `account_id` = " .. player:getAccountId() .. ";")
22 local served = false
23
24 -- Detect if we got any results
25 if orderQuery ~= false then
26 repeat
27 -- Fetch order values
28 local q_id = result.getNumber(orderQuery, "id")
29 local q_type = result.getNumber(orderQuery, "type")
30 local q_itemid = result.getNumber(orderQuery, "itemid")
31 local q_count = result.getNumber(orderQuery, "count")
32
33 local description = "Unknown or custom type"
34 if type_desc[q_type] ~= nil then
35 description = type_desc[q_type]
36 end
37 print("Processing type "..q_type..": ".. description)
38
39 -- ORDER TYPE 1 (Regular item shop products)
40 if q_type == 1 then
41 served = true
42 -- Get weight
43 if player:getFreeCapacity() >= ItemType(q_itemid):getWeight(q_count) then
44 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
45 player:addItem(q_itemid, q_count)
46 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received " .. q_count .. " x " .. ItemType(q_itemid):getName() .. "!")
47 else
48 player:sendTextMessage(MESSAGE_STATUS_WARNING, "Need more CAP!")
49 end
50 end
51
52 -- ORDER TYPE 5 (Outfit and addon)
53 if q_type == 5 then
54 served = true
55
56 local itemid = q_itemid
57 local outfits = {}
58
59 if itemid > 1000 then
60 local first = math.floor(itemid/1000)
61 table.insert(outfits, first)
62 itemid = itemid - (first * 1000)
63 end
64 table.insert(outfits, itemid)
65
66 for _, outfitId in pairs(outfits) do
67 -- Make sure player don't already have this outfit and addon
68 if not player:hasOutfit(outfitId, q_count) then
69 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
70 player:addOutfit(outfitId)
71 player:addOutfitAddon(outfitId, q_count)
72 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new outfit!")
73 else
74 player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this outfit and addon!")
75 end
76 end
77 end
78
79 -- ORDER TYPE 6 (Mounts). itemid holds the mount id.
80 if q_type == 6 then
81 served = true
82 -- Make sure player don't already have this mount
83 if not player:hasMount(q_itemid) then
84 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
85 player:addMount(q_itemid)
86 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new mount!")
87 else
88 player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this mount!")
89 end
90 end
91
92 -- ORDER TYPE 7 (Direct house purchase)
93 if q_type == 7 then
94 served = true
95 local house = House(q_itemid)
96 -- Logged in player is not necessarily the player that bough the house. So we need to load player from db.
97 local buyerQuery = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = "..q_count.." LIMIT 1")
98 if buyerQuery ~= false then
99 local buyerName = result.getString(buyerQuery, "name")
100 result.free(buyerQuery)
101 if house then
102 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
103 house:setOwnerGuid(q_count)
104 player:sendTextMessage(MESSAGE_INFO_DESCR, "You have successfully bought the house "..house:getName().." on "..buyerName..", be sure to have the money for the rent in the bank.")
105 print("Process complete. [".. buyerName .."] has received house: ["..house:getName().."]")
106 end
107 end
108 end
109
110 -- Add custom order types here
111 -- Type 1 is for itemids (Already coded here)
112 -- Type 2 is for premium (Coded on web)
113 -- Type 3 is for gender change (Coded on web)
114 -- Type 4 is for character name change (Coded on web)
115 -- Type 5 is for character outfit and addon (Already coded here)
116 -- Type 6 is for mounts (Already coded here)
117 -- Type 7 is for Instant house purchase (Already coded here)
118 -- So use type 8+ for custom stuff, like etc packages.
119 -- if q_type == 8 then
120 -- end
121 until not result.next(orderQuery)
122 result.free(orderQuery)
123 if not served then
124 player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have no orders to process in-game.")
125 end
126 else
127 player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have no orders.")
128 end
129 else
130 player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Can only be executed once every " .. cooldown .. " seconds. Remaining cooldown: " .. player:getStorageValue(storage) - os.time())
131 end
132 return false
133end
134
135talkaction:register()
136
Top