-
Notifications
You must be signed in to change notification settings - Fork 1k
/
player.lua
317 lines (269 loc) · 9.24 KB
/
player.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
function Player:onBrowseField(position)
if EventCallback.onBrowseField then
return EventCallback.onBrowseField(self, position)
end
return true
end
function Player:onLook(thing, position, distance)
local description = ""
if EventCallback.onLook then
description = EventCallback.onLook(self, thing, position, distance, description)
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end
function Player:onLookInBattleList(creature, distance)
local description = ""
if EventCallback.onLookInBattleList then
description = EventCallback.onLookInBattleList(self, creature, distance, description)
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end
function Player:onLookInTrade(partner, item, distance)
local description = "You see " .. item:getDescription(distance)
if EventCallback.onLookInTrade then
description = EventCallback.onLookInTrade(self, partner, item, distance, description)
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end
function Player:onLookInShop(itemType, count)
local description = "You see "
if EventCallback.onLookInShop then
description = EventCallback.onLookInShop(self, itemType, count, description)
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end
function Player:onLookInMarket(itemType)
if EventCallback.onLookInMarket then
EventCallback.onLookInMarket(self, itemType)
end
end
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
if EventCallback.onMoveItem then
return EventCallback.onMoveItem(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
end
return RETURNVALUE_NOERROR
end
function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
if EventCallback.onItemMoved then
EventCallback.onItemMoved(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
end
end
function Player:onMoveCreature(creature, fromPosition, toPosition)
if EventCallback.onMoveCreature then
return EventCallback.onMoveCreature(self, creature, fromPosition, toPosition)
end
return true
end
function Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation)
if EventCallback.onReportRuleViolation then
EventCallback.onReportRuleViolation(self, targetName, reportType, reportReason, comment, translation)
end
end
function Player:onReportBug(message, position, category)
if EventCallback.onReportBug then
return EventCallback.onReportBug(self, message, position, category)
end
return true
end
function Player:onTurn(direction)
if EventCallback.onTurn then
return EventCallback.onTurn(self, direction)
end
return true
end
function Player:onTradeRequest(target, item)
if EventCallback.onTradeRequest then
return EventCallback.onTradeRequest(self, target, item)
end
return true
end
function Player:onTradeAccept(target, item, targetItem)
if EventCallback.onTradeAccept then
return EventCallback.onTradeAccept(self, target, item, targetItem)
end
return true
end
function Player:onTradeCompleted(target, item, targetItem, isSuccess)
if EventCallback.onTradeCompleted then
EventCallback.onTradeCompleted(self, target, item, targetItem, isSuccess)
end
end
function Player:onPodiumRequest(item)
if not item:isPodium() then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return
end
self:sendEditPodium(item)
end
function Player:onPodiumEdit(item, outfit, direction, isVisible)
if not item:isPodium() then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return
end
if not self:getGroup():getAccess() then
-- check if the player is in melee range
if getDistanceBetween(self:getPosition(), item:getPosition()) > 1 then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return
end
-- reset outfit if unable to wear
if not self:canWearOutfit(outfit.lookType, outfit.lookAddons) then
outfit.lookType = 0
end
-- reset mount if unable to ride
local mount = Game.getMountIdByLookType(outfit.lookMount)
if not (mount and self:hasMount(mount)) then
outfit.lookMount = 0
end
end
local podiumOutfit = item:getOutfit()
local playerOutfit = self:getOutfit()
-- use player outfit if podium is empty
if podiumOutfit.lookType == 0 then
podiumOutfit.lookType = playerOutfit.lookType
podiumOutfit.lookHead = playerOutfit.lookHead
podiumOutfit.lookBody = playerOutfit.lookBody
podiumOutfit.lookLegs = playerOutfit.lookLegs
podiumOutfit.lookFeet = playerOutfit.lookFeet
podiumOutfit.lookAddons = playerOutfit.lookAddons
end
-- set player mount colors podium is empty
if podiumOutfit.lookMount == 0 then
podiumOutfit.lookMount = playerOutfit.lookMount
podiumOutfit.lookMountHead = playerOutfit.lookMountHead
podiumOutfit.lookMountBody = playerOutfit.lookMountBody
podiumOutfit.lookMountLegs = playerOutfit.lookMountLegs
podiumOutfit.lookMountFeet = playerOutfit.lookMountFeet
end
-- "outfit" box checked
if outfit.lookType ~= 0 then
podiumOutfit.lookType = outfit.lookType
podiumOutfit.lookHead = outfit.lookHead
podiumOutfit.lookBody = outfit.lookBody
podiumOutfit.lookLegs = outfit.lookLegs
podiumOutfit.lookFeet = outfit.lookFeet
podiumOutfit.lookAddons = outfit.lookAddons
end
-- "mount" box checked
if outfit.lookMount ~= 0 then
podiumOutfit.lookMount = outfit.lookMount
podiumOutfit.lookMountHead = outfit.lookMountHead
podiumOutfit.lookMountBody = outfit.lookMountBody
podiumOutfit.lookMountLegs = outfit.lookMountLegs
podiumOutfit.lookMountFeet = outfit.lookMountFeet
end
-- prevent invisible podium state
if outfit.lookType == 0 and outfit.lookMount == 0 then
isVisible = true
end
-- save player choices
item:setFlag(PODIUM_SHOW_PLATFORM, isVisible)
item:setFlag(PODIUM_SHOW_OUTFIT, outfit.lookType ~= 0)
item:setFlag(PODIUM_SHOW_MOUNT, outfit.lookMount ~= 0)
item:setDirection(direction < DIRECTION_NORTHEAST and direction or DIRECTION_SOUTH)
item:setOutfit(podiumOutfit)
end
local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)
local function useStamina(player)
local staminaMinutes = player:getStamina()
if staminaMinutes == 0 then
return
end
local playerId = player:getId()
if not nextUseStaminaTime[playerId] then
nextUseStaminaTime[playerId] = 0
end
local currentTime = os.time()
local timePassed = currentTime - nextUseStaminaTime[playerId]
if timePassed <= 0 then
return
end
if timePassed > 60 then
if staminaMinutes > 2 then
staminaMinutes = staminaMinutes - 2
else
staminaMinutes = 0
end
nextUseStaminaTime[playerId] = currentTime + 120
else
staminaMinutes = staminaMinutes - 1
nextUseStaminaTime[playerId] = currentTime + 60
end
player:setStamina(staminaMinutes)
end
function Player:onGainExperience(source, exp, rawExp)
if not source or source:isPlayer() then
return exp
end
-- Soul regeneration
local vocation = self:getVocation()
if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
self:addCondition(soulCondition)
end
-- Apply experience stage multiplier
exp = exp * Game.getExperienceStage(self:getLevel())
-- Stamina modifier
if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
useStamina(self)
local staminaMinutes = self:getStamina()
if staminaMinutes > 2340 and self:isPremium() then
exp = exp * 1.5
elseif staminaMinutes <= 840 then
exp = exp * 0.5
end
end
return EventCallback.onGainExperience and EventCallback.onGainExperience(self, source, exp, rawExp) or exp
end
function Player:onLoseExperience(exp)
return EventCallback.onLoseExperience and EventCallback.onLoseExperience(self, exp) or exp
end
function Player:onGainSkillTries(skill, tries)
if not APPLY_SKILL_MULTIPLIER then
return EventCallback.onGainSkillTries and EventCallback.onGainSkillTries(self, skill, tries) or tries
end
if skill == SKILL_MAGLEVEL then
tries = tries * configManager.getNumber(configKeys.RATE_MAGIC)
return EventCallback.onGainSkillTries and EventCallback.onGainSkillTries(self, skill, tries) or tries
end
tries = tries * configManager.getNumber(configKeys.RATE_SKILL)
return EventCallback.onGainSkillTries and EventCallback.onGainSkillTries(self, skill, tries) or tries
end
function Player:onWrapItem(item)
local topCylinder = item:getTopParent()
if not topCylinder then
return
end
local tile = Tile(topCylinder:getPosition())
if not tile then
return
end
local house = tile:getHouse()
if not house then
self:sendCancelMessage("You can only wrap and unwrap this item inside a house.")
return
end
if house ~= self:getHouse() and not string.find(house:getAccessList(SUBOWNER_LIST):lower(), "%f[%a]" .. self:getName():lower() .. "%f[%A]") then
self:sendCancelMessage("You cannot wrap or unwrap items from a house, which you are only guest to.")
return
end
local wrapId = item:getAttribute("wrapid")
if wrapId == 0 then
return
end
if not EventCallback.onWrapItem or EventCallback.onWrapItem(self, item) then
local oldId = item:getId()
item:remove(1)
local item = tile:addItem(wrapId)
if item then
item:setAttribute("wrapid", oldId)
end
end
end
function Player:onInventoryUpdate(item, slot, equip)
if EventCallback.onInventoryUpdate then
EventCallback.onInventoryUpdate(self, item, slot, equip)
end
end