1Icons = {}
2Icons[PlayerStates.Poison] = { tooltip = tr('You are poisoned'), path = '/images/game/states/poisoned', id = 'condition_poisoned' }
3Icons[PlayerStates.Burn] = { tooltip = tr('You are burning'), path = '/images/game/states/burning', id = 'condition_burning' }
4Icons[PlayerStates.Energy] = { tooltip = tr('You are electrified'), path = '/images/game/states/electrified', id = 'condition_electrified' }
5Icons[PlayerStates.Drunk] = { tooltip = tr('You are drunk'), path = '/images/game/states/drunk', id = 'condition_drunk' }
6Icons[PlayerStates.ManaShield] = { tooltip = tr('You are protected by a magic shield'), path = '/images/game/states/magic_shield', id = 'condition_magic_shield' }
7Icons[PlayerStates.Paralyze] = { tooltip = tr('You are paralysed'), path = '/images/game/states/slowed', id = 'condition_slowed' }
8Icons[PlayerStates.Haste] = { tooltip = tr('You are hasted'), path = '/images/game/states/haste', id = 'condition_haste' }
9Icons[PlayerStates.Swords] = { tooltip = tr('You may not logout during a fight'), path = '/images/game/states/logout_block', id = 'condition_logout_block' }
10Icons[PlayerStates.Drowning] = { tooltip = tr('You are drowning'), path = '/images/game/states/drowning', id = 'condition_drowning' }
11Icons[PlayerStates.Freezing] = { tooltip = tr('You are freezing'), path = '/images/game/states/freezing', id = 'condition_freezing' }
12Icons[PlayerStates.Dazzled] = { tooltip = tr('You are dazzled'), path = '/images/game/states/dazzled', id = 'condition_dazzled' }
13Icons[PlayerStates.Cursed] = { tooltip = tr('You are cursed'), path = '/images/game/states/cursed', id = 'condition_cursed' }
14Icons[PlayerStates.PartyBuff] = { tooltip = tr('You are strengthened'), path = '/images/game/states/strengthened', id = 'condition_strengthened' }
15Icons[PlayerStates.PzBlock] = { tooltip = tr('You may not logout or enter a protection zone'), path = '/images/game/states/protection_zone_block', id = 'condition_protection_zone_block' }
16Icons[PlayerStates.Pz] = { tooltip = tr('You are within a protection zone'), path = '/images/game/states/protection_zone', id = 'condition_protection_zone' }
17Icons[PlayerStates.Bleeding] = { tooltip = tr('You are bleeding'), path = '/images/game/states/bleeding', id = 'condition_bleeding' }
18Icons[PlayerStates.Hungry] = { tooltip = tr('You are hungry'), path = '/images/game/states/hungry', id = 'condition_hungry' }
19
20InventorySlotStyles = {
21 [InventorySlotHead] = "HeadSlot",
22 [InventorySlotNeck] = "NeckSlot",
23 [InventorySlotBack] = "BackSlot",
24 [InventorySlotBody] = "BodySlot",
25 [InventorySlotRight] = "RightSlot",
26 [InventorySlotLeft] = "LeftSlot",
27 [InventorySlotLeg] = "LegSlot",
28 [InventorySlotFeet] = "FeetSlot",
29 [InventorySlotFinger] = "FingerSlot",
30 [InventorySlotAmmo] = "AmmoSlot"
31}
32
33inventoryWindow = nil
34inventoryPanel = nil
35inventoryButton = nil
36purseButton = nil
37
38combatControlsWindow = nil
39fightOffensiveBox = nil
40fightBalancedBox = nil
41fightDefensiveBox = nil
42chaseModeButton = nil
43safeFightButton = nil
44mountButton = nil
45fightModeRadioGroup = nil
46buttonPvp = nil
47
48soulLabel = nil
49capLabel = nil
50conditionPanel = nil
51
52function init()
53 connect(LocalPlayer, {
54 onInventoryChange = onInventoryChange,
55 onBlessingsChange = onBlessingsChange
56 })
57 connect(g_game, { onGameStart = refresh })
58
59 g_keyboard.bindKeyDown('Ctrl+I', toggle)
60
61
62 inventoryWindow = g_ui.loadUI('inventory', modules.game_interface.getRightPanel())
63 inventoryWindow:disableResize()
64 inventoryPanel = inventoryWindow:getChildById('contentsPanel'):getChildById('inventoryPanel')
65 if not inventoryWindow.forceOpen then
66 --inventoryButton = modules.client_topmenu.addRightGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', '/images/topbuttons/inventory', toggle)
67 --inventoryButton:setOn(true)
68 end
69
70 purseButton = inventoryWindow:recursiveGetChildById('purseButton')
71 purseButton.onClick = function()
72 local purse = g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)
73 if purse then
74 g_game.use(purse)
75 end
76 end
77
78 -- controls
79 fightOffensiveBox = inventoryWindow:recursiveGetChildById('fightOffensiveBox')
80 fightBalancedBox = inventoryWindow:recursiveGetChildById('fightBalancedBox')
81 fightDefensiveBox = inventoryWindow:recursiveGetChildById('fightDefensiveBox')
82
83 chaseModeButton = inventoryWindow:recursiveGetChildById('chaseModeBox')
84 safeFightButton = inventoryWindow:recursiveGetChildById('safeFightBox')
85 buttonPvp = inventoryWindow:recursiveGetChildById('buttonPvp')
86
87 mountButton = inventoryWindow:recursiveGetChildById('mountButton')
88 mountButton.onClick = onMountButtonClick
89
90 whiteDoveBox = inventoryWindow:recursiveGetChildById('whiteDoveBox')
91 whiteHandBox = inventoryWindow:recursiveGetChildById('whiteHandBox')
92 yellowHandBox = inventoryWindow:recursiveGetChildById('yellowHandBox')
93 redFistBox = inventoryWindow:recursiveGetChildById('redFistBox')
94
95 fightModeRadioGroup = UIRadioGroup.create()
96 fightModeRadioGroup:addWidget(fightOffensiveBox)
97 fightModeRadioGroup:addWidget(fightBalancedBox)
98 fightModeRadioGroup:addWidget(fightDefensiveBox)
99
100 connect(fightModeRadioGroup, { onSelectionChange = onSetFightMode })
101 connect(chaseModeButton, { onCheckChange = onSetChaseMode })
102 connect(safeFightButton, { onCheckChange = onSetSafeFight })
103 if buttonPvp then
104 connect(buttonPvp, { onClick = onSetSafeFight2 })
105 end
106 connect(g_game, {
107 onGameStart = online,
108 onGameEnd = offline,
109 onFightModeChange = update,
110 onChaseModeChange = update,
111 onSafeFightChange = update,
112 onPVPModeChange = update,
113 onWalk = check,
114 onAutoWalk = check
115 })
116
117 connect(LocalPlayer, { onOutfitChange = onOutfitChange })
118
119 if g_game.isOnline() then
120 online()
121 end
122-- controls end
123
124-- status
125 soulLabel = inventoryWindow:recursiveGetChildById('soulLabel')
126 capLabel = inventoryWindow:recursiveGetChildById('capLabel')
127 conditionPanel = inventoryWindow:recursiveGetChildById('conditionPanel')
128
129
130 connect(LocalPlayer, { onStatesChange = onStatesChange,
131 onSoulChange = onSoulChange,
132 onFreeCapacityChange = onFreeCapacityChange })
133-- status end
134
135 refresh()
136 inventoryWindow:setup()
137end
138
139function terminate()
140 disconnect(LocalPlayer, {
141 onInventoryChange = onInventoryChange,
142 onBlessingsChange = onBlessingsChange
143 })
144 disconnect(g_game, { onGameStart = refresh })
145
146 g_keyboard.unbindKeyDown('Ctrl+I')
147
148 -- controls
149 if g_game.isOnline() then
150 offline()
151 end
152
153 fightModeRadioGroup:destroy()
154
155 disconnect(g_game, {
156 onGameStart = online,
157 onGameEnd = offline,
158 onFightModeChange = update,
159 onChaseModeChange = update,
160 onSafeFightChange = update,
161 onPVPModeChange = update,
162 onWalk = check,
163 onAutoWalk = check
164 })
165
166 disconnect(LocalPlayer, { onOutfitChange = onOutfitChange })
167 -- controls end
168 -- status
169 disconnect(LocalPlayer, { onStatesChange = onStatesChange,
170 onSoulChange = onSoulChange,
171 onFreeCapacityChange = onFreeCapacityChange })
172 -- status end
173
174 inventoryWindow:destroy()
175 --if inventoryButton then
176 -- inventoryButton:destroy()
177 --end
178end
179
180function toggleAdventurerStyle(hasBlessing)
181 for slot = InventorySlotFirst, InventorySlotLast do
182 local itemWidget = inventoryPanel:getChildById('slot' .. slot)
183 if itemWidget then
184 itemWidget:setOn(hasBlessing)
185 end
186 end
187end
188
189function refresh()
190 local player = g_game.getLocalPlayer()
191 for i = InventorySlotFirst, InventorySlotPurse do
192 if g_game.isOnline() then
193 onInventoryChange(player, i, player:getInventoryItem(i))
194 else
195 onInventoryChange(player, i, nil)
196 end
197 toggleAdventurerStyle(player and Bit.hasBit(player:getBlessings(), Blessings.Adventurer) or false)
198 end
199 if player then
200 onSoulChange(player, player:getSoul())
201 onFreeCapacityChange(player, player:getFreeCapacity())
202 onStatesChange(player, player:getStates(), 0)
203 end
204
205 purseButton:setVisible(g_game.getFeature(GamePurseSlot))
206end
207
208function toggle()
209 --if not inventoryButton then
210 -- return
211 --end
212 --if inventoryButton:isOn() then
213 -- inventoryWindow:close()
214 -- inventoryButton:setOn(false)
215 --else
216 -- inventoryWindow:open()
217 -- inventoryButton:setOn(true)
218 --end
219end
220
221function onMiniWindowClose()
222 --if not inventoryButton then
223 -- return
224 --end
225 --inventoryButton:setOn(false)
226end
227
228-- hooked events
229function onInventoryChange(player, slot, item, oldItem)
230 if slot > InventorySlotPurse then return end
231
232 if slot == InventorySlotPurse then
233 if g_game.getFeature(GamePurseSlot) then
234 --purseButton:setEnabled(item and true or false)
235 end
236 return
237 end
238
239 local itemWidget = inventoryPanel:getChildById('slot' .. slot)
240 if item then
241 itemWidget:setStyle('InventoryItem')
242 itemWidget:setItem(item)
243 else
244 itemWidget:setStyle(InventorySlotStyles[slot])
245 itemWidget:setItem(nil)
246 end
247end
248
249function onBlessingsChange(player, blessings, oldBlessings)
250 local hasAdventurerBlessing = Bit.hasBit(blessings, Blessings.Adventurer)
251 if hasAdventurerBlessing ~= Bit.hasBit(oldBlessings, Blessings.Adventurer) then
252 toggleAdventurerStyle(hasAdventurerBlessing)
253 end
254end
255
256
257-- controls
258function update()
259 local fightMode = g_game.getFightMode()
260 if fightMode == FightOffensive then
261 fightModeRadioGroup:selectWidget(fightOffensiveBox)
262 elseif fightMode == FightBalanced then
263 fightModeRadioGroup:selectWidget(fightBalancedBox)
264 else
265 fightModeRadioGroup:selectWidget(fightDefensiveBox)
266 end
267
268 local chaseMode = g_game.getChaseMode()
269 chaseModeButton:setChecked(chaseMode == ChaseOpponent)
270
271 local safeFight = g_game.isSafeFight()
272 safeFightButton:setChecked(not safeFight)
273 if buttonPvp then
274 if safeFight then
275 buttonPvp:setOn(false)
276 else
277 buttonPvp:setOn(true)
278 end
279 end
280
281 if g_game.getFeature(GamePVPMode) then
282 local pvpMode = g_game.getPVPMode()
283 local pvpWidget = getPVPBoxByMode(pvpMode)
284 end
285end
286
287function check()
288 if modules.client_options.getOption('autoChaseOverride') then
289 if g_game.isAttacking() and g_game.getChaseMode() == ChaseOpponent then
290 g_game.setChaseMode(DontChase)
291 end
292 end
293end
294
295function online()
296 local player = g_game.getLocalPlayer()
297 if player then
298 local char = g_game.getCharacterName()
299
300 local lastCombatControls = g_settings.getNode('LastCombatControls')
301
302 if not table.empty(lastCombatControls) then
303 if lastCombatControls[char] then
304 g_game.setFightMode(lastCombatControls[char].fightMode)
305 g_game.setChaseMode(lastCombatControls[char].chaseMode)
306 g_game.setSafeFight(lastCombatControls[char].safeFight)
307 if lastCombatControls[char].pvpMode then
308 g_game.setPVPMode(lastCombatControls[char].pvpMode)
309 end
310 end
311 end
312
313 if g_game.getFeature(GamePlayerMounts) then
314 mountButton:setVisible(true)
315 mountButton:setChecked(player:isMounted())
316 else
317 mountButton:setVisible(false)
318 end
319 end
320
321 update()
322end
323
324function offline()
325 local lastCombatControls = g_settings.getNode('LastCombatControls')
326 if not lastCombatControls then
327 lastCombatControls = {}
328 end
329
330 conditionPanel:destroyChildren()
331
332 local player = g_game.getLocalPlayer()
333 if player then
334 local char = g_game.getCharacterName()
335 lastCombatControls[char] = {
336 fightMode = g_game.getFightMode(),
337 chaseMode = g_game.getChaseMode(),
338 safeFight = g_game.isSafeFight()
339 }
340
341 if g_game.getFeature(GamePVPMode) then
342 lastCombatControls[char].pvpMode = g_game.getPVPMode()
343 end
344
345 -- save last combat control settings
346 g_settings.setNode('LastCombatControls', lastCombatControls)
347 end
348end
349
350function onSetFightMode(self, selectedFightButton)
351 if selectedFightButton == nil then return end
352 local buttonId = selectedFightButton:getId()
353 local fightMode
354 if buttonId == 'fightOffensiveBox' then
355 fightMode = FightOffensive
356 elseif buttonId == 'fightBalancedBox' then
357 fightMode = FightBalanced
358 else
359 fightMode = FightDefensive
360 end
361 g_game.setFightMode(fightMode)
362end
363
364function onSetChaseMode(self, checked)
365 local chaseMode
366 if checked then
367 chaseMode = ChaseOpponent
368 else
369 chaseMode = DontChase
370 end
371 g_game.setChaseMode(chaseMode)
372end
373
374function onSetSafeFight(self, checked)
375 g_game.setSafeFight(not checked)
376 if buttonPvp then
377 if not checked then
378 buttonPvp:setOn(false)
379 else
380 buttonPvp:setOn(true)
381 end
382 end
383end
384
385function onSetSafeFight2(self)
386 onSetSafeFight(self, not safeFightButton:isChecked())
387end
388
389function onSetPVPMode(self, selectedPVPButton)
390 if selectedPVPButton == nil then
391 return
392 end
393
394 local buttonId = selectedPVPButton:getId()
395 local pvpMode = PVPWhiteDove
396 if buttonId == 'whiteDoveBox' then
397 pvpMode = PVPWhiteDove
398 elseif buttonId == 'whiteHandBox' then
399 pvpMode = PVPWhiteHand
400 elseif buttonId == 'yellowHandBox' then
401 pvpMode = PVPYellowHand
402 elseif buttonId == 'redFistBox' then
403 pvpMode = PVPRedFist
404 end
405
406 g_game.setPVPMode(pvpMode)
407end
408
409function onMountButtonClick(self, mousePos)
410 local player = g_game.getLocalPlayer()
411 if player then
412 player:toggleMount()
413 end
414end
415
416function onOutfitChange(localPlayer, outfit, oldOutfit)
417 if outfit.mount == oldOutfit.mount then
418 return
419 end
420
421 mountButton:setChecked(outfit.mount ~= nil and outfit.mount > 0)
422end
423
424function getPVPBoxByMode(mode)
425 local widget = nil
426 if mode == PVPWhiteDove then
427 widget = whiteDoveBox
428 elseif mode == PVPWhiteHand then
429 widget = whiteHandBox
430 elseif mode == PVPYellowHand then
431 widget = yellowHandBox
432 elseif mode == PVPRedFist then
433 widget = redFistBox
434 end
435 return widget
436end
437
438-- status
439function toggleIcon(bitChanged)
440 local icon = conditionPanel:getChildById(Icons[bitChanged].id)
441 if icon then
442 icon:destroy()
443 else
444 icon = loadIcon(bitChanged)
445 icon:setParent(conditionPanel)
446 end
447end
448
449function loadIcon(bitChanged)
450 local icon = g_ui.createWidget('ConditionWidget', conditionPanel)
451 icon:setId(Icons[bitChanged].id)
452 icon:setImageSource(Icons[bitChanged].path)
453 icon:setTooltip(Icons[bitChanged].tooltip)
454 return icon
455end
456
457function onSoulChange(localPlayer, soul)
458 if not soul then return end
459 soulLabel:setText(tr('Soul') .. ':\n' .. soul)
460end
461
462function onFreeCapacityChange(player, freeCapacity)
463 if not freeCapacity then return end
464 if freeCapacity > 99 then
465 freeCapacity = math.floor(freeCapacity * 10) / 10
466 end
467 if freeCapacity > 999 then
468 freeCapacity = math.floor(freeCapacity)
469 end
470 if freeCapacity > 99999 then
471 freeCapacity = math.min(9999, math.floor(freeCapacity/1000)) .. "k"
472 end
473 capLabel:setText(tr('Cap') .. ':\n' .. freeCapacity)
474end
475
476function onStatesChange(localPlayer, now, old)
477 if now == old then return end
478 local bitsChanged = bit32.bxor(now, old)
479 for i = 1, 32 do
480 local pow = math.pow(2, i-1)
481 if pow > bitsChanged then break end
482 local bitChanged = bit32.band(bitsChanged, pow)
483 if bitChanged ~= 0 then
484 toggleIcon(bitChanged)
485 end
486 end
487end