otclient-redemption/modules/game_shaders/shaders.lua
kokekanon 7f16fc7c73
cleanup: minor otui errors (#1692)
New Features:
- Added chat channel features: invite/exclude players, dedicated loot channel, owner channel management.
- Fist Weapons category added to market system.

Bug Fixes:
- Improved null safety for local player checks across multiple systems.
- Fixed drag-and-drop validation.
- Prevented division-by-zero errors in calculations.
- Fixed port parsing from URLs.

Improvements:
- Enhanced window toggle button synchronization.
- Refined store description rendering with icons.
- Adjusted UI layouts and spacing across. multiple windows.
- Improved console channel handling.
2026-05-16 22:15:12 -03:00

244 lines
6.6 KiB
Lua

local HOTKEY = 'Ctrl+Y'
local MAP_SHADERS = { {
name = 'Map - Default',
frag = nil
}, {
name = 'Map - Fog',
frag = 'shaders/fragment/fog.frag',
tex1 = 'images/clouds'
}, {
name = 'Map - Rain',
frag = 'shaders/fragment/rain.frag'
}, {
name = 'Map - Snow',
frag = 'shaders/fragment/snow.frag',
tex1 = 'images/snow'
}, {
name = 'Map - Gray Scale',
frag = 'shaders/fragment/grayscale.frag'
}, {
name = 'Map - Bloom',
frag = 'shaders/fragment/bloom.frag'
}, {
name = 'Map - Sepia',
frag = 'shaders/fragment/sepia.frag'
}, {
name = 'Map - Pulse',
frag = 'shaders/fragment/pulse.frag',
drawViewportEdge = true
}, {
name = 'Map - Old Tv',
frag = 'shaders/fragment/oldtv.frag'
}, {
name = 'Map - Party',
frag = 'shaders/fragment/party.frag'
}, {
name = 'Map - Radial Blur',
frag = 'shaders/fragment/radialblur.frag',
drawViewportEdge = true
}, {
name = 'Map - Zomg',
frag = 'shaders/fragment/zomg.frag',
drawViewportEdge = true
}, {
name = 'Map - Heat',
frag = 'shaders/fragment/heat.frag',
drawViewportEdge = true
}, {
name = 'Map - Noise',
frag = 'shaders/fragment/noise.frag'
} }
local OUTFIT_SHADERS = { {
name = 'Outfit - Default',
frag = nil
}, {
name = 'Outfit - Rainbow',
frag = 'shaders/fragment/party.frag'
}, {
name = 'Outfit - Ghost',
frag = 'shaders/fragment/radialblur.frag',
drawColor = false
}, {
name = 'Outfit - Jelly',
frag = 'shaders/fragment/heat.frag'
}, {
name = 'Outfit - Fragmented',
frag = 'shaders/fragment/noise.frag'
}, {
name = 'Outfit - cyclopedia-black',
frag = 'shaders/fragment/cyclopedia.frag'
}, {
name = 'Outfit - Outline',
useFramebuffer = true,
frag = 'shaders/fragment/outline.frag'
}, {
name = 'Outfit - ForgeDonor',
useFramebuffer = true,
frag = 'shaders/fragment/forge_donor.frag'
}, {
name = 'Outfit - ForgeSuccess',
useFramebuffer = true,
frag = 'shaders/fragment/forge_success.frag'
}, {
name = 'Outfit - ForgeFailed',
useFramebuffer = true,
frag = 'shaders/fragment/forge_failed.frag'
}, }
local MOUNT_SHADERS = { {
name = 'Mount - Default',
frag = nil
}, {
name = 'Mount - Rainbow',
frag = 'shaders/fragment/party.frag'
} }
-- Text shaders for improved readability and visual effects
-- All shaders use multi-sample circular sampling for smooth outlines
local TEXT_SHADERS = { {
name = 'Text - Default',
frag = nil -- No shader, standard text rendering
}, {
name = 'Text - Gold Outline',
frag = 'shaders/fragment/text_golden_shadow_bold_fragment.frag' -- Smooth gold (#ee8413) outline
}, {
name = 'Text - Black Outline',
frag = 'shaders/fragment/text_black_outline.frag' -- Classic black outline, max readability
}, {
name = 'Text - Glow',
frag = 'shaders/fragment/text_glow.frag' -- Soft glow effect (higher GPU cost)
} }
local function attachShaders()
local map = modules.game_interface.getMapPanel()
map:setShader('Default')
local player = g_game.getLocalPlayer()
if player then
player:setShader('Default')
player:setMountShader('Default')
end
end
local registerShader = function(opts, method)
local fragmentShaderPath = resolvepath(opts.frag)
if fragmentShaderPath ~= nil then
-- local shader = g_shaders.createShader()
g_shaders.createFragmentShader(opts.name, opts.frag, opts.useFramebuffer or false)
if opts.tex1 then
g_shaders.addMultiTexture(opts.name, opts.tex1)
end
if opts.tex2 then
g_shaders.addMultiTexture(opts.name, opts.tex2)
end
-- Setup proper uniforms
g_shaders[method](opts.name)
end
end
ShaderController = Controller:new()
function ShaderController:onInit()
for _, opts in pairs(MAP_SHADERS) do
registerShader(opts, 'setupMapShader')
end
for _, opts in pairs(OUTFIT_SHADERS) do
registerShader(opts, 'setupOutfitShader')
end
for _, opts in pairs(MOUNT_SHADERS) do
registerShader(opts, 'setupMountShader')
end
for _, opts in pairs(TEXT_SHADERS) do
registerShader(opts, 'setupTextShader')
end
Keybind.new('Windows', 'show/hide Shader Windows', HOTKEY, '')
Keybind.bind('Windows', 'show/hide Shader Windows', {
{
type = KEY_DOWN,
callback = function()
if ShaderController.ui then
ShaderController:unloadHtml()
else
ShaderController:open()
end
end,
}
})
end
function ShaderController:onTerminate()
g_shaders.clear()
Keybind.delete('Windows', 'show/hide Shader Windows')
end
function ShaderController:onGameStart()
attachShaders()
end
function ShaderController:onMapComboBoxChange(event)
local map = modules.game_interface.getMapPanel()
map:setShader(event.text)
local data = event.target:getCurrentOption().data
map:setDrawViewportEdge(data.drawViewportEdge == true)
end
function ShaderController:onOutfitComboBoxChange(event)
local player = g_game.getLocalPlayer()
if player then
player:setShader(event.text)
local data = event.target:getCurrentOption().data
player:setDrawOutfitColor(data.drawColor ~= false)
end
end
function ShaderController:onMountComboBoxChange(event)
local player = g_game.getLocalPlayer()
if player then
player:setMountShader(event.text)
end
end
function ShaderController:open()
self:loadHtml('shaders.html', modules.game_interface.getMapPanel())
for _, opts in pairs(MAP_SHADERS) do
self.ui.mapComboBox:addOption(opts.name, opts)
end
for _, opts in pairs(OUTFIT_SHADERS) do
self.ui.outfitComboBox:addOption(opts.name, opts)
end
for _, opts in pairs(MOUNT_SHADERS) do
self.ui.mountComboBox:addOption(opts.name, opts)
end
for _, opts in pairs(TEXT_SHADERS) do
self.ui.textComboBox:addOption(opts.name, opts)
end
end
function ShaderController:onTextComboBoxChange(event)
-- Apply text shader to local player's name
-- This affects how the player's name is rendered above their character
local player = g_game.getLocalPlayer()
if player then
-- If using widget-based name rendering
local infoWidget = player:getWidgetInformation()
if infoWidget then
infoWidget:setShader(event.text)
end
-- Apply to engine-level name rendering (requires C++ support)
if player.setNameShader then
player:setNameShader(event.text)
end
end
end