create StateManager, change all State calls to managed calls

Introduced state_manager.js almost all State gets/sets are now run
through the manager (alias $SM). For now it was a simple, mostly
straightforward replacement of calls. This means that there are
redundancies and a lot of now unneeded code for things the SM will
handle. However, since I had trouble with making those changes as well
as introducing the manager all at once my first attempt, I am taking the
wiser approach and making "one change" at a time like I should have
instead of being too sure of myself.

At this point, it seems to work, but there may be bugs I didn't catch.
There was also no attempt made to update old saves to work with this. In
theory, it shouldn't be too hard. (included is a list of all state
changes)

TODO:
Save Update.
Refactor: a lot, many many redundancies now.
Refactor: "location centric" to "global centric".
Relocate all calls to different update functions to event listeners
where possible.

======================================================

The changes to State are as follows:

.room (exists) > features.location.room
.room > game.room
.room.builder > game.room.builder
.room.temperature > game.room.temperature
.room.fire > game.room.fire
.room.buttons > game.room.buttons

.outside (exists) > features.location.outside
.outside > game.outside
.outside.population > game.outside.population
.outside.buildings > game.outside.buildings
.outside.workers > game.outside.workers
.outside.seenForest > game.outside.seenForest

.world (exists) > features.location.world
.world > game.world
.world.map > game.world.map
.world.mask > game.world.mask
.starved > character.starved
.dehydrated > character.dehydrated

.ship (exists) > featuers.location.spaceShip
.ship > game.spaceShip
.ship.hull > game.spaceShip.hull
.ship.thrusters > game.spaceShip.thrusters
.ship.seenWarning > game.spaceShip.seenWarning
.ship.seenShip > game.spaceShip.seenShip

.punches > character.punches
.perks > character.perks

.thieves > game.thieves
.stolen > game.stolen
.cityCleared > game.cityCleared

