Client Upload Part 2

RD Core / Commit #5

Commit Client Upload Part 2

Alex Alex committed 19/10/2026 00:06 main Patch
1,244 files +271,215 -0
A RD_Client/modules/game_playerdeath/deathwindow.otui +30-0 View file
@@ -0,0 +1,30 @@
1+DeathWindow < MainWindow
2+ id: deathWindow
3+ !text: tr('You are dead')
4+ &baseWidth: 350
5+ &baseHeight: 15
6+
7+ Label
8+ id: labelText
9+ width: 550
10+ height: 140
11+ anchors.left: parent.left
12+ anchors.top: parent.top
13+ margin-left: 10
14+ margin-top: 2
15+
16+ Button
17+ id: buttonOk
18+ !text: tr('Ok')
19+ width: 64
20+ anchors.left: parent.left
21+ anchors.bottom: parent.bottom
22+ margin-left: 160
23+
24+ Button
25+ id: buttonCancel
26+ !text: tr('Cancel')
27+ width: 64
28+ anchors.left: prev.right
29+ anchors.bottom: parent.bottom
30+ margin-left: 5
A RD_Client/modules/game_playerdeath/playerdeath.lua +86-0 View file
@@ -0,0 +1,86 @@
1+deathWindow = nil
2+
3+local deathTexts = {
4+ regular = {text = 'Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!', height = 140, width = 0},
5+ unfair = {text = 'Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nThis death penalty has been reduced by %i%%\nbecause it was an unfair fight.\n\nSimply click on Ok to resume your journeys!', height = 185, width = 0},
6+ blessed = {text = 'Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back into this world\n\nThis death penalty has been reduced by 100%\nbecause you are blessed with the Adventurer\'s Blessing\n\nSimply click on Ok to resume your journeys!', height = 170, width = 90}
7+}
8+
9+function init()
10+ g_ui.importStyle('deathwindow')
11+
12+ connect(g_game, { onDeath = display,
13+ onGameEnd = reset })
14+end
15+
16+function terminate()
17+ disconnect(g_game, { onDeath = display,
18+ onGameEnd = reset })
19+
20+ reset()
21+end
22+
23+function reset()
24+ if deathWindow then
25+ deathWindow:destroy()
26+ deathWindow = nil
27+ end
28+end
29+
30+function display(deathType, penalty)
31+ displayDeadMessage()
32+ openWindow(deathType, penalty)
33+end
34+
35+function displayDeadMessage()
36+ local advanceLabel = modules.game_interface.getRootPanel():recursiveGetChildById('middleCenterLabel')
37+ if advanceLabel:isVisible() then return end
38+
39+ modules.game_textmessage.displayGameMessage(tr('You are dead.'))
40+end
41+
42+function openWindow(deathType, penalty)
43+ if deathWindow then
44+ deathWindow:destroy()
45+ return
46+ end
47+
48+ deathWindow = g_ui.createWidget('DeathWindow', rootWidget)
49+
50+ local textLabel = deathWindow:getChildById('labelText')
51+ if deathType == DeathType.Regular then
52+ if penalty == 100 then
53+ textLabel:setText(deathTexts.regular.text)
54+ deathWindow:setHeight(deathWindow.baseHeight + deathTexts.regular.height)
55+ deathWindow:setWidth(deathWindow.baseWidth + deathTexts.regular.width)
56+ else
57+ textLabel:setText(string.format(deathTexts.unfair.text, 100 - penalty))
58+ deathWindow:setHeight(deathWindow.baseHeight + deathTexts.unfair.height)
59+ deathWindow:setWidth(deathWindow.baseWidth + deathTexts.unfair.width)
60+ end
61+ elseif deathType == DeathType.Blessed then
62+ textLabel:setText(deathTexts.blessed.text)
63+ deathWindow:setHeight(deathWindow.baseHeight + deathTexts.blessed.height)
64+ deathWindow:setWidth(deathWindow.baseWidth + deathTexts.blessed.width)
65+ end
66+
67+ local okButton = deathWindow:getChildById('buttonOk')
68+ local cancelButton = deathWindow:getChildById('buttonCancel')
69+
70+ local okFunc = function()
71+ CharacterList.doLogin()
72+ okButton:getParent():destroy()
73+ deathWindow = nil
74+ end
75+ local cancelFunc = function()
76+ g_game.safeLogout()
77+ cancelButton:getParent():destroy()
78+ deathWindow = nil
79+ end
80+
81+ deathWindow.onEnter = okFunc
82+ deathWindow.onEscape = cancelFunc
83+
84+ okButton.onClick = okFunc
85+ cancelButton.onClick = cancelFunc
86+end
A RD_Client/modules/game_playerdeath/playerdeath.otmod +9-0 View file
@@ -0,0 +1,9 @@
1+Module
2+ name: game_playerdeath
3+ description: Manage player deaths
4+ author: BeniS, edubart
5+ website: https://github.com/edubart/otclient
6+ sandboxed: true
7+ scripts: [ playerdeath ]
8+ @onLoad: init()
9+ @onUnload: terminate()
A RD_Client/modules/game_playermount/playermount.lua +48-0 View file
@@ -0,0 +1,48 @@
1+function init()
2+ connect(g_game, {
3+ onGameStart = online,
4+ onGameEnd = offline
5+ })
6+ if g_game.isOnline() then online() end
7+end
8+
9+function terminate()
10+ disconnect(g_game, {
11+ onGameStart = online,
12+ onGameEnd = offline
13+ })
14+ offline()
15+end
16+
17+function online()
18+ if g_game.getFeature(GamePlayerMounts) then
19+ g_keyboard.bindKeyDown('Ctrl+R', toggleMount)
20+ end
21+end
22+
23+function offline()
24+ if g_game.getFeature(GamePlayerMounts) then
25+ g_keyboard.unbindKeyDown('Ctrl+R')
26+ end
27+end
28+
29+function toggleMount()
30+ local player = g_game.getLocalPlayer()
31+ if player then
32+ player:toggleMount()
33+ end
34+end
35+
36+function mount()
37+ local player = g_game.getLocalPlayer()
38+ if player then
39+ player:mount()
40+ end
41+end
42+
43+function dismount()
44+ local player = g_game.getLocalPlayer()
45+ if player then
46+ player:dismount()
47+ end
48+end
A RD_Client/modules/game_playermount/playermount.otmod +9-0 View file
@@ -0,0 +1,9 @@
1+Module
2+ name: game_playermount
3+ description: Manage player mounts
4+ author: BeniS
5+ website: https://github.com/edubart/otclient
6+ sandboxed: true
7+ scripts: [ playermount ]
8+ @onLoad: init()
9+ @onUnload: terminate()
A RD_Client/modules/game_playertrade/playertrade.lua +81-0 View file
@@ -0,0 +1,81 @@
1+tradeWindow = nil
2+
3+function init()
4+ g_ui.importStyle('tradewindow')
5+
6+ connect(g_game, { onOwnTrade = onGameOwnTrade,
7+ onCounterTrade = onGameCounterTrade,
8+ onCloseTrade = onGameCloseTrade,
9+ onGameEnd = onGameCloseTrade })
10+end
11+
12+function terminate()
13+ disconnect(g_game, { onOwnTrade = onGameOwnTrade,
14+ onCounterTrade = onGameCounterTrade,
15+ onCloseTrade = onGameCloseTrade,
16+ onGameEnd = onGameCloseTrade })
17+
18+ if tradeWindow then
19+ tradeWindow:destroy()
20+ end
21+end
22+
23+function createTrade()
24+ tradeWindow = g_ui.createWidget('TradeWindow', modules.game_interface.getRightPanel())
25+ tradeWindow.onClose = function()
26+ g_game.rejectTrade()
27+ tradeWindow:hide()
28+ end
29+ tradeWindow:setup()
30+end
31+
32+function fillTrade(name, items, counter)
33+ if not tradeWindow then
34+ createTrade()
35+ end
36+
37+ local tradeItemWidget = tradeWindow:getChildById('tradeItem')
38+ tradeItemWidget:setItemId(items[1]:getId())
39+
40+ local tradeContainer
41+ local label
42+ local countLabel
43+ if counter then
44+ tradeContainer = tradeWindow:recursiveGetChildById('counterTradeContainer')
45+ label = tradeWindow:recursiveGetChildById('counterTradeLabel')
46+ countLabel = tradeWindow:recursiveGetChildById('counterTradeCountLabel')
47+ tradeWindow:recursiveGetChildById('acceptButton'):enable()
48+ else
49+ tradeContainer = tradeWindow:recursiveGetChildById('ownTradeContainer')
50+ label = tradeWindow:recursiveGetChildById('ownTradeLabel')
51+ countLabel = tradeWindow:recursiveGetChildById('ownTradeCountLabel')
52+ end
53+ label:setText(name)
54+ countLabel:setText(tr("Items") .. ": " .. #items)
55+
56+
57+ for index,item in ipairs(items) do
58+ local itemWidget = g_ui.createWidget('Item', tradeContainer)
59+ itemWidget:setItem(item)
60+ itemWidget:setVirtual(true)
61+ itemWidget:setMargin(0)
62+ itemWidget.onClick = function()
63+ g_game.inspectTrade(counter, index-1)
64+ end
65+ end
66+end
67+
68+function onGameOwnTrade(name, items)
69+ fillTrade(name, items, false)
70+end
71+
72+function onGameCounterTrade(name, items)
73+ fillTrade(name, items, true)
74+end
75+
76+function onGameCloseTrade()
77+ if tradeWindow then
78+ tradeWindow:destroy()
79+ tradeWindow = nil
80+ end
81+end
A RD_Client/modules/game_playertrade/playertrade.otmod +9-0 View file
@@ -0,0 +1,9 @@
1+Module
2+ name: game_playertrade
3+ description: Allow to trade items with players
4+ author: edubart
5+ website: https://github.com/edubart/otclient
6+ sandboxed: true
7+ scripts: [ playertrade ]
8+ @onLoad: init()
9+ @onUnload: terminate()
A RD_Client/modules/game_playertrade/tradewindow.otui +112-0 View file
@@ -0,0 +1,112 @@
1+TradeWindow < MiniWindow
2+ !text: tr('Trade')
3+ height: 150
4+
5+ UIItem
6+ id: tradeItem
7+ virtual: true
8+ size: 16 16
9+ anchors.top: parent.top
10+ anchors.left: parent.left
11+ margin-top: 4
12+ margin-left: 4
13+
14+ MiniWindowContents
15+ padding: 2
16+
17+ Label
18+ id: ownTradeLabel
19+ anchors.top: parent.top
20+ anchors.left: parent.left
21+ anchors.right: parent.horizontalCenter
22+
23+ Label
24+ id: counterTradeLabel
25+ anchors.top: parent.top
26+ anchors.left: parent.horizontalCenter
27+ anchors.right: parent.right
28+
29+ Label
30+ id: ownTradeCountLabel
31+ anchors.top: ownTradeLabel.bottom
32+ anchors.left: ownTradeLabel.left
33+ anchors.right: ownTradeLabel.right
34+ font: verdana-9px-bold
35+ text-align: center
36+
37+ Label
38+ id: counterTradeCountLabel
39+ anchors.top: counterTradeLabel.bottom
40+ anchors.left: counterTradeLabel.left
41+ anchors.right: counterTradeLabel.right
42+ font: verdana-9px-bold
43+ text-align: center
44+
45+ ScrollableFlatPanel
46+ id: ownTradeContainer
47+ anchors.top: ownTradeCountLabel.bottom
48+ anchors.bottom: acceptButton.top
49+ anchors.left: ownTradeCountLabel.left
50+ anchors.right: ownTradeCountLabel.right
51+ margin-bottom: 3
52+ padding: 2
53+ layout:
54+ type: grid
55+ cell-size: 34 34
56+ flow: true
57+ cell-spacing: 1
58+ vertical-scrollbar: ownTradeScrollBar
59+
60+ VerticalScrollBar
61+ id: ownTradeScrollBar
62+ anchors.top: ownTradeContainer.top
63+ anchors.bottom: ownTradeContainer.bottom
64+ anchors.right: parent.horizontalCenter
65+ step: 14
66+ pixels-scroll: true
67+ $!on:
68+ width: 0
69+
70+ ScrollableFlatPanel
71+ id: counterTradeContainer
72+ anchors.top: counterTradeCountLabel.bottom
73+ anchors.bottom: acceptButton.top
74+ anchors.left: counterTradeCountLabel.left
75+ anchors.right: counterTradeCountLabel.right
76+ margin-bottom: 3
77+ padding: 2
78+ layout:
79+ type: grid
80+ cell-size: 34 34
81+ flow: true
82+ cell-spacing: 1
83+ vertical-scrollbar: counterTradeScrollBar
84+
85+ VerticalScrollBar
86+ id: counterTradeScrollBar
87+ anchors.top: counterTradeContainer.top
88+ anchors.bottom: counterTradeContainer.bottom
89+ anchors.right: parent.right
90+ step: 14
91+ pixels-scroll: true
92+ $!on:
93+ width: 0
94+
95+ Button
96+ !text: tr('Accept')
97+ id: acceptButton
98+ anchors.bottom: parent.bottom
99+ anchors.left: parent.left
100+ anchors.right: parent.horizontalCenter
101+ margin-right: 2
102+ enabled: false
103+ @onClick: g_game.acceptTrade(); self:disable()
104+
105+ Button
106+ !text: tr('Reject')
107+ id: rejectButton
108+ anchors.bottom: parent.bottom
109+ anchors.right: parent.right
110+ anchors.left: parent.horizontalCenter
111+ margin-left: 2
112+ @onClick: g_game.rejectTrade()
A RD_Client/modules/game_prey/prey.lua +310-0 View file
@@ -0,0 +1,310 @@
1+-- sponsored by kivera-global.com
2+
3+local preyWindow
4+local preyButton
5+local msgWindow
6+local bankGold = 0
7+local inventoryGold = 0
8+local rerollPrice = 0
9+local bonusRerolls = 0
10+
11+local PREY_BONUS_DAMAGE_BOOST = 0
12+local PREY_BONUS_DAMAGE_REDUCTION = 1
13+local PREY_BONUS_XP_BONUS = 2
14+local PREY_BONUS_IMPROVED_LOOT = 3
15+local PREY_BONUS_NONE = 4
16+
17+local PREY_ACTION_LISTREROLL = 0
18+local PREY_ACTION_BONUSREROLL = 1
19+local PREY_ACTION_MONSTERSELECTION = 2
20+local PREY_ACTION_REQUEST_ALL_MONSTERS = 3
21+local PREY_ACTION_CHANGE_FROM_ALL = 4
22+local PREY_ACTION_LOCK_PREY = 5
23+
24+
25+function bonusDescription(bonusType, bonusValue, bonusGrade)
26+ if bonusType == PREY_BONUS_DAMAGE_BOOST then
27+ return "Damage bonus (" .. bonusGrade .. "/10)"
28+ elseif bonusType == PREY_BONUS_DAMAGE_REDUCTION then
29+ return "Damage reduction bonus (" .. bonusGrade .. "/10)"
30+ elseif bonusType == PREY_BONUS_XP_BONUS then
31+ return "XP bonus (" .. bonusGrade .. "/10)"
32+ elseif bonusType == PREY_BONUS_IMPROVED_LOOT then
33+ return "Loot bonus (" .. bonusGrade .. "/10)"
34+ elseif bonusType == PREY_BONUS_DAMAGE_BOOST then
35+ return "-"
36+ end
37+ return "Uknown bonus"
38+end
39+
40+function timeleftTranslation(timeleft, forPreyTimeleft) -- in seconds
41+ if timeleft == 0 then
42+ if forPreyTimeleft then
43+ return tr("infinite bonus")
44+ end
45+ return tr("Available now")
46+ end
47+ local minutes = math.ceil(timeleft / 60)
48+ local hours = math.floor(minutes / 60)
49+ minutes = minutes - hours * 60
50+ if hours > 0 then
51+ if forPreyTimeleft then
52+ return "" .. hours .. "h " .. minutes .. "m"
53+ end
54+ return tr("Available in") .. " " .. hours .. "h " .. minutes .. "m"
55+ end
56+ if forPreyTimeleft then
57+ return "" .. minutes .. "m"
58+ end
59+ return tr("Available in") .. " " .. minutes .. "m"
60+end
61+
62+function init()
63+ connect(g_game, {
64+ onGameStart = check,
65+ onGameEnd = hide,
66+ onResourceBalance = onResourceBalance,
67+ onPreyFreeRolls = onPreyFreeRolls,
68+ onPreyTimeLeft = onPreyTimeLeft,
69+ onPreyPrice = onPreyPrice,
70+ onPreyLocked = onPreyLocked,
71+ onPreyInactive = onPreyInactive,
72+ onPreyActive = onPreyActive,
73+ onPreySelection = onPreySelection
74+ })
75+
76+ preyWindow = g_ui.displayUI('prey')
77+ preyWindow:hide()
78+ if g_game.isOnline() then
79+ check()
80+ end
81+end
82+
83+function terminate()
84+ disconnect(g_game, {
85+ onGameStart = check,
86+ onGameEnd = hide,
87+ onResourceBalance = onResourceBalance,
88+ onPreyFreeRolls = onPreyFreeRolls,
89+ onPreyTimeLeft = onPreyTimeLeft,
90+ onPreyPrice = onPreyPrice,
91+ onPreyLocked = onPreyLocked,
92+ onPreyInactive = onPreyInactive,
93+ onPreyActive = onPreyActive,
94+ onPreySelection = onPreySelection
95+ })
96+
97+ if preyButton then
98+ preyButton:destroy()
99+ end
100+ preyWindow:destroy()
101+ if msgWindow then
102+ msgWindow:destroy()
103+ msgWindow = nil
104+ end
105+end
106+
107+function check()
108+ if g_game.getFeature(GamePrey) then
109+ if not preyButton then
110+ preyButton = modules.client_topmenu.addRightGameToggleButton('preyButton', tr('Preys'), '/images/topbuttons/prey', toggle)
111+ end
112+ elseif preyButton then
113+ preyButton:destroy()
114+ preyButton = nil
115+ end
116+end
117+
118+function hide()
119+ preyWindow:hide()
120+ if msgWindow then
121+ msgWindow:destroy()
122+ msgWindow = nil
123+ end
124+end
125+
126+function show()
127+ if not g_game.getFeature(GamePrey) then
128+ return hide()
129+ end
130+ preyWindow:show()
131+ preyWindow:raise()
132+ preyWindow:focus()
133+ --g_game.preyRequest() -- update preys, it's for tibia 12
134+end
135+
136+function toggle()
137+ if preyWindow:isVisible() then
138+ return hide()
139+ end
140+ show()
141+end
142+
143+function onPreyFreeRolls(slot, timeleft)
144+ local prey = preyWindow["slot" .. (slot + 1)]
145+ if not prey then return end
146+ if prey.state ~= "active" and prey.state ~= "selection" then
147+ return
148+ end
149+ prey.bottomLabel:setText(tr("Free list reroll") .. ": \n" .. timeleftTranslation(timeleft * 60))
150+end
151+
152+function onPreyTimeLeft(slot, timeleft)
153+ local prey = preyWindow["slot" .. (slot + 1)]
154+ if not prey then return end
155+ if prey.state ~= "active" then
156+ return
157+ end
158+ prey.description:setText(tr("Time left") .. ": " .. timeleftTranslation(timeleft, true))
159+end
160+
161+function onPreyPrice(price)
162+ rerollPrice = price
163+ preyWindow.rerollPrice:setText(tr("Reroll price") .. ":\n" .. price)
164+end
165+
166+function onPreyLocked(slot, unlockState, timeUntilFreeReroll)
167+ local prey = preyWindow["slot" .. (slot + 1)]
168+ if not prey then return end
169+ prey.state = "locked"
170+ prey.title:setText(tr("Prey Locked"))
171+ prey.list:hide()
172+ prey.listScrollbar:hide()
173+ prey.creature:hide()
174+ prey.description:hide()
175+ prey.bonuses:hide()
176+ prey.button:hide()
177+ prey.bottomLabel:show()
178+ if unlockState == 0 then
179+ prey.bottomLabel:setText(tr("You need to have premium account and buy this prey slot in the game store."))
180+ elseif unlockState == 1 then
181+ prey.bottomLabel:setText(tr("You need to buy this prey slot in the game store."))
182+ else
183+ prey.bottomLabel:setText(tr("You can't unlock it."))
184+ prey.bottomButton:hide()
185+ end
186+ if (unlockState == 0 or unlockState == 1) and modules.game_shop then
187+ prey.bottomButton:setText("Open game store")
188+ prey.bottomButton.onClick = function() hide() modules.game_shop.show() end
189+ prey.bottomButton:show()
190+ end
191+end
192+
193+function onPreyInactive(slot, timeUntilFreeReroll)
194+ local prey = preyWindow["slot" .. (slot + 1)]
195+ if not prey then return end
196+ prey.state = "inactive"
197+ prey.title:setText(tr("Prey Inactive"))
198+ prey.list:hide()
199+ prey.listScrollbar:hide()
200+ prey.creature:hide()
201+ prey.description:hide()
202+ prey.bonuses:hide()
203+ prey.button:hide()
204+ prey.bottomLabel:hide()
205+
206+ prey.bottomLabel:setText(tr("Free list reroll")..": \n" .. timeleftTranslation(timeUntilFreeReroll * 60))
207+ prey.bottomLabel:show()
208+ if timeUntilFreeReroll > 0 then
209+ prey.bottomButton:setText(tr("Buy list reroll"))
210+ else
211+ prey.bottomButton:setText(tr("Free list reroll"))
212+ end
213+ prey.bottomButton:show()
214+ prey.bottomButton.onClick = function()
215+ g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0)
216+ end
217+end
218+
219+function onPreyActive(slot, currentHolderName, currentHolderOutfit, bonusType, bonusValue, bonusGrade, timeLeft, timeUntilFreeReroll)
220+ local prey = preyWindow["slot" .. (slot + 1)]
221+ if not prey then return end
222+ prey.state = "active"
223+ prey.title:setText(currentHolderName)
224+ prey.list:hide()
225+ prey.listScrollbar:hide()
226+ prey.creature:show()
227+ prey.creature:setOutfit(currentHolderOutfit)
228+ prey.description:setText(tr("Time left") .. ": " .. timeleftTranslation(timeLeft, true))
229+ prey.description:show()
230+ prey.bonuses:setText(bonusDescription(bonusType, bonusValue, bonusGrade))
231+ prey.bonuses:show()
232+ prey.button:setText(tr("Bonus reroll"))
233+ prey.button:show()
234+ prey.bottomLabel:setText(tr("Free list reroll")..": \n" .. timeleftTranslation(timeUntilFreeReroll * 60))
235+ prey.bottomLabel:show()
236+ if timeUntilFreeReroll > 0 then
237+ prey.bottomButton:setText(tr("Buy list reroll"))
238+ else
239+ prey.bottomButton:setText(tr("Free list reroll"))
240+ end
241+ prey.bottomButton:show()
242+
243+ prey.button.onClick = function()
244+ if bonusRerolls == 0 then
245+ return showMessage(tr("Error"), tr("You don't have any bonus rerolls.\nYou can buy them in ingame store."))
246+ end
247+ g_game.preyAction(slot, PREY_ACTION_BONUSREROLL, 0)
248+ end
249+
250+ prey.bottomButton.onClick = function()
251+ g_game.preyAction(slot, PREY_ACTION_LISTREROLL, 0)
252+ end
253+end
254+
255+function onPreySelection(slot, bonusType, bonusValue, bonusGrade, names, outfits, timeUntilFreeReroll)
256+ local prey = preyWindow["slot" .. (slot + 1)]
257+ if not prey then return end
258+ prey.state = "selection"
259+ prey.title:setText(tr("Select monster"))
260+ prey.list:show()
261+ prey.listScrollbar:show()
262+ prey.creature:hide()
263+ prey.description:hide()
264+ prey.bonuses:hide()
265+ prey.button:setText(tr("Select"))
266+ prey.button:show()
267+ prey.bottomLabel:setText("Free list reroll: \n" .. timeleftTranslation(timeUntilFreeReroll * 60))
268+ prey.bottomLabel:show()
269+ prey.bottomButton:hide()
270+ prey.list:destroyChildren()
271+ for i, name in ipairs(names) do
272+ local label = g_ui.createWidget("PreySelectionLabel", prey.list)
273+ label:setText(name)
274+ label.creature:setOutfit(outfits[i])
275+ end
276+ prey.button.onClick = function()
277+ local child = prey.list:getFocusedChild()
278+ if not child then
279+ return showMessage(tr("Error"), tr("Select monster to proceed."))
280+ end
281+ local index = prey.list:getChildIndex(child)
282+ g_game.preyAction(slot, PREY_ACTION_MONSTERSELECTION, index - 1)
283+ end
284+end
285+
286+function onResourceBalance(type, balance)
287+ if type == 0 then -- bank gold
288+ bankGold = balance
289+ elseif type == 1 then -- inventory gold
290+ inventoryGold = balance
291+ elseif type == 10 then -- bonus rerolls
292+ bonusRerolls = balance
293+ preyWindow.bonusRerolls:setText(tr("Available bonus rerolls") .. ":\n" .. balance)
294+ end
295+
296+ if type == 0 or type == 1 then
297+ preyWindow.balance:setText(tr("Balance") .. ":\n" .. (bankGold + inventoryGold))
298+ end
299+end
300+
301+function showMessage(title, message)
302+ if msgWindow then
303+ msgWindow:destroy()
304+ end
305+
306+ msgWindow = displayInfoBox(title, message)
307+ msgWindow:show()
308+ msgWindow:raise()
309+ msgWindow:focus()
310+end
A RD_Client/modules/game_prey/prey.otmod +10-0 View file
@@ -0,0 +1,10 @@
1+Module
2+ name: game_prey
3+ description: Preys, sponsored by kivera-global.com
4+ author: otclient.ovh & kivera-global.com
5+ website: http://otclient.ovh
6+ sandboxed: true
7+ scripts: [ prey ]
8+ dependencies: [ client_topmenu ]
9+ @onLoad: init()
10+ @onUnload: terminate()
A RD_Client/modules/game_prey/prey.otui +199-0 View file
@@ -0,0 +1,199 @@
1+PreySelectionLabel < Label
2+ font: verdana-11px-monochrome
3+ background-color: alpha
4+ text-offset: 34 0
5+ margin-right: 5
6+ text-align: center
7+ text-wrap: true
8+ focusable: true
9+ height: 34
10+
11+ $focus:
12+ background-color: #00000055
13+ color: #ffffff
14+
15+ UICreature
16+ id: creature
17+ size: 32 32
18+ anchors.top: parent.top
19+ anchors.left: parent.left
20+ margin-top: 1
21+
22+PreySlot < Panel
23+ width: 190
24+ height: 280
25+ border: 1 black
26+ padding: 5
27+
28+ Label
29+ id: title
30+ anchors.top: parent.top
31+ anchors.left: parent.left
32+ anchors.right: parent.right
33+ text-align: center
34+ !text: tr("Prey Inactive")
35+
36+ TextList
37+ id: list
38+ anchors.top: parent.top
39+ anchors.left: parent.left
40+ anchors.right: parent.right
41+ margin-top: 15
42+ margin-right: 10
43+ vertical-scrollbar: listScrollbar
44+ height: 150
45+ visible: false
46+ focusable: false
47+
48+ VerticalScrollBar
49+ id: listScrollbar
50+ anchors.top: prev.top
51+ anchors.bottom: prev.bottom
52+ anchors.right: parent.right
53+ pixels-scroll: true
54+ visible: false
55+ step: 10
56+
57+ UICreature
58+ id: creature
59+ anchors.top: parent.top
60+ anchors.horizontalCenter: parent.horizontalCenter
61+ margin-top: 40
62+ height: 64
63+ width: 64
64+ visible: false
65+
66+ Label
67+ id: description
68+ margin-top: 30
69+ margin-left: 5
70+ margin-right: 5
71+ anchors.top: prev.bottom
72+ anchors.left: parent.left
73+ anchors.right: parent.right
74+ text-auto-resize: true
75+ text-align: center
76+ text-wrap: true
77+ visible: false
78+
79+ Label
80+ id: bonuses
81+ margin-top: 5
82+ margin-left: 5
83+ margin-right: 5
84+ anchors.top: prev.bottom
85+ anchors.left: parent.left
86+ anchors.right: parent.right
87+ text-auto-resize: true
88+ text-align: center
89+ text-wrap: true
90+ visible: false
91+
92+ Button
93+ id: button
94+ margin-top: 5
95+ anchors.top: prev.bottom
96+ anchors.left: parent.left
97+ anchors.right: parent.right
98+ margin-left: 10
99+ margin-right: 10
100+ visible: false
101+
102+ Label
103+ id: bottomLabel
104+ margin-left: 5
105+ margin-right: 5
106+ margin-bottom: 5
107+ anchors.bottom: next.top
108+ anchors.left: parent.left
109+ anchors.right: parent.right
110+ text-auto-resize: true
111+ text-align: center
112+ text-wrap: true
113+ visible: false
114+
115+ Button
116+ id: bottomButton
117+ anchors.bottom: parent.bottom
118+ anchors.left: parent.left
119+ anchors.right: parent.right
120+ margin-left: 10
121+ margin-right: 10
122+ text: 11
123+ visible: false
124+
125+ $hidden:
126+ height: 0
127+
128+ $!hidden:
129+ height: 22
130+
131+MainWindow
132+ id: preyWindow
133+ !text: tr('Preys')
134+ size: 600 405
135+ background-color: #AAAAAA
136+ @onEscape: modules.game_prey.hide()
137+
138+ PreySlot
139+ id: slot1
140+ anchors.left: parent.left
141+ anchors.top: parent.top
142+
143+ PreySlot
144+ id: slot2
145+ anchors.left: prev.right
146+ anchors.top: prev.top
147+
148+ PreySlot
149+ id: slot3
150+ anchors.left: prev.right
151+ anchors.top: prev.top
152+
153+ HorizontalSeparator
154+ id: mainSeparator
155+ anchors.top: slot3.bottom
156+ anchors.left: parent.left
157+ anchors.right: parent.right
158+ margin-top: 5
159+
160+ Label
161+ id: rerollPrice
162+ anchors.top: mainSeparator.bottom
163+ anchors.left: parent.left
164+ margin-top: 5
165+ width: 190
166+ height: 30
167+ text-align: center
168+
169+ Label
170+ id: balance
171+ anchors.top: mainSeparator.bottom
172+ anchors.left: prev.right
173+ margin-top: 5
174+ width: 190
175+ height: 30
176+ text-align: center
177+
178+ Label
179+ id: bonusRerolls
180+ anchors.top: mainSeparator.bottom
181+ anchors.left: prev.right
182+ margin-top: 5
183+ width: 190
184+ height: 30
185+ text-align: center
186+
187+ HorizontalSeparator
188+ anchors.bottom: buttonCancel.top
189+ anchors.left: parent.left
190+ anchors.right: parent.right
191+ margin-bottom: 5
192+
193+ Button
194+ id: buttonCancel
195+ !text: tr('Close')
196+ width: 64
197+ anchors.right: parent.right
198+ anchors.bottom: parent.bottom
199+ @onClick: modules.game_prey.hide()
A RD_Client/modules/game_protocol/protocol.lua +7-0 View file
@@ -0,0 +1,7 @@
1+function init()
2+end
3+
4+function terminate()
5+end
6+
7+
A RD_Client/modules/game_protocol/protocol.otmod +11-0 View file
@@ -0,0 +1,11 @@
1+Module
2+ name: game_protocol
3+ description: Game protocol
4+ author: otclientv8
5+ website: http://otclient.ovh
6+ scripts: [ protocol ]
7+ sandboxed: true
8+ autoload: true
9+ autoload-priority: 500
10+ @onLoad: init()
11+ @onUnload: terminate()
A RD_Client/modules/game_questlog/questlinewindow.otui +51-0 View file
@@ -0,0 +1,51 @@
1+MissionLabel < Label
2+ font: verdana-11px-monochrome
3+ background-color: alpha
4+ text-offset: 2 0
5+ focusable: true
6+
7+ $focus:
8+ background-color: #ffffff22
9+ color: #ffffff
10+
11+QuestLineWindow < MainWindow
12+ id: questLineWindow
13+ !text: tr('Quest Log')
14+ size: 500 400
15+ @onEscape: self:destroy()
16+
17+ TextList
18+ id: missionList
19+ anchors.top: parent.top
20+ anchors.left: parent.left
21+ anchors.right: missionListScrollBar.left
22+ height: 100
23+ padding: 1
24+ focusable: false
25+ vertical-scrollbar: missionListScrollBar
26+
27+ VerticalScrollBar
28+ id: missionListScrollBar
29+ anchors.top: parent.top
30+ anchors.right: parent.right
31+ height: 100
32+ step: 14
33+ pixels-scroll: true
34+
35+ FlatLabel
36+ id: missionDescription
37+ anchors.top: missionList.bottom
38+ anchors.left: parent.left
39+ anchors.right: missionListScrollBar.right
40+ anchors.bottom: closeButton.top
41+ margin-bottom: 10
42+ margin-top: 10
43+ text-wrap: true
44+
45+ Button
46+ id: closeButton
47+ anchors.bottom: parent.bottom
48+ anchors.right: parent.right
49+ !text: tr('Close')
50+ width: 90
51+ @onClick: self:getParent():destroy()
A RD_Client/modules/game_questlog/questlog.lua +92-0 View file
@@ -0,0 +1,92 @@
1+questLogButton = nil
2+questLineWindow = nil
3+
4+function init()
5+ g_ui.importStyle('questlogwindow')
6+ g_ui.importStyle('questlinewindow')
7+
8+ if not g_app.isMobile() then
9+ --questLogButton = modules.client_topmenu.addLeftGameButton('questLogButton', tr('Quest Log'), '/images/topbuttons/questlog', function() g_game.requestQuestLog() end, false, 8)
10+ end
11+
12+ connect(g_game, { onQuestLog = onGameQuestLog,
13+ onQuestLine = onGameQuestLine,
14+ onGameEnd = destroyWindows})
15+end
16+
17+function terminate()
18+ disconnect(g_game, { onQuestLog = onGameQuestLog,
19+ onQuestLine = onGameQuestLine,
20+ onGameEnd = destroyWindows})
21+
22+ destroyWindows()
23+ --if questLogButton then
24+ -- questLogButton:destroy()
25+ --end
26+end
27+
28+function destroyWindows()
29+ if questLogWindow then
30+ questLogWindow:destroy()
31+ end
32+
33+ if questLineWindow then
34+ questLineWindow:destroy()
35+ end
36+end
37+
38+function onGameQuestLog(quests)
39+ destroyWindows()
40+
41+ questLogWindow = g_ui.createWidget('QuestLogWindow', rootWidget)
42+ local questList = questLogWindow:getChildById('questList')
43+
44+ for i,questEntry in pairs(quests) do
45+ local id, name, completed = unpack(questEntry)
46+
47+ local questLabel = g_ui.createWidget('QuestLabel', questList)
48+ questLabel:setOn(completed)
49+ questLabel:setText(name)
50+ questLabel.onDoubleClick = function()
51+ questLogWindow:hide()
52+ g_game.requestQuestLine(id)
53+ end
54+ end
55+
56+ questLogWindow.onDestroy = function()
57+ questLogWindow = nil
58+ end
59+
60+ questList:focusChild(questList:getFirstChild())
61+end
62+
63+function onGameQuestLine(questId, questMissions)
64+ if questLogWindow then questLogWindow:hide() end
65+ if questLineWindow then questLineWindow:destroy() end
66+
67+ questLineWindow = g_ui.createWidget('QuestLineWindow', rootWidget)
68+ local missionList = questLineWindow:getChildById('missionList')
69+ local missionDescription = questLineWindow:getChildById('missionDescription')
70+
71+ connect(missionList, { onChildFocusChange = function(self, focusedChild)
72+ if focusedChild == nil then return end
73+ missionDescription:setText(focusedChild.description)
74+ end })
75+
76+ for i,questMission in pairs(questMissions) do
77+ local name, description = unpack(questMission)
78+
79+ local missionLabel = g_ui.createWidget('MissionLabel')
80+ missionLabel:setText(name)
81+ missionLabel.description = description
82+ missionList:addChild(missionLabel)
83+ end
84+
85+ questLineWindow.onDestroy = function()
86+ if questLogWindow then questLogWindow:show() end
87+ questLineWindow = nil
88+ end
89+
90+ missionList:focusChild(missionList:getFirstChild())
91+end
92+
A RD_Client/modules/game_questlog/questlog.otmod +9-0 View file
@@ -0,0 +1,9 @@
1+Module
2+ name: game_questlog
3+ description: View game quests status
4+ author: edubart
5+ website: https://github.com/edubart/otclient
6+ sandboxed: true
7+ scripts: [ questlog ]
8+ @onLoad: init()
9+ @onUnload: terminate()
A RD_Client/modules/game_questlog/questlogwindow.otui +54-0 View file
@@ -0,0 +1,54 @@
1+QuestLabel < Label
2+ font: verdana-11px-monochrome
3+ text-offset: 2 0
4+ focusable: true
5+ color: #aaaaaa
6+ background-color: alpha
7+
8+ $on:
9+ color: #00aa00
10+ $!on:
11+ color: #aaaaaa
12+
13+ $focus:
14+ background-color: #444444
15+
16+ $on focus:
17+ color: #00ff00
18+ $!on focus:
19+ color: #ffffff
20+
21+QuestLogWindow < MainWindow
22+ id: questLogWindow
23+ !text: tr('Quest Log')
24+ size: 500 400
25+ @onEscape: self:destroy()
26+ $mobile:
27+ size: 500 350
28+
29+ TextList
30+ id: questList
31+ anchors.top: parent.top
32+ anchors.bottom: closeButton.top
33+ anchors.left: parent.left
34+ anchors.right: questListScrollBar.left
35+ margin-bottom: 10
36+ focusable: false
37+ vertical-scrollbar: questListScrollBar
38+
39+ VerticalScrollBar
40+ id: questListScrollBar
41+ anchors.top: parent.top
42+ anchors.bottom: closeButton.top
43+ anchors.right: parent.right
44+ margin-bottom: 10
45+ step: 14
46+ pixels-scroll: true
47+
48+ Button
49+ id: closeButton
50+ anchors.bottom: parent.bottom
51+ anchors.right: parent.right
52+ !text: tr('Close')
53+ width: 90
54+ @onClick: self:getParent():destroy()
A RD_Client/modules/game_ruleviolation/ruleviolation.lua +151-0 View file
@@ -0,0 +1,151 @@
1+rvreasons = {}
2+rvreasons[1] = tr("1a) Offensive Name")
3+rvreasons[2] = tr("1b) Invalid Name Format")
4+rvreasons[3] = tr("1c) Unsuitable Name")
5+rvreasons[4] = tr("1d) Name Inciting Rule Violation")
6+rvreasons[5] = tr("2a) Offensive Statement")
7+rvreasons[6] = tr("2b) Spamming")
8+rvreasons[7] = tr("2c) Illegal Advertising")
9+rvreasons[8] = tr("2d) Off-Topic Public Statement")
10+rvreasons[9] = tr("2e) Non-English Public Statement")
11+rvreasons[10] = tr("2f) Inciting Rule Violation")
12+rvreasons[11] = tr("3a) Bug Abuse")
13+rvreasons[12] = tr("3b) Game Weakness Abuse")
14+rvreasons[13] = tr("3c) Using Unofficial Software to Play")
15+rvreasons[14] = tr("3d) Hacking")
16+rvreasons[15] = tr("3e) Multi-Clienting")
17+rvreasons[16] = tr("3f) Account Trading or Sharing")
18+rvreasons[17] = tr("4a) Threatening Gamemaster")
19+rvreasons[18] = tr("4b) Pretending to Have Influence on Rule Enforcement")
20+rvreasons[19] = tr("4c) False Report to Gamemaster")
21+rvreasons[20] = tr("Destructive Behaviour")
22+rvreasons[21] = tr("Excessive Unjustified Player Killing")
23+
24+rvactions = {}
25+rvactions[0] = tr("Notation")
26+rvactions[1] = tr("Name Report")
27+rvactions[2] = tr("Banishment")
28+rvactions[3] = tr("Name Report + Banishment")
29+rvactions[4] = tr("Banishment + Final Warning")
30+rvactions[5] = tr("Name Report + Banishment + Final Warning")
31+rvactions[6] = tr("Statement Report")
32+
33+ruleViolationWindow = nil
34+reasonsTextList = nil
35+actionsTextList = nil
36+
37+function init()
38+ connect(g_game, { onGMActions = loadReasons })
39+
40+ ruleViolationWindow = g_ui.displayUI('ruleviolation')
41+ ruleViolationWindow:setVisible(false)
42+
43+ reasonsTextList = ruleViolationWindow:getChildById('reasonList')
44+ actionsTextList = ruleViolationWindow:getChildById('actionList')
45+
46+ g_keyboard.bindKeyDown('Ctrl+Y', function() show() end)
47+
48+ if g_game.isOnline() then
49+ loadReasons()
50+ end
51+end
52+
53+function terminate()
54+ disconnect(g_game, { onGMActions = loadReasons })
55+ g_keyboard.unbindKeyDown('Ctrl+Y')
56+
57+ ruleViolationWindow:destroy()
58+end
59+
60+function hasWindowAccess()
61+ return reasonsTextList:getChildCount() > 0
62+end
63+
64+function loadReasons()
65+ reasonsTextList:destroyChildren()
66+ actionsTextList:destroyChildren()
67+
68+ local actions = g_game.getGMActions()
69+ for reason, actionFlags in pairs(actions) do
70+ local label = g_ui.createWidget('RVListLabel', reasonsTextList)
71+ label.onFocusChange = onSelectReason
72+ label:setText(rvreasons[reason])
73+ label.reasonId = reason
74+ label.actionFlags = actionFlags
75+ end
76+
77+ if not hasWindowAccess() and ruleViolationWindow:isVisible() then hide() end
78+end
79+
80+function show(target, statement)
81+ if g_game.isOnline() and hasWindowAccess() then
82+ if target then
83+ ruleViolationWindow:getChildById('nameText'):setText(target)
84+ end
85+
86+ if statement then
87+ ruleViolationWindow:getChildById('statementText'):setText(statement)
88+ end
89+
90+ ruleViolationWindow:show()
91+ ruleViolationWindow:raise()
92+ ruleViolationWindow:focus()
93+ ruleViolationWindow:getChildById('commentText'):focus()
94+ end
95+end
96+
97+function hide()
98+ ruleViolationWindow:hide()
99+ clearForm()
100+end
101+
102+function onSelectReason(reasonLabel, focused)
103+ if reasonLabel.actionFlags and focused then
104+ actionsTextList:destroyChildren()
105+ for actionBaseFlag = 0, #rvactions do
106+ local actionFlagString = rvactions[actionBaseFlag]
107+ if bit32.band(reasonLabel.actionFlags, math.pow(2, actionBaseFlag)) > 0 then
108+ local label = g_ui.createWidget('RVListLabel', actionsTextList)
109+ label:setText(actionFlagString)
110+ label.actionId = actionBaseFlag
111+ end
112+ end
113+ end
114+end
115+
116+function report()
117+ local reasonLabel = reasonsTextList:getFocusedChild()
118+ if not reasonLabel then
119+ displayErrorBox(tr("Error"), tr("You must select a reason."))
120+ return
121+ end
122+
123+ local actionLabel = actionsTextList:getFocusedChild()
124+ if not actionLabel then
125+ displayErrorBox(tr("Error"), tr("You must select an action."))
126+ return
127+ end
128+
129+ local target = ruleViolationWindow:getChildById('nameText'):getText()
130+ local reason = reasonLabel.reasonId
131+ local action = actionLabel.actionId
132+ local comment = ruleViolationWindow:getChildById('commentText'):getText()
133+ local statement = ruleViolationWindow:getChildById('statementText'):getText()
134+ local statementId = 0 -- TODO: message unique id ?
135+ local ipBanishment = ruleViolationWindow:getChildById('ipBanCheckBox'):isChecked()
136+ if action == 6 and statement == "" then
137+ displayErrorBox(tr("Error"), tr("No statement has been selected."))
138+ elseif comment == "" then
139+ displayErrorBox(tr("Error"), tr("You must enter a comment."))
140+ else
141+ g_game.reportRuleViolation(target, reason, action, comment, statement, statementId, ipBanishment)
142+ hide()
143+ end
144+end
145+
146+function clearForm()
147+ ruleViolationWindow:getChildById('nameText'):clearText()
148+ ruleViolationWindow:getChildById('commentText'):clearText()
149+ ruleViolationWindow:getChildById('statementText'):clearText()
150+ ruleViolationWindow:getChildById('ipBanCheckBox'):setChecked(false)
151+end
A RD_Client/modules/game_ruleviolation/ruleviolation.otmod +9-0 View file
@@ -0,0 +1,9 @@
1+Module
2+ name: game_ruleviolation
3+ description: Rule violation interface (Ctrl+Y)
4+ author: andrefaramir
5+ website: https://github.com/edubart/otclient
6+ sandboxed: true
7+ scripts: [ ruleviolation ]
8+ @onLoad: init()
9+ @onUnload: terminate()
A RD_Client/modules/game_ruleviolation/ruleviolation.otui +120-0 View file
@@ -0,0 +1,120 @@
1+RVListLabel < Label
2+ background-color: alpha
3+ text-offset: 2 0
4+ focusable: true
5+
6+ $focus:
7+ background-color: #ffffff22
8+ color: #ffffff
9+
10+RVLabel < Label
11+ anchors.left: parent.left
12+ anchors.right: parent.right
13+
14+ $first:
15+ anchors.top: parent.top
16+
17+ $!first:
18+ margin-top: 10
19+ anchors.top: prev.bottom
20+
21+RVTextEdit < TextEdit
22+ margin-top: 2
23+ anchors.left: parent.left
24+ anchors.right: parent.right
25+
26+ $first:
27+ anchors.top: parent.top
28+
29+ $!first:
30+ anchors.top: prev.bottom
31+
32+MainWindow
33+ id: ruleViolationWindow
34+ size: 400 445
35+ text: Rule Violation
36+ @onEscape: hide()
37+
38+ RVLabel
39+ !text: tr('Name') .. ':'
40+
41+ RVTextEdit
42+ id: nameText
43+
44+ RVLabel
45+ !text: tr('Statement') .. ':'
46+
47+ RVTextEdit
48+ id: statementText
49+ enabled: false
50+
51+ RVLabel
52+ !text: tr('Reason') .. ':'
53+
54+ TextList
55+ id: reasonList
56+ height: 100
57+ anchors.top: prev.bottom
58+ anchors.left: parent.left
59+ anchors.right: parent.right
60+ margin-top: 2
61+ focusable: false
62+ vertical-scrollbar: reasonListScrollBar
63+
64+ VerticalScrollBar
65+ id: reasonListScrollBar
66+ anchors.top: reasonList.top
67+ anchors.bottom: reasonList.bottom
68+ anchors.right: reasonList.right
69+ step: 14
70+ pixels-scroll: true
71+
72+ RVLabel
73+ !text: tr('Action') .. ':'
74+
75+ TextList
76+ id: actionList
77+ height: 60
78+ anchors.top: prev.bottom
79+ anchors.left: parent.left
80+ anchors.right: parent.right
81+ margin-top: 2
82+ focusable: false
83+ vertical-scrollbar: actionListScrollBar
84+
85+ VerticalScrollBar
86+ id: actionListScrollBar
87+ anchors.top: actionList.top
88+ anchors.bottom: actionList.bottom
89+ anchors.right: actionList.right
90+ step: 14
91+ pixels-scroll: true
92+
93+ CheckBox
94+ id: ipBanCheckBox
95+ !text: tr('IP Address Banishment')
96+ margin-top: 10
97+ anchors.top: prev.bottom
98+ anchors.left: parent.left
99+ anchors.right: parent.right
100+
101+ RVLabel
102+ !text: tr('Comment') .. ':'
103+
104+ RVTextEdit
105+ id: commentText
106+
107+ Button
108+ !text: tr('Cancel')
109+ width: 64
110+ anchors.right: parent.right
111+ anchors.bottom: parent.bottom
112+ @onClick: hide()
113+
114+ Button
115+ !text: tr('Ok')
116+ width: 64
117+ margin-right: 5
118+ anchors.right: prev.left
119+ anchors.bottom: parent.bottom
120+ @onClick: report()
A RD_Client/modules/game_runeeffects/game_runeeffects.lua +32-0 View file
@@ -0,0 +1,32 @@
1+local showRuneEffect = true
2+
3+local function onOutfitChange(creature)
4+ if not showRuneEffect then
5+ local outfit = creature:getOutfit()
6+ if outfit.runeeffect and outfit.runeeffect > 0 then
7+ outfit.runeeffect = 0
8+ creature:setOutfit(outfit)
9+ end
10+ end
11+end
12+
13+function init()
14+ connect(Creature, {onOutfitChange = onOutfitChange})
15+end
16+
17+function terminate()
18+ disconnect(Creature, {onOutfitChange = onOutfitChange})
19+end
20+
21+function setRuneEffectVisible(visible)
22+ showRuneEffect = visible
23+end
24+
25+function isRuneEffectVisible()
26+ return showRuneEffect
27+end
28+
29+game_runeeffects = {
30+ setRuneEffectVisible = setRuneEffectVisible,
31+ isRuneEffectVisible = isRuneEffectVisible
32+}
A RD_Client/modules/game_runeeffects/game_runeeffects.otmod +10-0 View file
@@ -0,0 +1,10 @@
1+Module
2+ name: game_runeeffects
3+ description: Manages rune effect visibility and texture loading for creature outfits.
4+ autoload: true
5+ reloadable: true
6+ sandboxed: true
7+ version: 1.0
8+ scripts: [ game_runeeffects ]
9+ @onLoad: init()
10+ @onUnload: terminate()
A RD_Client/modules/game_shaders/shaders.html +22-0 View file
@@ -0,0 +1,22 @@
1+<style>
2+ .content {
3+ border-color: red;
4+ border-width: 1;
5+ margin-top: 80;
6+ margin-left: 5;
7+ width: 200;
8+ display: none;
9+ }
10+
11+ select {
12+ margin-bottom: 5;
13+ }
14+</style>
15+
16+<div focusable="false" class="content" anchor="parent" layout="type: verticalBox; fit-children: true">
17+ <label style="text-align: center; margin-top: 10">Shaders Map/Outfit/Mount</label>
18+ <hr />
19+ <select id="mapComboBox" onchange="self:onMapComboBoxChange(event)"></select>
20+ <select id="outfitComboBox" onchange="self:onOutfitComboBoxChange(event)"></select>
21+ <select id="mountComboBox" onchange="self:onMountComboBoxChange(event)"></select>
22+</div>
A RD_Client/modules/game_shaders/shaders.lua +215-0 View file
@@ -0,0 +1,215 @@
1+function init()
2+
3+
4+ -- Item shaders
5+ g_shaders.createShader("item_veil", "/shaders/item_vertex", "/shaders/item_veil_fragment", false)
6+ g_shaders.createShader("item_exploding", "/shaders/item_vertex", "/shaders/item_exploding_fragment", false)
7+ g_shaders.createShader("item_dark", "/shaders/item_vertex", "/shaders/item_dark_fragment", false)
8+ g_shaders.addTexture("item_dark", "/images/shaders/purpleneon.png")
9+ g_shaders.createShader("mirrored", "/shaders/widget_default_vertex", "/shaders/mirrored_fragment", true)
10+
11+ -- map shaders
12+ g_shaders.createShader("map_default", "/shaders/map_default_vertex", "/shaders/map_default_fragment")
13+ g_shaders.createShader("map_noise", "/shaders/default_vertex", "/shaders/noise", false)
14+ g_shaders.createShader("map_grayscale", "/shaders/default_vertex", "/shaders/grayscale", false)
15+ g_shaders.createShader("map_sepia", "/shaders/default_vertex", "/shaders/sepia", false)
16+ g_shaders.createShader("map_bloom", "/shaders/default_vertex", "/shaders/bloom", false)
17+ g_shaders.createShader("map_oldtv", "/shaders/default_vertex", "/shaders/oldtv", false)
18+ g_shaders.createShader("map_pulse", "/shaders/default_vertex", "/shaders/pulse", false)
19+ g_shaders.createShader("map_party", "/shaders/default_vertex", "/shaders/party", false)
20+ g_shaders.createShader("map_radialblur", "/shaders/default_vertex", "/shaders/radialblur", false)
21+ g_shaders.createShader("map_radialblur_intensity_1", "/shaders/default_vertex", "/shaders/radialblur_intensity_1", false)
22+ g_shaders.createShader("map_radialblur_intensity_2", "/shaders/default_vertex", "/shaders/radialblur_intensity_2", false)
23+ g_shaders.createShader("map_radialblur_intensity_3", "/shaders/default_vertex", "/shaders/radialblur_intensity_3", false)
24+ g_shaders.createShader("map_radialblur_intensity_4", "/shaders/default_vertex", "/shaders/radialblur_intensity_4", false)
25+ g_shaders.createShader("map_radialblur_intensity_5", "/shaders/default_vertex", "/shaders/radialblur_intensity_5", false)
26+ g_shaders.createShader("map_radialblur_intensity_6", "/shaders/default_vertex", "/shaders/radialblur_intensity_6", false)
27+ g_shaders.createShader("map_radialblur_intensity_7", "/shaders/default_vertex", "/shaders/radialblur_intensity_7", false)
28+ g_shaders.createShader("map_radialblur_intensity_8", "/shaders/default_vertex", "/shaders/radialblur_intensity_8", false)
29+ g_shaders.createShader("map_radialblur_intensity_9", "/shaders/default_vertex", "/shaders/radialblur_intensity_9", false)
30+ g_shaders.createShader("map_intenseradialblur", "/shaders/default_vertex", "/shaders/intenseradialblur", false)
31+ g_shaders.createShader("map_heat", "/shaders/map_vertex_with_static", "/shaders/map_heat", false)
32+ g_shaders.createShader("map_icy", "/shaders/map_vertex_with_static", "/shaders/map_icy", false)
33+ g_shaders.addTexture("map_icy", "/images/shaders/ice2.png")
34+ g_shaders.createShader("map_death", "/shaders/map_vertex_with_static", "/shaders/map_death", false)
35+ g_shaders.addTexture("map_death", "/images/shaders/purpleneon.png")
36+ g_shaders.createShader("map_dark", "/shaders/map_vertex_with_static", "/shaders/map_dark", false)
37+ g_shaders.addTexture("map_dark", "/images/shaders/purpleneon.png")
38+ g_shaders.createShader("map_magma", "/shaders/map_vertex_with_static", "/shaders/map_magma", false)
39+ g_shaders.addTexture("map_magma", "/images/shaders/magma.png")
40+ g_shaders.createShader("map_fog", "/shaders/map_vertex", "/shaders/fog", false)
41+ g_shaders.addTexture("map_fog", "/images/shaders/heavy_fog.png")
42+ g_shaders.createShader("map_toxic_fog", "/shaders/map_vertex", "/shaders/map_toxic_fog", false)
43+ g_shaders.addTexture("map_toxic_fog", "/images/shaders/clouds.png")
44+ g_shaders.createShader("map_snow", "/shaders/map_vertex", "/shaders/map_snow", false)
45+ g_shaders.createShader("red_alarm", "/shaders/map_vertex", "/shaders/red_alarm", tr)
46+ g_shaders.createShader("black_screen", "/shaders/map_vertex", "/shaders/black_screen", false)
47+ g_shaders.createShader("map_rainbow", "/shaders/map_rainbow_vertex", "/shaders/map_rainbow_fragment")
48+ g_shaders.addTexture("map_rainbow", "/images/shaders/rainbow.png")
49+
50+ -- map_snow with walkOffset support (commit fab1f9f: shader moves with player walk)
51+ g_shaders.createShader("map_snow_woffset", "/shaders/map_snow_vertex", "/shaders/map_snow_fragment")
52+ g_shaders.addTexture("map_snow_woffset", "/images/shaders/snow.png")
53+
54+ -- Iluminación avanzada: sombras proyectadas + vignette
55+ g_shaders.createShader("map_light_shadow", "/shaders/map_vertex", "/shaders/map_light_shadow", false)
56+ g_shaders.createShader("rain", "/shaders/map_vertex", "/shaders/rain")
57+ g_shaders.createShader("snow", "/shaders/map_vertex", "/shaders/snow")
58+ g_shaders.addTexture("snow", "/images/shaders/snow.png")
59+
60+ -- Forest shader (uses u_WalkOffset)
61+ g_shaders.createShader("map_forest", "/shaders/map_snow_vertex", "/shaders/forest")
62+ g_shaders.addTexture("map_forest", "/images/shaders/forest.png")
63+
64+ g_shaders.createShader("grayscale", "/shaders/map_vertex", "/shaders/grayscale")
65+ g_shaders.createShader("bloom", "/shaders/map_vertex", "/shaders/bloom")
66+ g_shaders.createShader("sepia", "/shaders/map_vertex", "/shaders/sepia")
67+ g_shaders.createShader("sepiap", "/shaders/map_vertex", "/shaders/sepiap")
68+ g_shaders.createShader("pulse", "/shaders/map_vertex", "/shaders/pulse")
69+ g_shaders.createShader("oldtv", "/shaders/map_vertex", "/shaders/oldtv")
70+ g_shaders.createShader("party", "/shaders/map_vertex", "/shaders/party")
71+ g_shaders.createShader("radialblur", "/shaders/map_vertex", "/shaders/radialblur")
72+ g_shaders.createShader("zomg", "/shaders/map_vertex", "/shaders/zomg")
73+ g_shaders.createShader("heat", "/shaders/map_vertex", "/shaders/heat")
74+ g_shaders.createShader("noise", "/shaders/map_vertex", "/shaders/noise")
75+ g_shaders.createShader("blink", "/shaders/map_vertex", "/shaders/outfit_blink")
76+ g_shaders.createShader("shaky", "/shaders/map_vertex", "/shaders/shaky")
77+ g_shaders.createShader("dizzy", "/shaders/map_vertex", "/shaders/dizzy")
78+
79+ -- outfit shaders
80+ g_shaders.createOutfitShader("outfit_default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment")
81+ g_shaders.createOutfitShader("Line", "/shaders/outfit_line_vertex", "/shaders/outfit_line_fragment")
82+ g_shaders.createOutfitShader("Shine", "/shaders/outfit_circle_vertex", "/shaders/outfit_circle_fragment")
83+ g_shaders.createOutfitShader("Shine 2", "/shaders/outfit_circle2_vertex", "/shaders/outfit_circle2_fragment")
84+ g_shaders.createOutfitShader("Shine 3", "/shaders/outfit_circle3_vertex", "/shaders/outfit_circle3_fragment")
85+ g_shaders.createOutfitShader("Shine 4", "/shaders/outfit_circle4_vertex", "/shaders/outfit_circle4_fragment")
86+ g_shaders.createOutfitShader("Rainbow Outline", "/shaders/rainbow_outline_vert", "/shaders/rainbow_outline_frag")
87+ g_shaders.createOutfitShader("Glitch", "/shaders/glitch_vertex", "/shaders/glitch_fragment")
88+ g_shaders.createOutfitShader("Empty", "/shaders/image_vertex", "/shaders/empty_outline")
89+ g_shaders.createOutfitShader("3 Color Galaxy", "/shaders/outfit_default_vertex.frag", "/shaders/3galaxy_fragment")
90+ g_shaders.createOutfitShader("Drunk", "/shaders/outfit_default_vertex.frag", "/shaders/drunk_fragment")
91+ g_shaders.createOutfitShader("Red Rage", "/shaders/outfit_default_vertex.frag", "/shaders/red_fragment")
92+ g_shaders.addTexture("Red Rage", "/images/shaders/red.png")
93+ g_shaders.createOutfitShader("Green Rage", "/shaders/outfit_default_vertex.frag", "/shaders/green_fragment")
94+ g_shaders.addTexture("Green Rage", "/images/shaders/green.png")
95+ g_shaders.createOutfitShader("Oru 1", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_1.frag")
96+ g_shaders.createOutfitShader("Oru 2", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_2.frag")
97+ g_shaders.createOutfitShader("Oru 3", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_3.frag")
98+ g_shaders.createOutfitShader("Oru 4", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_4.frag")
99+ g_shaders.createOutfitShader("Oru 5", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_5.frag")
100+ g_shaders.createOutfitShader("Oru 6", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_6.frag")
101+ g_shaders.createOutfitShader("Oru 7", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_7.frag")
102+ g_shaders.createOutfitShader("Oru 8", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_8.frag")
103+ g_shaders.createOutfitShader("Oru 9", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_9.frag")
104+ g_shaders.createOutfitShader("Oru 10", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_10.frag")
105+ g_shaders.createOutfitShader("Oru 11", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_11.frag")
106+ g_shaders.createOutfitShader("Oru 12", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_12.frag")
107+ g_shaders.createOutfitShader("Oru 13", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_13.frag")
108+ g_shaders.createOutfitShader("Oru 14", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_14.frag")
109+ g_shaders.createOutfitShader("Oru 15", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_15.frag")
110+ g_shaders.createOutfitShader("Oru 16", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_16.frag")
111+ g_shaders.createOutfitShader("Oru 17", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_17.frag")
112+ g_shaders.createOutfitShader("Oru 18", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_18.frag")
113+ g_shaders.createOutfitShader("Oru 19", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_19.frag")
114+ g_shaders.createOutfitShader("Oru 20", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_20.frag")
115+ g_shaders.createOutfitShader("Oru 21", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_21.frag")
116+ g_shaders.createOutfitShader("Oru 22", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_22.frag")
117+ g_shaders.createOutfitShader("Oru 23", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_23.frag")
118+ g_shaders.createOutfitShader("Oru 24", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_24.frag")
119+ g_shaders.createOutfitShader("Oru 25", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_25.frag")
120+ g_shaders.createOutfitShader("Oru 26", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_26.frag")
121+ g_shaders.createOutfitShader("Oru 27", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_27.frag")
122+ g_shaders.createOutfitShader("Oru 28", "/shaders/outfit_default_vertex.frag", "/shaders/outfit_outline_28.frag")
123+ g_shaders.createOutfitShader("Rainbow", "/shaders/outfit_rainbow_old_vertex", "/shaders/outfit_rainbow_old_fragment")
124+ g_shaders.addTexture("Rainbow", "/images/shaders/rainbow.png")
125+ g_shaders.createOutfitShader("Stars", "/shaders/outfit_stars_vertex", "/shaders/outfit_stars_fragment")
126+ g_shaders.addTexture("Stars", "/images/shaders/stars.png")
127+ g_shaders.createOutfitShader("Blue Energy", "/shaders/outfit_blue_energy_vertex", "/shaders/outfit_blue_energy_fragment")
128+ g_shaders.addTexture("Blue Energy", "/images/shaders/blueenergy.png")
129+ g_shaders.createOutfitShader("Red Energy", "/shaders/outfit_red_energy_vertex", "/shaders/outfit_red_energy_fragment")
130+ g_shaders.addTexture("Red Energy", "/images/shaders/blueenergy.png")
131+ g_shaders.createOutfitShader("Purple Energy", "/shaders/outfit_purple_energy_vertex", "/shaders/outfit_purple_energy_fragment")
132+ g_shaders.addTexture("Purple Energy", "/images/shaders/blueenergy.png")
133+ g_shaders.createOutfitShader("Green Energy", "/shaders/outfit_green_energy_vertex", "/shaders/outfit_green_energy_fragment")
134+ g_shaders.addTexture("Green Energy", "/images/shaders/blueenergy.png")
135+ g_shaders.createOutfitShader("Blood", "/shaders/outfit_blood_vertex", "/shaders/outfit_blood_fragment")
136+ g_shaders.addTexture("Blood", "/images/shaders/blood.png")
137+ g_shaders.createOutfitShader("Sun", "/shaders/outfit_sun_vertex", "/shaders/outfit_sun_fragment")
138+ g_shaders.addTexture("Sun", "/images/shaders/sun.png")
139+ g_shaders.createOutfitShader("Gold", "/shaders/outfit_gold_vertex", "/shaders/outfit_gold_fragment")
140+ g_shaders.addTexture("Gold", "/images/shaders/gold.png")
141+ g_shaders.createOutfitShader("3 Lines", "/shaders/outfit_3line_vertex", "/shaders/outfit_3line_fragment")
142+ g_shaders.createOutfitShader("Ice", "/shaders/outfit_ice_vertex", "/shaders/outfit_ice_fragment")
143+ g_shaders.addTexture("Ice", "/images/shaders/ice.png")
144+ g_shaders.createOutfitShader("Camouflage", "/shaders/outfit_camouflage_vertex", "/shaders/outfit_camouflage_fragment")
145+ g_shaders.addTexture("Camouflage", "/images/shaders/camouflage.png")
146+ g_shaders.createOutfitShader("Cosmos", "/shaders/outfit_cosmos_vertex", "/shaders/outfit_cosmos_fragment")
147+ g_shaders.addTexture("Cosmos", "/images/shaders/cosmos2.png")
148+ g_shaders.createOutfitShader("Pop", "/shaders/outfit_glitch_vertex", "/shaders/outfit_glitch_fragment")
149+ g_shaders.addTexture("Pop", "/images/shaders/glitch2.png")
150+ g_shaders.createOutfitShader("Purple Neon", "/shaders/outfit_purpleneon_vertex", "/shaders/outfit_purpleneon_fragment")
151+ g_shaders.addTexture("Purple Neon", "/images/shaders/purpleneon.png")
152+ g_shaders.createOutfitShader("Purple Sky", "/shaders/outfit_purplesky_vertex", "/shaders/outfit_purplesky_fragment")
153+ g_shaders.addTexture("Purple Sky", "/images/shaders/purplesky.png")
154+ g_shaders.createOutfitShader("Static", "/shaders/outfit_static_vertex", "/shaders/outfit_static_fragment")
155+ g_shaders.addTexture("Static", "/images/shaders/static.png")
156+ g_shaders.createOutfitShader("Red Hollow", "/shaders/red_halloween_vert", "/shaders/red_halloween")
157+ g_shaders.createOutfitShader("Mirage", "/shaders/vertex", "/shaders/heat")
158+ g_shaders.createOutfitShader("Noise", "/shaders/vertex", "/shaders/noise")
159+ g_shaders.createOutfitShader("Party", "/shaders/vertex", "/shaders/party")
160+ g_shaders.createOutfitShader("Reo", "/shaders/outfit_outline_vertex", "/shaders/outfit_reo_frag")
161+ g_shaders.createOutfitShader("Roah", "/shaders/outfit_outline_vertex", "/shaders/outfit_roah")
162+ g_shaders.createOutfitShader("Veno", "/shaders/outfit_outline_vertex", "/shaders/outfit_veno")
163+ g_shaders.createOutfitShader("Loie", "/shaders/outfit_outline_vertex", "/shaders/outfit_loie")
164+ g_shaders.createOutfitShader("Dizzy", "/shaders/outfit_vertex", "/shaders/outfit_dizzy")
165+ g_shaders.createOutfitShader("Blink", "/shaders/outfit_vertex", "/shaders/outfit_blink")
166+ g_shaders.createOutfitShader("Horan", "/shaders/outfit_horan_vert", "/shaders/outfit_horan")
167+ g_shaders.createOutfitShader("Pixels", "/shaders/outfit_vertex", "/shaders/outfit_pixels")
168+ g_shaders.createOutfitShader("Spiral", "/shaders/outfit_vertex", "/shaders/outfit_spiral")
169+ g_shaders.createOutfitShader("Fire Blooded", "/shaders/outfit_vertex", "/shaders/outfit_fblooded")
170+ g_shaders.createOutfitShader("Procedural", "/shaders/outfit_procedural_vertex", "/shaders/outfit_procedural_fragment")
171+ g_shaders.addTexture("Procedural", "/images/shaders/procedural.png")
172+ g_shaders.createOutfitShader("Green Ilu", "/shaders/outfit_gilu_vertex", "/shaders/outfit_gilu_fragment")
173+ g_shaders.addTexture("Green Ilu", "/images/shaders/gilu.png")
174+ g_shaders.createOutfitShader("Light Ori", "/shaders/outfit_lori_vertex", "/shaders/outfit_lori_fragment")
175+ g_shaders.addTexture("Light Ori", "/images/shaders/lori.png")
176+ g_shaders.createOutfitShader("Heat", "/shaders/outfit_heat_vertex", "/shaders/outfit_heat_fragment")
177+ g_shaders.addTexture("Heat", "/images/shaders/heat.png")
178+ g_shaders.createOutfitShader("Kors", "/shaders/outfit_kors_vertex", "/shaders/outfit_kors_fragment")
179+ g_shaders.addTexture("Kors", "/images/shaders/kors.png")
180+ g_shaders.createOutfitShader("Ori", "/shaders/outfit_ori_vertex", "/shaders/outfit_ori_fragment")
181+ g_shaders.addTexture("Ori", "/images/shaders/ori.png")
182+ g_shaders.createOutfitShader("Blue Voltage", "/shaders/outfit_bvoltage_vertex", "/shaders/outfit_bvoltage_fragment")
183+ g_shaders.addTexture("Blue Voltage", "/images/shaders/bvoltage.png")
184+ g_shaders.createOutfitShader("Purple Voltage", "/shaders/outfit_purpvoltage_vertex", "/shaders/outfit_purpvoltage_fragment")
185+ g_shaders.addTexture("Purple Voltage", "/images/shaders/purpvoltage.png")
186+ g_shaders.createOutfitShader("Green Shine", "/shaders/outfit_greenshine_vertex", "/shaders/outfit_greenshine_fragment")
187+ g_shaders.addTexture("Green Shine", "/images/shaders/greenshine.png")
188+ g_shaders.createOutfitShader("Red Voltage", "/shaders/outfit_rvoltage_vertex", "/shaders/outfit_rvoltage_fragment")
189+ g_shaders.addTexture("Red Voltage", "/images/shaders/fire2.png")
190+ g_shaders.createOutfitShader("Liquid Marble", "/shaders/outfit_lmarble_vertex", "/shaders/outfit_lmarble_fragment")
191+ g_shaders.addTexture("Liquid Marble", "/images/shaders/lmarble.png")
192+ g_shaders.createOutfitShader("Pink Voltage", "/shaders/outfit_pvoltage_vertex", "/shaders/outfit_pvoltage_fragment")
193+ g_shaders.addTexture("Pink Voltage", "/images/shaders/pvoltage.png")
194+ g_shaders.createOutfitShader("Peakpx", "/shaders/outfit_peakpx_vertex", "/shaders/outfit_peakpx_fragment")
195+ g_shaders.addTexture("Peakpx", "/images/shaders/peakpx.png")
196+ g_shaders.createOutfitShader("Glowing Red Outline", "/shaders/outfit_outline_vertex", "/shaders/outfit_outline_fragment")
197+ g_shaders.createOutfitShader("Glowing Pink Outline", "/shaders/pink_outline_vert", "/shaders/pink_outline_frag")
198+ g_shaders.createOutfitShader("White Outline", "/shaders/white_non_glow_vert", "/shaders/white_non_glow_frag")
199+ g_shaders.createOutfitShader("Ghost", "/shaders/new_ghost_vert", "/shaders/new_ghost_frag")
200+ g_shaders.createOutfitShader("Glowing Yellow Outline", "/shaders/glowing_yellow_vert", "/shaders/glowing_yellow_frag")
201+ g_shaders.createOutfitShader("Glowing Purple Outline", "/shaders/glowing_purple_vert", "/shaders/glowing_purple_frag")
202+ g_shaders.createOutfitShader("Glowing Green Outline", "/shaders/glowing_green_vert", "/shaders/glowing_green_frag")
203+ g_shaders.createOutfitShader("Glowing Blue Outline", "/shaders/glowing_blue_vert", "/shaders/glowing_blue_frag")
204+ g_shaders.createOutfitShader("Faded Ghost", "/shaders/ghost_no_face_vert", "/shaders/ghost_no_face_frag")
205+ g_shaders.addTexture("Faded Ghost", "/images/shaders/seamlessNoise.png")
206+ g_shaders.createOutfitShader("Black Outline", "/shaders/black_non_glow_vert", "/shaders/black_non_glow_frag")
207+
208+
209+ g_shaders.createOutfitShader("outfit sweden", "/shaders/outfit_sweden_vertex", "/shaders/outfit_sweden_fragment")
210+
211+end
212+
213+function terminate()
214+end
215+
Top