From 09bdd90a0bcf6b344cdbf4bdbcc06d18a71b6ba1 Mon Sep 17 00:00:00 2001 From: Igor Santos de Lima Date: Fri, 16 Mar 2018 22:26:40 -0300 Subject: [PATCH 1/2] :star2: Sound Manager Improvement(BGM Volume and FX Volume) --- .vscode/settings.json | 5 +++++ README.md | 30 ++++++++++++++++++++++++++++++ config.json | 2 +- package-lock.json | 2 +- src/client/audiomanager.js | 23 ++++++++++++++++++++++- src/client/maplecharacter.js | 29 +++++++++++++++-------------- src/client/monster.js | 17 +++++++++-------- src/client/playaudio.js | 5 +++-- src/client/uicommon.js | 17 +++++++++-------- src/client/uilogin.js | 6 +++--- 10 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..75341fa --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "favorites.resources": [ + "src\\server\\server.js" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index d1ffbbf..6426aff 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,33 @@ * `npm install` * `npm run local` to start the application with inspectable client code. * `npm run dev` to start the application with minified IIFE client code. + + +## Ragezone Post + +* Hi all, + +* After futzing around with the physics, I've come to realize that replicating the physics from the original client will be a much harder task than I anticipated. As such, I will have to slow down development and take time to do research and reverse engineer (as best as possible) the physics. You won't see many updates in the near future, but I assure you all that I am still actively working on this project. + +* Additionally, because I spent a lot of time working on the client, I acknowledge that some very important things are lacking: documentation and unit tests. These will be added soon. + +* In lieu of updates, I am opening up the project for anyone to clone and play around with. See it here: https://github.com/johncintron/nodin. + +* Edit: Answers to what I suspect will be FAQs: + +* How do I get past the login screen? +* Go in the developer console and enter: LoginState.enterGame(); You can also move up the login map by mutating the Camera.y attribute. + +* How do I switch maps? +* MapleMap.load(id); where id is the map id you want to load. + +* How do I attach equips to the character? +* MyCharacter.attachEquip(slot, id); where slot is the equip slot and id is the equip id. + +* How do I spawn another player? +* MapleCharacter.fromOpts(obj).then(m => MapleMap.characters.push(m)); + +* Why no WebGL? +* I ditched Phaser because it was too heavy and some MapleStory-specific things were hard to implement using Phaser. Implementing the rendering engine in WebGL would have taken me forever and the game as it stands today runs at 60 FPS on Firefox and Chrome with an i7 processor. + +* If anyone wishes to contribute, feel free to PM me and I will add you as a collaborator. I welcome all pull requests! \ No newline at end of file diff --git a/config.json b/config.json index 7ba64aa..4595d31 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,4 @@ { - "PORT": 8000, + "PORT": 8100, "SERVER_WZ_ROOT_DIR": "./wz_server/" } diff --git a/package-lock.json b/package-lock.json index 52f3d1e..9d6fbaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "nodin_browser", + "name": "nodin", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/src/client/audiomanager.js b/src/client/audiomanager.js index c5fddca..3ce9968 100644 --- a/src/client/audiomanager.js +++ b/src/client/audiomanager.js @@ -2,7 +2,10 @@ import WZManager from './wzmanager'; const AudioManager = {}; -AudioManager.playBGM = async function(name) { +var musicVolume = 1; +var SFXVolume = 1; + +AudioManager.playBGM = async function (name) { if (name !== this.bgmName) { if (!!this.bgm) { this.bgm.pause(); @@ -13,11 +16,29 @@ AudioManager.playBGM = async function(name) { return; } const [filename, child] = name.split('/'); + console.log(filename, child); const wzNode = await WZManager.get(`Sound.wz/${filename}.img/${child}`); this.bgm = wzNode.nGetAudio(); this.bgm.loop = true; this.bgm.play(); + + //Debug + this.setMusicVolume(0.01); + this.setSFXVolume(0.01); } }; +AudioManager.setMusicVolume = async function (vol) { + if (typeof (vol) === 'number') { + this.musicVolume = vol; + this.bgm.volume = this.musicVolume; + } +} + +AudioManager.setSFXVolume = async function (vol) { + if (typeof (vol) === 'number') { + this.SFXVolume = vol; + } +} + export default AudioManager; diff --git a/src/client/maplecharacter.js b/src/client/maplecharacter.js index 2a8ea38..b69d131 100644 --- a/src/client/maplecharacter.js +++ b/src/client/maplecharacter.js @@ -1,3 +1,4 @@ +import AudioManager from './audiomanager'; import WZManager from './wzmanager'; import DRAW_IMAGE from './drawimage'; import DRAW_TEXT from './drawtext'; @@ -80,13 +81,13 @@ class MapleCharacter { await this.setHair(this.hair); this.setStance(this.stance); } - async setSkinColor(sc=0) { + async setSkinColor(sc = 0) { this.head = await WZManager.get(`Character.wz/0001200${sc}.img`); this.body = await WZManager.get(`Character.wz/0000200${sc}.img`); this.baseBody = await WZManager.get(`Character.wz/00002000.img`); this.skinColor = sc; } - setStance(stance='stand1', frame=0) { + setStance(stance = 'stand1', frame = 0) { if (!!this.baseBody[stance]) { this.stance = stance; this.setFrame(frame); @@ -94,7 +95,7 @@ class MapleCharacter { this.oscillateFactor = 1; } } - setFrame(frame=0, carryOverDelay=0) { + setFrame(frame = 0, carryOverDelay = 0) { this.frame = !this.baseBody[this.stance][frame] ? 0 : frame; this.delay = carryOverDelay; @@ -107,31 +108,31 @@ class MapleCharacter { if (!this.oscillateFrames) { this.setFrame(this.frame + 1, carryOverDelay); } else { - const nextFrame = this.frame + 1*this.oscillateFactor; + const nextFrame = this.frame + 1 * this.oscillateFactor; if (!this.baseBody[this.stance][nextFrame]) { this.oscillateFactor *= -1; } - const nextOscillatedFrame = this.frame + 1*this.oscillateFactor; + const nextOscillatedFrame = this.frame + 1 * this.oscillateFactor; this.setFrame(nextOscillatedFrame, carryOverDelay); } } - async setFace(face=20000) { + async setFace(face = 20000) { this.Face = await WZManager.get(`Character.wz/Face/000${face}.img`); this.face = face; } - setFaceExpr(faceExpr='blink', faceFrame=0) { + setFaceExpr(faceExpr = 'blink', faceFrame = 0) { if (!!this.Face[faceExpr]) { this.faceExpr = faceExpr; this.setFaceFrame(faceFrame); } } - setFaceFrame(faceFrame=0) { + setFaceFrame(faceFrame = 0) { this.faceFrame = !this.Face[this.faceExpr][faceFrame] ? 0 : faceFrame; } advanceFaceFrame() { this.setFaceFrame(this.faceFrame + 1); } - async setHair(hair=30030) { + async setHair(hair = 30030) { this.Hair = await WZManager.get(`Character.wz/Hair/000${hair}.img`); this.hair = hair; } @@ -214,7 +215,7 @@ class MapleCharacter { const lu = await WZManager.get('Effect.wz/BasicEff.img/LevelUp'); this.levelUpFrames = lu.nChildren; - PLAY_AUDIO(levelUpAudio); + PLAY_AUDIO(levelUpAudio, AudioManager.SFXVolume); this.levelingUp = true; this.levelUpFrame = 0; this.levelUpDelay = 0; @@ -257,8 +258,8 @@ class MapleCharacter { const twoChars = /.{1,2}/g; const [hat, faceAcc, ...equips] = this.equips; - const hatVslot = !hat? '' : hat.info.vslot.nValue; - const hatParts = !hat? [] : getParts(hat).filter(isDrawable); + const hatVslot = !hat ? '' : hat.info.vslot.nValue; + const hatParts = !hat ? [] : getParts(hat).filter(isDrawable); const hatSmapValues = hatParts.reduce((acc, p) => { try { const part = p.nTagName === 'uol' ? p.nResolveUOL() : p; @@ -309,7 +310,7 @@ class MapleCharacter { }); const originX = part.origin.nX; - const adjustX = !flipped ? originX : (part.nWidth-originX); + const adjustX = !flipped ? originX : (part.nWidth - originX); x -= adjustX; y -= part.origin.nY; @@ -432,7 +433,7 @@ class MapleCharacter { align: 'center', }; const nameWidth = Math.ceil(MEASURE_TEXT(nameOpts).width + tagPadding); - const nameTagX = Math.round(this.x - camera.x - nameWidth/2); + const nameTagX = Math.round(this.x - camera.x - nameWidth / 2); DRAW_RECT({ x: nameTagX, y: Math.floor(this.y - camera.y + offsetFromY), diff --git a/src/client/monster.js b/src/client/monster.js index 979781b..ecf9c27 100644 --- a/src/client/monster.js +++ b/src/client/monster.js @@ -1,3 +1,4 @@ +import AudioManager from './audiomanager'; import WZManager from './wzmanager'; import PLAY_AUDIO from './playaudio'; import DRAW_IMAGE from './drawimage'; @@ -49,7 +50,7 @@ class Monster { this.setFrame(!this.stances.fly ? 'stand' : 'fly', 0); } - loadStance(wzNode={}, stance='stand') { + loadStance(wzNode = {}, stance = 'stand') { if (!wzNode[stance]) { return { frames: [], @@ -73,7 +74,7 @@ class Monster { } playAudio(name) { if (!!this.sounds[name]) { - PLAY_AUDIO(this.sounds[name]); + PLAY_AUDIO(this.sounds[name], AudioManager.SFXVolume); } } die() { @@ -84,7 +85,7 @@ class Monster { destroy() { this.destroyed = true; } - setFrame(stance, frame=0, carryOverDelay=0) { + setFrame(stance, frame = 0, carryOverDelay = 0) { if (!this.stances[stance]) { return; } @@ -101,12 +102,12 @@ class Monster { this.delay += msPerTick; if (this.delay > this.nextDelay) { - const hasNextFrame = !!this.stances[this.stance].frames[this.frame+1]; + const hasNextFrame = !!this.stances[this.stance].frames[this.frame + 1]; if (!!this.dying && !hasNextFrame) { this.destroy(); return; } - this.setFrame(this.stance, this.frame+1, this.delay-this.nextDelay); + this.setFrame(this.stance, this.frame + 1, this.delay - this.nextDelay); } } draw(camera, lag, msPerTick, tdelta) { @@ -116,12 +117,12 @@ class Monster { const originX = currentFrame.nGet('origin').nGet('nX', 0); const originY = currentFrame.nGet('origin').nGet('nY', 0); - const adjustX = !this.flipped ? originX : (currentFrame.nWidth-originX); + const adjustX = !this.flipped ? originX : (currentFrame.nWidth - originX); DRAW_IMAGE({ img: currentImage, - dx: this.x-camera.x-adjustX, - dy: this.y-camera.y-originY, + dx: this.x - camera.x - adjustX, + dy: this.y - camera.y - originY, flipped: !!this.flipped, }); } diff --git a/src/client/playaudio.js b/src/client/playaudio.js index 8268907..b1340eb 100644 --- a/src/client/playaudio.js +++ b/src/client/playaudio.js @@ -8,9 +8,10 @@ * @param {Audio} audio - The audio object. * @param {float} [volume=1] - Loudness of audio. */ -function PLAY_AUDIO(audio, volume=1) { + +function PLAY_AUDIO(audio, vol) { const concurrentAudio = audio.cloneNode(); - concurrentAudio.volume = volume; + concurrentAudio.volume = vol; concurrentAudio.play(); } diff --git a/src/client/uicommon.js b/src/client/uicommon.js index f766580..506c2d0 100644 --- a/src/client/uicommon.js +++ b/src/client/uicommon.js @@ -1,11 +1,12 @@ +import AudioManager from './audiomanager'; import DRAW_IMAGE from './drawimage'; import GameCanvas from './gamecanvas'; -import WZManager from './wzmanager'; import PLAY_AUDIO from './playaudio'; +import WZManager from './wzmanager'; const UICommon = {}; -UICommon.initialize = async function() { +UICommon.initialize = async function () { const cursor = await WZManager.get('UI.wz/Basic.img/Cursor'); this.cursorImg = cursor[0][0].nGetImage(); @@ -21,18 +22,18 @@ UICommon.initialize = async function() { this.hoverAudio = sounds.BtMouseOver.nGetAudio(); }; -UICommon.playMouseClickAudio = function() { - PLAY_AUDIO(this.clickAudio); +UICommon.playMouseClickAudio = function () { + PLAY_AUDIO(this.clickAudio, AudioManager.SFXVolume); }; -UICommon.playMouseHoverAudio = function() { - PLAY_AUDIO(this.hoverAudio); +UICommon.playMouseHoverAudio = function () { + PLAY_AUDIO(this.hoverAudio, AudioManager.SFXVolume); }; -UICommon.doUpdate = function(msPerTick) { +UICommon.doUpdate = function (msPerTick) { }; -UICommon.doRender = function(camera, lag, msPerTick, tdelta) { +UICommon.doRender = function (camera, lag, msPerTick, tdelta) { const clicked = GameCanvas.clicked; const cursorImg = !clicked ? this.cursorImg : this.cursorDownImg; const cursorOrigin = !clicked ? this.cursorOrigin : this.cursorDownOrigin; diff --git a/src/client/uilogin.js b/src/client/uilogin.js index 1646bd0..d30b79e 100644 --- a/src/client/uilogin.js +++ b/src/client/uilogin.js @@ -111,7 +111,7 @@ UILogin.doUpdate = function(msPerTick, camera) { this.loginButton.stance = 'normal'; if (this.activeButton === this.loginButton) { - UICommon.playMouseHoverAudio(); + UICommon.playMouseHoverAudio(1); this.loginButton.stance = 'mouseOver'; } } @@ -129,7 +129,7 @@ UILogin.doUpdate = function(msPerTick, camera) { this.loginButton.stance = 'mouseOver'; const trigger = releasedClick && originallyClickedLoginButton; if (trigger) { - UICommon.playMouseClickAudio(); + UICommon.playMouseClickAudio(1); console.log('login!'); } } @@ -141,7 +141,7 @@ UILogin.doUpdate = function(msPerTick, camera) { if (releasedClick && originallyClickedDice && this.canClickDice) { this.canClickDice = false; this.updateDice = true; - UICommon.playMouseClickAudio(); + UICommon.playMouseClickAudio(1); } } From 699c86cd5ca83765bd2b9d0a1cc3d2f80e94ed47 Mon Sep 17 00:00:00 2001 From: Igor Santos de Lima Date: Fri, 16 Mar 2018 22:27:25 -0300 Subject: [PATCH 2/2] :star2: Sound Manager Improvement(BGM Volume and FX Volume) 2 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 832c3c5..a07de09 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /client/wz_client/ /node_modules/ /client/bundle.js +/.vscode/ \ No newline at end of file