diff --git a/script/engine.js b/script/engine.js index ef0d725..bf643c3 100644 --- a/script/engine.js +++ b/script/engine.js @@ -7,6 +7,7 @@ var Engine = { * That would be so elegant and awesome. */ SITE_URL: encodeURIComponent("http://adarkroom.doublespeakgames.com"), + VERSION: 1.2; MAX_STORE: 99999999999999, SAVE_DISPLAY: 30 * 1000, @@ -117,10 +118,10 @@ var Engine = { Events.init(); Room.init(); - if(Engine.storeAvailable('wood')) { + if($SM.get('stores.wood')) { Outside.init(); } - if(Engine.getStore('compass') > 0) { + if($SM.get('stores.compass', true) > 0) { Path.init(); } if($SM.get('features.location.spaceShip')) { @@ -160,41 +161,15 @@ var Engine = { var savedState = JSON.parse(localStorage.gameState); if(savedState) { State = savedState; - Engine.upgradeState(); + $SM.updateOldState(); Engine.log("loaded save!"); } } catch(e) { - State = { - version: 1.2, - }; + $SM.set('verson', Engine.VERSION); Engine.event('progress', 'new game'); } }, - upgradeState: function() { - /* Use this function to make old - * save games compatible with newer versions */ - if(typeof State.version != 'number') { - Engine.log('upgraded save to v1.0'); - State.version = 1.0; - } - if(State.version == 1.0) { - // v1.1 introduced the Lodge, so get rid of lodgeless hunters - delete State.outside.workers.hunter; - delete State.income.hunter; - Engine.log('upgraded save to v1.1'); - State.version = 1.1; - } - if(State.version == 1.1) { - //v1.2 added the Swamp to the map, so add it to already generated maps - if(State.world) { - World.placeLandmark(15, World.RADIUS * 1.5, World.TILE.SWAMP, State.world.map); - } - Engine.log('upgraded save to v1.2'); - State.version = 1.2; - } - }, - event: function(cat, act) { if(typeof ga === 'function') { ga('send', 'event', cat, act); @@ -297,7 +272,7 @@ var Engine = { var diff = Math.abs(panelIndex - currentIndex); slider.animate({left: -(panelIndex * 700) + 'px'}, 300 * diff); - if(Engine.storeAvailable('wood')) { + if($SM.get('stores.wood')) { // FIXME Why does this work if there's an animation queue...? stores.animate({right: -(panelIndex * 700) + 'px'}, 300 * diff); } @@ -321,182 +296,6 @@ var Engine = { Notifications.printQueue(module); } }, - - addPerk: function(name) { - if(!$SM.get('character.perks')) { - $SM.set('character.perks', {}); - } - $SM.set('character.perks[\''+name+'\']', true); - Notifications.notify(null, Engine.Perks[name].notify); - if(Engine.activeModule == Path) { - Path.updatePerks(); - } - }, - - hasPerk: function(name) { - return typeof $SM.get('character.perks') == 'object' && $SM.get('character.perks[\''+name+'\']') == true; - }, - - setStore: function(name, number) { - $SM.set('stores[\''+name+'\']', number); - Room.updateStoresView(); - Room.updateBuildButtons(); - if($SM.get('features.location.outside')) { - Outside.updateVillage(); - } - Engine.saveGame(); - }, - - setStores: function(list) { - for(k in list) { - $SM.set('stores[\''+k+'\']', list[k]); - } - Room.updateStoresView(); - Room.updateBuildButtons(); - if($SM.get('features.location.outside')) { - Outside.updateVillage(); - } - Engine.saveGame(); - }, - - addStore: function(name, number) { - var num = $SM.get('stores[\''+name+'\']'); - if(typeof num != 'number' || isNaN(num) || num < 0) num = 0; - num += number; - if(num > Engine.MAX_STORE) num = Engine.MAX_STORE; - $SM.set('stores[\''+name+'\']', num); - Room.updateStoresView(); - Room.updateBuildButtons(); - Outside.updateVillage(); - if(Engine.activeModule == Path) { - Path.updateOutfitting(); - } - Engine.saveGame(); - }, - - addStores: function(list, ignoreCosts) { - // Make sure any income costs can be paid - if(!ignoreCosts) { - for(k in list) { - var num = $SM.get('stores[\''+k+'\']'); - if(typeof num != 'number' || isNaN(num) || num < 0) num = 0; - if(num + list[k] < 0) { - return false; - } - } - } - - // Actually do the update - for(k in list) { - var num = $SM.get('stores[\''+k+'\']'); - if(typeof num != 'number') num = 0; - num += list[k]; - num = num < 0 ? 0 : num; - num = num > Engine.MAX_STORE ? Engine.MAX_STORE : num; - $SM.set('stores[\''+k+'\']', num); - } - Room.updateStoresView(); - Room.updateBuildButtons(); - Outside.updateVillage(); - if(Engine.activeModule == Path) { - Path.updateOutfitting(); - } - Engine.saveGame(); - return true; - }, - - storeAvailable: function(name) { - return typeof $SM.get('stores[\''+name+'\']') == 'number'; - }, - - getStore: function(name) { - if(typeof $SM.get('stores[\''+name+'\']') == 'undefined') { - return 0; - } - return $SM.get('stores[\''+name+'\']'); - }, - - setIncome: function(source, options) { - var existing = $SM.get('income[\''+source+'\']'); - if(typeof existing != 'undefined') { - options.timeLeft = existing.timeLeft; - } - $SM.set('income[\''+source+'\']', options); - }, - - getIncome: function(source) { - var existing = $SM.get('income[\''+source+'\']'); - if(typeof existing != 'undefined') { - return existing; - } - return {}; - }, - - removeIncome: function(source) { - $SM.remove('income[\''+source+'\']'); - Room.updateIncomeView(); - }, - - collectIncome: function() { - if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) { - var changed = false; - for(var source in $SM.get('income')) { - var income = $SM.get('income[\''+source+'\']'); - if(typeof income.timeLeft != 'number') - { - income.timeLeft = 0; - } - income.timeLeft--; - - if(income.timeLeft <= 0) { - Engine.log('collection income from ' + source); - if(source == 'thieves') { - Engine.addStolen(income.stores); - } - changed = Engine.addStores(income.stores) || changed; - if(typeof income.delay == 'number') { - income.timeLeft = income.delay; - } - } - } - if(changed) { - Room.updateStoresView(); - Room.updateBuildButtons(); - Engine.saveGame(); - if(Events.activeEvent() != null) { - Events.updateButtons(); - } - } - } - Engine._incomeTimeout = setTimeout(Engine.collectIncome, 1000); - }, - - openPath: function() { - Path.init(); - Engine.event('progress', 'path'); - Notifications.notify(Room, 'the compass points ' + World.dir); - }, - - addStolen: function(stores) { - if(!$SM.get('game.stolen')) $SM.set('game.stolen', {}); - for(var k in stores) { - if(!$SM.get('game.stolen[\''+k+'\']')) $SM.set('game.stolen[\''+k+'\']', 0); - $SM.add('game.stolen[\''+k+'\']', stores[k] * -1); - } - }, - - startThieves: function() { - $SM.set('game.thieves', 1); - Engine.setIncome('thieves', { - delay: 10, - stores: { - 'wood': -10, - 'fur': -5, - 'meat': -5 - } - }); - Room.updateIncomeView(); - }, // Move the stores panel beneath top_container (or to top: 0px if top_container // either hasn't been filled in or is null) using transition_diff to sync with @@ -521,18 +320,6 @@ var Engine = { } }, - num: function(name, craftable) { - switch(craftable.type) { - case 'good': - case 'tool': - case 'weapon': - case 'upgrade': - return Engine.getStore(name); - case 'building': - return Outside.numBuilding(name); - } - }, - log: function(msg) { if(this._log) { console.log(msg); @@ -593,9 +380,16 @@ var Engine = { if(Engine.activeModule.swipeDown) { Engine.activeModule.swipeDown(e); } - } + }, + + handleStateUpdates: function(e){ + + }, }; +//listener for StateManager update events +$(Engine).on('stateUpdate', Engine.handleStateUpdates); + $(function() { Engine.init(); }); \ No newline at end of file diff --git a/script/events.js b/script/events.js index 1148c2e..e76af55 100644 --- a/script/events.js +++ b/script/events.js @@ -41,7 +41,7 @@ var Events = { // Scene reward if(scene.reward) { - Engine.addStores(scene.reward, true); + $SM.addM('stores', scene.reward); } // onLoad @@ -157,7 +157,7 @@ var Events = { var weapon = World.Weapons[weaponName]; var cd = weapon.cooldown; if(weapon.type == 'unarmed') { - if(Engine.hasPerk('unarmed master')) { + if($SM.hasPerk('unarmed master')) { cd /= 2; } } @@ -245,12 +245,12 @@ var Events = { if(weapon.type == 'unarmed') { if(!$SM.get('character.punches')) $SM.set('character.punches', 0); $SM.add('character.punches', 1); - if($SM.get('character.punches') == 50 && !Engine.hasPerk('boxer')) { - Engine.addPerk('boxer'); - } else if($SM.get('character.punches') == 150 && !Engine.hasPerk('martial artist')) { - Engine.addPerk('martial artist'); - } else if($SM.get('character.punches') == 300 && !Engine.hasPerk('unarmed master')) { - Engine.addPerk('unarmed master'); + if($SM.get('character.punches') == 50 && !$SM.hasPerk('boxer')) { + $SM.addPerk('boxer'); + } else if($SM.get('character.punches') == 150 && !$SM.hasPerk('martial artist')) { + $SM.addPerk('martial artist'); + } else if($SM.get('character.punches') == 300 && !$SM.hasPerk('unarmed master')) { + $SM.addPerk('unarmed master'); } } @@ -294,16 +294,16 @@ var Events = { if(Math.random() <= World.getHitChance()) { dmg = weapon.damage; if(typeof dmg == 'number') { - if(weapon.type == 'unarmed' && Engine.hasPerk('boxer')) { + if(weapon.type == 'unarmed' && $SM.hasPerk('boxer')) { dmg *= 2 } - if(weapon.type == 'unarmed' && Engine.hasPerk('martial artist')) { + if(weapon.type == 'unarmed' && $SM.hasPerk('martial artist')) { dmg *= 3; } - if(weapon.type == 'unarmed' && Engine.hasPerk('unarmed master')) { + if(weapon.type == 'unarmed' && $SM.hasPerk('unarmed master')) { dmg *= 2; } - if(weapon.type == 'melee' && Engine.hasPerk('barbarian')) { + if(weapon.type == 'melee' && $SM.hasPerk('barbarian')) { dmg = Math.floor(dmg * 1.5); } } @@ -417,7 +417,7 @@ var Events = { if(!$('#enemy').data('stunned')) { var toHit = scene.hit; - toHit *= Engine.hasPerk('evasive') ? 0.8 : 1; + toHit *= $SM.hasPerk('evasive') ? 0.8 : 1; var dmg = -1; if(Math.random() <= toHit) { dmg = scene.damage; @@ -646,7 +646,7 @@ var Events = { } else if(b.cost) { var disabled = false; for(var store in b.cost) { - var num = Engine.activeModule == World ? Path.outfit[store] : Engine.getStore(store); + var num = Engine.activeModule == World ? Path.outfit[store] : $SM.get('stores[\''+store+'\']', true); if(typeof num != 'number') num = 0; if(num < b.cost[store]) { // Too expensive @@ -665,7 +665,7 @@ var Events = { var costMod = {}; if(info.cost) { for(var store in info.cost) { - var num = Engine.activeModule == World ? Path.outfit[store] : Engine.getStore(store); + var num = Engine.activeModule == World ? Path.outfit[store] : $SM.get('stores[\''+store+'\']', true); if(typeof num != 'number') num = 0; if(num < info.cost[store]) { // Too expensive @@ -679,7 +679,7 @@ var Events = { } World.updateSupplies(); } else { - Engine.addStores(costMod); + $SM.addM('stores', costMod); } } @@ -689,7 +689,7 @@ var Events = { // Reward if(info.reward) { - Engine.addStores(info.reward); + $SM.addM('stores', info.reward); } Events.updateButtons(); @@ -803,5 +803,15 @@ var Events = { // Force refocus on the body. I hate you, IE. $('body').focus(); }); - } -}; \ No newline at end of file + }, + + handleStateUpdates: function(e){ + //updates to run on stores changes if an event is active + if(e.stateName.indexOf('stores') == 0 && Events.activeEvent() != null){ + Events.updateButtons(); + } + }, +}; + +//listener for StateManager update events +$(Events).on('stateUpdate', Events.handleStateUpdates); \ No newline at end of file diff --git a/script/events/global.js b/script/events/global.js index 7c623b0..85ca99a 100644 --- a/script/events/global.js +++ b/script/events/global.js @@ -33,8 +33,8 @@ Events.Global = [ ], onLoad: function() { $SM.set('game.thieves', 2); - Engine.removeIncome('thieves'); - Engine.addStores($SM.get('game.stolen')); + $SM.remove('income.thieves'); + $SM.addM('stores', $SM.get('game.stolen')); }, buttons: { 'leave': { @@ -50,8 +50,8 @@ Events.Global = [ ], onLoad: function() { $SM.set('game.thieves', 2); - Engine.removeIncome('thieves'); - Engine.addPerk('stealthy'); + $SM.remove('income.thieves'); + $SM.addPerk('stealthy'); }, buttons: { 'leave': { diff --git a/script/events/room.js b/script/events/room.js index 0350053..5d1742b 100644 --- a/script/events/room.js +++ b/script/events/room.js @@ -5,7 +5,7 @@ Events.Room = [ { /* The Nomad -- Merchant */ title: 'The Nomad', isAvailable: function() { - return Engine.activeModule == Room && Engine.getStore('fur') > 0; + return Engine.activeModule == Room && $SM.get('stores.fur', true) > 0; }, scenes: { 'start': { @@ -33,13 +33,13 @@ Events.Room = [ }, 'buyCompass': { available: function() { - return Engine.getStore('compass') < 1; + return $SM.get('stores.compass', true) < 1; }, text: 'buy compass', cost: { fur: 300, scales: 15, teeth: 5 }, reward: { 'compass': 1 }, notification: 'the old compass is dented and dusty, but it looks to work.', - onChoose: Engine.openPath + onChoose: Path.openPath }, 'goodbye': { text: 'say goodbye', @@ -51,7 +51,7 @@ Events.Room = [ }, { /* Noises Outside -- gain wood/fur */ title: 'Noises', isAvailable: function() { - return Engine.activeModule == Room && Engine.storeAvailable('wood'); + return Engine.activeModule == Room && $SM.get('stores.wood'); }, scenes: { 'start': { @@ -101,7 +101,7 @@ Events.Room = [ { /* Noises Inside -- trade wood for better good */ title: 'Noises', isAvailable: function() { - return Engine.activeModule == Room && Engine.storeAvailable('wood'); + return Engine.activeModule == Room && $SM.get('stores.wood'); }, scenes: { start: { @@ -127,12 +127,12 @@ Events.Room = [ 'the ground is littered with small scales' ], onLoad: function() { - var numWood = Engine.getStore('wood'); + var numWood = $SM.get('stores.wood', true); numWood = Math.floor(numWood * 0.1); if(numWood == 0) numWood = 1; var numScales = Math.floor(numWood / 5); if(numScales == 0) numScales = 1; - Engine.addStores({wood: -numWood, scales: numScales}); + $SM.addM('stores', {'wood': -numWood, 'scales': numScales}); }, buttons: { 'leave': { @@ -147,12 +147,12 @@ Events.Room = [ 'the ground is littered with small teeth' ], onLoad: function() { - var numWood = Engine.getStore('wood'); + var numWood = $SM.get('stores.wood', true); numWood = Math.floor(numWood * 0.1); if(numWood == 0) numWood = 1; var numTeeth = Math.floor(numWood / 5); if(numTeeth == 0) numTeeth = 1; - Engine.addStores({wood: -numWood, teeth: numTeeth}); + $SM.addM('stores', {'wood': -numWood, 'teeth': numTeeth}); }, buttons: { 'leave': { @@ -167,12 +167,12 @@ Events.Room = [ 'the ground is littered with scraps of cloth' ], onLoad: function() { - var numWood = Engine.getStore('wood'); + var numWood = $SM.get('stores.wood', true); numWood = Math.floor(numWood * 0.1); if(numWood == 0) numWood = 1; var numCloth = Math.floor(numWood / 5); if(numCloth == 0) numCloth = 1; - Engine.addStores({wood: -numWood, cloth: numCloth}); + $SM.addM('stores', {'wood': -numWood, 'cloth': numCloth}); }, buttons: { 'leave': { @@ -186,7 +186,7 @@ Events.Room = [ { /* The Beggar -- trade fur for better good */ title: 'The Beggar', isAvailable: function() { - return Engine.activeModule == Room && Engine.storeAvailable('fur'); + return Engine.activeModule == Room && $SM.get('stores.fur'); }, scenes: { start: { @@ -257,7 +257,7 @@ Events.Room = [ { /* Mysterious Wanderer -- wood gambling */ title: 'The Mysterious Wanderer', isAvailable: function() { - return Engine.activeModule == Room && Engine.storeAvailable('wood'); + return Engine.activeModule == Room && $SM.get('stores.wood'); }, scenes: { start: { @@ -290,7 +290,7 @@ Events.Room = [ onLoad: function() { if(Math.random() < 0.5) { setTimeout(function() { - Engine.addStore('wood', 300); + $SM.add('stores.wood', 300); Notifications.notify(Room, 'the mysterious wanderer returns, cart piled high with wood.'); }, 60 * 1000); } @@ -309,7 +309,7 @@ Events.Room = [ onLoad: function() { if(Math.random() < 0.3) { setTimeout(function() { - Engine.addStore('wood', 1500); + $SM.add('stores.wood', 1500); Notifications.notify(Room, 'the mysterious wanderer returns, cart piled high with wood.'); }, 60 * 1000); } @@ -327,7 +327,7 @@ Events.Room = [ { /* Mysterious Wanderer -- fur gambling */ title: 'The Mysterious Wanderer', isAvailable: function() { - return Engine.activeModule == Room && Engine.storeAvailable('fur'); + return Engine.activeModule == Room && $SM.get('stores.fur'); }, scenes: { start: { @@ -360,7 +360,7 @@ Events.Room = [ onLoad: function() { if(Math.random() < 0.5) { setTimeout(function() { - Engine.addStore('fur', 300); + $SM.add('stores.fur', 300); Notifications.notify(Room, 'the mysterious wanderer returns, cart piled high with furs.'); }, 60 * 1000); } @@ -379,7 +379,7 @@ Events.Room = [ onLoad: function() { if(Math.random() < 0.3) { setTimeout(function() { - Engine.addStore('fur', 1500); + $SM.add('stores.fur', 1500); Notifications.notify(Room, 'the mysterious wanderer returns, cart piled high with furs.'); }, 60 * 1000); } @@ -417,10 +417,10 @@ Events.Room = [ text: 'learn scouting', cost: { 'fur': 1000, 'scales': 50, 'teeth': 20 }, available: function() { - return !Engine.hasPerk('scout'); + return !$SM.hasPerk('scout'); }, onChoose: function() { - Engine.addPerk('scout'); + $SM.addPerk('scout'); } }, 'leave': { @@ -468,30 +468,30 @@ Events.Room = [ 'evasion': { text: 'evasion', available: function() { - return !Engine.hasPerk('evasive'); + return !$SM.hasPerk('evasive'); }, onChoose: function() { - Engine.addPerk('evasive'); + $SM.addPerk('evasive'); }, nextScene: 'end' }, 'precision': { text: 'precision', available: function() { - return !Engine.hasPerk('precise'); + return !$SM.hasPerk('precise'); }, onChoose: function() { - Engine.addPerk('precise'); + $SM.addPerk('precise'); }, nextScene: 'end' }, 'force': { text: 'force', available: function() { - return !Engine.hasPerk('barbarian'); + return !$SM.hasPerk('barbarian'); }, onChoose: function() { - Engine.addPerk('barbarian'); + $SM.addPerk('barbarian'); }, nextScene: 'end' }, @@ -536,7 +536,7 @@ Events.Room = [ 'some weird metal he picked up on his travels.' ], onLoad: function() { - Engine.addStore('alien alloy', 1); + $SM.add('stores[\'alien alloy\']', 1); }, buttons: { 'bye': { @@ -552,7 +552,7 @@ Events.Room = [ 'some weird glowing boxes he picked up on his travels.' ], onLoad: function() { - Engine.addStore('energy cell', 3); + $SM.add('stores[\'energy cell\']', 3); }, buttons: { 'bye': { @@ -568,7 +568,7 @@ Events.Room = [ 'all he has are some scales.' ], onLoad: function() { - Engine.addStore('scales', 5); + $SM.add('stores.scales', 5); }, buttons: { 'bye': { diff --git a/script/events/setpieces.js b/script/events/setpieces.js index 9e00e9f..1eaa283 100644 --- a/script/events/setpieces.js +++ b/script/events/setpieces.js @@ -74,7 +74,7 @@ Events.Setpieces = { 'his time here, now, is his penance.' ], onLoad: function() { - Engine.addPerk('gastronome'); + $SM.addPerk('gastronome'); World.markVisited(World.curPos[0], World.curPos[1]); }, buttons: { diff --git a/script/outside.js b/script/outside.js index c86c002..bee2027 100644 --- a/script/outside.js +++ b/script/outside.js @@ -432,7 +432,7 @@ var Outside = { for(var k in $SM.get('game.outside.buildings')) { if(k == 'trap') { var numTraps = $SM.get('game.outside.buildings[\''+k+'\']'); - var numBait = Engine.getStore('bait'); + var numBait = $SM.get('stores.bait', true); var traps = numTraps - numBait; traps = traps < 0 ? 0 : traps; Outside.updateVillageRow(k, traps, village); @@ -510,7 +510,7 @@ var Outside = { var tooltip = $('.tooltip', 'div#workers_row_' + worker.replace(' ', '-')); tooltip.empty(); var needsUpdate = false; - var curIncome = Engine.getIncome(worker); + var curIncome = $SM.getIncome(worker); for(var store in income.stores) { stores[store] = income.stores[store] * num; if(curIncome[store] != stores[store]) needsUpdate = true; @@ -520,7 +520,7 @@ var Outside = { row.appendTo(tooltip); } if(needsUpdate) { - Engine.setIncome(worker, { + $SM.setIncome(worker, { delay: income.delay, stores: stores }); @@ -588,14 +588,15 @@ var Outside = { gatherWood: function() { Notifications.notify(Outside, "dry brush and dead branches litter the forest floor") - Engine.setStore('wood', Engine.getStore('wood') + (Outside.numBuilding('cart') > 0 ? 50 : 10)); + var gatherAmt = Outside.numBuilding('cart') > 0 ? 50 : 10; + $SM.add('stores.wood', gatherAmt); }, checkTraps: function() { var drops = {}; var msg = []; var numTraps = Outside.numBuilding('trap'); - var numBait = Engine.getStore('bait'); + var numBait = $SM.get('stores.bait', true); var numDrops = numTraps + (numBait < numTraps ? numBait : numTraps); for(var i = 0; i < numDrops; i++) { var roll = Math.random(); @@ -626,6 +627,16 @@ var Outside = { drops['bait'] = -baitUsed; Notifications.notify(Outside, s); - Engine.addStores(drops); - } -} \ No newline at end of file + $SM.addM('stores', drops); + }, + + handleStateUpdates: function(e){ + //updates to run on stores changes + if(e.stateName.indexOf('stores') == 0){ + Outside.updateVillage(); + } + }, +}; + +//listener for StateManager update events +$(Outside).on('stateUpdate', Outside.handleStateUpdates); \ No newline at end of file diff --git a/script/path.js b/script/path.js index d880eb2..8153e64 100644 --- a/script/path.js +++ b/script/path.js @@ -51,6 +51,12 @@ var Path = { Engine.updateSlider(); }, + openPath: function() { + Path.init(); + Engine.event('progress', 'path'); + Notifications.notify(Room, 'the compass points ' + World.dir); + }, + getWeight: function(thing) { var w = Path.Weight[thing]; if(typeof w != 'number') w = 1; @@ -59,11 +65,11 @@ var Path = { }, getCapacity: function() { - if(Engine.getStore('convoy') > 0) { + if($SM.get('stores.convoy', true) > 0) { return Path.DEFAULT_BAG_SPACE + 60; - } else if(Engine.getStore('wagon') > 0) { + } else if($SM.get('stores.wagon', true) > 0) { return Path.DEFAULT_BAG_SPACE + 30; - } else if(Engine.getStore('rucksack') > 0) { + } else if($SM.get('stores.rucksack', true) > 0) { return Path.DEFAULT_BAG_SPACE + 10; } return Path.DEFAULT_BAG_SPACE; @@ -121,11 +127,11 @@ var Path = { // Add the armour row var armour = "none"; - if(Engine.getStore('s armour') > 0) + if($SM.get('stores[\'s armour\']', true) > 0) armour = "steel"; - else if(Engine.getStore('i armour') > 0) + else if($SM.get('stores[\'i armour\']', true) > 0) armour = "iron"; - else if(Engine.getStore('l armour') > 0) + else if($SM.get('stores[\'l armour']', true) > 0) armour = "leather"; var aRow = $('#armourRow'); if(aRow.length == 0) { @@ -169,7 +175,7 @@ var Path = { var have = $SM.get('stores[\''+k+'\']'); var num = Path.outfit[k]; num = typeof num == 'number' ? num : 0; - var numAvailable = Engine.getStore(k); + var numAvailable = $SM.get('stores[\''+k+'\']', true); var row = $('div#outfit_row_' + k.replace(' ', '-'), outfit); if((store.type == 'tool' || store.type == 'weapon') && have > 0) { total += num * Path.getWeight(k); @@ -238,7 +244,7 @@ var Path = { $('
').addClass('dnManyBtn').appendTo(val).click([10], Path.decreaseSupply); $('
').addClass('clear').appendTo(row); - var numAvailable = Engine.getStore(name); + var numAvailable = $SM.get('stores[\''+name+'\']', true); var tt = $('
').addClass('tooltip bottom right').appendTo(row); $('
').addClass('row_key').text('weight').appendTo(tt); $('
').addClass('row_val').text(Path.getWeight(name)).appendTo(tt); @@ -253,9 +259,9 @@ var Path = { Engine.log('increasing ' + supply + ' by up to ' + btn.data); var cur = Path.outfit[supply]; cur = typeof cur == 'number' ? cur : 0; - if(Path.getFreeSpace() >= Path.getWeight(supply) && cur < Engine.getStore(supply)) { + if(Path.getFreeSpace() >= Path.getWeight(supply) && cur < $SM.get('stores[\''+supply+'\']', true)) { var maxExtraByWeight = Math.floor(Path.getFreeSpace() / Path.getWeight(supply)); - var maxExtraByStore = Engine.getStore(supply) - cur; + var maxExtraByStore = $SM.get('stores[\''+supply+'\']', true) - cur; var maxExtraByBtn = btn.data; Path.outfit[supply] = cur + Math.min(maxExtraByBtn, Math.min(maxExtraByWeight, maxExtraByStore)); Path.updateOutfitting(); @@ -287,10 +293,19 @@ var Path = { embark: function() { for(var k in Path.outfit) { - Engine.addStore(k, -Path.outfit[k]); + $SM.add('stores[\''+k+'\']', -Path.outfit[k]); } World.onArrival(); $('#outerSlider').animate({left: '-700px'}, 300); Engine.activeModule = World; - } -} \ No newline at end of file + }, + + handleStateUpdates: function(e){ + if(e.stateName.indexOf('character.perks') == 0 && Engine.activeModule == Path){ + Path.updatePerks(); + }; + }, +}; + +//listener for StateManager update events +$(Path).on('stateUpdate', Path.handleStateUpdates); \ No newline at end of file diff --git a/script/room.js b/script/room.js index 3131269..cb89384 100644 --- a/script/room.js +++ b/script/room.js @@ -506,10 +506,10 @@ var Room = { if($SM.get('game.room.builder') >= 0 && $SM.get('game.room.builder') < 3) { Room._builderTimer = setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); } - if($SM.get('game.room.builder') == 1 && Engine.getStore('wood') < 0) { + if($SM.get('game.room.builder') == 1 && $SM.get('stores.wood', true) < 0) { setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY); } - setTimeout(Engine.collectIncome, 1000); + setTimeout($SM.collectIncome, 1000); Notifications.notify(Room, "the room is " + $SM.get('game.room.temperature.text')); Notifications.notify(Room, "the fire is " + $SM.get('game.room.fire.text')); @@ -526,7 +526,7 @@ var Room = { } if($SM.get('game.room.builder') == 3) { $SM.add('game.room.builder', 1); - Engine.setIncome('builder', { + $SM.setIncome('builder', { delay: 10, stores: {'wood' : 2 } }); @@ -594,7 +594,7 @@ var Room = { } } - if(!Engine.storeAvailable('wood')) { + if(!$SM.get('stores.wood')) { light.addClass('free'); stoke.addClass('free'); } else { @@ -606,27 +606,27 @@ var Room = { _fireTimer: null, _tempTimer: null, lightFire: function() { - var wood = Engine.getStore('wood'); - if(Engine.storeAvailable('wood') && wood < 5) { + var wood = $SM.get('stores.wood', true); + if(wood < 5) { Notifications.notify(Room, "not enough wood to get the fire going"); Button.clearCooldown($('#lightButton.button')); return; } else if(wood > 4) { - Engine.setStore('wood', wood - 5); + $SM.set('stores.wood', wood - 5); } $SM.set('game.room.fire', Room.FireEnum.Burning); Room.onFireChange(); }, stokeFire: function() { - var wood = Engine.getStore('wood'); - if(Engine.storeAvailable('wood') && wood == 0) { + var wood = $SM.get('stores.wood', true); + if(wood === 0) { Notifications.notify(Room, "the wood has run out"); Button.clearCooldown($('#stokeButton.button')); return; } if(wood > 0) { - Engine.setStore('wood', wood - 1); + $SM.set('stores.wood', wood - 1); } if($SM.get('game.room.fire.value') < 4) { $SM.set('game.room.fire', Room.FireEnum.fromInt($SM.get('game.room.fire.value') + 1)); @@ -651,10 +651,11 @@ var Room = { }, coolFire: function() { + var wood = $SM.get('stores.wood'); if($SM.get('game.room.fire.value') <= Room.FireEnum.Flickering.value && - $SM.get('game.room.builder') > 3 && Engine.getStore('wood') > 0) { + $SM.get('game.room.builder') > 3 && wood > 0) { Notifications.notify(Room, "builder stokes the fire", true); - Engine.setStore('wood', Engine.getStore('wood') - 1); + $SM.set('stores.wood', wood - 1); $SM.set('game.room.fire', Room.FireEnum.fromInt($SM.get('game.room.fire.value') + 1)); } if($SM.get('game.room.fire.value') > 0) { @@ -681,7 +682,7 @@ var Room = { }, unlockForest: function() { - Engine.setStore('wood', 4); + $SM.set('stores.wood', 4); Room.updateButton(); Outside.init(); Room.updateStoresView(); @@ -848,7 +849,7 @@ var Room = { buy: function(buyBtn) { var thing = $(buyBtn).attr('buildThing'); var good = Room.TradeGoods[thing]; - var numThings = Engine.getStore(thing); + var numThings = $SM.get('stores[\''+thing+'\']', true); if(numThings < 0) numThings = 0; if(good.maximum <= numThings) { return; @@ -857,7 +858,7 @@ var Room = { var storeMod = {}; var cost = good.cost(); for(var k in cost) { - var have = Engine.getStore(k) + var have = $SM.get('stores[\''+k+'\']', true); if(have < cost[k]) { Notifications.notify(Room, "not enough " + k); return false; @@ -865,16 +866,16 @@ var Room = { storeMod[k] = have - cost[k]; } } - Engine.setStores(storeMod); + $SM.setM('stores', storeMod); Notifications.notify(Room, good.buildMsg); - Engine.addStore(thing, 1); + $SM.add('stores[\''+thing+'\']', 1); Room.updateBuildButtons(); if(thing == 'compass') { - Engine.openPath(); + Path.openPath(); } }, @@ -892,7 +893,7 @@ var Room = { case 'weapon': case 'tool': case 'upgrade': - numThings = Engine.getStore(thing); + numThings = $SM.get('stores[\''+thing+'\']', true); break; case 'building': numThings = Outside.numBuilding(thing); @@ -907,7 +908,7 @@ var Room = { var storeMod = {}; var cost = craftable.cost(); for(var k in cost) { - var have = Engine.getStore(k) + var have = $SM.get('stores[\''+k+'\']', true); if(have < cost[k]) { Notifications.notify(Room, "not enough " + k); return false; @@ -915,7 +916,7 @@ var Room = { storeMod[k] = have - cost[k]; } } - Engine.setStores(storeMod); + $SM.setM('stores', storeMod); Notifications.notify(Room, craftable.buildMsg); @@ -924,7 +925,7 @@ var Room = { case 'weapon': case 'upgrade': case 'tool': - Engine.addStore(thing, 1); + $SM.add('stores[\''+thing+'\']', 1); break; case 'building': Outside.addBuilding(thing, 1); @@ -951,11 +952,11 @@ var Room = { var cost = craftable.cost(); // Show buttons if we have at least 1/2 the wood, and all other components have been seen. - if(Engine.getStore('wood') < cost['wood'] * 0.5) { + if($SM.get('stores.wood', true) < cost['wood'] * 0.5) { return false; } for(var c in cost) { - if(!Engine.storeAvailable(c)) { + if(!$SM.get('stores[\''+c'\']')) { return false; } } @@ -971,7 +972,7 @@ var Room = { $SM.get('game.room.buttons[\''+thing+'\']')) { return true; } else if(Outside.numBuilding('trading post') > 0) { - if(thing == 'compass' || Engine.storeAvailable(thing)) { + if(thing == 'compass' || $SM.get('stores[\''+thing+'\']')) { // Allow the purchase of stuff once you've seen it return true; } @@ -1003,7 +1004,7 @@ var Room = { for(var k in Room.Craftables) { craftable = Room.Craftables[k]; - var max = Engine.num(k, craftable) + 1 > craftable.maximum; + var max = $SM.num(k, craftable) + 1 > craftable.maximum; if(craftable.button == null) { if(Room.craftUnlocked(k)) { var loc = Room.needsWorkshop(craftable.type) ? craftSection : buildSection; @@ -1038,7 +1039,7 @@ var Room = { for(var k in Room.TradeGoods) { good = Room.TradeGoods[k]; - var max = Engine.num(k, good) + 1 > good.maximum; + var max = $SM.num(k, good) + 1 > good.maximum; if(good.button == null) { if(Room.buyUnlocked(k)) { good.button = new Button.Button({ @@ -1078,5 +1079,18 @@ var Room = { if(bNeedsAppend && buildSection.children().length > 0) { buySection.appendTo('div#roomPanel').animate({opacity: 1}, 300, 'linear'); } - } -}; \ No newline at end of file + }, + + handleStateUpdates: function(e){ + //updates to run on stores changes + if(e.stateName.indexOf('stores') == 0){ + Room.updateStoresView(); + Room.updateBuildButtons(); + } else if(e.stateName.indexOf('income') == 0){ + Room.updateIncomeView(); + }; + }, +}; + +//listener for StateManager update events +$(Room).on('stateUpdate', Room.handleStateUpdates); \ No newline at end of file diff --git a/script/ship.js b/script/ship.js index 64dce98..202dde7 100644 --- a/script/ship.js +++ b/script/ship.js @@ -100,11 +100,11 @@ var Ship = { }, reinforceHull: function() { - if(Engine.getStore('alien alloy') < Ship.ALLOY_PER_HULL) { + if($SM.get('stores[\'alien alloy\']', true) < Ship.ALLOY_PER_HULL) { Notifications.notify(Ship, "not enough alien alloy"); return false; } - Engine.addStore('alien alloy', -Ship.ALLOY_PER_HULL); + $SM.add('stores[\'alien alloy\']', -Ship.ALLOY_PER_HULL); $SM.add('game.spaceShip.hull', 1); if($SM.get('game.spaceShip.hull') > 0) { Button.setDisabled($('#liftoffButton', Ship.panel), false); @@ -113,11 +113,11 @@ var Ship = { }, upgradeEngine: function() { - if(Engine.getStore('alien alloy') < Ship.ALLOY_PER_THRUSTER) { + if($SM.get('stores[\'alien alloy\']', true) < Ship.ALLOY_PER_THRUSTER) { Notifications.notify(Ship, "not enough alien alloy"); return false; } - Engine.addStore('alien alloy', -Ship.ALLOY_PER_THRUSTER); + $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')); }, @@ -164,5 +164,12 @@ var Ship = { $('#outerSlider').animate({top: '700px'}, 300); Space.onArrival(); Engine.activeModule = Space; - } -}; \ No newline at end of file + }, + + handleStateUpdates: function(e){ + + }, +}; + +//listener for StateManager update events +$(Ship).on('stateUpdate', Ship.handleStateUpdates); \ No newline at end of file diff --git a/script/space.js b/script/space.js index 16b8c64..9752340 100644 --- a/script/space.js +++ b/script/space.js @@ -445,5 +445,12 @@ var Space = { Engine.log('right off'); break; } - } -}; \ No newline at end of file + }, + + handleStateUpdates: function(e){ + + }, +}; + +//listener for StateManager update events +$(Space).on('stateUpdate', Space.handleStateUpdates); \ No newline at end of file diff --git a/script/state_manager.js b/script/state_manager.js index 5615bda..25c4b7d 100644 --- a/script/state_manager.js +++ b/script/state_manager.js @@ -55,6 +55,9 @@ var StateManager = { var lastOB = stateName.lastIndexOf('['); //make sure last bracket isn't just end of the line var lastCB = stateName.substr(0, stateName.length -1).lastIndexOf(']'); + //account for state[foo][bar] double bracket and state[foo].bar + if(lastCB == lastOB - 1) lastOB = -1; + if(lastCB == lastDot -1) lastDot = -1; //find last child or return if no more children var cutoff = Math.max(lastDot, lastOB, lastCB); if(cutoff <= 0) return; @@ -65,7 +68,7 @@ var StateManager = { try { eval('('+parentPath+') = {}'); } catch (e) { - //need to go up another level and make parent of whichParent + //need to go up another level and make parent of parent $SM.createParent(stateName.substr(0,cutoff)); //then it will definitely work if not, something is fubar eval('('+parentPath+') = {}'); @@ -121,11 +124,17 @@ var StateManager = { //shortcut for altering number values, return 1 if state wasn't a number add: function(stateName, value, noEvent) { var err = 0; - //0 if undefined, null (but not {}) should allow adding to new objects, helps avoid existence checks and NaN for stores - //could also add in a true = 1 thing, to have something go from existing (true) to be a count, but that might be unwanted behavior + //0 if undefined, null (but not {}) should allow adding to new objects + //could also add in a true = 1 thing, to have something go from existing (true) + //to be a count, but that might be unwanted behavior (add with loose eval probably will happen anyways) var old = $SM.get(stateName, true); - if(typeof old != 'number' || typeof value != 'number'){ + //check for NaN (old == old) and non number values + if(old == old){ + Engine.log('WARNING: '+stateName+' was corrupted (NaN). Resetting to 0.'); + old = 0; + $SM.set(stateName, old + value, noEvent);//setState handles event and save + } else if(typeof old != 'number' || typeof value != 'number'){ Engine.log('WARNING: Can not do math with state:'+stateName+' or value:'+value+' because at least one is not a number.'); err = 1 } else { @@ -170,7 +179,7 @@ var StateManager = { else return whichState; }, - remove: function(stateName) { + remove: function(stateName, noEvent) { var whichState = $SM.buildPath(whichState); try{ delete eval(whichState); @@ -178,8 +187,10 @@ var StateManager = { //it didn't exist in the first place Engine.log('WARNING: Tried to remove non-existant state \''+stateName+'\'.'); } - Engine.saveGame(); - $SM.fireUpdate(stateName); + if(!noEvent){ + Engine.saveGame(); + $SM.fireUpdate(stateName); + }; }, //creates full reference from input @@ -200,6 +211,122 @@ var StateManager = { if(save) Engine.saveGame(); }, + //Use this function to make old save games compatible with new version + updateOldState: function(){ + var version = $SM.get('version'); + if(typeof version != 'number') version = 1.0; + if(version == 1.0) { + // v1.1 introduced the Lodge, so get rid of lodgeless hunters + $SM.remove('outside.workers.hunter', true); + $SM.remove('income.hunter', true); + Engine.log('upgraded save to v1.1'); + version = 1.1; + }; + if(version == 1.1) { + //v1.2 added the Swamp to the map, so add it to already generated maps + if($SM.get('world')) { + World.placeLandmark(15, World.RADIUS * 1.5, World.TILE.SWAMP, $SM.get('world.map')); + } + Engine.log('upgraded save to v1.2'); + version = 1.2; + }; + if(version == 1.2) { + //StateManager added, so move data to new locations + }; + }, + + /****************************************************************** + * Start of specific state functions + ******************************************************************/ + //PERKS + addPerk: function(name) { + $SM.set('character.perks[\''+name+'\']', true); + Notifications.notify(null, Engine.Perks[name].notify); + }, + + hasPerk: function(name) { + return $SM.get('character.perks[\''+name+'\']') == true; + }, + + //INCOME + setIncome: function(source, options) { + var existing = $SM.get('income[\''+source+'\']'); + if(typeof existing != 'undefined') { + options.timeLeft = existing.timeLeft; + } + $SM.set('income[\''+source+'\']', options); + }, + + getIncome: function(source) { + var existing = $SM.get('income[\''+source+'\']'); + if(typeof existing != 'undefined') { + return existing; + } + return {}; + }, + + collectIncome: function() { + if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) { + for(var source in $SM.get('income')) { + var income = $SM.get('income[\''+source+'\']'); + if(typeof income.timeLeft != 'number') + { + income.timeLeft = 0; + } + income.timeLeft--; + + if(income.timeLeft <= 0) { + Engine.log('collection income from ' + source); + if(source == 'thieves') $SM.addStolen(income.stores); + $SM.addM('stores', income.stores); + if(typeof income.delay == 'number') { + income.timeLeft = income.delay; + } + } + } + } + Engine._incomeTimeout = setTimeout($SM.collectIncome, 1000); + }, + + //Thieves + addStolen: function(stores) { + for(var k in stores) { + var old = $SM.get('stores[\''+k+'\']', true); + var short = old - stores[k]; + //if they would steal more than actually owned + if(short < 0){ + $SM.add('game.stolen[\''+k+'\']', (stores[k] * -1) + short); + } else { + $SM.add('game.stolen[\''+k+'\']', stores[k] * -1); + } + }; + }, + + startThieves: function() { + $SM.set('game.thieves', 1); + $SM.setIncome('thieves', { + delay: 10, + stores: { + 'wood': -10, + 'fur': -5, + 'meat': -5 + } + }); + }, + + //Misc + num: function(name, craftable) { + switch(craftable.type) { + case 'good': + case 'tool': + case 'weapon': + case 'upgrade': + return $SM.get('stores[\''+name+'\']', true); + case 'building': + return Outside.numBuilding(name); + } + }, + handleStateUpdates: function(e){ }, diff --git a/script/world.js b/script/world.js index c608aab..45e174f 100644 --- a/script/world.js +++ b/script/world.js @@ -266,7 +266,7 @@ var World = { // Update label var t = 'pockets'; - if(Engine.getStore('rucksack') > 0) { + if($SM.get('stores.rucksack', true) > 0) { t = 'rucksack'; } $('#backpackTitle').text(t); @@ -401,11 +401,11 @@ var World = { checkDanger: function() { World.danger = typeof World.danger == 'undefined' ? false: World.danger; if(!World.danger) { - if(!Engine.getStore('i armour') > 0 && World.getDistance() >= 8) { + if(!$SM.get('stores[\'i armour\']', true) > 0 && World.getDistance() >= 8) { World.danger = true; return true; } - if(!Engine.getStore('s armour') > 0 && World.getDistance() >= 18) { + if(!$SM.get('stores[\'s armour\']', true) > 0 && World.getDistance() >= 18) { World.danger = true; return true; } @@ -414,7 +414,7 @@ var World = { World.danger = false; return true; } - if(World.getDistance < 18 && Engine.getStore('i armour') > 0) { + if(World.getDistance < 18 && $SM.get('stores[\'i armour\']', true) > 0) { World.danger = false; return true; } @@ -427,7 +427,7 @@ var World = { World.waterMove++; // Food var movesPerFood = World.MOVES_PER_FOOD; - movesPerFood *= Engine.hasPerk('slow metabolism') ? 2 : 1; + movesPerFood *= $SM.hasPerk('slow metabolism') ? 2 : 1; if(World.foodMove >= movesPerFood) { World.foodMove = 0; var num = Path.outfit['cured meat']; @@ -443,8 +443,8 @@ var World = { } else { $SM.set('character.starved', $SM.get('character.starved', true)); $SM.add('character.starved', 1); - if($SM.get('character.starved') >= 10 && !Engine.hasPerk('slow metabolism')) { - Engine.addPerk('slow metabolism'); + if($SM.get('character.starved') >= 10 && !$SM.hasPerk('slow metabolism')) { + $SM.addPerk('slow metabolism'); } World.die(); return false; @@ -457,7 +457,7 @@ var World = { } // Water var movesPerWater = World.MOVES_PER_WATER; - movesPerWater *= Engine.hasPerk('desert rat') ? 2 : 1; + movesPerWater *= $SM.hasPerk('desert rat') ? 2 : 1; if(World.waterMove >= movesPerWater) { World.waterMove = 0; var water = World.water; @@ -472,8 +472,8 @@ var World = { } else { $SM.set('character.dehydrated', $SM.get('character.dehydrated', true)); $SM.add('character.dehydrated', 1); - if($SM.get('character.dehydrated') >= 10 && !Engine.hasPerk('desert rat')) { - Engine.addPerk('desert rat'); + if($SM.get('character.dehydrated') >= 10 && !$SM.hasPerk('desert rat')) { + $SM.addPerk('desert rat'); } World.die(); return false; @@ -488,7 +488,7 @@ var World = { }, meatHeal: function() { - return World.MEAT_HEAL * (Engine.hasPerk('gastronome') ? 2 : 1); + return World.MEAT_HEAL * ($SM.hasPerk('gastronome') ? 2 : 1); }, medsHeal: function() { @@ -500,7 +500,7 @@ var World = { World.fightMove++; if(World.fightMove > World.FIGHT_DELAY) { var chance = World.FIGHT_CHANCE; - chance *= Engine.hasPerk('stealthy') ? 0.5 : 1; + chance *= $SM.hasPerk('stealthy') ? 0.5 : 1; if(Math.random() < chance) { World.fightMove = 0; Events.triggerFight(); @@ -584,7 +584,7 @@ var World = { lightMap: function(x, y, mask) { var r = World.LIGHT_RADIUS; - r *= Engine.hasPerk('scout') ? 2 : 1; + r *= $SM.hasPerk('scout') ? 2 : 1; World.uncoverMap(x, y, r, mask); return mask; }, @@ -849,7 +849,7 @@ var World = { } for(var k in Path.outfit) { - Engine.addStore(k, Path.outfit[k]); + $SM.add('stores[\''+k+'\']', Path.outfit[k]); if(World.leaveItAtHome(k)) { Path.outfit[k] = 0; } @@ -866,29 +866,29 @@ var World = { }, getMaxHealth: function() { - if(Engine.getStore('s armour') > 0) { + if($SM.get('stores[\'s armour\']', true) > 0) { return World.BASE_HEALTH + 35; - } else if(Engine.getStore('i armour') > 0) { + } else if($SM.get('stores[\'i armour\']', true) > 0) { return World.BASE_HEALTH + 15; - } else if(Engine.getStore('l armour') > 0) { + } else if($SM.get('stores[\'l armour']', true) > 0) { return World.BASE_HEALTH + 5; } return World.BASE_HEALTH; }, getHitChance: function() { - if(Engine.hasPerk('precise')) { + if($SM.hasPerk('precise')) { return World.BASE_HIT_CHANCE + 0.1; } return World.BASE_HIT_CHANCE; }, getMaxWater: function() { - if(Engine.getStore('water tank') > 0) { + if($SM.get('stores[\'water tank\']', true) > 0) { return World.BASE_WATER + 50; - } else if(Engine.getStore('cask') > 0) { + } else if($SM.get('stores.cask', true) > 0) { return World.BASE_WATER + 20; - } else if(Engine.getStore('waterskin') > 0) { + } else if($SM.get('stores.waterskin', true) > 0) { return World.BASE_WATER + 10; } return World.BASE_WATER; @@ -936,5 +936,12 @@ var World = { copyPos: function(pos) { return [pos[0], pos[1]]; - } -}; \ No newline at end of file + }, + + handleStateUpdates: function(e){ + + }, +}; + +//listener for StateManager update events +$(World).on('stateUpdate', World.handleStateUpdates); \ No newline at end of file