diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 0dd603f..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 3252725..ce94b37 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .idea lang/.DS_Store .DS_Store +node_modules diff --git a/audio/asteroid-hit-1.flac b/audio/asteroid-hit-1.flac new file mode 100644 index 0000000..c9925aa Binary files /dev/null and b/audio/asteroid-hit-1.flac differ diff --git a/audio/asteroid-hit-2.flac b/audio/asteroid-hit-2.flac new file mode 100644 index 0000000..ae19a76 Binary files /dev/null and b/audio/asteroid-hit-2.flac differ diff --git a/audio/asteroid-hit-3.flac b/audio/asteroid-hit-3.flac new file mode 100644 index 0000000..67dfedf Binary files /dev/null and b/audio/asteroid-hit-3.flac differ diff --git a/audio/asteroid-hit-4.flac b/audio/asteroid-hit-4.flac new file mode 100644 index 0000000..55b6420 Binary files /dev/null and b/audio/asteroid-hit-4.flac differ diff --git a/audio/asteroid-hit-5.flac b/audio/asteroid-hit-5.flac new file mode 100644 index 0000000..df4ab96 Binary files /dev/null and b/audio/asteroid-hit-5.flac differ diff --git a/audio/asteroid-hit-6.flac b/audio/asteroid-hit-6.flac new file mode 100644 index 0000000..a40bf00 Binary files /dev/null and b/audio/asteroid-hit-6.flac differ diff --git a/audio/asteroid-hit-7.flac b/audio/asteroid-hit-7.flac new file mode 100644 index 0000000..35e785d Binary files /dev/null and b/audio/asteroid-hit-7.flac differ diff --git a/audio/asteroid-hit-8.flac b/audio/asteroid-hit-8.flac new file mode 100644 index 0000000..5a640bf Binary files /dev/null and b/audio/asteroid-hit-8.flac differ diff --git a/audio/build.flac b/audio/build.flac new file mode 100644 index 0000000..488089a Binary files /dev/null and b/audio/build.flac differ diff --git a/audio/buy.flac b/audio/buy.flac new file mode 100644 index 0000000..8039406 Binary files /dev/null and b/audio/buy.flac differ diff --git a/audio/check-traps.flac b/audio/check-traps.flac new file mode 100644 index 0000000..7650ba7 Binary files /dev/null and b/audio/check-traps.flac differ diff --git a/audio/craft.flac b/audio/craft.flac new file mode 100644 index 0000000..148fe5f Binary files /dev/null and b/audio/craft.flac differ diff --git a/audio/crash.flac b/audio/crash.flac new file mode 100644 index 0000000..95ba4fa Binary files /dev/null and b/audio/crash.flac differ diff --git a/audio/death.flac b/audio/death.flac new file mode 100644 index 0000000..57b980f Binary files /dev/null and b/audio/death.flac differ diff --git a/audio/dusty-path.flac b/audio/dusty-path.flac new file mode 100644 index 0000000..29185e1 Binary files /dev/null and b/audio/dusty-path.flac differ diff --git a/audio/eat-meat.flac b/audio/eat-meat.flac new file mode 100644 index 0000000..fe98308 Binary files /dev/null and b/audio/eat-meat.flac differ diff --git a/audio/embark.flac b/audio/embark.flac new file mode 100644 index 0000000..f95b7c0 Binary files /dev/null and b/audio/embark.flac differ diff --git a/audio/encounter-tier-1.flac b/audio/encounter-tier-1.flac new file mode 100644 index 0000000..91cd213 Binary files /dev/null and b/audio/encounter-tier-1.flac differ diff --git a/audio/encounter-tier-2.flac b/audio/encounter-tier-2.flac new file mode 100644 index 0000000..fe7bc79 Binary files /dev/null and b/audio/encounter-tier-2.flac differ diff --git a/audio/encounter-tier-3.flac b/audio/encounter-tier-3.flac new file mode 100644 index 0000000..8d8b84b Binary files /dev/null and b/audio/encounter-tier-3.flac differ diff --git a/audio/ending.flac b/audio/ending.flac new file mode 100644 index 0000000..263a6b0 Binary files /dev/null and b/audio/ending.flac differ diff --git a/audio/event-beast-attack.flac b/audio/event-beast-attack.flac new file mode 100644 index 0000000..b373ad1 Binary files /dev/null and b/audio/event-beast-attack.flac differ diff --git a/audio/event-beggar.flac b/audio/event-beggar.flac new file mode 100644 index 0000000..e4b4b7a Binary files /dev/null and b/audio/event-beggar.flac differ diff --git a/audio/event-hut-fire.flac b/audio/event-hut-fire.flac new file mode 100644 index 0000000..7fa6671 Binary files /dev/null and b/audio/event-hut-fire.flac differ diff --git a/audio/event-mysterious-wanderer.flac b/audio/event-mysterious-wanderer.flac new file mode 100644 index 0000000..039711f Binary files /dev/null and b/audio/event-mysterious-wanderer.flac differ diff --git a/audio/event-noises-inside.flac b/audio/event-noises-inside.flac new file mode 100644 index 0000000..10f52fd Binary files /dev/null and b/audio/event-noises-inside.flac differ diff --git a/audio/event-noises-outside.flac b/audio/event-noises-outside.flac new file mode 100644 index 0000000..ba8abd7 Binary files /dev/null and b/audio/event-noises-outside.flac differ diff --git a/audio/event-nomad.flac b/audio/event-nomad.flac new file mode 100644 index 0000000..2a0ccec Binary files /dev/null and b/audio/event-nomad.flac differ diff --git a/audio/event-plague.flac b/audio/event-plague.flac new file mode 100644 index 0000000..ca932bb Binary files /dev/null and b/audio/event-plague.flac differ diff --git a/audio/event-ruined-trap.flac b/audio/event-ruined-trap.flac new file mode 100644 index 0000000..6c0a793 Binary files /dev/null and b/audio/event-ruined-trap.flac differ diff --git a/audio/event-scout.flac b/audio/event-scout.flac new file mode 100644 index 0000000..f805584 Binary files /dev/null and b/audio/event-scout.flac differ diff --git a/audio/event-shady-builder.flac b/audio/event-shady-builder.flac new file mode 100644 index 0000000..3f3a446 Binary files /dev/null and b/audio/event-shady-builder.flac differ diff --git a/audio/event-sick-man.flac b/audio/event-sick-man.flac new file mode 100644 index 0000000..78edf25 Binary files /dev/null and b/audio/event-sick-man.flac differ diff --git a/audio/event-sickness.flac b/audio/event-sickness.flac new file mode 100644 index 0000000..2bc3ce3 Binary files /dev/null and b/audio/event-sickness.flac differ diff --git a/audio/event-soldier-attack.flac b/audio/event-soldier-attack.flac new file mode 100644 index 0000000..25e240a Binary files /dev/null and b/audio/event-soldier-attack.flac differ diff --git a/audio/event-thief.flac b/audio/event-thief.flac new file mode 100644 index 0000000..3e892d3 Binary files /dev/null and b/audio/event-thief.flac differ diff --git a/audio/event-wandering-master.flac b/audio/event-wandering-master.flac new file mode 100644 index 0000000..08b12f7 Binary files /dev/null and b/audio/event-wandering-master.flac differ diff --git a/audio/fire-burning.flac b/audio/fire-burning.flac new file mode 100644 index 0000000..4001198 Binary files /dev/null and b/audio/fire-burning.flac differ diff --git a/audio/fire-dead.flac b/audio/fire-dead.flac new file mode 100644 index 0000000..ef908ad Binary files /dev/null and b/audio/fire-dead.flac differ diff --git a/audio/fire-flickering.flac b/audio/fire-flickering.flac new file mode 100644 index 0000000..ac4099f Binary files /dev/null and b/audio/fire-flickering.flac differ diff --git a/audio/fire-roaring.flac b/audio/fire-roaring.flac new file mode 100644 index 0000000..1bf5cfd Binary files /dev/null and b/audio/fire-roaring.flac differ diff --git a/audio/fire-smoldering.flac b/audio/fire-smoldering.flac new file mode 100644 index 0000000..bb05cef Binary files /dev/null and b/audio/fire-smoldering.flac differ diff --git a/audio/footsteps-1.flac b/audio/footsteps-1.flac new file mode 100644 index 0000000..17cd3c3 Binary files /dev/null and b/audio/footsteps-1.flac differ diff --git a/audio/footsteps-2.flac b/audio/footsteps-2.flac new file mode 100644 index 0000000..bb0918c Binary files /dev/null and b/audio/footsteps-2.flac differ diff --git a/audio/footsteps-3.flac b/audio/footsteps-3.flac new file mode 100644 index 0000000..a04f571 Binary files /dev/null and b/audio/footsteps-3.flac differ diff --git a/audio/footsteps-4.flac b/audio/footsteps-4.flac new file mode 100644 index 0000000..c5d232c Binary files /dev/null and b/audio/footsteps-4.flac differ diff --git a/audio/footsteps-5.flac b/audio/footsteps-5.flac new file mode 100644 index 0000000..42046a8 Binary files /dev/null and b/audio/footsteps-5.flac differ diff --git a/audio/footsteps-6.flac b/audio/footsteps-6.flac new file mode 100644 index 0000000..5c29363 Binary files /dev/null and b/audio/footsteps-6.flac differ diff --git a/audio/gather-wood.flac b/audio/gather-wood.flac new file mode 100644 index 0000000..3ecb921 Binary files /dev/null and b/audio/gather-wood.flac differ diff --git a/audio/landmark-battlefield.flac b/audio/landmark-battlefield.flac new file mode 100644 index 0000000..83bedae Binary files /dev/null and b/audio/landmark-battlefield.flac differ diff --git a/audio/landmark-borehole.flac b/audio/landmark-borehole.flac new file mode 100644 index 0000000..726641e Binary files /dev/null and b/audio/landmark-borehole.flac differ diff --git a/audio/landmark-cave.flac b/audio/landmark-cave.flac new file mode 100644 index 0000000..6d2e325 Binary files /dev/null and b/audio/landmark-cave.flac differ diff --git a/audio/landmark-city.flac b/audio/landmark-city.flac new file mode 100644 index 0000000..bfa8627 Binary files /dev/null and b/audio/landmark-city.flac differ diff --git a/audio/landmark-coalmine.flac b/audio/landmark-coalmine.flac new file mode 100644 index 0000000..a6f9e0a Binary files /dev/null and b/audio/landmark-coalmine.flac differ diff --git a/audio/landmark-crashed-ship.flac b/audio/landmark-crashed-ship.flac new file mode 100644 index 0000000..9252fca Binary files /dev/null and b/audio/landmark-crashed-ship.flac differ diff --git a/audio/landmark-destroyed-village.flac b/audio/landmark-destroyed-village.flac new file mode 100644 index 0000000..00f6153 Binary files /dev/null and b/audio/landmark-destroyed-village.flac differ diff --git a/audio/landmark-friendly-outpost.flac b/audio/landmark-friendly-outpost.flac new file mode 100644 index 0000000..aaded16 Binary files /dev/null and b/audio/landmark-friendly-outpost.flac differ diff --git a/audio/landmark-house.flac b/audio/landmark-house.flac new file mode 100644 index 0000000..54cca37 Binary files /dev/null and b/audio/landmark-house.flac differ diff --git a/audio/landmark-ironmine.flac b/audio/landmark-ironmine.flac new file mode 100644 index 0000000..912e66c Binary files /dev/null and b/audio/landmark-ironmine.flac differ diff --git a/audio/landmark-sulphurmine.flac b/audio/landmark-sulphurmine.flac new file mode 100644 index 0000000..76566c6 Binary files /dev/null and b/audio/landmark-sulphurmine.flac differ diff --git a/audio/landmark-swamp.flac b/audio/landmark-swamp.flac new file mode 100644 index 0000000..54835b1 Binary files /dev/null and b/audio/landmark-swamp.flac differ diff --git a/audio/landmark-town.flac b/audio/landmark-town.flac new file mode 100644 index 0000000..147d28b Binary files /dev/null and b/audio/landmark-town.flac differ diff --git a/audio/large-village.flac b/audio/large-village.flac new file mode 100644 index 0000000..784cc01 Binary files /dev/null and b/audio/large-village.flac differ diff --git a/audio/lift-off.flac b/audio/lift-off.flac new file mode 100644 index 0000000..2d71374 Binary files /dev/null and b/audio/lift-off.flac differ diff --git a/audio/light-fire.flac b/audio/light-fire.flac new file mode 100644 index 0000000..41f16dc Binary files /dev/null and b/audio/light-fire.flac differ diff --git a/audio/lonely-hut.flac b/audio/lonely-hut.flac new file mode 100644 index 0000000..c44a55a Binary files /dev/null and b/audio/lonely-hut.flac differ diff --git a/audio/modest-village.flac b/audio/modest-village.flac new file mode 100644 index 0000000..5f9f5be Binary files /dev/null and b/audio/modest-village.flac differ diff --git a/audio/raucous-village.flac b/audio/raucous-village.flac new file mode 100644 index 0000000..8f25473 Binary files /dev/null and b/audio/raucous-village.flac differ diff --git a/audio/reinforce-hull.flac b/audio/reinforce-hull.flac new file mode 100644 index 0000000..bb1afe9 Binary files /dev/null and b/audio/reinforce-hull.flac differ diff --git a/audio/ship.flac b/audio/ship.flac new file mode 100644 index 0000000..8699628 Binary files /dev/null and b/audio/ship.flac differ diff --git a/audio/silent-forest.flac b/audio/silent-forest.flac new file mode 100644 index 0000000..a08e412 Binary files /dev/null and b/audio/silent-forest.flac differ diff --git a/audio/space.flac b/audio/space.flac new file mode 100644 index 0000000..5bbe559 Binary files /dev/null and b/audio/space.flac differ diff --git a/audio/stoke-fire.flac b/audio/stoke-fire.flac new file mode 100644 index 0000000..1889375 Binary files /dev/null and b/audio/stoke-fire.flac differ diff --git a/audio/tiny-village.flac b/audio/tiny-village.flac new file mode 100644 index 0000000..c61671b Binary files /dev/null and b/audio/tiny-village.flac differ diff --git a/audio/upgrade-engine.flac b/audio/upgrade-engine.flac new file mode 100644 index 0000000..05fa516 Binary files /dev/null and b/audio/upgrade-engine.flac differ diff --git a/audio/use-meds.flac b/audio/use-meds.flac new file mode 100644 index 0000000..0e63bb1 Binary files /dev/null and b/audio/use-meds.flac differ diff --git a/audio/weapon-melee-1.flac b/audio/weapon-melee-1.flac new file mode 100644 index 0000000..ed0c0dd Binary files /dev/null and b/audio/weapon-melee-1.flac differ diff --git a/audio/weapon-melee-2.flac b/audio/weapon-melee-2.flac new file mode 100644 index 0000000..d203c3d Binary files /dev/null and b/audio/weapon-melee-2.flac differ diff --git a/audio/weapon-melee-3.flac b/audio/weapon-melee-3.flac new file mode 100644 index 0000000..7094f9d Binary files /dev/null and b/audio/weapon-melee-3.flac differ diff --git a/audio/weapon-ranged-1.flac b/audio/weapon-ranged-1.flac new file mode 100644 index 0000000..a12399e Binary files /dev/null and b/audio/weapon-ranged-1.flac differ diff --git a/audio/weapon-ranged-2.flac b/audio/weapon-ranged-2.flac new file mode 100644 index 0000000..f813a89 Binary files /dev/null and b/audio/weapon-ranged-2.flac differ diff --git a/audio/weapon-ranged-3.flac b/audio/weapon-ranged-3.flac new file mode 100644 index 0000000..c29fb98 Binary files /dev/null and b/audio/weapon-ranged-3.flac differ diff --git a/audio/weapon-unarmed-1.flac b/audio/weapon-unarmed-1.flac new file mode 100644 index 0000000..076a74d Binary files /dev/null and b/audio/weapon-unarmed-1.flac differ diff --git a/audio/weapon-unarmed-2.flac b/audio/weapon-unarmed-2.flac new file mode 100644 index 0000000..45a4ad9 Binary files /dev/null and b/audio/weapon-unarmed-2.flac differ diff --git a/audio/weapon-unarmed-3.flac b/audio/weapon-unarmed-3.flac new file mode 100644 index 0000000..6987bbf Binary files /dev/null and b/audio/weapon-unarmed-3.flac differ diff --git a/audio/world.flac b/audio/world.flac new file mode 100644 index 0000000..a264b2e Binary files /dev/null and b/audio/world.flac differ diff --git a/dev-server.js b/dev-server.js new file mode 100644 index 0000000..0f3693d --- /dev/null +++ b/dev-server.js @@ -0,0 +1,8 @@ +import express from 'express'; + +const PORT = 8080; + +const app = express(); +app.use(express.static('.')); + +app.listen(PORT, () => console.log(`Listening on port ${PORT}`)); diff --git a/index.html b/index.html index c72e9c0..8d65dbf 100644 --- a/index.html +++ b/index.html @@ -48,6 +48,8 @@ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..a8e24a7 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "adarkroom", + "type": "module", + "version": "1.0.0", + "private": true, + "repository": "git@github.com:doublespeakgames/adarkroom.git", + "author": "Michael Townsend ", + "license": "MPL-2.0", + "scripts": { + "start": "node dev-server.js" + }, + "dependencies": { + "express": "^4.17.1" + } +} diff --git a/script/audio.js b/script/audio.js new file mode 100644 index 0000000..d5df7aa --- /dev/null +++ b/script/audio.js @@ -0,0 +1,236 @@ +/** + * Module that takes care of audio playback + */ +var AudioEngine = { + FADE_TIME: 1, + AUDIO_BUFFER_CACHE: {}, + _audioContext: null, + _master: null, + _currentBackgroundMusic: null, + _currentEventAudio: null, + _currentSoundEffectAudio: null, + init: function () { + AudioEngine._initAudioContext(); + }, + _initAudioContext: function () { + AudioEngine._audioContext = new (window.AudioContext || window.webkitAudioContext); + AudioEngine._createMasterChannel(); + }, + _createMasterChannel: function () { + // create master + AudioEngine._master = AudioEngine._audioContext.createGain(); + AudioEngine._master.gain.setValueAtTime(1.0, AudioEngine._audioContext.currentTime); + AudioEngine._master.connect(AudioEngine._audioContext.destination); + }, + _getMissingAudioBuffer: function () { + // plays beeping sound to indicate missing audio + var buffer = AudioEngine._audioContext.createBuffer( + 1, + AudioEngine._audioContext.sampleRate, + AudioEngine._audioContext.sampleRate + ); + // Fill the buffer + var bufferData = buffer.getChannelData(0); + for (var i = 0; i < buffer.length / 2; i++) { + bufferData[i] = Math.sin(i * 0.05) / 4; // max .25 gain value + } + return buffer; + }, + _playSound: function (buffer) { + if (AudioEngine._currentSoundEffectAudio && + AudioEngine._currentSoundEffectAudio.source.buffer == buffer) { + return; + } + + var source = AudioEngine._audioContext.createBufferSource(); + source.buffer = buffer; + source.onended = function(event) { + // dereference current sound effect when finished + if (AudioEngine._currentSoundEffectAudio && + AudioEngine._currentSoundEffectAudio.source.buffer == buffer) { + AudioEngine._currentSoundEffectAudio = null; + } + }; + + source.connect(AudioEngine._master); + source.start(); + + AudioEngine._currentSoundEffectAudio = { + source: source + }; + }, + _playBackgroundMusic: function (buffer) { + var source = AudioEngine._audioContext.createBufferSource(); + source.buffer = buffer; + source.loop = true; + + var envelope = AudioEngine._audioContext.createGain(); + envelope.gain.setValueAtTime(0.0, AudioEngine._audioContext.currentTime); + + var fadeTime = AudioEngine._audioContext.currentTime + AudioEngine.FADE_TIME; + + // fade out current background music + if (AudioEngine._currentBackgroundMusic && + AudioEngine._currentBackgroundMusic.source && + AudioEngine._currentBackgroundMusic.source.playbackState !== 0) { + var currentBackgroundGainValue = AudioEngine._currentBackgroundMusic.envelope.gain.value; + AudioEngine._currentBackgroundMusic.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.setValueAtTime(currentBackgroundGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.linearRampToValueAtTime(0.0, fadeTime); + AudioEngine._currentBackgroundMusic.source.stop(fadeTime + 0.3); // make sure fade has completed + } + + // fade in new backgorund music + source.connect(envelope); + envelope.connect(AudioEngine._master); + source.start(); + envelope.gain.linearRampToValueAtTime(1.0, fadeTime); + + // update current background music + AudioEngine._currentBackgroundMusic = { + source: source, + envelope: envelope + }; + }, + _playEventMusic: function (buffer) { + var source = AudioEngine._audioContext.createBufferSource(); + source.buffer = buffer; + source.loop = true; + + var envelope = AudioEngine._audioContext.createGain(); + envelope.gain.setValueAtTime(0.0, AudioEngine._audioContext.currentTime); + + var fadeTime = AudioEngine._audioContext.currentTime + AudioEngine.FADE_TIME * 2; + + // turn down current background music + if (AudioEngine._currentBackgroundMusic != null) { + var currentBackgroundGainValue = AudioEngine._currentBackgroundMusic.envelope.gain.value; + AudioEngine._currentBackgroundMusic.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.setValueAtTime(currentBackgroundGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.linearRampToValueAtTime(0.2, fadeTime); + } + + // fade in event music + source.connect(envelope); + envelope.connect(AudioEngine._master); + source.start(); + envelope.gain.linearRampToValueAtTime(1.0, fadeTime); + + // update reference + AudioEngine._currentEventAudio = { + source: source, + envelope: envelope + }; + }, + _stopEventMusic: function () { + var fadeTime = AudioEngine._audioContext.currentTime + AudioEngine.FADE_TIME * 2; + + // fade out event music and stop + if (AudioEngine._currentEventAudio) { + var currentEventGainValue = AudioEngine._currentEventAudio.envelope.gain.value; + AudioEngine._currentEventAudio.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._currentEventAudio.envelope.gain.setValueAtTime(currentEventGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._currentEventAudio.envelope.gain.linearRampToValueAtTime(0.0, fadeTime); + AudioEngine._currentEventAudio.source.stop(fadeTime + 1); // make sure fade has completed + AudioEngine._currentEventAudio = null; + } + + // turn up background music + if (AudioEngine._currentBackgroundMusic) { + var currentBackgroundGainValue = AudioEngine._currentBackgroundMusic.envelope.gain.value; + AudioEngine._currentBackgroundMusic.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.setValueAtTime(currentBackgroundGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.linearRampToValueAtTime(1.0, fadeTime); + } + }, + isAudioContextRunning: function () { + return AudioEngine._audioContext.state !== 'suspended'; + }, + tryResumingAudioContext: function() { + if (AudioEngine._audioContext.state === 'suspended') { + AudioEngine._audioContext.resume(); + } + }, + playBackgroundMusic: function (src) { + AudioEngine.loadAudioFile(src) + .then(function (buffer) { + AudioEngine._playBackgroundMusic(buffer); + }); + }, + playEventMusic: function (src) { + AudioEngine.loadAudioFile(src) + .then(function (buffer) { + AudioEngine._playEventMusic(buffer); + }); + }, + stopEventMusic: function () { + AudioEngine._stopEventMusic(); + }, + playSound: function (src) { + AudioEngine.loadAudioFile(src) + .then(function (buffer) { + AudioEngine._playSound(buffer); + }); + }, + loadAudioFile: function (src) { + if (src.indexOf('http') === -1) { + src = window.location + src; + } + if (AudioEngine.AUDIO_BUFFER_CACHE[src]) { + return new Promise(function (resolve, reject) { + resolve(AudioEngine.AUDIO_BUFFER_CACHE[src]); + }); + } else { + var request = new Request(src); + return fetch(request).then(function (response) { + return response.arrayBuffer(); + }).then(function (buffer) { + if (buffer.byteLength === 0) { + console.error('cannot load audio from ' + src); + return AudioEngine._getMissingAudioBuffer(); + } + + return AudioEngine._audioContext.decodeAudioData(buffer, function (decodedData) { + AudioEngine.AUDIO_BUFFER_CACHE[src] = decodedData; + return AudioEngine.AUDIO_BUFFER_CACHE[src]; + }); + }); + } + }, + setBackgroundMusicVolume: function (volume, s) { + if (AudioEngine._master == null) return; // master may not be ready yet + if (volume === undefined) { + volume = 1.0; + } + if (s === undefined) { + s = 1.0; + } + + // cancel any current schedules and then ramp + var currentBackgroundGainValue = AudioEngine._currentBackgroundMusic.envelope.gain.value; + AudioEngine._currentBackgroundMusic.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.setValueAtTime(currentBackgroundGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._currentBackgroundMusic.envelope.gain.linearRampToValueAtTime( + volume, + AudioEngine._audioContext.currentTime + s + ); + }, + setMasterVolume: function (volume, s) { + if (AudioEngine._master == null) return; // master may not be ready yet + if (volume === undefined) { + volume = 1.0; + } + if (s === undefined) { + s = 1.0; + } + + // cancel any current schedules and then ramp + var currentGainValue = AudioEngine._master.gain.value; + AudioEngine._master.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); + AudioEngine._master.gain.setValueAtTime(currentGainValue, AudioEngine._audioContext.currentTime); + AudioEngine._master.gain.linearRampToValueAtTime( + volume, + AudioEngine._audioContext.currentTime + s + ); + } +}; diff --git a/script/audioLibrary.js b/script/audioLibrary.js new file mode 100644 index 0000000..6a7e028 --- /dev/null +++ b/script/audioLibrary.js @@ -0,0 +1,91 @@ +/** + * Module that defines all audio files + */ +var AudioLibrary = { + MUSIC_DUSTY_PATH: 'audio/dusty-path.flac', + MUSIC_SILENT_FOREST: 'audio/silent-forest.flac', + MUSIC_LONELY_HUT: 'audio/lonely-hut.flac', + MUSIC_TINY_VILLAGE: 'audio/tiny-village.flac', + MUSIC_MODEST_VILLAGE: 'audio/modest-village.flac', + MUSIC_LARGE_VILLAGE: 'audio/large-village.flac', + MUSIC_RAUCOUS_VILLAGE: 'audio/raucous-village.flac', + MUSIC_FIRE_DEAD: 'audio/fire-dead.flac', + MUSIC_FIRE_SMOLDERING: 'audio/fire-smoldering.flac', + MUSIC_FIRE_FLICKERING: 'audio/fire-flickering.flac', + MUSIC_FIRE_BURNING: 'audio/fire-burning.flac', + MUSIC_FIRE_ROARING: 'audio/fire-roaring.flac', + MUSIC_WORLD: 'audio/world.flac', + MUSIC_SPACE: 'audio/space.flac', + MUSIC_ENDING: 'audio/ending.flac', + MUSIC_SHIP: 'audio/ship.flac', + EVENT_NOMAD: 'audio/event-nomad.flac', + EVENT_NOISES_OUTSIDE: 'audio/event-noises-outside.flac', + EVENT_NOISES_INSIDE: 'audio/event-noises-inside.flac', + EVENT_BEGGAR: 'audio/event-beggar.flac', + EVENT_SHADY_BUILDER: 'audio/event-shady-builder.flac', + EVENT_MYSTERIOUS_WANDERER: 'audio/event-mysterious-wanderer.flac', + EVENT_SCOUT: 'audio/event-scout.flac', + EVENT_WANDERING_MASTER: 'audio/event-wandering-master.flac', + EVENT_SICK_MAN: 'audio/event-sick-man.flac', + EVENT_RUINED_TRAP: 'audio/event-ruined-trap.flac', + EVENT_HUT_FIRE: 'audio/event-hut-fire.flac', + EVENT_SICKNESS: 'audio/event-sickness.flac', + EVENT_PLAGUE: 'audio/event-plague.flac', + EVENT_BEAST_ATTACK: 'audio/event-beast-attack.flac', + EVENT_SOLDIER_ATTACK: 'audio/event-soldier-attack.flac', + EVENT_THIEF: 'audio/event-thief.flac', + LANDMARK_FRIENDLY_OUTPOST: 'audio/landmark-friendly-outpost.flac', + LANDMARK_SWAMP: 'audio/landmark-swamp.flac', + LANDMARK_CAVE: 'audio/landmark-cave.flac', + LANDMARK_TOWN: 'audio/landmark-town.flac', + LANDMARK_CITY: 'audio/landmark-city.flac', + LANDMARK_HOUSE: 'audio/landmark-house.flac', + LANDMARK_BATTLEFIELD: 'audio/landmark-battlefield.flac', + LANDMARK_BOREHOLE: 'audio/landmark-borehole.flac', + LANDMARK_CRASHED_SHIP: 'audio/landmark-crashed-ship.flac', + LANDMARK_SULPHUR_MINE: 'audio/landmark-sulphurmine.flac', + LANDMARK_COAL_MINE: 'audio/landmark-coalmine.flac', + LANDMARK_IRON_MINE: 'audio/landmark-ironmine.flac', + LANDMARK_DESTROYED_VILLAGE: 'audio/landmark-destroyed-village.flac', + ENCOUNTER_TIER_1: 'audio/encounter-tier-1.flac', + ENCOUNTER_TIER_2: 'audio/encounter-tier-2.flac', + ENCOUNTER_TIER_3: 'audio/encounter-tier-3.flac', + LIGHT_FIRE: 'audio/light-fire.flac', + STOKE_FIRE: 'audio/stoke-fire.flac', + BUILD: 'audio/build.flac', + CRAFT: 'audio/craft.flac', + BUY: 'audio/buy.flac', + GATHER_WOOD: 'audio/gather-wood.flac', + CHECK_TRAPS: 'audio/check-traps.flac', + EMBARK: 'audio/embark.flac', + FOOTSTEPS_1: 'audio/footsteps-1.flac', + FOOTSTEPS_2: 'audio/footsteps-2.flac', + FOOTSTEPS_3: 'audio/footsteps-3.flac', + FOOTSTEPS_4: 'audio/footsteps-4.flac', + FOOTSTEPS_5: 'audio/footsteps-5.flac', + FOOTSTEPS_6: 'audio/footsteps-6.flac', + EAT_MEAT: 'audio/eat-meat.flac', + USE_MEDS: 'audio/use-meds.flac', + WEAPON_UNARMED_1: 'audio/weapon-unarmed-1.flac', + WEAPON_UNARMED_2: 'audio/weapon-unarmed-2.flac', + WEAPON_UNARMED_3: 'audio/weapon-unarmed-3.flac', + WEAPON_MELEE_1: 'audio/weapon-melee-1.flac', + WEAPON_MELEE_2: 'audio/weapon-melee-2.flac', + WEAPON_MELEE_3: 'audio/weapon-melee-3.flac', + WEAPON_RANGED_1: 'audio/weapon-ranged-1.flac', + WEAPON_RANGED_2: 'audio/weapon-ranged-2.flac', + WEAPON_RANGED_3: 'audio/weapon-ranged-3.flac', + DEATH: 'audio/death.flac', + REINFORCE_HULL: 'audio/reinforce-hull.flac', + UPGRADE_ENGINE: 'audio/upgrade-engine.flac', + LIFT_OFF: 'audio/lift-off.flac', + ASTEROID_HIT_1: 'audio/asteroid-hit-1.flac', + ASTEROID_HIT_2: 'audio/asteroid-hit-2.flac', + ASTEROID_HIT_3: 'audio/asteroid-hit-3.flac', + ASTEROID_HIT_4: 'audio/asteroid-hit-4.flac', + ASTEROID_HIT_5: 'audio/asteroid-hit-5.flac', + ASTEROID_HIT_6: 'audio/asteroid-hit-6.flac', + ASTEROID_HIT_7: 'audio/asteroid-hit-7.flac', + ASTEROID_HIT_8: 'audio/asteroid-hit-8.flac', + CRASH: 'audio/crash.flac', +}; \ No newline at end of file diff --git a/script/engine.js b/script/engine.js index 4d91a3a..264b79d 100644 --- a/script/engine.js +++ b/script/engine.js @@ -75,7 +75,7 @@ debug: false, log: false, dropbox: false, - doubleTime: false + doubleTime: true }, init: function(options) { @@ -104,6 +104,15 @@ Engine.loadGame(); } + // start loading music and events early + for (var key in AudioLibrary) { + if ( + key.toString().indexOf('MUSIC_') > -1 || + key.toString().indexOf('EVENT_') > -1) { + AudioEngine.loadAudioFile(AudioLibrary[key]); + } + } + $('
').attr('id', 'locationSlider').appendTo('#main'); var menu = $('
') @@ -133,6 +142,12 @@ }); } + $('') + .addClass('volume menuBtn') + .text(_('sound on.')) + .click(() => Engine.toggleVolume()) + .appendTo(menu); + $('') .addClass('appStore menuBtn') .text(_('get the app.')) @@ -200,10 +215,12 @@ $.Dispatch('stateUpdate').subscribe(Engine.handleStateUpdates); $SM.init(); + AudioEngine.init(); Notifications.init(); Events.init(); Room.init(); + if(typeof $SM.get('stores.wood') != 'undefined') { Outside.init(); } @@ -215,18 +232,32 @@ } if($SM.get('config.lightsOff', true)){ - Engine.turnLightsOff(); + Engine.turnLightsOff(); } if($SM.get('config.hyperMode', true)){ - Engine.triggerHyperMode(); + Engine.triggerHyperMode(); } + Engine.toggleVolume(Boolean($SM.get('config.soundOn'))); + if(!AudioEngine.isAudioContextRunning()){ + document.addEventListener('click', Engine.resumeAudioContext, true); + } + Engine.saveLanguage(); Engine.travelTo(Room); - }, + setTimeout(notifyAboutSound, 3000); + }, + resumeAudioContext: function () { + AudioEngine.tryResumingAudioContext(); + + // turn on music! + AudioEngine.setMasterVolume($SM.get('config.soundOn') ? 1.0 : 0.0, 0); + + document.removeEventListener('click', Engine.resumeAudioContext); + }, browserValid: function() { return ( location.search.indexOf( 'ignorebrowser=true' ) >= 0 || ( typeof Storage != 'undefined' && !oldIE ) ); }, @@ -596,7 +627,6 @@ Engine.activeModule = module; module.onArrival(diff); Notifications.printQueue(module); - } }, @@ -782,6 +812,21 @@ } }, + toggleVolume: function(enabled /* optional */) { + if (enabled == null) { + enabled = !$SM.get('config.soundOn'); + } + if (!enabled) { + $('.volume').text(_('sound on.')); + $SM.set('config.soundOn', false); + AudioEngine.setMasterVolume(0.0); + } else { + $('.volume').text(_('sound off.')); + $SM.set('config.soundOn', true); + AudioEngine.setMasterVolume(1.0); + } + }, + setInterval: function(callback, interval, skipDouble){ if( Engine.options.doubleTime && !skipDouble ){ Engine.log('Double time, cutting interval in half'); @@ -802,7 +847,6 @@ return setTimeout(callback, timeout); } - }; function eventNullifier(e) { @@ -813,6 +857,38 @@ return true; } + function notifyAboutSound() { + if ($SM.get('playStats.audioAlertShown')) { + return; + } + + // Tell new users that there's sound now! + $SM.set('playStats.audioAlertShown', true); + Events.startEvent({ + title: _('Sound Available!'), + scenes: { + start: { + text: [ + _('ears flooded with new sensations.'), + _('perhaps silence is safer?') + ], + buttons: { + 'yes': { + text: _('enable audio'), + nextScene: 'end', + onChoose: () => Engine.toggleVolume(true) + }, + 'no': { + text: _('disable audio'), + nextScene: 'end', + onChoose: () => Engine.toggleVolume(false) + } + } + } + } + }); + } + })(); function inView(dir, elem){ diff --git a/script/events.js b/script/events.js index 9e111aa..f67f42e 100644 --- a/script/events.js +++ b/script/events.js @@ -11,7 +11,6 @@ var Events = { _LEAVE_COOLDOWN: 1, STUN_DURATION: 4000, BLINK_INTERVAL: false, - init: function(options) { this.options = $.extend( this.options, @@ -135,7 +134,7 @@ var Events = { } $('
').addClass('clear').appendTo(healBtns); Events.setHeal(healBtns); - + // Set up the enemy attack timer Events._enemyAttackTimer = Engine.setInterval(Events.enemyAttack, scene.attackDelay * 1000); }, @@ -340,10 +339,12 @@ var Events = { eatMeat: function(btn) { Events.doHeal('cured meat', World.meatHeal(), btn); + AudioEngine.playSound(AudioLibrary.EAT_MEAT); }, useMeds: function(btn) { Events.doHeal('medicine', World.medsHeal(), btn); + AudioEngine.playSound(AudioLibrary.USE_MEDS); }, useWeapon: function(btn) { @@ -416,8 +417,23 @@ var Events = { } } } - + var attackFn = weapon.type == 'ranged' ? Events.animateRanged : Events.animateMelee; + + // play variation audio for weapon type + var r = Math.floor(Math.random() * 2) + 1; + switch (weapon.type) { + case 'unarmed': + AudioEngine.playSound(AudioLibrary['WEAPON_UNARMED_' + r]); + break; + case 'melee': + AudioEngine.playSound(AudioLibrary['WEAPON_MELEE_' + r]); + break; + case 'ranged': + AudioEngine.playSound(AudioLibrary['WEAPON_RANGED_' + r]); + break; + } + attackFn($('#wanderer'), dmg, function() { if($('#enemy').data('hp') <= 0 && !Events.won) { // Success! @@ -427,7 +443,7 @@ var Events = { } }, - damage: function(fighter, enemy, dmg) { + damage: function(fighter, enemy, dmg, type) { var enemyHp = enemy.data('hp'); var msg = ""; if(typeof dmg == 'number') { @@ -443,6 +459,20 @@ var Events = { Events.setHeal(); } Events.updateFighterDiv(enemy); + + // play variation audio for weapon type + var r = Math.floor(Math.random() * 2) + 1; + switch (type) { + case 'unarmed': + AudioEngine.playSound(AudioLibrary['WEAPON_UNARMED_' + r]); + break; + case 'melee': + AudioEngine.playSound(AudioLibrary['WEAPON_MELEE_' + r]); + break; + case 'ranged': + AudioEngine.playSound(AudioLibrary['WEAPON_RANGED_' + r]); + break; + } } } else { if(dmg == 'stun') { @@ -468,7 +498,7 @@ var Events = { fighter.stop(true, true).animate(start, Events._FIGHT_SPEED, function() { - Events.damage(fighter, enemy, dmg); + Events.damage(fighter, enemy, dmg, 'melee'); $(this).animate(end, Events._FIGHT_SPEED, callback); }); @@ -489,7 +519,7 @@ var Events = { $('
').css(start).addClass('bullet').text('o').appendTo('#description') .animate(end, Events._FIGHT_SPEED * 2, 'linear', function() { - Events.damage(fighter, enemy, dmg); + Events.damage(fighter, enemy, dmg, 'ranged'); $(this).remove(); if(typeof callback == 'function') { @@ -519,6 +549,7 @@ var Events = { clearTimeout(Events._enemyAttackTimer); Events.endEvent(); World.die(); + AudioEngine.playSound(AudioLibrary.LOSE_FIGHT); } }); } @@ -536,6 +567,7 @@ var Events = { return; } Events.endFight(); + // AudioEngine.playSound(AudioLibrary.WIN_FIGHT); $('#enemy').animate({opacity: 0}, 300, 'linear', function() { Engine.setTimeout(function() { var scene = Events.activeEvent().scenes[Events.activeScene]; @@ -1018,6 +1050,7 @@ var Events = { } else { var r = Math.floor(Math.random()*(possibleEvents.length)); Events.startEvent(possibleEvents[r]); + AudioEngine.playEventMusic(possibleEvents[r].audio); } } @@ -1035,6 +1068,20 @@ var Events = { var r = Math.floor(Math.random()*(possibleFights.length)); Events.startEvent(possibleFights[r]); + + // play audio only when fight is possible + if (possibleFights.length > 0) { + if (World.getDistance() > 20) { + // Tier 3 + AudioEngine.playEventMusic(AudioLibrary.ENCOUNTER_TIER_3); + } else if (World.getDistance() > 10) { + // Tier 2 + AudioEngine.playEventMusic(AudioLibrary.ENCOUNTER_TIER_2); + } else { + // Tier 1 + AudioEngine.playEventMusic(AudioLibrary.ENCOUNTER_TIER_1); + } + } }, activeEvent: function() { @@ -1080,6 +1127,7 @@ var Events = { }, endEvent: function() { + AudioEngine.stopEventMusic(); Events.eventPanel().animate({opacity:0}, Events._PANEL_FADE, 'linear', function() { Events.eventPanel().remove(); Events.activeEvent().eventPanel = null; diff --git a/script/events/global.js b/script/events/global.js index ff6e662..8cefbf8 100644 --- a/script/events/global.js +++ b/script/events/global.js @@ -61,6 +61,7 @@ Events.Global = [ } } } - } + }, + audio: AudioLibrary.EVENT_THIEF } ]; diff --git a/script/events/outside.js b/script/events/outside.js index 1a6e763..b0b5b15 100644 --- a/script/events/outside.js +++ b/script/events/outside.js @@ -63,7 +63,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_RUINED_TRAP }, { /* Hut fire */ title: _('Fire'), @@ -89,7 +90,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_HUT_FIRE }, { /* Sickness */ title: _('Sickness'), @@ -146,7 +148,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_SICKNESS }, { /* Plague */ @@ -217,7 +220,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_PLAGUE }, { /* Beast attack */ @@ -251,7 +255,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_BEAST_ATTACK }, { /* Soldier attack */ @@ -285,7 +290,8 @@ Events.Outside = [ } } } - } + }, + audio: AudioLibrary.EVENT_SOLDIER_ATTACK } ]; diff --git a/script/events/room.js b/script/events/room.js index 1e70a3e..6879458 100644 --- a/script/events/room.js +++ b/script/events/room.js @@ -47,7 +47,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_NOMAD }, { /* Noises Outside -- gain wood/fur */ title: _('Noises'), @@ -98,7 +99,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_NOISES_OUTSIDE }, { /* Noises Inside -- trade wood for better good */ title: _('Noises'), @@ -184,7 +186,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_NOISES_INSIDE }, { /* The Beggar -- trade fur for better good */ title: _('The Beggar'), @@ -255,7 +258,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_BEGGAR }, {/* The Shady Builder */ title: _('The Shady Builder'), @@ -311,7 +315,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_SHADY_BUILDER }, { /* Mysterious Wanderer -- wood gambling */ @@ -390,7 +395,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_MYSTERIOUS_WANDERER }, { /* Mysterious Wanderer -- fur gambling */ @@ -469,7 +475,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_MYSTERIOUS_WANDERER }, { /* The Scout -- Map Merchant */ @@ -511,7 +518,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_SCOUT }, { /* The Wandering Master */ @@ -584,7 +592,8 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_WANDERING_MASTER }, { /* The Sick Man */ @@ -672,6 +681,7 @@ Events.Room = [ } } } - } + }, + audio: AudioLibrary.EVENT_SICK_MAN } ]; diff --git a/script/events/setpieces.js b/script/events/setpieces.js index 9f4012b..dadf91e 100644 --- a/script/events/setpieces.js +++ b/script/events/setpieces.js @@ -28,7 +28,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_FRIENDLY_OUTPOST }, "swamp": { /* Swamp */ title: _('A Murky Swamp'), @@ -85,7 +86,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_SWAMP }, "cave": { /* Cave */ title: _('A Damp Cave'), @@ -516,7 +518,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_CAVE }, "town": { /* Town */ title: _('A Deserted Town'), @@ -1233,7 +1236,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_TOWN }, "city": { /* City */ title: _('A Ruined City'), @@ -2928,7 +2932,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_CITY }, "house": { /* Abandoned House */ title: _('An Old House'), @@ -3045,7 +3050,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_HOUSE }, "battlefield": { /* Discovering an old battlefield */ title: _('A Forgotten Battlefield'), @@ -3098,7 +3104,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_BATTLEFIELD }, "borehole": { /* Admiring a huge borehole */ title: _('A Huge Borehole'), @@ -3127,7 +3134,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_BOREHOLE }, "ship": { /* Finding a way off this rock */ title: _('A Crashed Ship'), @@ -3150,7 +3158,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_CRASHED_SHIP }, "sulphurmine": { /* Clearing the Sulphur Mine */ title: _('The Sulphur Mine'), @@ -3299,7 +3308,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_SULPHUR_MINE }, "coalmine": { /* Clearing the Coal Mine */ title: _('The Coal Mine'), @@ -3441,7 +3451,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_COAL_MINE }, "ironmine": { /* Clearing the Iron Mine */ title: _('The Iron Mine'), @@ -3517,7 +3528,8 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_IRON_MINE }, "cache": { /* Cache - contains some of supplies from previous game */ @@ -3569,6 +3581,7 @@ Events.Setpieces = { } } } - } + }, + audio: AudioLibrary.LANDMARK_DESTROYED_VILLAGE } }; diff --git a/script/outside.js b/script/outside.js index 881bc43..ef3f1a8 100644 --- a/script/outside.js +++ b/script/outside.js @@ -94,7 +94,6 @@ var Outside = { } } }, - TrapDrops: [ { rollUnder: 0.5, @@ -588,12 +587,29 @@ var Outside = { Outside.updateVillage(true); Engine.moveStoresView($('#village'), transition_diff); + + // set music + var numberOfHuts = $SM.get('game.buildings["hut"]', true); + if(numberOfHuts === 0) { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_SILENT_FOREST); + } else if(numberOfHuts == 1) { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_LONELY_HUT); + } else if(numberOfHuts <= 4) { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_TINY_VILLAGE); + } else if(numberOfHuts <= 8) { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_MODEST_VILLAGE); + } else if(numberOfHuts <= 14) { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_LARGE_VILLAGE); + } else { + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_RAUCOUS_VILLAGE); + } }, gatherWood: function() { Notifications.notify(Outside, _("dry brush and dead branches litter the forest floor")); var gatherAmt = $SM.get('game.buildings["cart"]', true) > 0 ? 50 : 10; $SM.add('stores.wood', gatherAmt); + AudioEngine.playSound(AudioLibrary.GATHER_WOOD); }, checkTraps: function() { @@ -634,6 +650,7 @@ var Outside = { Notifications.notify(Outside, s); $SM.addM('stores', drops); + AudioEngine.playSound(AudioLibrary.CHECK_TRAPS); }, handleStateUpdates: function(e){ diff --git a/script/path.js b/script/path.js index 250b9ea..8ee517d 100644 --- a/script/path.js +++ b/script/path.js @@ -1,5 +1,4 @@ var Path = { - DEFAULT_BAG_SPACE: 10, _STORES_OFFSET: 0, // Everything not in this list weighs 1 @@ -304,6 +303,8 @@ var Path = { Path.setTitle(); Path.updateOutfitting(); Path.updatePerks(true); + + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_DUSTY_PATH); Engine.moveStoresView($('#perks'), transition_diff); }, @@ -319,6 +320,7 @@ var Path = { World.onArrival(); $('#outerSlider').animate({left: '-700px'}, 300); Engine.activeModule = World; + AudioEngine.playSound(AudioLibrary.EMBARK); }, handleStateUpdates: function(e){ diff --git a/script/room.js b/script/room.js index 7705994..5567ce7 100644 --- a/script/room.js +++ b/script/room.js @@ -8,9 +8,7 @@ var Room = { _BUILDER_STATE_DELAY: 0.5 * 60 * 1000, // time between builder state updates _STOKE_COOLDOWN: 10, // cooldown to stoke the fire _NEED_WOOD_DELAY: 15 * 1000, // from when the stranger shows up, to when you need wood - - buttons:{}, - + buttons: {}, Craftables: { 'trap': { name: _('trap'), @@ -20,12 +18,13 @@ var Room = { buildMsg: _('more traps to catch more creatures'), maxMsg: _("more traps won't help now"), type: 'building', - cost: function() { + cost: function () { var n = $SM.get('game.buildings["trap"]', true); return { - 'wood': 10 + (n*10) + 'wood': 10 + (n * 10) }; - } + }, + audio: AudioLibrary.BUILD_TRAP }, 'cart': { name: _('cart'), @@ -34,11 +33,12 @@ var Room = { availableMsg: _('builder says she can make a cart for carrying wood'), buildMsg: _('the rickety cart will carry more wood from the forest'), type: 'building', - cost: function() { + cost: function () { return { 'wood': 30 }; - } + }, + audio: AudioLibrary.BUILD_CART }, 'hut': { name: _('hut'), @@ -48,12 +48,13 @@ var Room = { buildMsg: _('builder puts up a hut, out in the forest. says word will get around.'), maxMsg: _('no more room for huts.'), type: 'building', - cost: function() { + cost: function () { var n = $SM.get('game.buildings["hut"]', true); return { - 'wood': 100 + (n*50) + 'wood': 100 + (n * 50) }; - } + }, + audio: AudioLibrary.BUILD_HUT }, 'lodge': { name: _('lodge'), @@ -62,13 +63,14 @@ var Room = { availableMsg: _('villagers could help hunt, given the means'), buildMsg: _('the hunting lodge stands in the forest, a ways out of town'), type: 'building', - cost: function() { + cost: function () { return { wood: 200, fur: 10, meat: 5 }; - } + }, + audio: AudioLibrary.BUILD_LODGE }, 'trading post': { name: _('trading post'), @@ -77,12 +79,13 @@ var Room = { availableMsg: _("a trading post would make commerce easier"), buildMsg: _("now the nomads have a place to set up shop, they might stick around a while"), type: 'building', - cost: function() { + cost: function () { return { 'wood': 400, 'fur': 100 }; - } + }, + audio: AudioLibrary.BUILD_TRADING_POST }, 'tannery': { name: _('tannery'), @@ -91,12 +94,13 @@ var Room = { availableMsg: _("builder says leather could be useful. says the villagers could make it."), buildMsg: _('tannery goes up quick, on the edge of the village'), type: 'building', - cost: function() { + cost: function () { return { 'wood': 500, 'fur': 50 }; - } + }, + audio: AudioLibrary.BUILD_TANNERY }, 'smokehouse': { name: _('smokehouse'), @@ -105,12 +109,13 @@ var Room = { availableMsg: _("should cure the meat, or it'll spoil. builder says she can fix something up."), buildMsg: _('builder finishes the smokehouse. she looks hungry.'), type: 'building', - cost: function() { + cost: function () { return { 'wood': 600, 'meat': 50 }; - } + }, + audio: AudioLibrary.BUILD_SMOKEHOUSE }, 'workshop': { name: _('workshop'), @@ -119,13 +124,14 @@ var Room = { availableMsg: _("builder says she could make finer things, if she had the tools"), buildMsg: _("workshop's finally ready. builder's excited to get to it"), type: 'building', - cost: function() { + cost: function () { return { 'wood': 800, 'leather': 100, 'scales': 10 }; - } + }, + audio: AudioLibrary.BUILD_WORKSHOP }, 'steelworks': { name: _('steelworks'), @@ -134,13 +140,14 @@ var Room = { availableMsg: _("builder says the villagers could make steel, given the tools"), buildMsg: _("a haze falls over the village as the steelworks fires up"), type: 'building', - cost: function() { + cost: function () { return { 'wood': 1500, 'iron': 100, 'coal': 100 }; - } + }, + audio: AudioLibrary.BUILD_STEELWORKS }, 'armoury': { name: _('armoury'), @@ -149,25 +156,27 @@ var Room = { availableMsg: _("builder says it'd be useful to have a steady source of bullets"), buildMsg: _("armoury's done, welcoming back the weapons of the past."), type: 'building', - cost: function() { + cost: function () { return { 'wood': 3000, 'steel': 100, 'sulphur': 50 }; - } + }, + audio: AudioLibrary.BUILD_ARMOURY }, 'torch': { name: _('torch'), button: null, type: 'tool', buildMsg: _('a torch to keep the dark away'), - cost: function() { + cost: function () { return { 'wood': 1, 'cloth': 1 }; - } + }, + audio: AudioLibrary.CRAFT_TORCH }, 'waterskin': { name: _('waterskin'), @@ -175,11 +184,12 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('this waterskin\'ll hold a bit of water, at least'), - cost: function() { + cost: function () { return { 'leather': 50 }; - } + }, + audio: AudioLibrary.CRAFT_WATERSKIN }, 'cask': { name: _('cask'), @@ -187,12 +197,13 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('the cask holds enough water for longer expeditions'), - cost: function() { + cost: function () { return { 'leather': 100, 'iron': 20 }; - } + }, + audio: AudioLibrary.CRAFT_CASK }, 'water tank': { name: _('water tank'), @@ -200,24 +211,26 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('never go thirsty again'), - cost: function() { + cost: function () { return { 'iron': 100, 'steel': 50 }; - } + }, + audio: AudioLibrary.CRAFT_WATER_TANK }, 'bone spear': { name: _('bone spear'), button: null, type: 'weapon', buildMsg: _("this spear's not elegant, but it's pretty good at stabbing"), - cost: function() { + cost: function () { return { 'wood': 100, 'teeth': 5 }; - } + }, + audio: AudioLibrary.CRAFT_BONE_SPEAR }, 'rucksack': { name: _('rucksack'), @@ -225,11 +238,12 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('carrying more means longer expeditions to the wilds'), - cost: function() { + cost: function () { return { 'leather': 200 }; - } + }, + audio: AudioLibrary.CRAFT_RUCKSACK }, 'wagon': { name: _('wagon'), @@ -237,12 +251,13 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('the wagon can carry a lot of supplies'), - cost: function() { + cost: function () { return { 'wood': 500, 'iron': 100 }; - } + }, + audio: AudioLibrary.CRAFT_WAGON }, 'convoy': { name: _('convoy'), @@ -250,248 +265,268 @@ var Room = { type: 'upgrade', maximum: 1, buildMsg: _('the convoy can haul mostly everything'), - cost: function() { + cost: function () { return { 'wood': 1000, 'iron': 200, 'steel': 100 }; - } + }, + audio: AudioLibrary.CRAFT_CONVOY }, 'l armour': { name: _('l armour'), type: 'upgrade', maximum: 1, buildMsg: _("leather's not strong. better than rags, though."), - cost: function() { + cost: function () { return { 'leather': 200, 'scales': 20 }; - } + }, + audio: AudioLibrary.CRAFT_LEATHER_ARMOUR }, 'i armour': { name: _('i armour'), type: 'upgrade', maximum: 1, buildMsg: _("iron's stronger than leather"), - cost: function() { + cost: function () { return { 'leather': 200, 'iron': 100 }; - } + }, + audio: AudioLibrary.CRAFT_IRON_ARMOUR }, 's armour': { name: _('s armour'), type: 'upgrade', maximum: 1, buildMsg: _("steel's stronger than iron"), - cost: function() { + cost: function () { return { 'leather': 200, 'steel': 100 }; - } + }, + audio: AudioLibrary.CRAFT_STEEL_ARMOUR }, 'iron sword': { name: _('iron sword'), button: null, type: 'weapon', buildMsg: _("sword is sharp. good protection out in the wilds."), - cost: function() { + cost: function () { return { 'wood': 200, 'leather': 50, 'iron': 20 }; - } + }, + audio: AudioLibrary.CRAFT_IRON_SWORD }, 'steel sword': { name: _('steel sword'), button: null, type: 'weapon', buildMsg: _("the steel is strong, and the blade true."), - cost: function() { + cost: function () { return { 'wood': 500, 'leather': 100, 'steel': 20 }; - } + }, + audio: AudioLibrary.CRAFT_STEEL_SWORD }, 'rifle': { name: _('rifle'), type: 'weapon', buildMsg: _("black powder and bullets, like the old days."), - cost: function() { + cost: function () { return { 'wood': 200, 'steel': 50, 'sulphur': 50 }; - } + }, + audio: AudioLibrary.CRAFT_RIFLE } }, - + TradeGoods: { 'scales': { type: 'good', - cost: function() { + cost: function () { return { fur: 150 }; - } + }, + audio: AudioLibrary.BUY_SCALES }, 'teeth': { type: 'good', - cost: function() { + cost: function () { return { fur: 300 }; - } + }, + audio: AudioLibrary.BUY_TEETH }, 'iron': { type: 'good', - cost: function() { + cost: function () { return { 'fur': 150, 'scales': 50 }; - } + }, + audio: AudioLibrary.BUY_IRON }, 'coal': { type: 'good', - cost: function() { + cost: function () { return { 'fur': 200, 'teeth': 50 }; - } + }, + audio: AudioLibrary.BUY_COAL }, 'steel': { type: 'good', - cost: function() { + cost: function () { return { 'fur': 300, 'scales': 50, 'teeth': 50 }; - } + }, + audio: AudioLibrary.BUY_STEEL }, 'medicine': { type: 'good', - cost: function() { + cost: function () { return { 'scales': 50, 'teeth': 30 }; - } + }, + audio: AudioLibrary.BUY_MEDICINE }, 'bullets': { type: 'good', - cost: function() { + cost: function () { return { 'scales': 10 }; - } + }, + audio: AudioLibrary.BUY_BULLETS }, 'energy cell': { type: 'good', - cost: function() { + cost: function () { return { 'scales': 10, 'teeth': 10 }; - } + }, + audio: AudioLibrary.BUY_ENERGY_CELL }, 'bolas': { type: 'weapon', - cost: function() { + cost: function () { return { 'teeth': 10 }; - } + }, + audio: AudioLibrary.BUY_BOLAS }, 'grenade': { type: 'weapon', - cost: function() { + cost: function () { return { 'scales': 100, 'teeth': 50 }; - } + }, + audio: AudioLibrary.BUY_GRENADES }, 'bayonet': { type: 'weapon', - cost: function() { + cost: function () { return { 'scales': 500, 'teeth': 250 }; - } + }, + audio: AudioLibrary.BUY_BAYONET }, 'alien alloy': { type: 'good', - cost: function() { + cost: function () { return { 'fur': 1500, 'scales': 750, 'teeth': 300 }; - } + }, + audio: AudioLibrary.BUY_ALIEN_ALLOY }, 'compass': { type: 'special', maximum: 1, - cost: function() { - return { - fur: 400, - scales: 20, - teeth: 10 + cost: function () { + return { + fur: 400, + scales: 20, + teeth: 10 }; - } + }, + audio: AudioLibrary.BUY_COMPASS } }, - + MiscItems: { 'laser rifle': { type: 'weapon' } }, - + name: _("Room"), - init: function(options) { + init: function (options) { this.options = $.extend( this.options, options ); - + Room.pathDiscovery = Boolean($SM.get('stores["compass"]')); - if(Engine._debug) { + if (Engine._debug) { this._ROOM_WARM_DELAY = 5000; this._BUILDER_STATE_DELAY = 5000; this._STOKE_COOLDOWN = 0; this._NEED_WOOD_DELAY = 5000; } - - if(typeof $SM.get('features.location.room') == 'undefined') { + + if (typeof $SM.get('features.location.room') == 'undefined') { $SM.set('features.location.room', true); $SM.set('game.builder.level', -1); } - + // If this is the first time playing, the fire is dead and it's freezing. // Otherwise grab past save state temp and fire level. - $SM.set('game.temperature', $SM.get('game.temperature.value')===undefined?this.TempEnum.Freezing:$SM.get('game.temperature')); - $SM.set('game.fire', $SM.get('game.fire.value')===undefined?this.FireEnum.Dead:$SM.get('game.fire')); - + $SM.set('game.temperature', $SM.get('game.temperature.value') === undefined ? this.TempEnum.Freezing : $SM.get('game.temperature')); + $SM.set('game.fire', $SM.get('game.fire.value') === undefined ? this.FireEnum.Dead : $SM.get('game.fire')); + // Create the room tab this.tab = Header.addLocation(_("A Dark Room"), "room", Room); - + // Create the Room panel this.panel = $('
') .attr('id', "roomPanel") .addClass('location') .appendTo('div#locationSlider'); - + Engine.updateSlider(); - + // Create the light button new Button.Button({ id: 'lightButton', @@ -499,9 +534,9 @@ var Room = { click: Room.lightFire, cooldown: Room._STOKE_COOLDOWN, width: '80px', - cost: {'wood': 5} + cost: { 'wood': 5 } }).appendTo('div#roomPanel'); - + // Create the stoke button new Button.Button({ id: 'stokeButton', @@ -509,23 +544,23 @@ var Room = { click: Room.stokeFire, cooldown: Room._STOKE_COOLDOWN, width: '80px', - cost: {'wood': 1} + cost: { 'wood': 1 } }).appendTo('div#roomPanel'); - + // Create the stores container $('
').attr('id', 'storesContainer').prependTo('div#roomPanel'); - + //subscribe to stateUpdates $.Dispatch('stateUpdate').subscribe(Room.handleStateUpdates); - + Room.updateButton(); Room.updateStoresView(); Room.updateIncomeView(); Room.updateBuildButtons(); - + Room._fireTimer = Engine.setTimeout(Room.coolFire, Room._FIRE_COOL_DELAY); Room._tempTimer = Engine.setTimeout(Room.adjustTemp, Room._ROOM_WARM_DELAY); - + /* * Builder states: * 0 - Approaching @@ -534,10 +569,10 @@ var Room = { * 3 - Sleeping * 4 - Helping */ - if($SM.get('game.builder.level') >= 0 && $SM.get('game.builder.level') < 3) { + if ($SM.get('game.builder.level') >= 0 && $SM.get('game.builder.level') < 3) { Room._builderTimer = Engine.setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); } - if($SM.get('game.builder.level') == 1 && $SM.get('stores.wood', true) < 0) { + if ($SM.get('game.builder.level') == 1 && $SM.get('stores.wood', true) < 0) { Engine.setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY); } Engine.setTimeout($SM.collectIncome, 1000); @@ -545,33 +580,35 @@ var Room = { Notifications.notify(Room, _("the room is {0}", Room.TempEnum.fromInt($SM.get('game.temperature.value')).text)); Notifications.notify(Room, _("the fire is {0}", Room.FireEnum.fromInt($SM.get('game.fire.value')).text)); }, - + options: {}, // Nothing for now - - onArrival: function(transition_diff) { + + onArrival: function (transition_diff) { Room.setTitle(); - if(Room.changed) { + if (Room.changed) { Notifications.notify(Room, _("the fire is {0}", Room.FireEnum.fromInt($SM.get('game.fire.value')).text)); Notifications.notify(Room, _("the room is {0}", Room.TempEnum.fromInt($SM.get('game.temperature.value')).text)); Room.changed = false; } - if($SM.get('game.builder.level') == 3) { + if ($SM.get('game.builder.level') == 3) { $SM.add('game.builder.level', 1); $SM.setIncome('builder', { delay: 10, - stores: {'wood' : 2 } + stores: { 'wood': 2 } }); Room.updateIncomeView(); Notifications.notify(Room, _("the stranger is standing by the fire. she says she can help. says she builds things.")); } Engine.moveStoresView(null, transition_diff); + + Room.setMusic(); }, - + TempEnum: { - fromInt: function(value) { - for(var k in this) { - if(typeof this[k].value != 'undefined' && this[k].value == value) { + fromInt: function (value) { + for (var k in this) { + if (typeof this[k].value != 'undefined' && this[k].value == value) { return this[k]; } } @@ -583,11 +620,11 @@ var Room = { Warm: { value: 3, text: _('warm') }, Hot: { value: 4, text: _('hot') } }, - + FireEnum: { - fromInt: function(value) { - for(var k in this) { - if(typeof this[k].value != 'undefined' && this[k].value == value) { + fromInt: function (value) { + for (var k in this) { + if (typeof this[k].value != 'undefined' && this[k].value == value) { return this[k]; } } @@ -599,33 +636,33 @@ var Room = { Burning: { value: 3, text: _('burning') }, Roaring: { value: 4, text: _('roaring') } }, - - setTitle: function() { + + setTitle: function () { var title = $SM.get('game.fire.value') < 2 ? _("A Dark Room") : _("A Firelit Room"); - if(Engine.activeModule == this) { + if (Engine.activeModule == this) { document.title = title; } $('div#location_room').text(title); }, - - updateButton: function() { + + updateButton: function () { var light = $('#lightButton.button'); var stoke = $('#stokeButton.button'); - if($SM.get('game.fire.value') == Room.FireEnum.Dead.value && stoke.css('display') != 'none') { + if ($SM.get('game.fire.value') == Room.FireEnum.Dead.value && stoke.css('display') != 'none') { stoke.hide(); light.show(); - if(stoke.hasClass('disabled')) { + if (stoke.hasClass('disabled')) { Button.cooldown(light); } - } else if(light.css('display') != 'none') { + } else if (light.css('display') != 'none') { stoke.show(); light.hide(); - if(light.hasClass('disabled')) { + if (light.hasClass('disabled')) { Button.cooldown(stoke); } } - - if(!$SM.get('stores.wood')) { + + if (!$SM.get('stores.wood')) { light.addClass('free'); stoke.addClass('free'); } else { @@ -633,215 +670,222 @@ var Room = { stoke.removeClass('free'); } }, - + _fireTimer: null, _tempTimer: null, - lightFire: function() { + lightFire: function () { var wood = $SM.get('stores.wood'); - if(wood < 5) { + if (wood < 5) { Notifications.notify(Room, _("not enough wood to get the fire going")); Button.clearCooldown($('#lightButton.button')); return; - } else if(wood > 4) { + } else if (wood > 4) { $SM.set('stores.wood', wood - 5); } $SM.set('game.fire', Room.FireEnum.Burning); + AudioEngine.playSound(AudioLibrary.LIGHT_FIRE); Room.onFireChange(); }, - - stokeFire: function() { + + stokeFire: function () { var wood = $SM.get('stores.wood'); - if(wood === 0) { + if (wood === 0) { Notifications.notify(Room, _("the wood has run out")); Button.clearCooldown($('#stokeButton.button')); return; } - if(wood > 0) { + if (wood > 0) { $SM.set('stores.wood', wood - 1); } - if($SM.get('game.fire.value') < 4) { + if ($SM.get('game.fire.value') < 4) { $SM.set('game.fire', Room.FireEnum.fromInt($SM.get('game.fire.value') + 1)); } + AudioEngine.playSound(AudioLibrary.STOKE_FIRE); Room.onFireChange(); }, - - onFireChange: function() { - if(Engine.activeModule != Room) { + + onFireChange: function () { + if (Engine.activeModule != Room) { Room.changed = true; } Notifications.notify(Room, _("the fire is {0}", Room.FireEnum.fromInt($SM.get('game.fire.value')).text), true); - if($SM.get('game.fire.value') > 1 && $SM.get('game.builder.level') < 0) { + if ($SM.get('game.fire.value') > 1 && $SM.get('game.builder.level') < 0) { $SM.set('game.builder.level', 0); Notifications.notify(Room, _("the light from the fire spills from the windows, out into the dark")); Engine.setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); - } + } window.clearTimeout(Room._fireTimer); Room._fireTimer = Engine.setTimeout(Room.coolFire, Room._FIRE_COOL_DELAY); Room.updateButton(); Room.setTitle(); + + // only update music if in the room + if (Engine.activeModule == Room) { + Room.setMusic(); + } }, - - coolFire: function() { + + coolFire: function () { var wood = $SM.get('stores.wood'); - if($SM.get('game.fire.value') <= Room.FireEnum.Flickering.value && + if ($SM.get('game.fire.value') <= Room.FireEnum.Flickering.value && $SM.get('game.builder.level') > 3 && wood > 0) { Notifications.notify(Room, _("builder stokes the fire"), true); $SM.set('stores.wood', wood - 1); - $SM.set('game.fire',Room.FireEnum.fromInt($SM.get('game.fire.value') + 1)); + $SM.set('game.fire', Room.FireEnum.fromInt($SM.get('game.fire.value') + 1)); } - if($SM.get('game.fire.value') > 0) { - $SM.set('game.fire',Room.FireEnum.fromInt($SM.get('game.fire.value') - 1)); + if ($SM.get('game.fire.value') > 0) { + $SM.set('game.fire', Room.FireEnum.fromInt($SM.get('game.fire.value') - 1)); Room._fireTimer = Engine.setTimeout(Room.coolFire, Room._FIRE_COOL_DELAY); Room.onFireChange(); } }, - - adjustTemp: function() { + + adjustTemp: function () { var old = $SM.get('game.temperature.value'); - if($SM.get('game.temperature.value') > 0 && $SM.get('game.temperature.value') > $SM.get('game.fire.value')) { - $SM.set('game.temperature',Room.TempEnum.fromInt($SM.get('game.temperature.value') - 1)); - Notifications.notify(Room, _("the room is {0}" , Room.TempEnum.fromInt($SM.get('game.temperature.value')).text), true); + if ($SM.get('game.temperature.value') > 0 && $SM.get('game.temperature.value') > $SM.get('game.fire.value')) { + $SM.set('game.temperature', Room.TempEnum.fromInt($SM.get('game.temperature.value') - 1)); + Notifications.notify(Room, _("the room is {0}", Room.TempEnum.fromInt($SM.get('game.temperature.value')).text), true); } - if($SM.get('game.temperature.value') < 4 && $SM.get('game.temperature.value') < $SM.get('game.fire.value')) { + if ($SM.get('game.temperature.value') < 4 && $SM.get('game.temperature.value') < $SM.get('game.fire.value')) { $SM.set('game.temperature', Room.TempEnum.fromInt($SM.get('game.temperature.value') + 1)); - Notifications.notify(Room, _("the room is {0}" , Room.TempEnum.fromInt($SM.get('game.temperature.value')).text), true); + Notifications.notify(Room, _("the room is {0}", Room.TempEnum.fromInt($SM.get('game.temperature.value')).text), true); } - if($SM.get('game.temperature.value') != old) { + if ($SM.get('game.temperature.value') != old) { Room.changed = true; } Room._tempTimer = Engine.setTimeout(Room.adjustTemp, Room._ROOM_WARM_DELAY); }, - - unlockForest: function() { + + unlockForest: function () { $SM.set('stores.wood', 4); Outside.init(); Notifications.notify(Room, _("the wind howls outside")); Notifications.notify(Room, _("the wood is running out")); Engine.event('progress', 'outside'); }, - - updateBuilderState: function() { + + updateBuilderState: function () { var lBuilder = $SM.get('game.builder.level'); - if(lBuilder === 0) { + if (lBuilder === 0) { Notifications.notify(Room, _("a ragged stranger stumbles through the door and collapses in the corner")); lBuilder = $SM.setget('game.builder.level', 1); Engine.setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY); - } - else if(lBuilder < 3 && $SM.get('game.temperature.value') >= Room.TempEnum.Warm.value) { + } + else if (lBuilder < 3 && $SM.get('game.temperature.value') >= Room.TempEnum.Warm.value) { var msg = ""; - switch(lBuilder) { - case 1: - msg = _("the stranger shivers, and mumbles quietly. her words are unintelligible."); - break; - case 2: - msg = _("the stranger in the corner stops shivering. her breathing calms."); - break; + switch (lBuilder) { + case 1: + msg = _("the stranger shivers, and mumbles quietly. her words are unintelligible."); + break; + case 2: + msg = _("the stranger in the corner stops shivering. her breathing calms."); + break; } Notifications.notify(Room, msg); - if(lBuilder < 3) { + if (lBuilder < 3) { lBuilder = $SM.setget('game.builder.level', lBuilder + 1); } } - if(lBuilder < 3) { + if (lBuilder < 3) { Engine.setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); } Engine.saveGame(); }, - - updateStoresView: function() { + + updateStoresView: function () { var stores = $('div#stores'); var resources = $('div#resources'); var special = $('div#special'); var weapons = $('div#weapons'); var needsAppend = false, rNeedsAppend = false, sNeedsAppend = false, wNeedsAppend = false, newRow = false; - if(stores.length === 0) { + if (stores.length === 0) { stores = $('
').attr({ 'id': 'stores', 'data-legend': _('stores') }).css('opacity', 0); needsAppend = true; } - if(resources.length === 0) { + if (resources.length === 0) { resources = $('
').attr({ id: 'resources' }).css('opacity', 0); rNeedsAppend = true; } - if(special.length === 0) { + if (special.length === 0) { special = $('
').attr({ id: 'special' }).css('opacity', 0); sNeedsAppend = true; } - if(weapons.length === 0) { + if (weapons.length === 0) { weapons = $('
').attr({ 'id': 'weapons', 'data-legend': _('weapons') }).css('opacity', 0); wNeedsAppend = true; } - for(var k in $SM.get('stores')) { - + for (var k in $SM.get('stores')) { + var type = null; - if(Room.Craftables[k]) { + if (Room.Craftables[k]) { type = Room.Craftables[k].type; - } else if(Room.TradeGoods[k]) { + } else if (Room.TradeGoods[k]) { type = Room.TradeGoods[k].type; } else if (Room.MiscItems[k]) { type = Room.MiscItems[k].type; } - + var location; - switch(type) { - case 'upgrade': - // Don't display upgrades on the Room screen - continue; - case 'building': - // Don't display buildings either - continue; - case 'weapon': - location = weapons; - break; - case 'special': - location = special; - break; - default: - location = resources; - break; + switch (type) { + case 'upgrade': + // Don't display upgrades on the Room screen + continue; + case 'building': + // Don't display buildings either + continue; + case 'weapon': + location = weapons; + break; + case 'special': + location = special; + break; + default: + location = resources; + break; } - + var id = "row_" + k.replace(' ', '-'); var row = $('div#' + id, location); - var num = $SM.get('stores["'+k+'"]'); - - if(typeof num != 'number' || isNaN(num)) { + var num = $SM.get('stores["' + k + '"]'); + + if (typeof num != 'number' || isNaN(num)) { // No idea how counts get corrupted, but I have reason to believe that they occassionally do. // Build a little fence around it! num = 0; - $SM.set('stores["'+k+'"]', 0); + $SM.set('stores["' + k + '"]', 0); } - + var lk = _(k); - + // thieves? - if(typeof $SM.get('game.thieves') == 'undefined' && num > 5000 && $SM.get('features.location.world')) { + if (typeof $SM.get('game.thieves') == 'undefined' && num > 5000 && $SM.get('features.location.world')) { $SM.startThieves(); } - - if(row.length === 0) { + + if (row.length === 0) { row = $('
').attr('id', id).addClass('storeRow'); $('
').addClass('row_key').text(lk).appendTo(row); $('
').addClass('row_val').text(Math.floor(num)).appendTo(row); $('
').addClass('clear').appendTo(row); var curPrev = null; - location.children().each(function(i) { + location.children().each(function (i) { var child = $(this); var cName = child.children('.row_key').text(); - if(cName < lk) { + if (cName < lk) { curPrev = child.attr('id'); } }); - if(curPrev == null) { + if (curPrev == null) { row.prependTo(location); } else { row.insertAfter(location.find('#' + curPrev)); @@ -851,55 +895,55 @@ var Room = { $('div#' + row.attr('id') + ' > div.row_val', location).text(Math.floor(num)); } } - - if(rNeedsAppend && resources.children().length > 0) { + + if (rNeedsAppend && resources.children().length > 0) { resources.prependTo(stores); - resources.animate({opacity: 1}, 300, 'linear'); + resources.animate({ opacity: 1 }, 300, 'linear'); } - - if(sNeedsAppend && special.children().length > 0) { + + if (sNeedsAppend && special.children().length > 0) { special.appendTo(stores); - special.animate({opacity: 1}, 300, 'linear'); + special.animate({ opacity: 1 }, 300, 'linear'); } - - if(needsAppend && stores.find('div.storeRow').length > 0) { + + if (needsAppend && stores.find('div.storeRow').length > 0) { stores.appendTo('div#storesContainer'); - stores.animate({opacity: 1}, 300, 'linear'); + stores.animate({ opacity: 1 }, 300, 'linear'); } - - if(wNeedsAppend && weapons.children().length > 0) { + + if (wNeedsAppend && weapons.children().length > 0) { weapons.appendTo('div#storesContainer'); - weapons.animate({opacity: 1}, 300, 'linear'); + weapons.animate({ opacity: 1 }, 300, 'linear'); } - - if(newRow) { + + if (newRow) { Room.updateIncomeView(); } - if($("div#outsidePanel").length) { + if ($("div#outsidePanel").length) { Outside.updateVillage(); } - if($SM.get('stores.compass') && !Room.pathDiscovery){ + if ($SM.get('stores.compass') && !Room.pathDiscovery) { Room.pathDiscovery = true; Path.openPath(); } }, - - updateIncomeView: function() { + + updateIncomeView: function () { var stores = $('div#resources'); var totalIncome = {}; - if(stores.length === 0 || typeof $SM.get('income') == 'undefined') return; - $('div.storeRow', stores).each(function(index, el) { + if (stores.length === 0 || typeof $SM.get('income') == 'undefined') return; + $('div.storeRow', stores).each(function (index, el) { el = $(el); $('div.tooltip', el).remove(); var ttPos = index > 10 ? 'top right' : 'bottom right'; var tt = $('
').addClass('tooltip ' + ttPos); var storeName = el.attr('id').substring(4).replace('-', ' '); - for(var incomeSource in $SM.get('income')) { - var income = $SM.get('income["'+incomeSource+'"]'); - for(var store in income.stores) { - if(store == storeName && income.stores[store] !== 0) { + for (var incomeSource in $SM.get('income')) { + var income = $SM.get('income["' + incomeSource + '"]'); + for (var store in income.stores) { + if (store == storeName && income.stores[store] !== 0) { $('
').addClass('row_key').text(_(incomeSource)).appendTo(tt); $('
') .addClass('row_val') @@ -913,7 +957,7 @@ var Room = { } } } - if(tt.children().length > 0) { + if (tt.children().length > 0) { var total = totalIncome[storeName].income; $('
').addClass('total row_key').text(_('total')).appendTo(tt); $('
').addClass('total row_val').text(Engine.getIncomeMsg(total, totalIncome[storeName].delay)).appendTo(tt); @@ -921,21 +965,21 @@ var Room = { } }); }, - - buy: function(buyBtn) { + + buy: function (buyBtn) { var thing = $(buyBtn).attr('buildThing'); var good = Room.TradeGoods[thing]; - var numThings = $SM.get('stores["'+thing+'"]', true); - if(numThings < 0) numThings = 0; - if(good.maximum <= numThings) { + var numThings = $SM.get('stores["' + thing + '"]', true); + if (numThings < 0) numThings = 0; + if (good.maximum <= numThings) { return; } - + var storeMod = {}; var cost = good.cost(); - for(var k in cost) { - var have = $SM.get('stores["'+k+'"]', true); - if(have < cost[k]) { + for (var k in cost) { + var have = $SM.get('stores["' + k + '"]', true); + if (have < cost[k]) { Notifications.notify(Room, _("not enough " + k)); return false; } else { @@ -943,141 +987,156 @@ var Room = { } } $SM.setM('stores', storeMod); - + Notifications.notify(Room, good.buildMsg); - - $SM.add('stores["'+thing+'"]', 1); + + $SM.add('stores["' + thing + '"]', 1); + + // audio + AudioEngine.playSound(AudioLibrary.BUY); }, - - build: function(buildBtn) { + + build: function (buildBtn) { var thing = $(buildBtn).attr('buildThing'); - if($SM.get('game.temperature.value') <= Room.TempEnum.Cold.value) { + if ($SM.get('game.temperature.value') <= Room.TempEnum.Cold.value) { Notifications.notify(Room, _("builder just shivers")); return false; } var craftable = Room.Craftables[thing]; - - var numThings = 0; - switch(craftable.type) { - case 'good': - case 'weapon': - case 'tool': - case 'upgrade': - numThings = $SM.get('stores["'+thing+'"]', true); - break; - case 'building': - numThings = $SM.get('game.buildings["'+thing+'"]', true); - break; + + var numThings = 0; + switch (craftable.type) { + case 'good': + case 'weapon': + case 'tool': + case 'upgrade': + numThings = $SM.get('stores["' + thing + '"]', true); + break; + case 'building': + numThings = $SM.get('game.buildings["' + thing + '"]', true); + break; } - - if(numThings < 0) numThings = 0; - if(craftable.maximum <= numThings) { + + if (numThings < 0) numThings = 0; + if (craftable.maximum <= numThings) { return; } - + var storeMod = {}; var cost = craftable.cost(); - for(var k in cost) { - var have = $SM.get('stores["'+k+'"]', true); - if(have < cost[k]) { - Notifications.notify(Room, _("not enough "+k)); + for (var k in cost) { + var have = $SM.get('stores["' + k + '"]', true); + if (have < cost[k]) { + Notifications.notify(Room, _("not enough " + k)); return false; } else { storeMod[k] = have - cost[k]; } } $SM.setM('stores', storeMod); - + Notifications.notify(Room, craftable.buildMsg); - - switch(craftable.type) { - case 'good': - case 'weapon': - case 'upgrade': - case 'tool': - $SM.add('stores["'+thing+'"]', 1); - break; - case 'building': - $SM.add('game.buildings["'+thing+'"]', 1); - break; - } + + switch (craftable.type) { + case 'good': + case 'weapon': + case 'upgrade': + case 'tool': + $SM.add('stores["' + thing + '"]', 1); + break; + case 'building': + $SM.add('game.buildings["' + thing + '"]', 1); + break; + } + + // audio + switch (craftable.type) { + case 'weapon': + case 'upgrade': + case 'tool': + AudioEngine.playSound(AudioLibrary.CRAFT); + break; + case 'building': + AudioEngine.playSound(AudioLibrary.BUILD); + break; + } }, - - needsWorkshop: function(type) { - return type == 'weapon' || type == 'upgrade' || type =='tool'; + + needsWorkshop: function (type) { + return type == 'weapon' || type == 'upgrade' || type == 'tool'; }, - - craftUnlocked: function(thing) { - if(Room.buttons[thing]) { + + craftUnlocked: function (thing) { + if (Room.buttons[thing]) { return true; } - if($SM.get('game.builder.level') < 4) return false; + if ($SM.get('game.builder.level') < 4) return false; var craftable = Room.Craftables[thing]; - if(Room.needsWorkshop(craftable.type) && $SM.get('game.buildings["'+'workshop'+'"]', true) === 0) return false; + if (Room.needsWorkshop(craftable.type) && $SM.get('game.buildings["' + 'workshop' + '"]', true) === 0) return false; var cost = craftable.cost(); - + //show button if one has already been built - if($SM.get('game.buildings["'+thing+'"]') > 0){ + if ($SM.get('game.buildings["' + thing + '"]') > 0) { Room.buttons[thing] = true; return true; } // Show buttons if we have at least 1/2 the wood, and all other components have been seen. - if($SM.get('stores.wood', true) < cost['wood'] * 0.5) { + if ($SM.get('stores.wood', true) < cost['wood'] * 0.5) { return false; } - for(var c in cost) { - if(!$SM.get('stores["'+c+'"]')) { + for (var c in cost) { + if (!$SM.get('stores["' + c + '"]')) { return false; } } - + Room.buttons[thing] = true; //don't notify if it has already been built before - if(!$SM.get('game.buildings["'+thing+'"]')){ + if (!$SM.get('game.buildings["' + thing + '"]')) { Notifications.notify(Room, craftable.availableMsg); } return true; }, - - buyUnlocked: function(thing) { - if(Room.buttons[thing]) { + + buyUnlocked: function (thing) { + if (Room.buttons[thing]) { return true; - } else if($SM.get('game.buildings["trading post"]', true) > 0) { - if(thing == 'compass' || typeof $SM.get('stores["'+thing+'"]') != 'undefined') { + } else if ($SM.get('game.buildings["trading post"]', true) > 0) { + if (thing == 'compass' || typeof $SM.get('stores["' + thing + '"]') != 'undefined') { // Allow the purchase of stuff once you've seen it return true; } } return false; }, - - updateBuildButtons: function() { + + updateBuildButtons: function () { var buildSection = $('#buildBtns'); var needsAppend = false; - if(buildSection.length === 0) { - buildSection = $('
').attr({'id': 'buildBtns', 'data-legend': _('build:')}).css('opacity', 0); + if (buildSection.length === 0) { + buildSection = $('
').attr({ 'id': 'buildBtns', 'data-legend': _('build:') }).css('opacity', 0); needsAppend = true; } - + var craftSection = $('#craftBtns'); var cNeedsAppend = false; - if(craftSection.length === 0 && $SM.get('game.buildings["workshop"]', true) > 0) { - craftSection = $('
').attr({'id': 'craftBtns', 'data-legend': _('craft:')}).css('opacity', 0); + if (craftSection.length === 0 && $SM.get('game.buildings["workshop"]', true) > 0) { + craftSection = $('
').attr({ 'id': 'craftBtns', 'data-legend': _('craft:') }).css('opacity', 0); cNeedsAppend = true; } - + var buySection = $('#buyBtns'); var bNeedsAppend = false; - if(buySection.length === 0 && $SM.get('game.buildings["trading post"]', true) > 0) { - buySection = $('
').attr({'id': 'buyBtns', 'data-legend': _('buy:')}).css('opacity', 0); + if (buySection.length === 0 && $SM.get('game.buildings["trading post"]', true) > 0) { + buySection = $('
').attr({ 'id': 'buyBtns', 'data-legend': _('buy:') }).css('opacity', 0); bNeedsAppend = true; } - - for(var k in Room.Craftables) { + + for (var k in Room.Craftables) { craftable = Room.Craftables[k]; var max = $SM.num(k, craftable) + 1 > craftable.maximum; - if(craftable.button == null) { - if(Room.craftUnlocked(k)) { + if (craftable.button == null) { + if (Room.craftUnlocked(k)) { var loc = Room.needsWorkshop(craftable.type) ? craftSection : buildSection; craftable.button = new Button.Button({ id: 'build_' + k, @@ -1086,33 +1145,33 @@ var Room = { click: Room.build, width: '80px', ttPos: loc.children().length > 10 ? 'top right' : 'bottom right' - }).css('opacity', 0).attr('buildThing', k).appendTo(loc).animate({opacity: 1}, 300, 'linear'); + }).css('opacity', 0).attr('buildThing', k).appendTo(loc).animate({ opacity: 1 }, 300, 'linear'); } } else { // refresh the tooltip var costTooltip = $('.tooltip', craftable.button); costTooltip.empty(); var cost = craftable.cost(); - for(var c in cost) { + for (var c in cost) { $("
").addClass('row_key').text(_(c)).appendTo(costTooltip); $("
").addClass('row_val').text(cost[c]).appendTo(costTooltip); } - if(max && !craftable.button.hasClass('disabled')) { + if (max && !craftable.button.hasClass('disabled')) { Notifications.notify(Room, craftable.maxMsg); } } - if(max) { + if (max) { Button.setDisabled(craftable.button, true); } else { Button.setDisabled(craftable.button, false); } } - - for(var g in Room.TradeGoods) { + + for (var g in Room.TradeGoods) { good = Room.TradeGoods[g]; var goodsMax = $SM.num(g, good) + 1 > good.maximum; - if(good.button == null) { - if(Room.buyUnlocked(g)) { + if (good.button == null) { + if (Room.buyUnlocked(g)) { good.button = new Button.Button({ id: 'build_' + g, cost: good.cost(), @@ -1120,55 +1179,77 @@ var Room = { click: Room.buy, width: '80px', ttPos: buySection.children().length > 10 ? 'top right' : 'bottom right' - }).css('opacity', 0).attr('buildThing', g).appendTo(buySection).animate({opacity:1}, 300, 'linear'); + }).css('opacity', 0).attr('buildThing', g).appendTo(buySection).animate({ opacity: 1 }, 300, 'linear'); } } else { // refresh the tooltip var goodsCostTooltip = $('.tooltip', good.button); goodsCostTooltip.empty(); var goodCost = good.cost(); - for(var gc in goodCost) { + for (var gc in goodCost) { $("
").addClass('row_key').text(_(gc)).appendTo(goodsCostTooltip); $("
").addClass('row_val').text(goodCost[gc]).appendTo(goodsCostTooltip); } - if(goodsMax && !good.button.hasClass('disabled')) { + if (goodsMax && !good.button.hasClass('disabled')) { Notifications.notify(Room, good.maxMsg); } } - if(goodsMax) { + if (goodsMax) { Button.setDisabled(good.button, true); } else { Button.setDisabled(good.button, false); } } - - if(needsAppend && buildSection.children().length > 0) { - buildSection.appendTo('div#roomPanel').animate({opacity: 1}, 300, 'linear'); + + if (needsAppend && buildSection.children().length > 0) { + buildSection.appendTo('div#roomPanel').animate({ opacity: 1 }, 300, 'linear'); } - if(cNeedsAppend && craftSection.children().length > 0) { - craftSection.appendTo('div#roomPanel').animate({opacity: 1}, 300, 'linear'); + if (cNeedsAppend && craftSection.children().length > 0) { + craftSection.appendTo('div#roomPanel').animate({ opacity: 1 }, 300, 'linear'); } - if(bNeedsAppend && buildSection.children().length > 0) { - buySection.appendTo('div#roomPanel').animate({opacity: 1}, 300, 'linear'); + if (bNeedsAppend && buildSection.children().length > 0) { + buySection.appendTo('div#roomPanel').animate({ opacity: 1 }, 300, 'linear'); } }, - - compassTooltip: function(direction){ + + compassTooltip: function (direction) { var ttPos = $('div#resources').children().length > 10 ? 'top right' : 'bottom right'; var tt = $('
').addClass('tooltip ' + ttPos); - $('
').addClass('row_key').text(_('the compass points '+ direction)).appendTo(tt); + $('
').addClass('row_key').text(_('the compass points ' + direction)).appendTo(tt); tt.appendTo($('#row_compass')); }, - - handleStateUpdates: function(e){ - if(e.category == 'stores'){ + + handleStateUpdates: function (e) { + if (e.category == 'stores') { Room.updateStoresView(); Room.updateBuildButtons(); - } else if(e.category == 'income'){ + } else if (e.category == 'income') { Room.updateStoresView(); Room.updateIncomeView(); - } else if(e.stateName.indexOf('game.buildings') === 0){ + } else if (e.stateName.indexOf('game.buildings') === 0) { Room.updateBuildButtons(); } + }, + + setMusic() { + // set music based on fire level + var fireValue = $SM.get('game.fire.value'); + switch (fireValue) { + case 0: + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_FIRE_DEAD); + break; + case 1: + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_FIRE_SMOLDERING); + break; + case 2: + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_FIRE_FLICKERING); + break; + case 3: + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_FIRE_BURNING); + break; + case 4: + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_FIRE_ROARING); + break; + } } }; diff --git a/script/ship.js b/script/ship.js index a513f9d..3cfd1bc 100644 --- a/script/ship.js +++ b/script/ship.js @@ -7,7 +7,6 @@ var Ship = { ALLOY_PER_THRUSTER: 1, BASE_HULL: 0, BASE_THRUSTERS: 1, - name: _("Ship"), init: function(options) { this.options = $.extend( @@ -91,6 +90,7 @@ var Ship = { Notifications.notify(Ship, _('somewhere above the debris cloud, the wanderer fleet hovers. been on this rock too long.')); $SM.set('game.spaceShip.seenShip', true); } + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_SHIP); Engine.moveStoresView(null, transition_diff); }, @@ -112,6 +112,7 @@ var Ship = { Button.setDisabled($('#liftoffButton', Ship.panel), false); } $('#hullRow .row_val', Ship.panel).text($SM.get('game.spaceShip.hull')); + AudioEngine.playSound(AudioLibrary.REINFORCE_HULL); }, upgradeEngine: function() { @@ -122,6 +123,7 @@ var Ship = { $SM.add('stores["alien alloy"]', -Ship.ALLOY_PER_THRUSTER); $SM.add('game.spaceShip.thrusters', 1); $('#engineRow .row_val', Ship.panel).text($SM.get('game.spaceShip.thrusters')); + AudioEngine.playSound(AudioLibrary.UPGRADE_ENGINE); }, getMaxHull: function() { @@ -166,6 +168,7 @@ var Ship = { $('#outerSlider').animate({top: '700px'}, 300); Space.onArrival(); Engine.activeModule = Space; + AudioEngine.playSound(AudioLibrary.LIFT_OFF); }, handleStateUpdates: function(e){ diff --git a/script/space.js b/script/space.js index 0c4c235..eb109c0 100644 --- a/script/space.js +++ b/script/space.js @@ -11,7 +11,6 @@ var Space = { NUM_STARS: 200, STAR_SPEED: 60000, FRAME_DELAY: 100, - stars: null, backStars: null, ship: null, @@ -54,6 +53,7 @@ var Space = { Space.hull = Ship.getMaxHull(); Space.altitude = 0; Space.setTitle(); + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_SPACE); Space.updateHull(); Space.up = @@ -67,6 +67,8 @@ var Space = { }); Space.startAscent(); Space._shipTimer = setInterval(Space.moveShip, 33); + Space._volumeTimer = setInterval(Space.lowerVolume, 1000); + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_SPACE); }, setTitle: function() { @@ -136,6 +138,21 @@ var Space = { t.remove(); Space.hull--; Space.updateHull(); + + // play audio on asteroid hit + // higher altitudes play higher frequency hits + var r = Math.floor(Math.random() * 2); + if(Space.altitude > 40) { + r += 6; + AudioEngine.playSound(AudioLibrary['ASTEROID_HIT_' + r]); + } else if(Space.altitude > 20) { + r += 4; + AudioEngine.playSound(AudioLibrary['ASTEROID_HIT_' + r]); + } else { + r += 1; + AudioEngine.playSound(AudioLibrary['ASTEROID_HIT_' + r]); + } + if(Space.hull === 0) { Space.crash(); } @@ -221,7 +238,7 @@ var Space = { left: x + 'px', top: y + 'px' }); - + Space.lastMove = Date.now(); }, @@ -325,6 +342,7 @@ var Space = { Space.done = true; clearInterval(Space._timer); clearInterval(Space._shipTimer); + clearInterval(Space._volumeTimer); clearTimeout(Space._panelTimeout); var body_color; if (Engine.isLightsOff()) @@ -358,6 +376,7 @@ var Space = { Ship.onArrival(); Button.cooldown($('#liftoffButton')); Engine.event('progress', 'crash'); + AudioEngine.playSound(AudioLibrary.CRASH); }, endGame: function() { @@ -366,6 +385,7 @@ var Space = { Space.done = true; clearInterval(Space._timer); clearInterval(Space._shipTimer); + clearInterval(Space._volumeTimer); clearTimeout(Engine._saveTimer); clearTimeout(Outside._popTimeout); clearTimeout(Engine._incomeTimeout); @@ -380,6 +400,8 @@ var Space = { } delete Outside._popTimeout; + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_ENDING); + $('#hullRemaining', Space.panel).animate({opacity: 0}, 500, 'linear'); Space.ship.animate({ top: '350px', @@ -532,5 +554,14 @@ var Space = { handleStateUpdates: function(e){ + }, + + lowerVolume: function () { + if (Space.done) return; + + // lower audio as ship gets further into space + var progress = Space.altitude / 60; + var newVolume = 1.0 - progress; + AudioEngine.setBackgroundMusicVolume(newVolume, 0.3); } }; diff --git a/script/world.js b/script/world.js index 12b1950..f6dc6d5 100644 --- a/script/world.js +++ b/script/world.js @@ -1,5 +1,4 @@ var World = { - RADIUS: 30, VILLAGE_POS: [30, 30], TILE: { @@ -347,6 +346,11 @@ var World = { World.lightMap(World.curPos[0], World.curPos[1], World.state.mask); World.drawMap(); World.doSpace(); + + // play random footstep + var randomFootstep = Math.floor(Math.random() * 5) + 1; + AudioEngine.playSound(AudioLibrary['FOOTSTEPS_' + randomFootstep]); + if(World.checkDanger()) { if(World.danger) { Notifications.notify(World, _('dangerous to be this far from the village without proper protection')); @@ -534,6 +538,7 @@ var World = { } else if(typeof World.LANDMARKS[curTile] != 'undefined') { if(curTile != World.TILE.OUTPOST || !World.outpostUsed()) { Events.startEvent(Events.Setpieces[World.LANDMARKS[curTile].scene]); + AudioEngine.playEventMusic(Events.Setpieces[World.LANDMARKS[curTile].scene].audio); } } else { if(World.useSupplies()) { @@ -883,6 +888,7 @@ var World = { World.state = null; Path.outfit = {}; $SM.remove('outfit'); + AudioEngine.playSound(AudioLibrary.DEATH); $('#outerSlider').animate({opacity: '0'}, 600, 'linear', function() { $('#outerSlider').css('left', '0px'); $('#locationSlider').css('left', '0px'); @@ -1006,6 +1012,7 @@ var World = { World.curPos = World.copyPos(World.VILLAGE_POS); World.drawMap(); World.setTitle(); + AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_WORLD); World.dead = false; $('div#bagspace-world > div').empty(); World.updateSupplies(); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..a2134bf --- /dev/null +++ b/yarn.lock @@ -0,0 +1,368 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=