outfit.lua

main 966 lines · 26.2 KB Raw
Alex Alex Commit Client Upload Part 2 19/10/2026 00:06
1local ADDON_SETS = {
2 {1}, {2}, {1,2}, {3}, {1,3}, {2,3}, {1,2,3}
3}
4
5local outfitDir = "/outfits/"
6
7local ignoreNextOutfitWindow = 0
8
9-- Module state
10local outfitWindow = nil
11local outfitFile = nil
12local outfits_list = nil
13local mounts_list = nil
14local wings_list = nil
15local auras_list = nil
16local shaders_list = nil
17local runeEffects_list = nil
18
19local previewDirection = 2
20local addons = nil
21local outfitsPreset = {}
22local colorBoxes = {}
23local currentColorBox = nil
24local currentClotheButtonBox = nil
25
26local selectorOutfit = nil
27local selectorMount = nil
28local selectorWings = nil
29local selectorAuras = nil
30local selectorShaders = nil
31local selectorRuneEffect = nil
32
33local typeBox = nil
34local mountBox = nil
35local wingsBox = nil
36local auraBox = nil
37local shaderBox = nil
38local runeEffectBox = nil
39
40local previewBox = nil
41local previewPanel = nil
42local OutfitPanel = nil
43local PresetPanel = nil
44local cOutfit = nil
45local sId = nil
46
47-- Forward declarations
48local destroy, accept, updateOutfit, onTypeChange
49local setupSelector, refreshSelector, refreshPreset
50local selectOutfit, getOutfitListById
51local onColorCheckChange, onClotheCheckChange, onAddonCheckChange
52local onOutfitCheckChange
53local outfitConfig_Load, outfitConfig_Save
54local randomizeAll, randomizeOutfit, randomizeColor
55local singlelineEditorWindow, outfitConfirmationWindow
56
57function init()
58 connect(g_game, {
59 onOpenOutfitWindow = create,
60 onGameEnd = destroy
61 })
62
63 if not g_resources.directoryExists("/outfits/") then
64 g_resources.makeDir("/outfits/")
65 end
66end
67
68function terminate()
69 disconnect(g_game, {
70 onOpenOutfitWindow = create,
71 onGameEnd = destroy
72 })
73 destroy()
74end
75
76function clearSearch()
77 local searchInput = outfitWindow.filter:getChildById("searchInput")
78 searchInput:setText("")
79 onSearch()
80end
81
82function onSearch()
83 scheduleEvent(function()
84 if not outfitWindow then return end
85 local panel = (sId == "preset") and PresetPanel or OutfitPanel
86 if not panel then return end
87 local searchInput = outfitWindow.filter:getChildById("searchInput")
88 local text = searchInput:getText():lower()
89 local children = panel:getChildCount()
90
91 if #text > 0 then
92 for i = 1, children do
93 local child = panel:getChildByIndex(i)
94 if child then
95 local childTitle = child:getChildById("title")
96 if childTitle then
97 if childTitle:getText():lower():find(text) then
98 child:show()
99 else
100 child:hide()
101 end
102 end
103 end
104 end
105 else
106 for i = 1, children do
107 local child = panel:getChildByIndex(i)
108 if child then
109 child:show()
110 end
111 end
112 end
113 end, 50)
114end
115
116function singlelineEditorWindow(text, options, callback)
117 options = options or {}
118 options.multiline = false
119 return modules.client_textedit.edit(text, options, callback)
120end
121
122function outfitConfirmationWindow(title, question, callback)
123 local window = nil
124
125 local function onConfirm()
126 window:destroy()
127 callback()
128 end
129
130 local function closeWindow()
131 window:destroy()
132 end
133
134 window = displayGeneralBox(title, question, {
135 {text = tr("Yes"), callback = onConfirm},
136 {text = tr("No"), callback = closeWindow},
137 anchor = AnchorHorizontalCenter
138 }, onConfirm, closeWindow)
139
140 return window
141end
142
143function getOutfitListById(id)
144 id = id or sId
145 local list = {}
146 local selector = nil
147
148 if (id == "outfit" or id == "type") and outfits_list then
149 list = outfits_list
150 selector = selectorOutfit
151 sId = "type"
152 elseif id == "mount" and mounts_list then
153 list = mounts_list
154 selector = selectorMount
155 elseif id == "wings" and wings_list then
156 list = wings_list
157 selector = selectorWings
158 elseif id == "aura" and auras_list then
159 list = auras_list
160 selector = selectorAuras
161 elseif id == "shader" and shaders_list then
162 list = shaders_list
163 selector = selectorShaders
164 elseif id == "runeeffect" and runeEffects_list then
165 list = runeEffects_list
166 selector = selectorRuneEffect
167 end
168
169 return list, selector
170end
171
172function setupSelector(widget, id, outfit, list)
173 widget:setId(id)
174
175 local name = (id == "type" and "Outfit") or id:gsub("^%l", string.upper)
176 outfitWindow.typeCombo:addOption(name, id)
177
178 if id ~= "type" or #list == 0 then
179 table.insert(list, 1, {0, "-"})
180 end
181
182 local pos = 1
183 for i, o in pairs(list) do
184 if (id == "shader" and outfit[id] == o[2]) or
185 (id == "runeeffect" and outfit.runeeffect == o[1]) or
186 outfit[id] == o[1] then
187 pos = i
188 end
189 end
190
191 if list[pos] then
192 widget.outfit = list[pos]
193
194 if id == "shader" then
195 widget.creature:setOutfit({shader = list[pos][2]})
196 elseif id == "runeeffect" then
197 widget.creature:setOutfit({runeeffect = list[pos][1]})
198 else
199 widget.creature:setOutfit({type = list[pos][1]})
200 end
201
202 widget.label:setText(list[pos][2])
203 end
204
205 return widget
206end
207
208function refreshSelector(id)
209 local widget, list = nil, nil
210
211 if id == "type" then
212 widget = selectorOutfit
213 list = outfits_list
214 elseif id == "mount" then
215 widget = selectorMount
216 list = mounts_list
217 elseif id == "wings" then
218 widget = selectorWings
219 list = wings_list
220 elseif id == "aura" then
221 widget = selectorAuras
222 list = auras_list
223 elseif id == "shader" then
224 widget = selectorShaders
225 list = shaders_list
226 elseif id == "runeeffect" then
227 widget = selectorRuneEffect
228 list = runeEffects_list
229 end
230
231 if not widget or not list then return false end
232
233 local outfit = widget.creature:getOutfit()
234 local pos = 1
235
236 for i, o in pairs(list) do
237 if (id == "shader" and outfit.shader == o[2]) or
238 (id == "wings" and outfit.wings == o[2]) or
239 (id == "aura" and outfit.aura == o[2]) or
240 (id == "runeeffect" and outfit.runeeffect == o[1]) or
241 outfit.type == o[1] then
242 pos = i
243 break
244 end
245 end
246
247 if list[pos] then
248 widget.label:setText(list[pos][2])
249 return true
250 end
251
252 return false
253end
254
255function selectOutfit(widget)
256 local list, sel = getOutfitListById()
257 if not list or not sel then return end
258 local pos = tonumber(widget:getId())
259
260 if sId ~= "healthBar" and sId ~= "manaBar" then
261 local outfit = sel.creature:getOutfit()
262
263 if sId == "shader" then
264 outfit.shader = list[pos][2]
265 elseif sId == "runeeffect" then
266 outfit.runeeffect = list[pos][1]
267 else
268 outfit.type = list[pos][1]
269 end
270
271 sel.outfit = list[pos]
272 sel.creature:setOutfit(outfit)
273 sel.label:setText(list[pos][2])
274 end
275
276 updateOutfit()
277end
278
279function onTypeChange(widgetType, option)
280 local list = {}
281 local current = 1
282
283 if type(widgetType) == "userdata" then
284 sId = widgetType:getCurrentOption().data
285 else
286 sId = widgetType
287 end
288
289 if sId == "preset" then
290 outfitConfig_Load()
291 refreshPreset()
292 return
293 end
294
295 OutfitPanel:destroyChildren()
296
297 local player = g_game.getLocalPlayer()
298 local specOutfit = player:getOutfit()
299 list = getOutfitListById()
300
301 if sId == "outfit" then
302 sId = "type"
303 end
304
305 for i, o in pairs(list) do
306 if (sId == "shader" and cOutfit.shader == o[2]) or
307 (sId == "runeeffect" and cOutfit.runeeffect == o[1]) or
308 cOutfit[sId] == o[1] then
309 current = i
310 end
311 end
312
313 if #list > 0 then
314 for i = 1, #list do
315 if sId == "runeeffect" then
316 local w = g_ui.createWidget("RuneEffectItem", OutfitPanel)
317 w:setId(i)
318 w:getChildById("title"):setText(list[i][2])
319
320 if list[i][1] > 0 then
321 w:getChildById("runeImage"):setImageSource("/data/images/runeeffects/" .. list[i][1] .. ".png")
322 else
323 w:getChildById("runeImage"):setImageSource("")
324 end
325
326 if current == i then
327 w:focus()
328 addEvent(function()
329 OutfitPanel:ensureChildVisible(w)
330 end)
331 end
332 else
333 local w = g_ui.createWidget("OutfitCreature", OutfitPanel)
334 w:setId(i)
335
336 local tmpOutfit = {
337 type = list[i][1],
338 addons = list[i][3] or 0,
339 mount = 0,
340 shader = "",
341 aura = 0,
342 wings = 0,
343 runeeffect = 0,
344 head = specOutfit.head,
345 body = specOutfit.body,
346 legs = specOutfit.legs,
347 feet = specOutfit.feet
348 }
349
350 if sId == "shader" then
351 tmpOutfit.shader = list[i][2]
352 if tmpOutfit.shader == "-" then
353 tmpOutfit.shader = ""
354 end
355 end
356
357 w:getChildById("title"):setText(list[i][2])
358 w:getChildById("outfit"):setOutfit(tmpOutfit)
359
360 if current == i then
361 w:focus()
362 addEvent(function()
363 OutfitPanel:ensureChildVisible(w)
364 end)
365 end
366 end
367 end
368 end
369
370 outfitWindow.outfits:setVisible(true)
371 outfitWindow.presetPanel:setVisible(false)
372 outfitWindow.presetOptions:setVisible(false)
373end
374
375function outfitConfig_Load()
376 if g_resources.fileExists(outfitFile) then
377 local status, result = pcall(function()
378 return json.decode(g_resources.readFileContents(outfitFile))
379 end)
380
381 if not status then
382 return onError("Error reading config (" .. outfitFile .. "): " .. result)
383 end
384
385 outfitsPreset = result
386 end
387end
388
389function outfitConfig_Save()
390 local status, result = pcall(function()
391 return json.encode(outfitsPreset, 2)
392 end)
393
394 if not status then
395 print("Error saving config: " .. result)
396 return
397 end
398
399 if #result > 104857600 then
400 print("Config too big, not saving")
401 return
402 end
403
404 g_resources.writeFileContents(outfitFile, result)
405end
406
407function refreshPreset(id)
408 PresetPanel:destroyChildren()
409
410 if outfitsPreset then
411 for i, outfit in pairs(outfitsPreset) do
412 local widget = g_ui.createWidget("PresetOutfitPanel", PresetPanel)
413 widget:setId(i)
414 widget:getChildById("title"):setText(outfit.name)
415 widget:getChildById("mount"):setOutfit({type = outfit.mount})
416 widget:getChildById("creature"):setOutfit(outfit.outfit)
417
418 widget.onDoubleClick = function()
419 scheduleEvent(function()
420 local tOutfit = {
421 type = outfit.outfit.type,
422 addons = outfit.outfit.addons,
423 head = outfit.outfit.head,
424 body = outfit.outfit.body,
425 legs = outfit.outfit.legs,
426 feet = outfit.outfit.feet
427 }
428
429 typeBox:setOutfit(tOutfit)
430 mountBox:setOutfit({type = outfit.mount})
431 wingsBox:setOutfit({type = outfit.outfit.wings})
432 auraBox:setOutfit({type = outfit.outfit.aura})
433 shaderBox:setOutfit({shader = outfit.outfit.shader})
434 if runeEffectBox and outfit.outfit.runeeffect then
435 runeEffectBox:setOutfit({runeeffect = outfit.outfit.runeeffect})
436 end
437 updateOutfit()
438 refreshSelector("type")
439 refreshSelector("mount")
440 refreshSelector("wings")
441 refreshSelector("aura")
442 refreshSelector("shader")
443 refreshSelector("runeeffect")
444 end, 20)
445 end
446
447 if id and i == #outfitsPreset then
448 widget:focus()
449 addEvent(function()
450 PresetPanel:ensureChildVisible(widget)
451 end)
452 end
453 end
454 end
455
456 outfitWindow.outfits:setVisible(false)
457 outfitWindow.presetPanel:setVisible(true)
458 outfitWindow.presetOptions:setVisible(true)
459end
460
461function presetAction(action)
462 local text, index = nil, nil
463 local data = typeBox:getOutfit()
464 local mount = mountBox:getOutfit()
465 local aura = auraBox:getOutfit()
466 local wings = wingsBox:getOutfit()
467 local shader = shaderBox:getOutfit()
468 local runeeffect = runeEffectBox and runeEffectBox:getOutfit() or nil
469
470 mount = (mount and mount.type) or 0
471 aura = (aura and aura.type) or 0
472 wings = (wings and wings.type) or 0
473 shader = (shader and shader.shader) or ""
474 runeeffect = (runeeffect and runeeffect.runeeffect) or 0
475
476 local selected = PresetPanel:getFocusedChild()
477 if selected then
478 index = PresetPanel:getChildIndex(selected)
479 text = selected:getChildById("title"):getText()
480 end
481
482 if action == "new" then
483 local tmpTitle = selectorOutfit.label:getText()
484 singlelineEditorWindow(tmpTitle, {title = "Enter outfit name."}, function(name)
485 if name and #name > 1 then
486 table.insert(outfitsPreset, {
487 name = name,
488 outfit = {
489 type = data.type,
490 head = data.head,
491 body = data.body,
492 legs = data.legs,
493 feet = data.feet,
494 addons = data.addons,
495 aura = aura,
496 wings = wings,
497 shader = shader,
498 runeeffect = runeeffect
499 },
500 mount = mount
501 })
502 outfitConfig_Save()
503 refreshPreset(true)
504 end
505 end)
506
507 elseif action == "rename" then
508 if index and index > 0 then
509 singlelineEditorWindow(text, {title = "Enter new name."}, function(name)
510 if name and #name > 3 then
511 outfitsPreset[index].name = name
512 selected:getChildById("title"):setText(name)
513 outfitConfig_Save()
514 selected:setBorderColor("green")
515 end
516 end)
517 end
518
519 elseif action == "save" then
520 if index and index > 0 then
521 outfitConfirmationWindow("Confirm Save?", tr("Are you sure you want to overwrite " .. text .. "?"), function()
522 outfitsPreset[index] = {
523 name = text,
524 outfit = {
525 type = data.type,
526 head = data.head,
527 body = data.body,
528 legs = data.legs,
529 feet = data.feet,
530 addons = data.addons,
531 aura = aura,
532 wings = wings,
533 shader = shader,
534 runeeffect = runeeffect
535 },
536 mount = mount
537 }
538 outfitConfig_Save()
539 refreshPreset(true)
540 selected:setBorderColor("green")
541 end)
542 end
543
544 elseif action == "delete" then
545 if index and index > 0 then
546 outfitConfirmationWindow("Confirm deletion?", tr("Are you sure you want to delete " .. text .. "?"), function()
547 table.remove(outfitsPreset, index)
548 outfitConfig_Save()
549 refreshPreset(true)
550 end)
551 end
552 end
553end
554
555function destroy()
556 if outfitWindow then
557 outfitWindow:destroy()
558 outfitWindow = nil
559 currentColorBox = nil
560 currentClotheButtonBox = nil
561 colorBoxes = {}
562 addons = nil
563 end
564end
565
566function create(currentOutfit, outfitList, mountList, wingList, auraList, shaderList, hpBarList, manaBarList, runeEffectList)
567 if ignoreNextOutfitWindow and g_clock.millis() < ignoreNextOutfitWindow + 1000 then
568 return
569 end
570
571 if outfitWindow and not outfitWindow:isHidden() then
572 return
573 end
574
575 destroy()
576
577 outfitFile = outfitDir .. g_game.getLocalPlayer():getName() .. "_outfit.json"
578 outfits_list = outfitList
579 mounts_list = mountList
580 wings_list = wingList
581 auras_list = auraList
582 shaders_list = shaderList
583 runeEffects_list = runeEffectList or {}
584 cOutfit = currentOutfit
585
586 outfitWindow = g_ui.displayUI("outfitwindow")
587
588 selectorOutfit = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "type", currentOutfit, outfitList)
589 typeBox = outfitWindow.extensions.type.creature
590
591 OutfitPanel = outfitWindow.outfits.list
592 PresetPanel = outfitWindow.presetPanel.list
593 previewPanel = outfitWindow.preview
594 previewBox = previewPanel.creature
595
596 local outfit = typeBox:getOutfit()
597 outfit.head = currentOutfit.head
598 outfit.body = currentOutfit.body
599 outfit.legs = currentOutfit.legs
600 outfit.feet = currentOutfit.feet
601 typeBox:setOutfit(outfit)
602
603 if g_game.getFeature(GamePlayerMounts) then
604 selectorMount = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "mount", currentOutfit, mountList)
605 mountBox = outfitWindow.extensions.mount.creature
606 end
607
608 if g_game.getFeature(GameWingsAndAura) then
609 selectorWings = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "wings", currentOutfit, wingList)
610 selectorAuras = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "aura", currentOutfit, auraList)
611 wingsBox = outfitWindow.extensions.wings.creature
612 auraBox = outfitWindow.extensions.aura.creature
613 end
614
615 if g_game.getFeature(GameOutfitShaders) then
616 selectorShaders = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "shader", currentOutfit, shaderList)
617 shaderBox = outfitWindow.extensions.shader.creature
618 end
619
620 if runeEffects_list and #runeEffects_list > 0 then
621 selectorRuneEffect = setupSelector(g_ui.createWidget("OutfitSelectorPanel", outfitWindow.extensions), "runeeffect", currentOutfit, runeEffects_list)
622 runeEffectBox = selectorRuneEffect.creature
623 end
624
625 outfitWindow.typeCombo:addOption("Preset", "preset")
626
627 addons = {
628 {value = 1, widget = outfitWindow.addon1},
629 {value = 2, widget = outfitWindow.addon2},
630 {value = 4, widget = outfitWindow.addon3}
631 }
632
633 outfitWindow.typeCombo.onOptionChange = onTypeChange
634
635 for j = 0, 6 do
636 for i = 0, 18 do
637 local colorId = j * 19 + i
638 local colorBox = g_ui.createWidget("ColorBox", outfitWindow.colorBoxPanel)
639 local outfitColor = getOutfitColor(colorId)
640
641 colorBox:setImageColor(outfitColor)
642 colorBox:setId("colorBox" .. colorId)
643 colorBox.colorId = colorId
644
645 if colorId == currentOutfit.head then
646 currentColorBox = colorBox
647 colorBox:setChecked(true)
648 end
649
650 colorBox.onCheckChange = onColorCheckChange
651 colorBoxes[#colorBoxes + 1] = colorBox
652 end
653 end
654
655 if previewPanel.showmount:isChecked() then
656 outfit.mount = currentOutfit.mount
657 else
658 outfit.mount = 0
659 end
660
661 previewBox:setOutfit(currentOutfit)
662
663 for _, addon in pairs(addons) do
664 addon.widget.onCheckChange = function(self)
665 onAddonCheckChange(self, addon.value)
666 end
667 end
668
669 if currentOutfit.addons and currentOutfit.addons > 0 then
670 for _, i in pairs(ADDON_SETS[currentOutfit.addons]) do
671 addons[i].widget:setChecked(true)
672 end
673 end
674
675 currentClotheButtonBox = outfitWindow.head
676 outfitWindow.head.onCheckChange = onClotheCheckChange
677 outfitWindow.primary.onCheckChange = onClotheCheckChange
678 outfitWindow.secondary.onCheckChange = onClotheCheckChange
679 outfitWindow.detail.onCheckChange = onClotheCheckChange
680
681 previewBox:setOutfit(outfit)
682 previewBox:setDirection(previewDirection)
683
684 previewPanel.turnLeft.onClick = function()
685 previewDirection = (previewDirection + 1) % 4
686 previewBox:setDirection(previewDirection)
687 end
688
689 previewPanel.turnRight.onClick = function()
690 previewDirection = (previewDirection - 1 + 4) % 4
691 previewBox:setDirection(previewDirection)
692 end
693
694 local optionOutfit = modules.client_options.getOption("showoutfit") or true
695 local optionMount = modules.client_options.getOption("showmount") or true
696 local optionWings = modules.client_options.getOption("showwings") or true
697 local optionAura = modules.client_options.getOption("showaura") or true
698 local optionShader = modules.client_options.getOption("showshader") or true
699 local optionRuneEffect = modules.client_options.getOption("showruneeffect") or true
700 local optionAnimated = modules.client_options.getOption("animated") or true
701
702 previewPanel.showoutfit:setChecked(optionOutfit)
703 previewPanel.showmount:setChecked(optionMount)
704 previewPanel.showwings:setChecked(optionWings)
705 previewPanel.showaura:setChecked(optionAura)
706 previewPanel.showshader:setChecked(optionShader)
707 if previewPanel.showruneeffect then
708 previewPanel.showruneeffect:setChecked(optionRuneEffect)
709 end
710 previewPanel.animated:setChecked(optionAnimated)
711
712 previewPanel.showoutfit.onCheckChange = onOutfitCheckChange
713 previewPanel.showmount.onCheckChange = onOutfitCheckChange
714 previewPanel.showwings.onCheckChange = onOutfitCheckChange
715 previewPanel.showaura.onCheckChange = onOutfitCheckChange
716 previewPanel.showshader.onCheckChange = onOutfitCheckChange
717 if previewPanel.showruneeffect then
718 previewPanel.showruneeffect.onCheckChange = onOutfitCheckChange
719 end
720 previewPanel.animated.onCheckChange = onOutfitCheckChange
721
722 onTypeChange("type")
723 updateOutfit()
724end
725
726function onColorCheckChange(colorBox)
727 local outfit = outfitWindow.extensions.type.creature:getOutfit()
728
729 if colorBox == currentColorBox then
730 colorBox.onCheckChange = nil
731 colorBox:setChecked(true)
732 colorBox.onCheckChange = onColorCheckChange
733 else
734 if currentColorBox then
735 currentColorBox.onCheckChange = nil
736 currentColorBox:setChecked(false)
737 currentColorBox.onCheckChange = onColorCheckChange
738 end
739
740 currentColorBox = colorBox
741
742 if currentClotheButtonBox:getId() == "head" then
743 outfit.head = currentColorBox.colorId
744 elseif currentClotheButtonBox:getId() == "primary" then
745 outfit.body = currentColorBox.colorId
746 elseif currentClotheButtonBox:getId() == "secondary" then
747 outfit.legs = currentColorBox.colorId
748 elseif currentClotheButtonBox:getId() == "detail" then
749 outfit.feet = currentColorBox.colorId
750 end
751
752 previewBox:setOutfit(outfit)
753 typeBox:setOutfit(outfit)
754 end
755end
756
757function onClotheCheckChange(clotheButtonBox)
758 local outfit = typeBox:getOutfit()
759
760 if clotheButtonBox == currentClotheButtonBox then
761 clotheButtonBox.onCheckChange = nil
762 clotheButtonBox:setChecked(true)
763 clotheButtonBox.onCheckChange = onClotheCheckChange
764 else
765 currentClotheButtonBox.onCheckChange = nil
766 currentClotheButtonBox:setChecked(false)
767 currentClotheButtonBox.onCheckChange = onClotheCheckChange
768 currentClotheButtonBox = clotheButtonBox
769
770 local colorId = 0
771 if currentClotheButtonBox:getId() == "head" then
772 colorId = outfit.head
773 elseif currentClotheButtonBox:getId() == "primary" then
774 colorId = outfit.body
775 elseif currentClotheButtonBox:getId() == "secondary" then
776 colorId = outfit.legs
777 elseif currentClotheButtonBox:getId() == "detail" then
778 colorId = outfit.feet
779 end
780
781 outfitWindow:recursiveGetChildById("colorBox" .. colorId):setChecked(true)
782 end
783end
784
785function onAddonCheckChange(addon, value)
786 local outfit = typeBox:getOutfit()
787
788 if addon:isChecked() then
789 outfit.addons = outfit.addons + value
790 else
791 outfit.addons = outfit.addons - value
792 end
793
794 typeBox:setOutfit(outfit)
795 previewBox:setOutfit(outfit)
796end
797
798function onOutfitCheckChange(addon, value)
799 modules.client_options.setOption(addon:getId(), value)
800 updateOutfit()
801end
802
803function updateOutfit()
804 if not outfitWindow then return end
805
806 local currentSelection = outfitWindow.extensions.type.outfit
807 if not currentSelection then return end
808
809 local outfit = outfitWindow.extensions.type.creature:getOutfit()
810 local availableAddons = currentSelection[3]
811
812 for _, addon in pairs(addons) do
813 addon.widget:setChecked(false)
814 addon.widget:setEnabled(false)
815 end
816
817 outfit.addons = 0
818
819 if selectorMount and previewPanel.showmount:isChecked() and mountBox then
820 outfit.mount = mountBox:getOutfit().type
821 else
822 outfit.mount = 0
823 end
824
825 if selectorWings and previewPanel.showwings:isChecked() and wingsBox then
826 outfit.wings = wingsBox:getOutfit().type
827 else
828 outfit.wings = 0
829 end
830
831 if selectorAuras and previewPanel.showaura:isChecked() and auraBox then
832 outfit.aura = auraBox:getOutfit().type
833 else
834 outfit.aura = 0
835 end
836
837 if selectorShaders and previewPanel.showshader:isChecked() and shaderBox then
838 outfit.shader = shaderBox:getOutfit().shader
839 else
840 outfit.shader = ""
841 end
842
843 if selectorRuneEffect and runeEffectBox then
844 outfit.runeeffect = runeEffectBox:getOutfit().runeeffect or 0
845 else
846 outfit.runeeffect = 0
847 end
848
849 previewBox:setOutfit(outfit)
850
851 if not previewPanel.showoutfit:isChecked() then
852 outfit.type = 800
853 outfit.shader = ""
854 end
855
856 if availableAddons and availableAddons > 0 then
857 for _, i in pairs(ADDON_SETS[availableAddons]) do
858 addons[i].widget:setEnabled(true)
859 addons[i].widget:setChecked(true)
860 end
861 end
862
863 outfit.addons = availableAddons or 0
864 previewBox:setOutfit(outfit)
865
866 if previewPanel.animated:isChecked() then
867 previewBox:setAnimate(true)
868 else
869 previewBox:setAnimate(false)
870 end
871
872 g_game.changeOutfit(outfit)
873end
874
875function randomizeAll()
876 local outfitTemplate = {
877 outfitWindow.head,
878 outfitWindow.primary,
879 outfitWindow.secondary,
880 outfitWindow.detail
881 }
882
883 for i = 1, #outfitTemplate do
884 outfitTemplate[i]:setChecked(true)
885 colorBoxes[math.random(1, #colorBoxes)]:setChecked(true)
886 outfitTemplate[i]:setChecked(false)
887 end
888
889 outfitTemplate[1]:setChecked(true)
890
891 local out = typeBox:getOutfit()
892 out.type = outfits_list[math.random(#outfits_list)][1]
893 local rndMount = mounts_list[math.random(1, #mounts_list)][1]
894 local rndWings = wings_list[math.random(1, #wings_list)][1]
895 local rndAura = auras_list[math.random(1, #auras_list)][1]
896 local rndShader = shaders_list[math.random(1, #shaders_list)][2]
897
898 if rndShader == "-" then
899 rndShader = ""
900 end
901
902 typeBox:setOutfit(out)
903 if mountBox then mountBox:setOutfit({type = rndMount}) end
904 if wingsBox then wingsBox:setOutfit({type = rndWings}) end
905 if auraBox then auraBox:setOutfit({type = rndAura}) end
906
907 out.shader = rndShader
908 if shaderBox then shaderBox:setOutfit(out) end
909
910 updateOutfit()
911 refreshSelector("type")
912 refreshSelector("mount")
913 refreshSelector("wings")
914 refreshSelector("aura")
915 refreshSelector("shader")
916 refreshSelector("runeeffect")
917end
918
919function randomizeOutfit()
920 local out = typeBox:getOutfit()
921 out.type = outfits_list[math.random(#outfits_list)][1]
922 typeBox:setOutfit(out)
923 updateOutfit()
924 refreshSelector("type")
925end
926
927function randomizeColor()
928 local outfitTemplate = {
929 outfitWindow.head,
930 outfitWindow.primary,
931 outfitWindow.secondary,
932 outfitWindow.detail
933 }
934
935 for i = 1, #outfitTemplate do
936 outfitTemplate[i]:setChecked(true)
937 colorBoxes[math.random(1, #colorBoxes)]:setChecked(true)
938 outfitTemplate[i]:setChecked(false)
939 end
940
941 outfitTemplate[1]:setChecked(true)
942 updateOutfit()
943end
944
945function accept()
946 local outfit = typeBox:getOutfit()
947
948 for _, child in pairs(outfitWindow.extensions:getChildren()) do
949 local childId = child:getId()
950 if childId == "healthBar" or childId == "manaBar" then
951 outfit[childId] = child.bar.selected
952 elseif child.creature and child.creature:getCreature() then
953 if childId == "shader" then
954 outfit[childId] = child.creature:getOutfit().shader
955 elseif childId == "runeeffect" then
956 outfit[childId] = child.creature:getOutfit().runeeffect or 0
957 else
958 outfit[childId] = child.creature:getOutfit().type
959 end
960 end
961 end
962
963 g_game.changeOutfit(outfit)
964 destroy()
965end
966
Top