1local globalevent = GlobalEvent("ShopSystemGlobal")
2
3function globalevent.onThink(...)
4 local shopTypes = {1,5,6,7}
5 local orderQuery = db.storeQuery([[
6 SELECT
7 MIN(`po`.`player_id`) AS `player_id`,
8 `shop`.`id`,
9 `shop`.`type`,
10 `shop`.`itemid`,
11 `shop`.`count`
12 FROM `players_online` AS `po`
13 INNER JOIN `players` AS `p`
14 ON `po`.`player_id` = `p`.`id`
15 INNER JOIN `znote_shop_orders` AS `shop`
16 ON `p`.`account_id` = `shop`.`account_id`
17 WHERE `shop`.`type` IN(]] .. table.concat(shopTypes, ",") .. [[)
18 GROUP BY `shop`.`id`
19 ]])
20 -- Detect if we got any results
21 if orderQuery ~= false then
22 local type_desc = {
23 "itemids",
24 "pending premium (skip)",
25 "pending gender change (skip)",
26 "pending character name change (skip)",
27 "Outfit and addons",
28 "Mounts",
29 "Instant house purchase"
30 }
31 repeat
32 local player_id = result.getNumber(orderQuery, 'player_id')
33 local orderId = result.getNumber(orderQuery, 'id')
34 local orderType = result.getNumber(orderQuery, 'type')
35 local orderItemId = result.getNumber(orderQuery, 'itemid')
36 local orderCount = result.getNumber(orderQuery, 'count')
37 local served = false
38
39 local player = Player(player_id)
40 if player ~= nil then
41
42 local description = "Unknown or custom type"
43 if type_desc[orderType] ~= nil then
44 description = type_desc[orderType]
45 end
46 print("Processing type "..orderType..": ".. description)
47 print("Processing shop order for: [".. player:getName() .."] type "..orderType..": ".. description)
48
49 local tile = Tile(player:getPosition())
50 if tile ~= nil and tile:hasFlag(TILESTATE_PROTECTIONZONE) then
51 -- ORDER TYPE 1 (Regular item shop products)
52 if orderType == 1 then
53 served = true
54 local itemType = ItemType(orderItemId)
55 -- Get weight
56 if player:getFreeCapacity() >= itemType:getWeight(orderCount) then
57 local backpack = player:getSlotItem(CONST_SLOT_BACKPACK)
58 -- variable = (condition) and (return if true) or (return if false)
59 local needslots = itemType:isStackable() and math.floor(orderCount / 100) + 1 or orderCount
60 if backpack ~= nil and backpack:getEmptySlots(false) >= needslots then
61 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
62 player:addItem(orderItemId, orderCount)
63 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. "!")
64 print("Process complete. [".. player:getName() .."] has received " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
65 else -- not enough slots
66 player:sendTextMessage(MESSAGE_STATUS_WARNING, "Your main backpack is full. You need to free up "..needslots.." available slots to get " .. orderCount .. " " .. ItemType(orderItemId):getName() .. "!")
67 print("Process canceled. [".. player:getName() .."] need more space in his backpack to get " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
68 end
69 else -- not enough cap
70 player:sendTextMessage(MESSAGE_STATUS_WARNING, "You need more CAP to carry this order!")
71 print("Process canceled. [".. player:getName() .."] need more cap to carry " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
72 end
73 end
74
75 -- ORDER TYPE 5 (Outfit and addon)
76 if orderType == 5 then
77 served = true
78
79 local itemid = orderItemId
80 local outfits = {}
81
82 if itemid > 1000 then
83 local first = math.floor(itemid/1000)
84 table.insert(outfits, first)
85 itemid = itemid - (first * 1000)
86 end
87 table.insert(outfits, itemid)
88
89 for _, outfitId in pairs(outfits) do
90 -- Make sure player don't already have this outfit and addon
91 if not player:hasOutfit(outfitId, orderCount) then
92 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
93 player:addOutfit(outfitId)
94 player:addOutfitAddon(outfitId, orderCount)
95 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new outfit!")
96 print("Process complete. [".. player:getName() .."] has received outfit: ["..outfitId.."] with addon: ["..orderCount.."]")
97 else -- Already has outfit
98 player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this outfit and addon!")
99 print("Process canceled. [".. player:getName() .."] already have outfit: ["..outfitId.."] with addon: ["..orderCount.."].")
100 end
101 end
102 end
103
104 -- ORDER TYPE 6 (Mounts)
105 if orderType == 6 then
106 served = true
107 -- Make sure player don't already have this outfit and addon
108 if not player:hasMount(orderItemId) then
109 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
110 player:addMount(orderItemId)
111 player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new mount!")
112 print("Process complete. [".. player:getName() .."] has received mount: ["..orderItemId.."]")
113 else -- Already has mount
114 player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this mount!")
115 print("Process canceled. [".. player:getName() .."] already have mount: ["..orderItemId.."].")
116 end
117 end
118
119 -- ORDER TYPE 7 (Direct house purchase)
120 if orderType == 7 then
121 served = true
122 local house = House(orderItemId)
123 -- Logged in player is not necessarily the player that bough the house. So we need to load player from db.
124 local buyerQuery = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = "..orderCount.." LIMIT 1")
125 if buyerQuery ~= false then
126 local buyerName = result.getString(buyerQuery, "name")
127 result.free(buyerQuery)
128 if house then
129 db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
130 house:setOwnerGuid(orderCount)
131 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.")
132 print("Process complete. [".. buyerName .."] has received house: ["..house:getName().."]")
133 else
134 print("Process canceled. Failed to load house with ID: "..orderItemId)
135 end
136 else
137 print("Process canceled. Failed to load player with ID: "..orderCount)
138 end
139 end
140
141 if not served then -- If this order hasn't been processed yet (missing type handling?)
142 print("Znote shop: Type ["..orderType.."] not properly processed. Missing Lua code?")
143 end
144 else -- Not in protection zone
145 player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have a pending shop order, please enter protection zone.')
146 print("Skipped one shop order. Reason: Player: [".. player:getName() .."] is not inside protection zone.")
147 end
148 else -- player not logged in
149 print("Skipped one shop order. Reason: Player with id [".. player_id .."] is not online.")
150 end
151
152 until not result.next(orderQuery)
153 result.free(orderQuery)
154 end
155 return true
156end
157
158globalevent:interval(30000)
159globalevent:register()
160