@@ -11,7 +11,7 @@ require.config({ | |||
helpers: 'js/misc/helpers', | |||
particles: 'plugins/pixi.particles.min', | |||
pixi: 'https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min', | |||
howler: 'https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.2/howler.core.min' | |||
howler: 'https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.3/howler.core.min' | |||
}, | |||
shim: { | |||
howler: { | |||
@@ -10,7 +10,9 @@ define([ | |||
playAudio: true, | |||
qualityIndicators: 'off', | |||
unusableIndicators: 'off', | |||
rememberChatChannel: true | |||
rememberChatChannel: true, | |||
soundVolume: 100, | |||
musicVolume: 100 | |||
}; | |||
const valueChains = { | |||
@@ -54,8 +56,12 @@ define([ | |||
if (currentValue === '{unset}') | |||
return; | |||
const morphedValue = valueChains[key] ? currentValue : (currentValue === 'true'); | |||
config[key] = morphedValue; | |||
if (['true', 'false'].includes(currentValue)) | |||
config[key] = currentValue === 'true'; | |||
else if (~~currentValue === parseInt(currentValue)) | |||
config[key] = ~~currentValue; | |||
else | |||
config[key] = currentValue; | |||
}; | |||
Object.keys(config).forEach(key => loadValue(key) ); | |||
@@ -11,11 +11,17 @@ define([ | |||
config, | |||
globals | |||
) { | |||
const globalVolume = 0.3; | |||
let soundVolume = config.soundVolume; | |||
let musicVolume = config.musicVolume; | |||
const globalScopes = ['ui']; | |||
const minDistance = 10; | |||
const globalVolume = 0.3; | |||
const fadeDuration = 1800; | |||
window.Howler.volume(globalVolume); | |||
return { | |||
sounds: [], | |||
@@ -26,6 +32,7 @@ define([ | |||
init: function () { | |||
events.on('onToggleAudio', this.onToggleAudio.bind(this)); | |||
events.on('onPlaySound', this.playSound.bind(this)); | |||
events.on('onManipulateVolume', this.onManipulateVolume.bind(this)); | |||
const { clientConfig: { sounds: loadSounds } } = globals; | |||
@@ -65,14 +72,15 @@ define([ | |||
if (!soundEntry) | |||
return; | |||
soundEntry.sound.play(); | |||
const { sound } = soundEntry; | |||
sound.volume(soundVolume / 100); | |||
sound.play(); | |||
}, | |||
playSoundHelper: function (soundEntry, volume) { | |||
const { sound } = soundEntry; | |||
volume *= globalVolume; | |||
if (!sound) { | |||
const { file, loop } = soundEntry; | |||
@@ -81,6 +89,10 @@ define([ | |||
return; | |||
} | |||
soundEntry.volume = volume; | |||
volume *= (soundVolume / 100); | |||
if (sound.playing()) { | |||
if (sound.volume() === volume) | |||
return; | |||
@@ -98,22 +110,26 @@ define([ | |||
if (!sound) { | |||
const { file, loop } = soundEntry; | |||
soundEntry.sound = this.loadSound(file, loop, true, globalVolume); | |||
soundEntry.volume = musicVolume; | |||
soundEntry.sound = this.loadSound(file, loop, true, musicVolume / 100); | |||
return; | |||
} | |||
if (!sound.playing()) { | |||
soundEntry.volume = 0; | |||
sound.volume(0); | |||
sound.play(); | |||
} | |||
if (this.currentMusic === soundEntry) | |||
if (this.currentMusic === soundEntry && sound.volume() === musicVolume / 100) | |||
return; | |||
soundEntry.volume = 1; | |||
this.currentMusic = soundEntry; | |||
sound.fade(sound.volume(), globalVolume, fadeDuration); | |||
sound.fade(sound.volume(), (musicVolume / 100), fadeDuration); | |||
}, | |||
stopSoundHelper: function (soundEntry) { | |||
@@ -247,6 +263,23 @@ define([ | |||
if (!window.player) | |||
return; | |||
const { player: { x, y } } = window; | |||
this.update(x, y); | |||
}, | |||
onManipulateVolume: function ({ soundType, delta }) { | |||
if (soundType === 'sound') | |||
soundVolume = Math.max(0, Math.min(100, soundVolume + delta)); | |||
else if (soundType === 'music') | |||
musicVolume = Math.max(0, Math.min(100, musicVolume + delta)); | |||
const volume = soundType === 'sound' ? soundVolume : musicVolume; | |||
events.emit('onVolumeChange', { | |||
soundType, | |||
volume | |||
}); | |||
const { player: { x, y } } = window; | |||
this.update(x, y); | |||
} | |||
@@ -36,22 +36,37 @@ define([ | |||
this.find('.item.events .name').on('click', this.toggleEvents.bind(this)); | |||
this.find('.item.quality .name').on('click', this.toggleQualityIndicators.bind(this)); | |||
this.find('.item.unusable .name').on('click', this.toggleUnusableIndicators.bind(this)); | |||
this.find('.item.audio .name').on('click', this.toggleAudio.bind(this)); | |||
this.find('.item.lastChannel .name').on('click', this.toggleLastChannel.bind(this)); | |||
this.find('.item.volume .btn').on('click', this.modifyVolume.bind(this)); | |||
this.onEvent('onResize', this.onResize.bind(this)); | |||
this.onEvent('onUiKeyDown', this.onKeyDown.bind(this)); | |||
this.onEvent('onToggleAudio', this.onToggleAudio.bind(this)); | |||
this.onEvent('onToggleNameplates', this.onToggleNameplates.bind(this)); | |||
this.onEvent('onToggleQualityIndicators', this.onToggleQualityIndicators.bind(this)); | |||
this.onEvent('onToggleUnusableIndicators', this.onToggleUnusableIndicators.bind(this)); | |||
this.onEvent('onToggleEventsVisibility', this.onToggleEventsVisibility.bind(this)); | |||
this.onEvent('onToggleQuestsVisibility', this.onToggleQuestsVisibility.bind(this)); | |||
this.onEvent('onToggleLastChannel', this.onToggleLastChannel.bind(this)); | |||
this.onEvent('onVolumeChange', this.onVolumeChange.bind(this)); | |||
this.find('.item').on('click', events.emit.bind(events, 'onClickOptionsItem')); | |||
}, | |||
modifyVolume: function (e) { | |||
const el = $(e.target); | |||
const isIncrease = el.hasClass('increase'); | |||
const delta = isIncrease ? 10 : -10; | |||
const soundType = el.parent().parent().hasClass('sound') ? 'sound' : 'music'; | |||
events.emit('onManipulateVolume', { | |||
soundType, | |||
delta | |||
}); | |||
}, | |||
toggleUnusableIndicators: function () { | |||
config.toggle('unusableIndicators'); | |||
@@ -154,6 +169,26 @@ define([ | |||
this.find('.item.lastChannel .value').html(newValue); | |||
}, | |||
onVolumeChange: function ({ soundType, volume }) { | |||
const item = this.find(`.item.volume.${soundType}`); | |||
item.find('.value').html(volume); | |||
const tickLeftPosition = `${volume}%`; | |||
item.find('.tick').css({ left: tickLeftPosition }); | |||
const btnDecrease = item.find('.btn.decrease').removeClass('disabled'); | |||
const btnIncrease = item.find('.btn.increase').removeClass('disabled'); | |||
if (volume === 0) | |||
btnDecrease.addClass('disabled'); | |||
else if (volume === 100) | |||
btnIncrease.addClass('disabled'); | |||
const configKey = `${soundType}Volume`; | |||
config.set(configKey, volume); | |||
}, | |||
build: function () { | |||
this.onToggleNameplates(config.showNames); | |||
this.onToggleAudio(config.playAudio); | |||
@@ -162,6 +197,18 @@ define([ | |||
this.onToggleQualityIndicators(config.qualityIndicators); | |||
this.onToggleUnusableIndicators(config.unusableIndicators); | |||
this.onToggleLastChannel(config.rememberChatChannel); | |||
console.log(config); | |||
this.onVolumeChange({ | |||
soundType: 'sound', | |||
volume: config.soundVolume | |||
}); | |||
this.onVolumeChange({ | |||
soundType: 'music', | |||
volume: config.musicVolume | |||
}); | |||
}, | |||
onAfterShow: function () { | |||
@@ -71,6 +71,71 @@ | |||
padding-right: 10px; | |||
} | |||
&.volume { | |||
flex-wrap: wrap; | |||
height: 60px; | |||
.name, | |||
.value { | |||
width: 50%; | |||
height: 30px; | |||
} | |||
.slider { | |||
padding: 0px 10px; | |||
width: 100%; | |||
height: 30px; | |||
display: flex; | |||
position: relative; | |||
.btn { | |||
width: 30px; | |||
margin-top: 5px; | |||
height: calc(100% - 10px); | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
color: @white; | |||
background-color: @blackA; | |||
padding-top: unset; | |||
&:first-child { | |||
margin-right: 10px; | |||
} | |||
&:last-child { | |||
margin-left: 10px; | |||
} | |||
&:hover { | |||
background-color: @grayD; | |||
} | |||
} | |||
.bar { | |||
width: 100%; | |||
background-color: @blueD; | |||
border-top: 10px solid @blackC; | |||
border-bottom: 10px solid @blackC; | |||
height: 100%; | |||
position: relative; | |||
.tick { | |||
position: absolute; | |||
width: 5px; | |||
height: 20px; | |||
top: -5px; | |||
left: 100%; | |||
background-color: @blueA; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -9,9 +9,27 @@ | |||
<div class="name">Fullscreen</div> | |||
<div class="value">Off</div> | |||
</div> | |||
<div class="item audio"> | |||
<div class="name">Audio</div> | |||
<div class="value">On</div> | |||
<div class="item volume sound"> | |||
<div class="name">Sound Volume</div> | |||
<div class="value">100</div> | |||
<div class="slider"> | |||
<div class="btn decrease">-</div> | |||
<div class="bar"> | |||
<div class="tick"></div> | |||
</div> | |||
<div class="btn increase">+</div> | |||
</div> | |||
</div> | |||
<div class="item volume music"> | |||
<div class="name">Music Volume</div> | |||
<div class="value">100</div> | |||
<div class="slider"> | |||
<div class="btn decrease">-</div> | |||
<div class="bar"> | |||
<div class="tick"></div> | |||
</div> | |||
<div class="btn increase">+</div> | |||
</div> | |||
</div> | |||
<div class="heading hud">HUD</div> | |||
<div class="item nameplates"> | |||