| | | @@ -0,0 +1,449 @@ |
| 1 | + | local defaultOptions = { |
| 2 | + | layout = DEFAULT_LAYOUT, -- set in init.lua |
| 3 | + | vsync = true, |
| 4 | + | showFps = true, |
| 5 | + | showPing = true, |
| 6 | + | fullscreen = false, |
| 7 | + | classicView = false,--not g_app.isMobile(), |
| 8 | + | cacheMap = g_app.isMobile(), |
| 9 | + | classicControl = not g_app.isMobile(), |
| 10 | + | smartWalk = true, |
| 11 | + | autoChaseOverride = true, |
| 12 | + | showStatusMessagesInConsole = true, |
| 13 | + | showEventMessagesInConsole = true, |
| 14 | + | showInfoMessagesInConsole = true, |
| 15 | + | showTimestampsInConsole = true, |
| 16 | + | showLevelsInConsole = true, |
| 17 | + | showPrivateMessagesInConsole = true, |
| 18 | + | showPrivateMessagesOnScreen = true, |
| 19 | + | rightPanels = 4, |
| 20 | + | leftPanels = 0, |
| 21 | + | containerPanel = 8, |
| 22 | + | backgroundFrameRate = 60, |
| 23 | + | enableAudio = true, |
| 24 | + | enableMusicSound = true, |
| 25 | + | musicSoundVolume = 50, |
| 26 | + | botSoundVolume = 100, |
| 27 | + | enableLights = true, |
| 28 | + | floorFading = 500, |
| 29 | + | crosshair = 0, |
| 30 | + | ambientLight = 36, |
| 31 | + | optimizationLevel = 1, |
| 32 | + | displayNames = true, |
| 33 | + | displayShadows = true, |
| 34 | + | displayHealth = true, |
| 35 | + | displayMana = false, |
| 36 | + | displayHealthOnTop = false, |
| 37 | + | showHealthManaCircle = false, |
| 38 | + | hidePlayerBars = true, |
| 39 | + | highlightThingsUnderCursor = false, |
| 40 | + | topHealtManaBar = true, |
| 41 | + | displayText = true, |
| 42 | + | dontStretchShrink = false, |
| 43 | + | turnDelay = 30, |
| 44 | + | hotkeyDelay = 30, |
| 45 | + | animatedTextScale = 0, |
| 46 | + | missilesOpacity = 0, |
| 47 | + | effectsOpacity = 0, |
| 48 | + | wsadWalking = false, |
| 49 | + | walkFirstStepDelay = 200, |
| 50 | + | walkTurnDelay = 100, |
| 51 | + | walkStairsDelay = 50, |
| 52 | + | walkTeleportDelay = 200, |
| 53 | + | walkCtrlTurnDelay = 150, |
| 54 | + | |
| 55 | + | actionBar = true |
| 56 | + | } |
| 57 | + | |
| 58 | + | local optionsWindow |
| 59 | + | --local optionsButton |
| 60 | + | optionsTabBar = nil |
| 61 | + | local options = {} |
| 62 | + | local extraOptions = {} |
| 63 | + | local generalPanel |
| 64 | + | local interfacePanel |
| 65 | + | local consolePanel |
| 66 | + | local graphicsPanel |
| 67 | + | local soundPanel |
| 68 | + | extrasPanel = nil |
| 69 | + | local audioButton |
| 70 | + | |
| 71 | + | function init() |
| 72 | + | -- Clear the retired Dash option, including values saved by older clients. |
| 73 | + | g_settings.set('dash', false) |
| 74 | + | g_game.setMaxPreWalkingSteps(1) |
| 75 | + | for k,v in pairs(defaultOptions) do |
| 76 | + | g_settings.setDefault(k, v) |
| 77 | + | options[k] = v |
| 78 | + | end |
| 79 | + | for _, v in ipairs(g_extras.getAll()) do |
| 80 | + | extraOptions[v] = g_extras.get(v) |
| 81 | + | g_settings.setDefault("extras_" .. v, extraOptions[v]) |
| 82 | + | end |
| 83 | + | |
| 84 | + | |
| 85 | + | optionsWindow = g_ui.displayUI('options') |
| 86 | + | optionsWindow:hide() |
| 87 | + | |
| 88 | + | optionsTabBar = optionsWindow:getChildById('optionsTabBar') |
| 89 | + | optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent')) |
| 90 | + | |
| 91 | + | g_keyboard.bindKeyDown('Ctrl+Shift+F', function() toggleOption('fullscreen') end) |
| 92 | + | g_keyboard.bindKeyDown('Ctrl+N', toggleDisplays) |
| 93 | + | |
| 94 | + | generalPanel = g_ui.loadUI('game') |
| 95 | + | optionsTabBar:addTab(tr('Game'), generalPanel, '/modules/client_options/settings/iconpanel') |
| 96 | + | |
| 97 | + | interfacePanel = g_ui.loadUI('interface') |
| 98 | + | optionsTabBar:addTab(tr('Interface'), interfacePanel, '/modules/client_options/settings/iconpanel') |
| 99 | + | |
| 100 | + | consolePanel = g_ui.loadUI('console') |
| 101 | + | optionsTabBar:addTab(tr('Console'), consolePanel, '/modules/client_options/settings/iconpanel') |
| 102 | + | |
| 103 | + | graphicsPanel = g_ui.loadUI('graphics') |
| 104 | + | optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/modules/client_options/settings/iconpanel') |
| 105 | + | |
| 106 | + | audioPanel = g_ui.loadUI('audio') |
| 107 | + | optionsTabBar:addTab(tr('Audio'), audioPanel, '/modules/client_options/settings/iconpanel') |
| 108 | + | |
| 109 | + | extrasPanel = g_ui.createWidget('OptionPanel') |
| 110 | + | for _, v in ipairs(g_extras.getAll()) do |
| 111 | + | local extrasButton = g_ui.createWidget('OptionCheckBox') |
| 112 | + | extrasButton:setId(v) |
| 113 | + | extrasButton:setText(g_extras.getDescription(v)) |
| 114 | + | extrasPanel:addChild(extrasButton) |
| 115 | + | end |
| 116 | + | --[[if not g_game.getFeature(GameNoDebug) and not g_app.isMobile() then |
| 117 | + | optionsTabBar:addTab(tr('Extras'), extrasPanel, '/images/optionstab/extras') |
| 118 | + | end]]-- |
| 119 | + | |
| 120 | + | --optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle) |
| 121 | + | audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end) |
| 122 | + | audioButton:hide() |
| 123 | + | if g_app.isMobile() then |
| 124 | + | audioButton:hide() |
| 125 | + | end |
| 126 | + | |
| 127 | + | addEvent(function() setup() end) |
| 128 | + | |
| 129 | + | connect(g_game, { onGameStart = online, |
| 130 | + | onGameEnd = offline }) |
| 131 | + | end |
| 132 | + | |
| 133 | + | function terminate() |
| 134 | + | disconnect(g_game, { onGameStart = online, |
| 135 | + | onGameEnd = offline }) |
| 136 | + | |
| 137 | + | g_keyboard.unbindKeyDown('Ctrl+Shift+F') |
| 138 | + | g_keyboard.unbindKeyDown('Ctrl+N') |
| 139 | + | optionsWindow:destroy() |
| 140 | + | --optionsButton:destroy() |
| 141 | + | audioButton:destroy() |
| 142 | + | end |
| 143 | + | |
| 144 | + | function setup() |
| 145 | + | -- load options |
| 146 | + | for k,v in pairs(defaultOptions) do |
| 147 | + | if type(v) == 'boolean' then |
| 148 | + | setOption(k, g_settings.getBoolean(k), true) |
| 149 | + | elseif type(v) == 'number' then |
| 150 | + | setOption(k, g_settings.getNumber(k), true) |
| 151 | + | elseif type(v) == 'string' then |
| 152 | + | setOption(k, g_settings.getString(k), true) |
| 153 | + | end |
| 154 | + | end |
| 155 | + | |
| 156 | + | for _, v in ipairs(g_extras.getAll()) do |
| 157 | + | g_extras.set(v, g_settings.getBoolean("extras_" .. v)) |
| 158 | + | local widget = extrasPanel:recursiveGetChildById(v) |
| 159 | + | if widget then |
| 160 | + | widget:setChecked(g_extras.get(v)) |
| 161 | + | end |
| 162 | + | end |
| 163 | + | |
| 164 | + | if g_game.isOnline() then |
| 165 | + | online() |
| 166 | + | end |
| 167 | + | end |
| 168 | + | |
| 169 | + | function toggle() |
| 170 | + | if optionsWindow:isVisible() then |
| 171 | + | hide() |
| 172 | + | else |
| 173 | + | show() |
| 174 | + | end |
| 175 | + | end |
| 176 | + | |
| 177 | + | function show() |
| 178 | + | optionsWindow:show() |
| 179 | + | optionsWindow:raise() |
| 180 | + | optionsWindow:focus() |
| 181 | + | if modules.game_console then |
| 182 | + | modules.game_console.manageButton('settingsButton', true) |
| 183 | + | end |
| 184 | + | end |
| 185 | + | |
| 186 | + | function hide() |
| 187 | + | optionsWindow:hide() |
| 188 | + | if modules.game_console then |
| 189 | + | modules.game_console.manageButton('settingsButton', false) |
| 190 | + | end |
| 191 | + | end |
| 192 | + | |
| 193 | + | function toggleDisplays() |
| 194 | + | if options['displayNames'] and options['displayHealth'] and options['displayMana'] then |
| 195 | + | setOption('displayNames', false) |
| 196 | + | elseif options['displayHealth'] then |
| 197 | + | setOption('displayHealth', false) |
| 198 | + | setOption('displayMana', false) |
| 199 | + | else |
| 200 | + | if not options['displayNames'] and not options['displayHealth'] then |
| 201 | + | setOption('displayNames', true) |
| 202 | + | else |
| 203 | + | setOption('displayHealth', true) |
| 204 | + | setOption('displayMana', true) |
| 205 | + | end |
| 206 | + | end |
| 207 | + | end |
| 208 | + | |
| 209 | + | function toggleOption(key) |
| 210 | + | setOption(key, not getOption(key)) |
| 211 | + | end |
| 212 | + | |
| 213 | + | function setOption(key, value, force) |
| 214 | + | if extraOptions[key] ~= nil then |
| 215 | + | g_extras.set(key, value) |
| 216 | + | g_settings.set("extras_" .. key, value) |
| 217 | + | if key == "debugProxy" and modules.game_proxy then |
| 218 | + | if value then |
| 219 | + | modules.game_proxy.show() |
| 220 | + | else |
| 221 | + | modules.game_proxy.hide() |
| 222 | + | end |
| 223 | + | end |
| 224 | + | return |
| 225 | + | end |
| 226 | + | |
| 227 | + | if modules.game_interface == nil then |
| 228 | + | return |
| 229 | + | end |
| 230 | + | |
| 231 | + | if not force and options[key] == value then return end |
| 232 | + | local gameMapPanel = modules.game_interface.getMapPanel() |
| 233 | + | |
| 234 | + | if key == 'vsync' then |
| 235 | + | g_window.setVerticalSync(value) |
| 236 | + | elseif key == 'showFps' then |
| 237 | + | if g_game.isOnline() then |
| 238 | + | modules.client_topmenu.setFpsVisible(value) |
| 239 | + | if modules.game_stats and modules.game_stats.ui.fps then |
| 240 | + | modules.game_stats.ui.fps:setVisible(value) |
| 241 | + | end |
| 242 | + | end |
| 243 | + | elseif key == 'showPing' then |
| 244 | + | modules.client_topmenu.setPingVisible(value) |
| 245 | + | if modules.game_stats and modules.game_stats.ui.ping then |
| 246 | + | modules.game_stats.ui.ping:setVisible(value) |
| 247 | + | end |
| 248 | + | elseif key == 'fullscreen' then |
| 249 | + | g_window.setFullscreen(value) |
| 250 | + | elseif key == 'enableAudio' then |
| 251 | + | if g_sounds ~= nil then |
| 252 | + | g_sounds.setAudioEnabled(value) |
| 253 | + | end |
| 254 | + | if value then |
| 255 | + | audioButton:setIcon('/images/topbuttons/audio') |
| 256 | + | else |
| 257 | + | audioButton:setIcon('/images/topbuttons/audio_mute') |
| 258 | + | end |
| 259 | + | elseif key == 'enableMusicSound' then |
| 260 | + | if g_sounds ~= nil then |
| 261 | + | g_sounds.getChannel(SoundChannels.Music):setEnabled(value) |
| 262 | + | end |
| 263 | + | elseif key == 'musicSoundVolume' then |
| 264 | + | if g_sounds ~= nil then |
| 265 | + | g_sounds.getChannel(SoundChannels.Music):setGain(value/100) |
| 266 | + | end |
| 267 | + | audioPanel:getChildById('musicSoundVolumeBG'):getChildById('musicSoundVolumeLabelBG'):setText(tr('%d', value)) |
| 268 | + | local valueScroll = ((value*200)/100) |
| 269 | + | audioPanel:getChildById('musicSoundVolumeBG'):getChildById('musicSoundVolume'):getChildById('activeScroll'):setWidth(valueScroll) |
| 270 | + | elseif key == 'botSoundVolume' then |
| 271 | + | if g_sounds ~= nil then |
| 272 | + | g_sounds.getChannel(SoundChannels.Bot):setGain(value/100) |
| 273 | + | end |
| 274 | + | audioPanel:getChildById('botSoundVolumeBG'):getChildById('botSoundVolumeLabelBG'):setText(tr('%d', value)) |
| 275 | + | local valueScroll = ((value*200)/100) |
| 276 | + | audioPanel:getChildById('botSoundVolumeBG'):getChildById('botSoundVolume'):getChildById('activeScroll'):setWidth(valueScroll) |
| 277 | + | elseif key == 'showHealthManaCircle' then |
| 278 | + | if modules.game_healthinfo then |
| 279 | + | if modules.game_healthinfo.healthCircle then |
| 280 | + | modules.game_healthinfo.healthCircle:setVisible(value) |
| 281 | + | end |
| 282 | + | if modules.game_healthinfo.healthCircleFront then |
| 283 | + | modules.game_healthinfo.healthCircleFront:setVisible(value) |
| 284 | + | end |
| 285 | + | if modules.game_healthinfo.manaCircle then |
| 286 | + | modules.game_healthinfo.manaCircle:setVisible(value) |
| 287 | + | end |
| 288 | + | if modules.game_healthinfo.manaCircleFront then |
| 289 | + | modules.game_healthinfo.manaCircleFront:setVisible(value) |
| 290 | + | end |
| 291 | + | end |
| 292 | + | elseif key == 'backgroundFrameRate' then |
| 293 | + | local text, v = value, value |
| 294 | + | if value <= 0 or value >= 201 then text = 'max' v = 60 end -- Limitamos a 60 FPS máximo para proteger la GPU |
| 295 | + | graphicsPanel:getChildById('backgroundFrameRateBG'):getChildById('backgroundFrameRateLabelBG'):setText(tr('%s', text)) |
| 296 | + | local valueScroll = ((value*200)/201) |
| 297 | + | graphicsPanel:getChildById('backgroundFrameRateBG'):getChildById('backgroundFrameRate'):getChildById('activeScroll'):setWidth(valueScroll) |
| 298 | + | g_app.setMaxFps(v) |
| 299 | + | elseif key == 'enableLights' then |
| 300 | + | gameMapPanel:setDrawLights(value and options['ambientLight'] < 100) |
| 301 | + | graphicsPanel:getChildById('ambientLightBG'):getChildById('ambientLight'):setEnabled(value) |
| 302 | + | elseif key == 'floorFading' then |
| 303 | + | gameMapPanel:setFloorFading(value) |
| 304 | + | interfacePanel:getChildById('floorFadingBG'):getChildById('floorFadingLabelBG'):setText(tr('%s ms', value)) |
| 305 | + | local valueScroll = ((value*200)/2000) |
| 306 | + | interfacePanel:getChildById('floorFadingBG'):getChildById('floorFading'):getChildById('activeScroll'):setWidth(valueScroll) |
| 307 | + | elseif key == 'crosshair' then |
| 308 | + | if value == 1 then |
| 309 | + | gameMapPanel:setCrosshair("") |
| 310 | + | elseif value == 2 then |
| 311 | + | gameMapPanel:setCrosshair("/images/crosshair/default.png") |
| 312 | + | elseif value == 3 then |
| 313 | + | gameMapPanel:setCrosshair("/images/crosshair/full.png") |
| 314 | + | end |
| 315 | + | elseif key == 'ambientLight' then |
| 316 | + | graphicsPanel:getChildById('ambientLightBG'):getChildById('ambientLightLabelBG'):setText(tr('%s%%', value)) |
| 317 | + | gameMapPanel:setMinimumAmbientLight(value/100) |
| 318 | + | gameMapPanel:setDrawLights(options['enableLights'] and value < 100) |
| 319 | + | local valueScroll = ((value*200)/100) |
| 320 | + | graphicsPanel:getChildById('ambientLightBG'):getChildById('ambientLight'):getChildById('activeScroll'):setWidth(valueScroll) |
| 321 | + | elseif key == 'missilesOpacity' then |
| 322 | + | graphicsPanel:getChildById('missilesOpacityBG'):getChildById('missilesOpacityLabelBG'):setText(tr('%s%%', value)) |
| 323 | + | local valueScroll = ((value*200)/100) |
| 324 | + | graphicsPanel:getChildById('missilesOpacityBG'):getChildById('missilesOpacity'):getChildById('activeScroll'):setWidth(valueScroll) |
| 325 | + | setMissilesOpacity(1 - value / 100) |
| 326 | + | elseif key == 'effectsOpacity' then |
| 327 | + | graphicsPanel:getChildById('effectsOpacityBG'):getChildById('effectsOpacityLabelBG'):setText(tr('%s%%', value)) |
| 328 | + | local valueScroll = ((value*200)/100) |
| 329 | + | graphicsPanel:getChildById('effectsOpacityBG'):getChildById('effectsOpacity'):getChildById('activeScroll'):setWidth(valueScroll) |
| 330 | + | if g_map and g_map.setEffectsOpacity then |
| 331 | + | g_map.setEffectsOpacity(1 - value / 100) |
| 332 | + | end |
| 333 | + | elseif key == 'optimizationLevel' then |
| 334 | + | g_adaptiveRenderer.setLevel(value - 2) |
| 335 | + | elseif key == 'displayNames' then |
| 336 | + | gameMapPanel:setDrawNames(value) |
| 337 | + | elseif key == 'displayShadows' then |
| 338 | + | if modules.game_creatureinfo and modules.game_creatureinfo.refreshShadows then |
| 339 | + | scheduleEvent(function() modules.game_creatureinfo.refreshShadows(value) end, 10) |
| 340 | + | end |
| 341 | + | elseif key == 'displayHealth' then |
| 342 | + | gameMapPanel:setDrawHealthBars(value) |
| 343 | + | elseif key == 'displayMana' then |
| 344 | + | gameMapPanel:setDrawManaBar(value) |
| 345 | + | elseif key == 'displayHealthOnTop' then |
| 346 | + | gameMapPanel:setDrawHealthBarsOnTop(value) |
| 347 | + | elseif key == 'hidePlayerBars' then |
| 348 | + | gameMapPanel:setDrawPlayerBars(value) |
| 349 | + | elseif key == 'topHealtManaBar' then |
| 350 | + | if modules.game_healthinfo then |
| 351 | + | if modules.game_healthinfo.topHealthBar then |
| 352 | + | modules.game_healthinfo.topHealthBar:setVisible(value) |
| 353 | + | end |
| 354 | + | if modules.game_healthinfo.topManaBar then |
| 355 | + | modules.game_healthinfo.topManaBar:setVisible(value) |
| 356 | + | end |
| 357 | + | end |
| 358 | + | elseif key == 'displayText' then |
| 359 | + | gameMapPanel:setDrawTexts(value) |
| 360 | + | elseif key == 'dontStretchShrink' then |
| 361 | + | addEvent(function() |
| 362 | + | modules.game_interface.updateStretchShrink() |
| 363 | + | end) |
| 364 | + | elseif key == 'wsadWalking' then |
| 365 | + | if modules.game_console then |
| 366 | + | modules.game_console.toggleChatByOptions(value) |
| 367 | + | end |
| 368 | + | end |
| 369 | + | |
| 370 | + | -- change value for keybind updates |
| 371 | + | for _,panel in pairs(optionsTabBar:getTabsPanel()) do |
| 372 | + | local widget = panel:recursiveGetChildById(key) |
| 373 | + | if widget then |
| 374 | + | if widget:getStyle().__class == 'UICheckBox' then |
| 375 | + | widget:setChecked(value) |
| 376 | + | elseif widget:getStyle().__class == 'UIScrollBar' then |
| 377 | + | widget:setValue(value) |
| 378 | + | elseif widget:getStyle().__class == 'UIComboBox' then |
| 379 | + | if type(value) == "string" then |
| 380 | + | widget:setCurrentOption(value, true) |
| 381 | + | break |
| 382 | + | end |
| 383 | + | if value == nil or value < 1 then |
| 384 | + | value = 1 |
| 385 | + | end |
| 386 | + | if widget.currentIndex ~= value then |
| 387 | + | widget:setCurrentIndex(value, true) |
| 388 | + | end |
| 389 | + | end |
| 390 | + | break |
| 391 | + | end |
| 392 | + | end |
| 393 | + | |
| 394 | + | g_settings.set(key, value) |
| 395 | + | options[key] = value |
| 396 | + | |
| 397 | + | if key == 'classicView' or key == 'rightPanels' or key == 'leftPanels' or key == 'cacheMap' then |
| 398 | + | modules.game_interface.refreshViewMode() |
| 399 | + | elseif key == 'actionBar' then |
| 400 | + | if modules.game_menu and modules.game_menu.setHudActionBarEnabled then |
| 401 | + | modules.game_menu.setHudActionBarEnabled(value) |
| 402 | + | end |
| 403 | + | if modules.game_spellbar and modules.game_spellbar.setBarEnabled then |
| 404 | + | modules.game_spellbar.setBarEnabled(value) |
| 405 | + | end |
| 406 | + | end |
| 407 | + | end |
| 408 | + | |
| 409 | + | function getOption(key) |
| 410 | + | return options[key] |
| 411 | + | end |
| 412 | + | |
| 413 | + | function addTab(name, panel, icon) |
| 414 | + | optionsTabBar:addTab(name, panel, icon) |
| 415 | + | end |
| 416 | + | |
| 417 | + | function addButton(name, func, icon) |
| 418 | + | optionsTabBar:addButton(name, func, icon) |
| 419 | + | end |
| 420 | + | |
| 421 | + | -- hide/show |
| 422 | + | |
| 423 | + | function online() |
| 424 | + | setLightOptionsVisibility(not g_game.getFeature(GameForceLight)) |
| 425 | + | audioButton:show() |
| 426 | + | end |
| 427 | + | |
| 428 | + | function offline() |
| 429 | + | setLightOptionsVisibility(true) |
| 430 | + | audioButton:hide() |
| 431 | + | end |
| 432 | + | |
| 433 | + | -- classic view |
| 434 | + | |
| 435 | + | -- graphics |
| 436 | + | function setLightOptionsVisibility(value) |
| 437 | + | graphicsPanel:getChildById('enableLights'):setEnabled(value) |
| 438 | + | graphicsPanel:getChildById('ambientLightBG'):getChildById('ambientLightLabelBG'):setEnabled(value) |
| 439 | + | graphicsPanel:getChildById('ambientLightBG'):getChildById('ambientLight'):setEnabled(value) |
| 440 | + | interfacePanel:getChildById('floorFadingBG'):getChildById('floorFading'):setEnabled(value) |
| 441 | + | interfacePanel:getChildById('floorFadingLabel'):setEnabled(value) |
| 442 | + | interfacePanel:getChildById('floorFadingLabel2'):setEnabled(value) |
| 443 | + | end |
| 444 | + | |
| 445 | + | -- Definición de la función setMissilesOpacity |
| 446 | + | function setMissilesOpacity(opacity) |
| 447 | + | -- Lógica para establecer la opacidad de los misiles |
| 448 | + | print("Opacidad de misiles establecida a " .. opacity) |
| 449 | + | end |