.stores > stores
.income > income
This commit is contained in:
LucidCrux
2013-07-23 01:24:47 -06:00
parent 1b1088db4f
commit db4a346d21
14 changed files with 418 additions and 221 deletions
+4 -1
View File
@@ -15,12 +15,15 @@
<meta itemprop="name" property="og:title" content="A Dark Room" /> <meta itemprop="name" property="og:title" content="A Dark Room" />
<link rel="shortcut icon" href="favicon.ico" /> <link rel="shortcut icon" href="favicon.ico" />
<link rel="image_src" href="img/adr.png" /> <link rel="image_src" href="img/adr.png" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
use local file for testing to avoid loads -->
<script src="lib/jquery.min.js"></script>
<script src="lib/jquery.color-2.1.2.min.js"></script> <script src="lib/jquery.color-2.1.2.min.js"></script>
<script src="lib/jquery.event.move.js"></script> <script src="lib/jquery.event.move.js"></script>
<script src="lib/jquery.event.swipe.js"></script> <script src="lib/jquery.event.swipe.js"></script>
<script src="script/Button.js"></script> <script src="script/Button.js"></script>
<script src="script/engine.js"></script> <script src="script/engine.js"></script>
<script src="script/state_manager.js"></script>
<script src="script/header.js"></script> <script src="script/header.js"></script>
<script src="script/notifications.js"></script> <script src="script/notifications.js"></script>
<script src="script/events.js"></script> <script src="script/events.js"></script>
+31 -54
View File
@@ -59,8 +59,8 @@ var Engine = {
options: { options: {
state: null, state: null,
debug: false, debug: true,
log: false log: true
}, },
init: function(options) { init: function(options) {
@@ -112,6 +112,7 @@ var Engine = {
swipeElement.on('swipeup', Engine.swipeUp); swipeElement.on('swipeup', Engine.swipeUp);
swipeElement.on('swipedown', Engine.swipeDown); swipeElement.on('swipedown', Engine.swipeDown);
$SM.init();
Notifications.init(); Notifications.init();
Events.init(); Events.init();
Room.init(); Room.init();
@@ -122,7 +123,7 @@ var Engine = {
if(Engine.getStore('compass') > 0) { if(Engine.getStore('compass') > 0) {
Path.init(); Path.init();
} }
if(State.ship) { if($SM.get('features.location.spaceShip')) {
Ship.init(); Ship.init();
} }
@@ -165,8 +166,6 @@ var Engine = {
} catch(e) { } catch(e) {
State = { State = {
version: 1.2, version: 1.2,
stores: {},
perks: {}
}; };
Engine.event('progress', 'new game'); Engine.event('progress', 'new game');
} }
@@ -324,10 +323,10 @@ var Engine = {
}, },
addPerk: function(name) { addPerk: function(name) {
if(!State.perks) { if(!$SM.get('character.perks')) {
State.perks = {}; $SM.set('character.perks', {});
} }
State.perks[name] = true; $SM.set('character.perks[\''+name+'\']', true);
Notifications.notify(null, Engine.Perks[name].notify); Notifications.notify(null, Engine.Perks[name].notify);
if(Engine.activeModule == Path) { if(Engine.activeModule == Path) {
Path.updatePerks(); Path.updatePerks();
@@ -335,47 +334,37 @@ var Engine = {
}, },
hasPerk: function(name) { hasPerk: function(name) {
return typeof State.perks == 'object' && State.perks[name] == true; return typeof $SM.get('character.perks') == 'object' && $SM.get('character.perks[\''+name+'\']') == true;
}, },
setStore: function(name, number) { setStore: function(name, number) {
if(typeof State.stores == 'undefined') { $SM.set('stores[\''+name+'\']', number);
State.stores = {};
}
if(number > Engine.MAX_STORE) number = Engine.MAX_STORE;
State.stores[name] = number;
Room.updateStoresView(); Room.updateStoresView();
Room.updateBuildButtons(); Room.updateBuildButtons();
if(State.outside) { if($SM.get('features.location.outside')) {
Outside.updateVillage(); Outside.updateVillage();
} }
Engine.saveGame(); Engine.saveGame();
}, },
setStores: function(list) { setStores: function(list) {
if(typeof State.stores == 'undefined') {
State.stores = {};
}
for(k in list) { for(k in list) {
State.stores[k] = list[k] > Engine.MAX_STORE ? Engine.MAX_STORE : list[k]; $SM.set('stores[\''+k+'\']', list[k]);
} }
Room.updateStoresView(); Room.updateStoresView();
Room.updateBuildButtons(); Room.updateBuildButtons();
if(State.outside) { if($SM.get('features.location.outside')) {
Outside.updateVillage(); Outside.updateVillage();
} }
Engine.saveGame(); Engine.saveGame();
}, },
addStore: function(name, number) { addStore: function(name, number) {
if(typeof State.stores == 'undefined') { var num = $SM.get('stores[\''+name+'\']');
State.stores = {};
}
var num = State.stores[name];
if(typeof num != 'number' || isNaN(num) || num < 0) num = 0; if(typeof num != 'number' || isNaN(num) || num < 0) num = 0;
num += number; num += number;
if(num > Engine.MAX_STORE) num = Engine.MAX_STORE; if(num > Engine.MAX_STORE) num = Engine.MAX_STORE;
State.stores[name] = num; $SM.set('stores[\''+name+'\']', num);
Room.updateStoresView(); Room.updateStoresView();
Room.updateBuildButtons(); Room.updateBuildButtons();
Outside.updateVillage(); Outside.updateVillage();
@@ -386,14 +375,10 @@ var Engine = {
}, },
addStores: function(list, ignoreCosts) { addStores: function(list, ignoreCosts) {
if(typeof State.stores == 'undefined') {
State.stores = {};
}
// Make sure any income costs can be paid // Make sure any income costs can be paid
if(!ignoreCosts) { if(!ignoreCosts) {
for(k in list) { for(k in list) {
var num = State.stores[k]; var num = $SM.get('stores[\''+k+'\']');
if(typeof num != 'number' || isNaN(num) || num < 0) num = 0; if(typeof num != 'number' || isNaN(num) || num < 0) num = 0;
if(num + list[k] < 0) { if(num + list[k] < 0) {
return false; return false;
@@ -403,12 +388,12 @@ var Engine = {
// Actually do the update // Actually do the update
for(k in list) { for(k in list) {
var num = State.stores[k]; var num = $SM.get('stores[\''+k+'\']');
if(typeof num != 'number') num = 0; if(typeof num != 'number') num = 0;
num += list[k]; num += list[k];
num = num < 0 ? 0 : num; num = num < 0 ? 0 : num;
num = num > Engine.MAX_STORE ? Engine.MAX_STORE : num; num = num > Engine.MAX_STORE ? Engine.MAX_STORE : num;
State.stores[k] = num; $SM.set('stores[\''+k+'\']', num);
} }
Room.updateStoresView(); Room.updateStoresView();
Room.updateBuildButtons(); Room.updateBuildButtons();
@@ -421,32 +406,26 @@ var Engine = {
}, },
storeAvailable: function(name) { storeAvailable: function(name) {
return typeof State.stores[name] == 'number'; return typeof $SM.get('stores[\''+name+'\']') == 'number';
}, },
getStore: function(name) { getStore: function(name) {
if(typeof State.stores == 'undefined' || typeof State.stores[name] == 'undefined' ) { if(typeof $SM.get('stores[\''+name+'\']') == 'undefined') {
return 0; return 0;
} }
return State.stores[name]; return $SM.get('stores[\''+name+'\']');
}, },
setIncome: function(source, options) { setIncome: function(source, options) {
if(typeof State.income == 'undefined') { var existing = $SM.get('income[\''+source+'\']');
State.income = {};
}
var existing = State.income[source];
if(typeof existing != 'undefined') { if(typeof existing != 'undefined') {
options.timeLeft = existing.timeLeft; options.timeLeft = existing.timeLeft;
} }
State.income[source] = options; $SM.set('income[\''+source+'\']', options);
}, },
getIncome: function(source) { getIncome: function(source) {
if(typeof State.income == 'undefined') { var existing = $SM.get('income[\''+source+'\']');
State.income = {};
}
var existing = State.income[source];
if(typeof existing != 'undefined') { if(typeof existing != 'undefined') {
return existing; return existing;
} }
@@ -454,17 +433,15 @@ var Engine = {
}, },
removeIncome: function(source) { removeIncome: function(source) {
if(State.income) { $SM.remove('income[\''+source+'\']');
delete State.income[source];
}
Room.updateIncomeView(); Room.updateIncomeView();
}, },
collectIncome: function() { collectIncome: function() {
if(typeof State.income != 'undefined' && Engine.activeModule != Space) { if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) {
var changed = false; var changed = false;
for(var source in State.income) { for(var source in $SM.get('income')) {
var income = State.income[source]; var income = $SM.get('income[\''+source+'\']');
if(typeof income.timeLeft != 'number') if(typeof income.timeLeft != 'number')
{ {
income.timeLeft = 0; income.timeLeft = 0;
@@ -501,15 +478,15 @@ var Engine = {
}, },
addStolen: function(stores) { addStolen: function(stores) {
if(!State.stolen) State.stolen = {}; if(!$SM.get('game.stolen')) $SM.set('game.stolen', {});
for(var k in stores) { for(var k in stores) {
if(!State.stolen[k]) State.stolen[k] = 0; if(!$SM.get('game.stolen[\''+k+'\']')) $SM.set('game.stolen[\''+k+'\']', 0);
State.stolen[k] -= stores[k]; $SM.add('game.stolen[\''+k+'\']', stores[k] * -1);
} }
}, },
startThieves: function() { startThieves: function() {
State.thieves = 1; $SM.set('game.thieves', 1);
Engine.setIncome('thieves', { Engine.setIncome('thieves', {
delay: 10, delay: 10,
stores: { stores: {
+5 -5
View File
@@ -243,13 +243,13 @@ var Events = {
var weaponName = btn.attr('id').substring(7).replace('-', ' '); var weaponName = btn.attr('id').substring(7).replace('-', ' ');
var weapon = World.Weapons[weaponName]; var weapon = World.Weapons[weaponName];
if(weapon.type == 'unarmed') { if(weapon.type == 'unarmed') {
if(!State.punches) State.punches = 0; if(!$SM.get('character.punches')) $SM.set('character.punches', 0);
State.punches++; $SM.add('character.punches', 1);
if(State.punches == 50 && !Engine.hasPerk('boxer')) { if($SM.get('character.punches') == 50 && !Engine.hasPerk('boxer')) {
Engine.addPerk('boxer'); Engine.addPerk('boxer');
} else if(State.punches == 150 && !Engine.hasPerk('martial artist')) { } else if($SM.get('character.punches') == 150 && !Engine.hasPerk('martial artist')) {
Engine.addPerk('martial artist'); Engine.addPerk('martial artist');
} else if(State.punches == 300 && !Engine.hasPerk('unarmed master')) { } else if($SM.get('character.punches') == 300 && !Engine.hasPerk('unarmed master')) {
Engine.addPerk('unarmed master'); Engine.addPerk('unarmed master');
} }
+4 -4
View File
@@ -5,7 +5,7 @@ Events.Global = [
{ /* The Thief */ { /* The Thief */
title: 'The Thief', title: 'The Thief',
isAvailable: function() { isAvailable: function() {
return (Engine.activeModule == Room || Engine.activeModule == Outside) && State.thieves == 1; return (Engine.activeModule == Room || Engine.activeModule == Outside) && $SM.get('game.thieves') == 1;
}, },
scenes: { scenes: {
'start': { 'start': {
@@ -32,9 +32,9 @@ Events.Global = [
'the point is made. in the next few days, the missing supplies are returned.' 'the point is made. in the next few days, the missing supplies are returned.'
], ],
onLoad: function() { onLoad: function() {
State.thieves = 2; $SM.set('game.thieves', 2);
Engine.removeIncome('thieves'); Engine.removeIncome('thieves');
Engine.addStores(State.stolen); Engine.addStores($SM.get('game.stolen'));
}, },
buttons: { buttons: {
'leave': { 'leave': {
@@ -49,7 +49,7 @@ Events.Global = [
"shares what he knows about sneaking before he goes." "shares what he knows about sneaking before he goes."
], ],
onLoad: function() { onLoad: function() {
State.thieves = 2; $SM.set('game.thieves', 2);
Engine.removeIncome('thieves'); Engine.removeIncome('thieves');
Engine.addPerk('stealthy'); Engine.addPerk('stealthy');
}, },
+1 -1
View File
@@ -211,7 +211,7 @@ Events.Outside = [
{ /* Soldier attack */ { /* Soldier attack */
title: 'A Military Raid', title: 'A Military Raid',
isAvailable: function() { isAvailable: function() {
return Engine.activeModule == Outside && Outside.getPopulation() > 0 && State.cityCleared; return Engine.activeModule == Outside && Outside.getPopulation() > 0 && $SM.get('game.cityCleared');;
}, },
scenes: { scenes: {
'start': { 'start': {
+3 -3
View File
@@ -397,7 +397,7 @@ Events.Room = [
{ /* The Scout -- Map Merchant */ { /* The Scout -- Map Merchant */
title: 'The Scout', title: 'The Scout',
isAvailable: function() { isAvailable: function() {
return Engine.activeModule == Room && typeof State.world == 'object'; return Engine.activeModule == Room && $SM.get('features.location.world');
}, },
scenes: { scenes: {
'start': { 'start': {
@@ -435,7 +435,7 @@ Events.Room = [
{ /* The Wandering Master */ { /* The Wandering Master */
title: 'The Master', title: 'The Master',
isAvailable: function() { isAvailable: function() {
return Engine.activeModule == Room && typeof State.world == 'object'; return Engine.activeModule == Room && $SM.get('features.location.world');
}, },
scenes: { scenes: {
'start': { 'start': {
@@ -507,7 +507,7 @@ Events.Room = [
{ /* The Sick Man */ { /* The Sick Man */
title: 'The Sick Man', title: 'The Sick Man',
isAvailable: function() { isAvailable: function() {
return Engine.activeModule == Room && typeof State.world == 'object'; return Engine.activeModule == Room && $SM.get('features.location.world');
}, },
scenes: { scenes: {
'start': { 'start': {
+15 -15
View File
@@ -2244,7 +2244,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
bullets: { bullets: {
@@ -2278,7 +2278,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
torch: { torch: {
@@ -2308,7 +2308,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
rifle: { rifle: {
@@ -2354,7 +2354,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
rifle: { rifle: {
@@ -2389,7 +2389,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
rifle: { rifle: {
@@ -2429,7 +2429,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'laser rifle': { 'laser rifle': {
@@ -2464,7 +2464,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'steel sword': { 'steel sword': {
@@ -2499,7 +2499,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'steel sword': { 'steel sword': {
@@ -2534,7 +2534,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'rifle': { 'rifle': {
@@ -2574,7 +2574,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'energy cell': { 'energy cell': {
@@ -2613,7 +2613,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'energy cell': { 'energy cell': {
@@ -2646,7 +2646,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'energy cell': { 'energy cell': {
@@ -2695,7 +2695,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'steel sword': { 'steel sword': {
@@ -2739,7 +2739,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'energy cell': { 'energy cell': {
@@ -2782,7 +2782,7 @@ Events.Setpieces = {
], ],
onLoad: function() { onLoad: function() {
World.clearDungeon(); World.clearDungeon();
State.cityCleared = true; $SM.set('game.cityCleared', true);
}, },
loot: { loot: {
'alien alloy': { 'alien alloy': {
+46 -45
View File
@@ -135,12 +135,13 @@ var Outside = {
.addClass('location') .addClass('location')
.appendTo('div#locationSlider'); .appendTo('div#locationSlider');
if(typeof State.outside == 'undefined') { if(typeof $SM.get('features.location.outside') == 'undefined') {
State.outside = { $SM.set('features.location.outside', true);
$SM.setM('game.outside', {
buildings: {}, buildings: {},
population: 0, population: 0,
workers: {} workers: {}
} });
} }
this.updateVillage(); this.updateVillage();
@@ -159,27 +160,27 @@ var Outside = {
}, },
numBuilding: function(bName) { numBuilding: function(bName) {
return State.outside && return $SM.get('features.location.outside') &&
State.outside.buildings && $SM.get('game.outside.buildings') &&
State.outside.buildings[bName] ? State.outside.buildings[bName] : 0; $SM.get('game.outside.buildings[\''+bName+'\']', true);
}, },
addBuilding: function(bName, num) { addBuilding: function(bName, num) {
var cur = State.outside.buildings[bName]; var cur = $SM.get('game.outside.buildings[\''+bName+'\']');
if(typeof cur != 'number') cur = 0; if(typeof cur != 'number') cur = 0;
cur += num; cur += num;
if(cur < 0) cur = 0; if(cur < 0) cur = 0;
State.outside.buildings[bName] = cur; $SM.set('game.outside.buildings[\''+bName+'\']', cur);
this.updateVillage(); this.updateVillage();
Engine.saveGame(); Engine.saveGame();
}, },
addBuildings: function(list) { addBuildings: function(list) {
for(k in list) { for(k in list) {
var num = State.outside.buildings[k]; var num = $SM.get('game.outside.buildings[\''+k+'\']');
if(typeof num != 'number') num = 0; if(typeof num != 'number') num = 0;
num += list[k]; num += list[k];
State.outside.buildings[k] = num; $SM.set('game.outside.buildings[\''+k+'\']', num);
} }
this.updateVillage(); this.updateVillage();
Engine.saveGame(); Engine.saveGame();
@@ -190,14 +191,14 @@ var Outside = {
}, },
getPopulation: function() { getPopulation: function() {
if(State.outside && State.outside.population) { if($SM.get('features.location.outside') && $SM.get('game.outside.population')) {
return State.outside.population; return $SM.get('game.outside.population');
} }
return 0; return 0;
}, },
increasePopulation: function() { increasePopulation: function() {
var space = Outside.getMaxPopulation() - State.outside.population; var space = Outside.getMaxPopulation() - $SM.get('game.outside.population');
if(space > 0) { if(space > 0) {
var num = Math.floor(Math.random()*(space/2) + space/2); var num = Math.floor(Math.random()*(space/2) + space/2);
if(num == 0) num = 1; if(num == 0) num = 1;
@@ -213,7 +214,7 @@ var Outside = {
Notifications.notify(null, "the town's booming. word does get around."); Notifications.notify(null, "the town's booming. word does get around.");
} }
Engine.log('population increased by ' + num); Engine.log('population increased by ' + num);
State.outside.population += num; $SM.add('game.outside.population', num);
Outside.updateVillage(); Outside.updateVillage();
Outside.updateWorkersView(); Outside.updateWorkersView();
Outside.updateVillageIncome(); Outside.updateVillageIncome();
@@ -222,20 +223,20 @@ var Outside = {
}, },
killVillagers: function(num) { killVillagers: function(num) {
State.outside.population -= num; $SM.add('game.outside.population', num * -1);
if(State.outside.population < 0) { if($SM.get('game.outside.population') < 0) {
State.outside.population = 0; $SM.set('game.outside.population', 0);
} }
var remaining = Outside.getNumGatherers(); var remaining = Outside.getNumGatherers();
if(remaining < 0) { if(remaining < 0) {
var gap = -remaining; var gap = -remaining;
for(var k in State.outside.workers) { for(var k in $SM.get('game.outside.workers')) {
var num = State.outside.workers[k]; var num = $SM.get('game.outside.workers[\''+k+'\']');
if(num < gap) { if(num < gap) {
gap -= num; gap -= num;
State.outside.workers[k] = 0; $SM.set('game.outside.workers[\''+k+'\']', 0);
} else { } else {
State.outside.workers[k] -= gap; $SM.add('game.outside.workers[\''+k+'\']', gap * -1);
break; break;
} }
} }
@@ -256,7 +257,7 @@ var Outside = {
// If our population is 0 and we don't already have a workers view, // If our population is 0 and we don't already have a workers view,
// there's nothing to do here. // there's nothing to do here.
if(!workers.length && State.outside.population == 0) return; if(!workers.length && $SM.get('game.outside.population') == 0) return;
var needsAppend = false; var needsAppend = false;
if(workers.length == 0) { if(workers.length == 0) {
@@ -264,13 +265,13 @@ var Outside = {
workers = $('<div>').attr('id', 'workers').css('opacity', 0); workers = $('<div>').attr('id', 'workers').css('opacity', 0);
} }
var numGatherers = State.outside.population; var numGatherers = $SM.get('game.outside.population');
var gatherer = $('div#workers_row_gatherer', workers); var gatherer = $('div#workers_row_gatherer', workers);
for(var k in State.outside.workers) { for(var k in $SM.get('game.outside.workers')) {
var row = $('div#workers_row_' + k.replace(' ', '-'), workers); var row = $('div#workers_row_' + k.replace(' ', '-'), workers);
if(row.length == 0) { if(row.length == 0) {
row = Outside.makeWorkerRow(k, State.outside.workers[k]); row = Outside.makeWorkerRow(k, $SM.get('game.outside.workers[\''+k+'\']'));
var curPrev = null; var curPrev = null;
workers.children().each(function(i) { workers.children().each(function(i) {
@@ -295,10 +296,10 @@ var Outside = {
} }
} else { } else {
$('div#' + row.attr('id') + ' > div.row_val > span', workers).text(State.outside.workers[k]); $('div#' + row.attr('id') + ' > div.row_val > span', workers).text($SM.get('game.outside.workers[\''+k+'\']'));
} }
numGatherers -= State.outside.workers[k]; numGatherers -= $SM.get('game.outside.workers[\''+k+'\']');
if(State.outside.workers[k] == 0) { if($SM.get('game.outside.workers[\''+k+'\']') == 0) {
$('.dnBtn', row).addClass('disabled'); $('.dnBtn', row).addClass('disabled');
$('.dnManyBtn', row).addClass('disabled'); $('.dnManyBtn', row).addClass('disabled');
} else { } else {
@@ -329,9 +330,9 @@ var Outside = {
}, },
getNumGatherers: function() { getNumGatherers: function() {
var num = State.outside.population; var num = $SM.get('game.outside.population');
for(var k in State.outside.workers) { for(var k in $SM.get('game.outside.workers')) {
num -= State.outside.workers[k]; num -= $SM.get('game.outside.workers[\''+k+'\']');
} }
return num; return num;
}, },
@@ -371,7 +372,7 @@ var Outside = {
if(Outside.getNumGatherers() > 0) { if(Outside.getNumGatherers() > 0) {
var increaseAmt = Math.min(Outside.getNumGatherers(), btn.data); var increaseAmt = Math.min(Outside.getNumGatherers(), btn.data);
Engine.log('increasing ' + worker + ' by ' + increaseAmt); Engine.log('increasing ' + worker + ' by ' + increaseAmt);
State.outside.workers[worker] += increaseAmt; $SM.add('game.outside.workers[\''+worker+'\']', increaseAmt);
Outside.updateVillageIncome(); Outside.updateVillageIncome();
Outside.updateWorkersView(); Outside.updateWorkersView();
} }
@@ -379,10 +380,10 @@ var Outside = {
decreaseWorker: function(btn) { decreaseWorker: function(btn) {
var worker = $(this).closest('.workerRow').children('.row_key').text(); var worker = $(this).closest('.workerRow').children('.row_key').text();
if(State.outside.workers[worker] > 0) { if($SM.get('game.outside.workers[\''+worker+'\']') > 0) {
var decreaseAmt = Math.min(State.outside.workers[worker] || 0, btn.data); var decreaseAmt = Math.min($SM.get('game.outside.workers[\''+worker+'\']') || 0, btn.data);
Engine.log('decreasing ' + worker + ' by ' + decreaseAmt); Engine.log('decreasing ' + worker + ' by ' + decreaseAmt);
State.outside.workers[worker] -= decreaseAmt; $SM.add('game.outside.workers[\''+worker+'\']', decreaseAmt * -1);
Outside.updateVillageIncome(); Outside.updateVillageIncome();
Outside.updateWorkersView(); Outside.updateWorkersView();
} }
@@ -428,9 +429,9 @@ var Outside = {
population = $('<div>').attr('id', 'population').appendTo(village); population = $('<div>').attr('id', 'population').appendTo(village);
} }
for(var k in State.outside.buildings) { for(var k in $SM.get('game.outside.buildings')) {
if(k == 'trap') { if(k == 'trap') {
var numTraps = State.outside.buildings[k]; var numTraps = $SM.get('game.outside.buildings[\''+k+'\']');
var numBait = Engine.getStore('bait'); var numBait = Engine.getStore('bait');
var traps = numTraps - numBait; var traps = numTraps - numBait;
traps = traps < 0 ? 0 : traps; traps = traps < 0 ? 0 : traps;
@@ -440,11 +441,11 @@ var Outside = {
if(Outside.checkWorker(k)) { if(Outside.checkWorker(k)) {
Outside.updateWorkersView(); Outside.updateWorkersView();
} }
Outside.updateVillageRow(k, State.outside.buildings[k], village); Outside.updateVillageRow(k, $SM.get('game.outside.buildings[\''+k+'\']'), village);
} }
} }
population.text('pop ' + State.outside.population + '/' + this.getMaxPopulation()); population.text('pop ' + $SM.get('game.outside.population') + '/' + this.getMaxPopulation());
var hasPeeps; var hasPeeps;
if(Outside.numBuilding('hut') == 0) { if(Outside.numBuilding('hut') == 0) {
@@ -488,10 +489,10 @@ var Outside = {
if(typeof jobs == 'object') { if(typeof jobs == 'object') {
for(var i = 0, len = jobs.length; i < len; i++) { for(var i = 0, len = jobs.length; i < len; i++) {
var job = jobs[i]; var job = jobs[i];
if(typeof State.outside.buildings[name] == 'number' && if(typeof $SM.get('game.outside.buildings[\''+name+'\']') == 'number' &&
typeof State.outside.workers[job] != 'number') { typeof $SM.get('game.outside.workers[\''+job+'\']') != 'number') {
Engine.log('adding ' + job + ' to the workers list') Engine.log('adding ' + job + ' to the workers list')
State.outside.workers[job] = 0; $SM.set('game.outside.workers[\''+job+'\']', 0);
added = true; added = true;
} }
} }
@@ -502,7 +503,7 @@ var Outside = {
updateVillageIncome: function() { updateVillageIncome: function() {
for(var worker in Outside._INCOME) { for(var worker in Outside._INCOME) {
var income = Outside._INCOME[worker]; var income = Outside._INCOME[worker];
var num = worker == 'gatherer' ? Outside.getNumGatherers() : State.outside.workers[worker]; var num = worker == 'gatherer' ? Outside.getNumGatherers() : $SM.get('game.outside.workers[\''+worker+'\']');
if(typeof num == 'number') { if(typeof num == 'number') {
var stores = {}; var stores = {};
if(num < 0) num = 0; if(num < 0) num = 0;
@@ -575,9 +576,9 @@ var Outside = {
onArrival: function(transition_diff) { onArrival: function(transition_diff) {
Outside.setTitle(); Outside.setTitle();
if(!State.seenForest) { if(!$SM.get('game.outside.seenForest')) {
Notifications.notify(Outside, "the sky is grey and the wind blows relentlessly"); Notifications.notify(Outside, "the sky is grey and the wind blows relentlessly");
State.seenForest = true; $SM.set('game.outside.seenForest', true);
} }
Outside.updateTrapButton(); Outside.updateTrapButton();
Outside.updateVillage(); Outside.updateVillage();
+4 -4
View File
@@ -85,17 +85,17 @@ var Path = {
}, },
updatePerks: function() { updatePerks: function() {
if(State.perks) { if($SM.get('character.perks')) {
var perks = $('#perks'); var perks = $('#perks');
var needsAppend = false; var needsAppend = false;
if(perks.length == 0) { if(perks.length == 0) {
needsAppend = true; needsAppend = true;
perks = $('<div>').attr('id', 'perks'); perks = $('<div>').attr('id', 'perks');
} }
for(var k in State.perks) { for(var k in $SM.get('character.perks')) {
var id = 'perk_' + k.replace(' ', '-'); var id = 'perk_' + k.replace(' ', '-');
var r = $('#' + id); var r = $('#' + id);
if(State.perks[k] && r.length == 0) { if($SM.get('character.perks[\''+k+'\']') && r.length == 0) {
r = $('<div>').attr('id', id).addClass('perkRow').appendTo(perks); r = $('<div>').attr('id', id).addClass('perkRow').appendTo(perks);
$('<div>').addClass('row_key').text(k).appendTo(r); $('<div>').addClass('row_key').text(k).appendTo(r);
$('<div>').addClass('tooltip bottom right').text(Engine.Perks[k].desc).appendTo(r); $('<div>').addClass('tooltip bottom right').text(Engine.Perks[k].desc).appendTo(r);
@@ -166,7 +166,7 @@ var Path = {
for(var k in carryable) { for(var k in carryable) {
var store = carryable[k]; var store = carryable[k];
var have = State.stores[k]; var have = $SM.get('stores[\''+k+'\']');
var num = Path.outfit[k]; var num = Path.outfit[k];
num = typeof num == 'number' ? num : 0; num = typeof num == 'number' ? num : 0;
var numAvailable = Engine.getStore(k); var numAvailable = Engine.getStore(k);
+60 -58
View File
@@ -437,19 +437,20 @@ var Room = {
); );
if(Engine._debug) { if(Engine._debug) {
this._ROOM_WARM_DELAY = 1; this._ROOM_WARM_DELAY = 5000;
this._BUILDER_STATE_DELAY = 1; this._BUILDER_STATE_DELAY = 5000;
this._STOKE_COOLDOWN = 0; this._STOKE_COOLDOWN = 0;
this._NEED_WOOD_DELAY = 1; this._NEED_WOOD_DELAY = 5000;
} }
if(typeof State.room == 'undefined') { if(typeof $SM.get('features.location.room') == 'undefined') {
State.room = { $SM.set('features.location.room', true);
$SM.set('game.room', {
temperature: this.TempEnum.Cold, temperature: this.TempEnum.Cold,
fire: this.FireEnum.Dead, fire: this.FireEnum.Dead,
buttons: {}, buttons: {},
builder: -1 builder: -1
}; });
} }
// Create the room tab // Create the room tab
@@ -502,16 +503,16 @@ var Room = {
* 3 - Sleeping * 3 - Sleeping
* 4 - Helping * 4 - Helping
*/ */
if(State.room.builder >= 0 && State.room.builder < 3) { if($SM.get('game.room.builder') >= 0 && $SM.get('game.room.builder') < 3) {
Room._builderTimer = setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); Room._builderTimer = setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY);
} }
if(State.room.builder == 1 && Engine.getStore('wood') < 0) { if($SM.get('game.room.builder') == 1 && Engine.getStore('wood') < 0) {
setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY); setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY);
} }
setTimeout(Engine.collectIncome, 1000); setTimeout(Engine.collectIncome, 1000);
Notifications.notify(Room, "the room is " + State.room.temperature.text); Notifications.notify(Room, "the room is " + $SM.get('game.room.temperature.text'));
Notifications.notify(Room, "the fire is " + State.room.fire.text); Notifications.notify(Room, "the fire is " + $SM.get('game.room.fire.text'));
}, },
options: {}, // Nothing for now options: {}, // Nothing for now
@@ -519,12 +520,12 @@ var Room = {
onArrival: function(transition_diff) { onArrival: function(transition_diff) {
Room.setTitle(); Room.setTitle();
if(Room.changed) { if(Room.changed) {
Notifications.notify(Room, "the fire is " + State.room.fire.text); Notifications.notify(Room, "the fire is " + $SM.get('game.room.fire.text'));
Notifications.notify(Room, "the room is " + State.room.temperature.text); Notifications.notify(Room, "the room is " + $SM.get('game.room.temperature.text'));
Room.changed = false; Room.changed = false;
} }
if(State.room.builder == 3) { if($SM.get('game.room.builder') == 3) {
State.room.builder++; $SM.add('game.room.builder', 1);
Engine.setIncome('builder', { Engine.setIncome('builder', {
delay: 10, delay: 10,
stores: {'wood' : 2 } stores: {'wood' : 2 }
@@ -569,7 +570,7 @@ var Room = {
}, },
setTitle: function() { setTitle: function() {
var title = State.room.fire.value < 2 ? "A Dark Room" : "A Firelit Room"; var title = $SM.get('game.room.fire.value') < 2 ? "A Dark Room" : "A Firelit Room";
if(Engine.activeModule == this) { if(Engine.activeModule == this) {
document.title = title; document.title = title;
} }
@@ -579,7 +580,7 @@ var Room = {
updateButton: function() { updateButton: function() {
var light = $('#lightButton.button'); var light = $('#lightButton.button');
var stoke = $('#stokeButton.button'); var stoke = $('#stokeButton.button');
if(State.room.fire.value == Room.FireEnum.Dead.value && stoke.css('display') != 'none') { if($SM.get('game.room.fire.value') == Room.FireEnum.Dead.value && stoke.css('display') != 'none') {
stoke.hide(); stoke.hide();
light.show(); light.show();
if(stoke.hasClass('disabled')) { if(stoke.hasClass('disabled')) {
@@ -613,7 +614,7 @@ var Room = {
} else if(wood > 4) { } else if(wood > 4) {
Engine.setStore('wood', wood - 5); Engine.setStore('wood', wood - 5);
} }
State.room.fire = Room.FireEnum.Burning; $SM.set('game.room.fire', Room.FireEnum.Burning);
Room.onFireChange(); Room.onFireChange();
}, },
@@ -627,8 +628,8 @@ var Room = {
if(wood > 0) { if(wood > 0) {
Engine.setStore('wood', wood - 1); Engine.setStore('wood', wood - 1);
} }
if(State.room.fire.value < 4) { if($SM.get('game.room.fire.value') < 4) {
State.room.fire = Room.FireEnum.fromInt(State.room.fire.value + 1); $SM.set('game.room.fire', Room.FireEnum.fromInt($SM.get('game.room.fire.value') + 1));
} }
Room.onFireChange(); Room.onFireChange();
}, },
@@ -637,9 +638,9 @@ var Room = {
if(Engine.activeModule != Room) { if(Engine.activeModule != Room) {
Room.changed = true; Room.changed = true;
} }
Notifications.notify(Room, "the fire is " + State.room.fire.text, true); Notifications.notify(Room, "the fire is " + $SM.get('game.room.fire.text'), true);
if(State.room.fire.value > 1 && State.room.builder < 0) { if($SM.get('game.room.fire.value') > 1 && $SM.get('game.room.builder') < 0) {
State.room.builder = 0; $SM.set('game.room.builder', 0);
Notifications.notify(Room, "the light from the fire spills from the windows, out into the dark"); Notifications.notify(Room, "the light from the fire spills from the windows, out into the dark");
setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY);
} }
@@ -650,30 +651,30 @@ var Room = {
}, },
coolFire: function() { coolFire: function() {
if(State.room.fire.value <= Room.FireEnum.Flickering.value && if($SM.get('game.room.fire.value') <= Room.FireEnum.Flickering.value &&
State.room.builder > 3 && Engine.getStore('wood') > 0) { $SM.get('game.room.builder') > 3 && Engine.getStore('wood') > 0) {
Notifications.notify(Room, "builder stokes the fire", true); Notifications.notify(Room, "builder stokes the fire", true);
Engine.setStore('wood', Engine.getStore('wood') - 1); Engine.setStore('wood', Engine.getStore('wood') - 1);
State.room.fire = Room.FireEnum.fromInt(State.room.fire.value + 1); $SM.set('game.room.fire', Room.FireEnum.fromInt($SM.get('game.room.fire.value') + 1));
} }
if(State.room.fire.value > 0) { if($SM.get('game.room.fire.value') > 0) {
State.room.fire = Room.FireEnum.fromInt(State.room.fire.value - 1); $SM.set('game.room.fire', Room.FireEnum.fromInt($SM.get('game.room.fire.value') - 1));
Room._fireTimer = setTimeout(Room.coolFire, Room._FIRE_COOL_DELAY); Room._fireTimer = setTimeout(Room.coolFire, Room._FIRE_COOL_DELAY);
Room.onFireChange(); Room.onFireChange();
} }
}, },
adjustTemp: function() { adjustTemp: function() {
var old = State.room.temperature.value; var old = $SM.get('game.room.temperature.value');
if(State.room.temperature.value > 0 && State.room.temperature.value > State.room.fire.value) { if($SM.get('game.room.temperature.value') > 0 && $SM.get('game.room.temperature.value') > $SM.get('game.room.fire.value')) {
State.room.temperature = Room.TempEnum.fromInt(State.room.temperature.value - 1); $SM.set('game.room.temperature', Room.TempEnum.fromInt($SM.get('game.room.temperature.value') - 1));
Notifications.notify(Room, "the room is " + State.room.temperature.text, true); Notifications.notify(Room, "the room is " + $SM.get('game.room.temperature.text'), true);
} }
if(State.room.temperature.value < 4 && State.room.temperature.value < State.room.fire.value) { if($SM.get('game.room.temperature.value') < 4 && $SM.get('game.room.temperature.value') < $SM.get('game.room.fire.value')) {
State.room.temperature = Room.TempEnum.fromInt(State.room.temperature.value + 1); $SM.set('game.room.temperature', Room.TempEnum.fromInt($SM.get('game.room.temperature.value') + 1));
Notifications.notify(Room, "the room is " + State.room.temperature.text, true); Notifications.notify(Room, "the room is " + $SM.get('game.room.temperature.text'), true);
} }
if(State.room.temperature.value != old) { if($SM.get('game.room.temperature.value') != old) {
Room.changed = true; Room.changed = true;
} }
Room._tempTimer = setTimeout(Room.adjustTemp, Room._ROOM_WARM_DELAY); Room._tempTimer = setTimeout(Room.adjustTemp, Room._ROOM_WARM_DELAY);
@@ -690,14 +691,14 @@ var Room = {
}, },
updateBuilderState: function() { updateBuilderState: function() {
if(State.room.builder == 0) { if($SM.get('game.room.builder') == 0) {
Notifications.notify(Room, "a ragged stranger stumbles through the door and collapses in the corner"); Notifications.notify(Room, "a ragged stranger stumbles through the door and collapses in the corner");
State.room.builder = 1; $SM.set('game.room.builder', 1);
setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY); setTimeout(Room.unlockForest, Room._NEED_WOOD_DELAY);
} }
else if(State.room.builder < 3 && State.room.temperature.value >= Room.TempEnum.Warm.value) { else if($SM.get('game.room.builder') < 3 && $SM.get('game.room.temperature.value') >= Room.TempEnum.Warm.value) {
var msg; var msg;
switch(State.room.builder) { switch($SM.get('game.room.builder')) {
case 1: case 1:
msg = "the stranger shivers, and mumbles quietly. her words are unintelligible."; msg = "the stranger shivers, and mumbles quietly. her words are unintelligible.";
break; break;
@@ -706,11 +707,11 @@ var Room = {
break; break;
} }
Notifications.notify(Room, msg); Notifications.notify(Room, msg);
if(State.room.builder < 3) { if($SM.get('game.room.builder') < 3) {
State.room.builder++; $SM.add('game.room.builder', 1);
} }
} }
if(State.room.builder < 3) { if($SM.get('game.room.builder') < 3) {
setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY); setTimeout(Room.updateBuilderState, Room._BUILDER_STATE_DELAY);
} }
Engine.saveGame(); Engine.saveGame();
@@ -732,7 +733,7 @@ var Room = {
}).css('opacity', 0); }).css('opacity', 0);
wNeedsAppend = true; wNeedsAppend = true;
} }
for(var k in State.stores) { for(var k in $SM.get('stores')) {
var type = null; var type = null;
if(Room.Craftables[k]) { if(Room.Craftables[k]) {
@@ -758,17 +759,18 @@ var Room = {
var id = "row_" + k.replace(' ', '-'); var id = "row_" + k.replace(' ', '-');
var row = $('div#' + id, location); var row = $('div#' + id, location);
var num = State.stores[k]; var num = $SM.get('stores[\''+k+'\']');
if(typeof num != 'number' || isNaN(num)) { if(typeof num != 'number' || isNaN(num)) {
// No idea how counts get corrupted, but I have reason to believe that they occassionally do. // No idea how counts get corrupted, but I have reason to believe that they occassionally do.
// Build a little fence around it! // Build a little fence around it!
num = State.stores[k] = 0; num = 0;
$SM.set('stores[\''+k+'\']', 0);
} }
// thieves? // thieves?
if(typeof State.thieves == 'undefined' && num > 5000 && State.world) { if(typeof $SM.get('game.thieves') == 'undefined' && num > 5000 && $SM.get('features.location.world')) {
Engine.startThieves(); Engine.startThieves();
} }
@@ -819,14 +821,14 @@ var Room = {
updateIncomeView: function() { updateIncomeView: function() {
var stores = $('div#stores'); var stores = $('div#stores');
if(stores.length == 0 || typeof State.income == 'undefined') return; if(stores.length == 0 || typeof $SM.get('income') == 'undefined') return;
$('div.storeRow', stores).each(function(index, el) { $('div.storeRow', stores).each(function(index, el) {
el = $(el); el = $(el);
$('div.tooltip', el).remove(); $('div.tooltip', el).remove();
var tt = $('<div>').addClass('tooltip bottom right'); var tt = $('<div>').addClass('tooltip bottom right');
var storeName = el.attr('id').substring(4).replace('-', ' '); var storeName = el.attr('id').substring(4).replace('-', ' ');
for(var incomeSource in State.income) { for(var incomeSource in $SM.get('income')) {
var income = State.income[incomeSource]; var income = $SM.get('income[\''+incomeSource+'\']');
for(var store in income.stores) { for(var store in income.stores) {
if(store == storeName && income.stores[store] != 0) { if(store == storeName && income.stores[store] != 0) {
$('<div>').addClass('row_key').text(incomeSource).appendTo(tt); $('<div>').addClass('row_key').text(incomeSource).appendTo(tt);
@@ -878,7 +880,7 @@ var Room = {
build: function(buildBtn) { build: function(buildBtn) {
var thing = $(buildBtn).attr('buildThing'); var thing = $(buildBtn).attr('buildThing');
if(State.room.temperature.value <= Room.TempEnum.Cold.value) { if($SM.get('game.room.temperature.value') <= Room.TempEnum.Cold.value) {
Notifications.notify(Room, "builder just shivers"); Notifications.notify(Room, "builder just shivers");
return false; return false;
} }
@@ -938,12 +940,12 @@ var Room = {
}, },
craftUnlocked: function(thing) { craftUnlocked: function(thing) {
if(typeof State.room != 'undefined' && if(typeof $SM.get('features.location.room') != 'undefined' &&
typeof State.room.buttons != 'undefined' && typeof $SM.get('game.room.buttons') != 'undefined' &&
State.room.buttons[thing]) { $SM.get('game.room.buttons[\''+thing+'\']')) {
return true; return true;
} }
if(State.room.builder < 4) return false; if($SM.get('game.room.builder') < 4) return false;
var craftable = Room.Craftables[thing]; var craftable = Room.Craftables[thing];
if(Room.needsWorkshop(craftable.type) && Outside.numBuilding('workshop') == 0) return false; if(Room.needsWorkshop(craftable.type) && Outside.numBuilding('workshop') == 0) return false;
var cost = craftable.cost(); var cost = craftable.cost();
@@ -958,15 +960,15 @@ var Room = {
} }
} }
State.room.buttons[thing] = true; $SM.set('game.room.buttons[\''+thing+'\']', true);
Notifications.notify(Room, craftable.availableMsg); Notifications.notify(Room, craftable.availableMsg);
return true; return true;
}, },
buyUnlocked: function(thing) { buyUnlocked: function(thing) {
if(typeof State.room != 'undefined' && if(typeof $SM.get('features.location.room') != 'undefined' &&
typeof State.room.buttons != 'undefined' && typeof $SM.get('game.room.buttons') != 'undefined' &&
State.room.buttons[thing]) { $SM.get('game.room.buttons[\''+thing+'\']')) {
return true; return true;
} else if(Outside.numBuilding('trading post') > 0) { } else if(Outside.numBuilding('trading post') > 0) {
if(thing == 'compass' || Engine.storeAvailable(thing)) { if(thing == 'compass' || Engine.storeAvailable(thing)) {
+17 -16
View File
@@ -15,11 +15,12 @@ var Ship = {
options options
); );
if(!State.ship) { if(!$SM.get('features.location.spaceShip')) {
State.ship = { $SM.set('features.location.spaceShip', true);
$SM.setM('game.spaceShip', {
hull: Ship.BASE_HULL, hull: Ship.BASE_HULL,
thrusters: Ship.BASE_THRUSTERS thrusters: Ship.BASE_THRUSTERS
} });
} }
// Create the Ship tab // Create the Ship tab
@@ -35,13 +36,13 @@ var Ship = {
// Draw the hull label // Draw the hull label
var hullRow = $('<div>').attr('id', 'hullRow').appendTo('div#shipPanel'); var hullRow = $('<div>').attr('id', 'hullRow').appendTo('div#shipPanel');
$('<div>').addClass('row_key').text('hull:').appendTo(hullRow); $('<div>').addClass('row_key').text('hull:').appendTo(hullRow);
$('<div>').addClass('row_val').text(State.ship.hull).appendTo(hullRow); $('<div>').addClass('row_val').text($SM.get('game.spaceShip.hull')).appendTo(hullRow);
$('<div>').addClass('clear').appendTo(hullRow); $('<div>').addClass('clear').appendTo(hullRow);
// Draw the thrusters label // Draw the thrusters label
var engineRow = $('<div>').attr('id', 'engineRow').appendTo('div#shipPanel'); var engineRow = $('<div>').attr('id', 'engineRow').appendTo('div#shipPanel');
$('<div>').addClass('row_key').text('engine:').appendTo(engineRow); $('<div>').addClass('row_key').text('engine:').appendTo(engineRow);
$('<div>').addClass('row_val').text(State.ship.thrusters).appendTo(engineRow); $('<div>').addClass('row_val').text($SM.get('game.spaceShip.thrusters')).appendTo(engineRow);
$('<div>').addClass('clear').appendTo(engineRow); $('<div>').addClass('clear').appendTo(engineRow);
// Draw the reinforce button // Draw the reinforce button
@@ -71,7 +72,7 @@ var Ship = {
cooldown: Ship.LIFTOFF_COOLDOWN cooldown: Ship.LIFTOFF_COOLDOWN
}).appendTo('div#shipPanel'); }).appendTo('div#shipPanel');
if(State.ship.hull <= 0) { if($SM.get('game.spaceShip.hull') <= 0) {
Button.setDisabled(b, true); Button.setDisabled(b, true);
} }
@@ -83,9 +84,9 @@ var Ship = {
onArrival: function(transition_diff) { onArrival: function(transition_diff) {
Ship.setTitle(); Ship.setTitle();
if(!State.seenShip) { if(!$SM.get('game.spaceShip.seenShip')) {
Notifications.notify(Ship, 'somewhere above the debris cloud, the wanderer fleet hovers. been on this rock too long.'); Notifications.notify(Ship, 'somewhere above the debris cloud, the wanderer fleet hovers. been on this rock too long.');
State.seenShip = true; $SM.set('game.spaceShip.seenShip', true);
Engine.saveGame(); Engine.saveGame();
} }
@@ -104,11 +105,11 @@ var Ship = {
return false; return false;
} }
Engine.addStore('alien alloy', -Ship.ALLOY_PER_HULL); Engine.addStore('alien alloy', -Ship.ALLOY_PER_HULL);
State.ship.hull++; $SM.add('game.spaceShip.hull', 1);
if(State.ship.hull > 0) { if($SM.get('game.spaceShip.hull') > 0) {
Button.setDisabled($('#liftoffButton', Ship.panel), false); Button.setDisabled($('#liftoffButton', Ship.panel), false);
} }
$('#hullRow .row_val', Ship.panel).text(State.ship.hull); $('#hullRow .row_val', Ship.panel).text($SM.get('game.spaceShip.hull'));
}, },
upgradeEngine: function() { upgradeEngine: function() {
@@ -117,16 +118,16 @@ var Ship = {
return false; return false;
} }
Engine.addStore('alien alloy', -Ship.ALLOY_PER_THRUSTER); Engine.addStore('alien alloy', -Ship.ALLOY_PER_THRUSTER);
State.ship.thrusters++; $SM.add('game.spaceShip.thrusters', 1)
$('#engineRow .row_val', Ship.panel).text(State.ship.thrusters); $('#engineRow .row_val', Ship.panel).text($SM.get('game.spaceShip.thrusters'));
}, },
getMaxHull: function() { getMaxHull: function() {
return State.ship.hull; return $SM.get('game.spaceShip.hull');
}, },
checkLiftOff: function() { checkLiftOff: function() {
if(!State.ship.seenWarning) { if(!$SM.get('game.spaceShip.seenWarning')) {
Events.startEvent({ Events.startEvent({
title: 'Ready to Leave?', title: 'Ready to Leave?',
scenes: { scenes: {
@@ -138,7 +139,7 @@ var Ship = {
'fly': { 'fly': {
text: 'lift off', text: 'lift off',
onChoose: function() { onChoose: function() {
State.ship.seenWarning = true; $SM.set('game.spaceShip.seenWarning', true);
Ship.liftOff(); Ship.liftOff();
}, },
nextScene: 'end' nextScene: 'end'
+1 -1
View File
@@ -87,7 +87,7 @@ var Space = {
}, },
getSpeed: function() { getSpeed: function() {
return Space.SHIP_SPEED + State.ship.thrusters; return Space.SHIP_SPEED + $SM.get('game.spaceShip.thrusters');
}, },
updateHull: function() { updateHull: function() {
+212
View File
@@ -0,0 +1,212 @@
/*
* Module for handling States
*
* All states should be get and set through the StateManager ($SM).
*
* The manager is intended to handle all needed checks and error catching.
* This includes creating the parents of layered/deep states so undefined states
* do not need to be tested for and created beforehand.
*
* When a state is changed, an update event is sent out containing the name of the state
* changed or in the case of multiple changes (.setM, .addM) the parent class changed.
* Event: type: 'stateUpdate', stateName: <path of state or parent state>
*
* Original file created by: Michael Galusha
*/
var StateManager = {
MAX_STORE: 99999999999999,
options: {},
init: function(options) {
this.options = $.extend(
this.options,
options
);
//create categories
var cats = [
'features', //big features like buildings, location availability, unlocks, etc
'stores', //little stuff, items, weapons, etc
'character', //this is for player's character stats such as perks
'income',
'timers',
'game', //mostly location related: fire temp, workers, population, world map, etc
'playStats', //anything play related: play time, loads, etc
];
for(var which in cats) {
if(!$SM.get(cats[which])) $SM.set(cats[which], {});
};
},
//create the parent of a given state, recursive as needed
createParent: function(stateName) {
var err = 0;
//parse path to find last child
var lastDot = stateName.lastIndexOf('.'); //if ends with a dot, there is a coding bug, not like ending in a bracket, so don't account for it
if(lastDot == stateName.length) {
Engine.log('ERROR: '+stateName+' is invalid. Cannot end in a dot.');
return;
}
var lastOB = stateName.lastIndexOf('[');
//make sure last bracket isn't just end of the line
var lastCB = stateName.substr(0, stateName.length -1).lastIndexOf(']');
//find last child or return if no more children
var cutoff = Math.max(lastDot, lastOB, lastCB);
if(cutoff <= 0) return;
var parentPath = $SM.buildPath(stateName.substr(0,cutoff));
//try creating the parent
try {
eval('('+parentPath+') = {}');
} catch (e) {
//need to go up another level and make parent of whichParent
$SM.createParent(stateName.substr(0,cutoff));
//then it will definitely work if not, something is fubar
eval('('+parentPath+') = {}');
}
},
//set single state
//if noEvent is true, the update event won't trigger, useful for setting multiple states first
set: function(stateName, value, noEvent) {
var fullPath = $SM.buildPath(stateName);
//make sure the value isn't over the engine maximum
if(typeof value == 'number' && value > $SM.MAX_STORE) value = $SM.MAX_STORE;
try{
eval('('+fullPath+') = value');
} catch (e) {
//parent doesn't exist, so make parent
$SM.createParent(stateName);
//now it will definitely work. if not, something is broken
eval('('+fullPath+') = value');
}
//stores values can not be negative
if(stateName.indexOf('stores') == 0 && $SM.get(stateName, true) < 0) {
eval('('+fullPath+') = 0');;
Engine.log('WARNING: state:' + stateName + ' can not be a negative value. Set to 0 instead.')
}
if(!noEvent) {
Engine.saveGame();
$SM.fireUpdate(stateName);
}
},
//sets a list of states
setM: function(parentName, list, noEvent) {
var whichParent = $SM.buildPath(parentName);
//make sure the state exists to avoid errors,
if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true);
for(var k in list){
$SM.set(parentName+'[\''+k+'\']', list[k], true);
}
if(!noEvent) {
Engine.saveGame();
$SM.fireUpdate(parentName);
}
},
//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
var old = $SM.get(stateName, true);
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 {
$SM.set(stateName, old + value, noEvent); //setState handles event and save
}
return err;
},
//alters multiple number values, return number of fails
addM: function(parentName, list, noEvent) {
var err = 0;
//make sure the parent exists to avoid errors
if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true);
for(var k in list){
if(!$SM.add(parentName+'[\''+k+'\']', list[k], true)) err++;
}
if(!noEvent) {
Engine.saveGame();
$SM.fireUpdate(parentName);
}
return err;
},
//return state, undefined or 0
get: function(stateName, requestZero) {
var whichState = null;
var fullPath = $SM.buildPath(stateName, name);
//catch errors if parent of state doesn't exist
try{
eval('whichState = ('+fullPath+')');
} catch (e) {
whichState = undefined;
}
//prevents repeated if undefined, null, false or {}, then x = 0 situations
if((!whichState || whichState == {}) && requestZero) return 0;
else return whichState;
},
remove: function(stateName) {
var whichState = $SM.buildPath(whichState);
try{
delete eval(whichState);
} catch (e) {
//it didn't exist in the first place
Engine.log('WARNING: Tried to remove non-existant state \''+stateName+'\'.');
}
Engine.saveGame();
$SM.fireUpdate(stateName);
},
//creates full reference from input
//hopefully this won't ever need to be more complicated
buildPath: function(input){
var dot = (input.charAt(0) == '[')? '' : '.'; //if it starts with [foo] no dot to join
return 'State' + dot + input;
},
fireUpdate: function(stateName, save){
if(stateName == undefined) stateName = 'all'; //best if this doesn't happen as it will trigger more stuff
$.event.trigger({
'type': 'stateUpdate',
'stateName': stateName,
});
if(save) Engine.saveGame();
},
handleStateUpdates: function(e){
},
};
//alias
var $SM = StateManager;
//listener for StateManager update events
$(StateManager).on('stateUpdate', $SM.handleStateUpdates);
+15 -14
View File
@@ -128,11 +128,12 @@ var World = {
World.LANDMARKS[World.TILE.BATTLEFIELD] = {num: 5, minRadius: 18, maxRadius: World.RADIUS * 1.5, scene: 'battlefield', label: 'A&nbsp;Battlefield'}; World.LANDMARKS[World.TILE.BATTLEFIELD] = {num: 5, minRadius: 18, maxRadius: World.RADIUS * 1.5, scene: 'battlefield', label: 'A&nbsp;Battlefield'};
World.LANDMARKS[World.TILE.SWAMP] = {num: 1, minRadius: 15, maxRadius: World.RADIUS * 1.5, scene: 'swamp', label: 'A&nbsp;Murky&nbsp;Swamp'}; World.LANDMARKS[World.TILE.SWAMP] = {num: 1, minRadius: 15, maxRadius: World.RADIUS * 1.5, scene: 'swamp', label: 'A&nbsp;Murky&nbsp;Swamp'};
if(typeof State.world == 'undefined') { if(typeof $SM.get('features.location.world') == 'undefined') {
State.world = { $SM.set('features.location.world', true);
$SM.setM('game.world', {
map: World.generateMap(), map: World.generateMap(),
mask: World.newMask() mask: World.newMask()
}; });
} }
// Create the World panel // Create the World panel
@@ -440,9 +441,9 @@ var World = {
Notifications.notify(World, 'starvation sets in') Notifications.notify(World, 'starvation sets in')
World.starvation = true; World.starvation = true;
} else { } else {
State.starved = State.starved ? State.starved : 0; $SM.set('character.starved', $SM.get('character.starved', true));
State.starved++; $SM.add('character.starved', 1);
if(State.starved >= 10 && !Engine.hasPerk('slow metabolism')) { if($SM.get('character.starved') >= 10 && !Engine.hasPerk('slow metabolism')) {
Engine.addPerk('slow metabolism'); Engine.addPerk('slow metabolism');
} }
World.die(); World.die();
@@ -469,9 +470,9 @@ var World = {
Notifications.notify(World, 'the thirst becomes unbearable'); Notifications.notify(World, 'the thirst becomes unbearable');
World.thirst = true; World.thirst = true;
} else { } else {
State.dehydrated = State.dehydrated ? State.dehydrated : 0; $SM.set('character.dehydrated', $SM.get('character.dehydrated', true));
State.dehydrated++; $SM.add('character.dehydrated', 1);
if(State.dehydrated >= 10 && !Engine.hasPerk('desert rat')) { if($SM.get('character.dehydrated') >= 10 && !Engine.hasPerk('desert rat')) {
Engine.addPerk('desert rat'); Engine.addPerk('desert rat');
} }
World.die(); World.die();
@@ -604,7 +605,7 @@ var World = {
applyMap: function() { applyMap: function() {
var x = Math.floor(Math.random() * (World.RADIUS * 2) + 1); var x = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
var y = Math.floor(Math.random() * (World.RADIUS * 2) + 1); var y = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
World.uncoverMap(x, y, 5, State.world.mask); World.uncoverMap(x, y, 5, $SM.get('game.world.mask'));
}, },
generateMap: function() { generateMap: function() {
@@ -822,7 +823,7 @@ var World = {
goHome: function() { goHome: function() {
// Home safe! Commit the changes. // Home safe! Commit the changes.
State.world = World.state; $SM.setM('game.world', World.state);
if(World.state.sulphurmine && Outside.numBuilding('sulphur mine') == 0) { if(World.state.sulphurmine && Outside.numBuilding('sulphur mine') == 0) {
Outside.addBuilding('sulphur mine', 1); Outside.addBuilding('sulphur mine', 1);
Engine.event('progress', 'sulphur mine'); Engine.event('progress', 'sulphur mine');
@@ -835,7 +836,7 @@ var World = {
Outside.addBuilding('coal mine', 1); Outside.addBuilding('coal mine', 1);
Engine.event('progress', 'coal mine'); Engine.event('progress', 'coal mine');
} }
if(World.state.ship && !State.ship) { if(World.state.ship && !$SM.get('features.location.spaceShip')) {
Ship.init(); Ship.init();
Engine.event('progress', 'ship'); Engine.event('progress', 'ship');
} }
@@ -904,7 +905,7 @@ var World = {
Notifications.notify(null, 'water replenished'); Notifications.notify(null, 'water replenished');
World.setWater(World.getMaxWater()); World.setWater(World.getMaxWater());
// Save progress at outposts // Save progress at outposts
State.world = World.state; $SM.setM('game.world', World.state);
// Mark this outpost as used // Mark this outpost as used
World.usedOutposts[World.curPos[0] + ',' + World.curPos[1]] = true; World.usedOutposts[World.curPos[0] + ',' + World.curPos[1]] = true;
}, },
@@ -912,7 +913,7 @@ var World = {
onArrival: function() { onArrival: function() {
Engine.keyLock = false; Engine.keyLock = false;
// Explore in a temporary world-state. We'll commit the changes if you return home safe. // Explore in a temporary world-state. We'll commit the changes if you return home safe.
World.state = $.extend(true, {}, State.world); World.state = $.extend(true, {}, $SM.get('game.world'));
World.setWater(World.getMaxWater()); World.setWater(World.getMaxWater());
World.setHp(World.getMaxHealth()); World.setHp(World.getMaxHealth());
World.foodMove = 0; World.foodMove = 0;