mirror of
https://github.com/mehah/otclient
synced 2026-08-15 16:29:06 -04:00
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.
244 lines
6.6 KiB
Lua
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
|