Remove ^M from file because to heck with them.

This commit is contained in:
Travis Weston
2015-02-06 16:02:37 -05:00
parent 7f59e166de
commit 5fcdf29601
+416 -416
View File
@@ -1,421 +1,421 @@
/* /*
* Module for handling States * Module for handling States
* *
* All states should be get and set through the StateManager ($SM). * All states should be get and set through the StateManager ($SM).
* *
* The manager is intended to handle all needed checks and error catching. * The manager is intended to handle all needed checks and error catching.
* This includes creating the parents of layered/deep states so undefined states * This includes creating the parents of layered/deep states so undefined states
* do not need to be tested for and created beforehand. * 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 * 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. * changed or in the case of multiple changes (.setM, .addM) the parent class changed.
* Event: type: 'stateUpdate', stateName: <path of state or parent state> * Event: type: 'stateUpdate', stateName: <path of state or parent state>
* *
* Original file created by: Michael Galusha * Original file created by: Michael Galusha
*/ */
var StateManager = { var StateManager = {
MAX_STORE: 99999999999999, MAX_STORE: 99999999999999,
options: {}, options: {},
init: function(options) { init: function(options) {
this.options = $.extend( this.options = $.extend(
this.options, this.options,
options options
); );
//create categories //create categories
var cats = [ var cats = [
'features', //big features like buildings, location availability, unlocks, etc 'features', //big features like buildings, location availability, unlocks, etc
'stores', //little stuff, items, weapons, etc 'stores', //little stuff, items, weapons, etc
'character', //this is for player's character stats such as perks 'character', //this is for player's character stats such as perks
'income', 'income',
'timers', 'timers',
'game', //mostly location related: fire temp, workers, population, world map, etc 'game', //mostly location related: fire temp, workers, population, world map, etc
'playStats', //anything play related: play time, loads, etc 'playStats', //anything play related: play time, loads, etc
'previous', // prestige, score, trophies (in future), achievements (again, not yet), etc 'previous', // prestige, score, trophies (in future), achievements (again, not yet), etc
'outfit' // used to temporarily store the items to be taken on the path 'outfit' // used to temporarily store the items to be taken on the path
]; ];
for(var which in cats) { for(var which in cats) {
if(!$SM.get(cats[which])) $SM.set(cats[which], {}); if(!$SM.get(cats[which])) $SM.set(cats[which], {});
}; };
//subscribe to stateUpdates //subscribe to stateUpdates
$.Dispatch('stateUpdate').subscribe($SM.handleStateUpdates); $.Dispatch('stateUpdate').subscribe($SM.handleStateUpdates);
}, },
//create all parents and then set state //create all parents and then set state
createState: function(stateName, value) { createState: function(stateName, value) {
var words = stateName.split(/[.\[\]'"]+/); var words = stateName.split(/[.\[\]'"]+/);
//for some reason there are sometimes empty strings //for some reason there are sometimes empty strings
for (var i = 0; i < words.length; i++) { for (var i = 0; i < words.length; i++) {
if (words[i] == '') { if (words[i] == '') {
words.splice(i, 1); words.splice(i, 1);
i--; i--;
} }
}; };
var obj = State; var obj = State;
var w = null; var w = null;
for(var i=0, len=words.length-1;i<len;i++){ for(var i=0, len=words.length-1;i<len;i++){
w = words[i]; w = words[i];
if(obj[w] === undefined ) obj[w] = {}; if(obj[w] === undefined ) obj[w] = {};
obj = obj[w]; obj = obj[w];
} }
obj[words[i]] = value; obj[words[i]] = value;
return obj; return obj;
}, },
//set single state //set single state
//if noEvent is true, the update event won't trigger, useful for setting multiple states first //if noEvent is true, the update event won't trigger, useful for setting multiple states first
set: function(stateName, value, noEvent) { set: function(stateName, value, noEvent) {
var fullPath = $SM.buildPath(stateName); var fullPath = $SM.buildPath(stateName);
//make sure the value isn't over the engine maximum //make sure the value isn't over the engine maximum
if(typeof value == 'number' && value > $SM.MAX_STORE) value = $SM.MAX_STORE; if(typeof value == 'number' && value > $SM.MAX_STORE) value = $SM.MAX_STORE;
try{ try{
eval('('+fullPath+') = value'); eval('('+fullPath+') = value');
} catch (e) { } catch (e) {
//parent doesn't exist, so make parent //parent doesn't exist, so make parent
$SM.createState(stateName, value); $SM.createState(stateName, value);
} }
//stores values can not be negative //stores values can not be negative
if(stateName.indexOf('stores') == 0 && $SM.get(stateName, true) < 0) { if(stateName.indexOf('stores') == 0 && $SM.get(stateName, true) < 0) {
eval('('+fullPath+') = 0'); eval('('+fullPath+') = 0');
Engine.log('WARNING: state:' + stateName + ' can not be a negative value. Set to 0 instead.'); Engine.log('WARNING: state:' + stateName + ' can not be a negative value. Set to 0 instead.');
} }
if(!noEvent) { if(!noEvent) {
Engine.saveGame(); Engine.saveGame();
$SM.fireUpdate(stateName); $SM.fireUpdate(stateName);
} }
}, },
//sets a list of states //sets a list of states
setM: function(parentName, list, noEvent) { setM: function(parentName, list, noEvent) {
$SM.buildPath(parentName); $SM.buildPath(parentName);
//make sure the state exists to avoid errors, //make sure the state exists to avoid errors,
if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true); if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true);
for(var k in list){ for(var k in list){
$SM.set(parentName+'["'+k+'"]', list[k], true); $SM.set(parentName+'["'+k+'"]', list[k], true);
} }
if(!noEvent) { if(!noEvent) {
Engine.saveGame(); Engine.saveGame();
$SM.fireUpdate(parentName); $SM.fireUpdate(parentName);
} }
}, },
//shortcut for altering number values, return 1 if state wasn't a number //shortcut for altering number values, return 1 if state wasn't a number
add: function(stateName, value, noEvent) { add: function(stateName, value, noEvent) {
var err = 0; var err = 0;
//0 if undefined, null (but not {}) should allow adding to new objects //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) //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) //to be a count, but that might be unwanted behavior (add with loose eval probably will happen anyways)
var old = $SM.get(stateName, true); var old = $SM.get(stateName, true);
//check for NaN (old != old) and non number values //check for NaN (old != old) and non number values
if(old != old){ if(old != old){
Engine.log('WARNING: '+stateName+' was corrupted (NaN). Resetting to 0.'); Engine.log('WARNING: '+stateName+' was corrupted (NaN). Resetting to 0.');
old = 0; old = 0;
$SM.set(stateName, old + value, noEvent); $SM.set(stateName, old + value, noEvent);
} else if(typeof old != 'number' || typeof value != 'number'){ } 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.'); Engine.log('WARNING: Can not do math with state:'+stateName+' or value:'+value+' because at least one is not a number.');
err = 1; err = 1;
} else { } else {
$SM.set(stateName, old + value, noEvent); //setState handles event and save $SM.set(stateName, old + value, noEvent); //setState handles event and save
} }
return err; return err;
}, },
//alters multiple number values, return number of fails //alters multiple number values, return number of fails
addM: function(parentName, list, noEvent) { addM: function(parentName, list, noEvent) {
var err = 0; var err = 0;
//make sure the parent exists to avoid errors //make sure the parent exists to avoid errors
if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true); if($SM.get(parentName) == undefined) $SM.set(parentName, {}, true);
for(var k in list){ for(var k in list){
if($SM.add(parentName+'["'+k+'"]', list[k], true)) err++; if($SM.add(parentName+'["'+k+'"]', list[k], true)) err++;
} }
if(!noEvent) { if(!noEvent) {
Engine.saveGame(); Engine.saveGame();
$SM.fireUpdate(parentName); $SM.fireUpdate(parentName);
} }
return err; return err;
}, },
//return state, undefined or 0 //return state, undefined or 0
get: function(stateName, requestZero) { get: function(stateName, requestZero) {
var whichState = null; var whichState = null;
var fullPath = $SM.buildPath(stateName); var fullPath = $SM.buildPath(stateName);
//catch errors if parent of state doesn't exist //catch errors if parent of state doesn't exist
try{ try{
eval('whichState = ('+fullPath+')'); eval('whichState = ('+fullPath+')');
} catch (e) { } catch (e) {
whichState = undefined; whichState = undefined;
} }
//prevents repeated if undefined, null, false or {}, then x = 0 situations //prevents repeated if undefined, null, false or {}, then x = 0 situations
if((!whichState || whichState == {}) && requestZero) return 0; if((!whichState || whichState == {}) && requestZero) return 0;
else return whichState; else return whichState;
}, },
//mainly for local copy use, add(M) can fail so we can't shortcut them //mainly for local copy use, add(M) can fail so we can't shortcut them
//since set does not fail, we know state exists and can simply return the object //since set does not fail, we know state exists and can simply return the object
setget: function(stateName, value, noEvent){ setget: function(stateName, value, noEvent){
$SM.set(stateName, value, noEvent); $SM.set(stateName, value, noEvent);
return eval('('+$SM.buildPath(stateName)+')'); return eval('('+$SM.buildPath(stateName)+')');
}, },
remove: function(stateName, noEvent) { remove: function(stateName, noEvent) {
var whichState = $SM.buildPath(stateName); var whichState = $SM.buildPath(stateName);
try{ try{
eval('(delete '+whichState+')'); eval('(delete '+whichState+')');
} catch (e) { } catch (e) {
//it didn't exist in the first place //it didn't exist in the first place
Engine.log('WARNING: Tried to remove non-existant state \''+stateName+'\'.'); Engine.log('WARNING: Tried to remove non-existant state \''+stateName+'\'.');
} }
if(!noEvent){ if(!noEvent){
Engine.saveGame(); Engine.saveGame();
$SM.fireUpdate(stateName); $SM.fireUpdate(stateName);
}; };
}, },
//creates full reference from input //creates full reference from input
//hopefully this won't ever need to be more complicated //hopefully this won't ever need to be more complicated
buildPath: function(input){ buildPath: function(input){
var dot = (input.charAt(0) == '[')? '' : '.'; //if it starts with [foo] no dot to join var dot = (input.charAt(0) == '[')? '' : '.'; //if it starts with [foo] no dot to join
return 'State' + dot + input; return 'State' + dot + input;
}, },
fireUpdate: function(stateName, save){ fireUpdate: function(stateName, save){
var category = $SM.getCategory(stateName); var category = $SM.getCategory(stateName);
if(stateName == undefined) stateName = category = 'all'; //best if this doesn't happen as it will trigger more stuff if(stateName == undefined) stateName = category = 'all'; //best if this doesn't happen as it will trigger more stuff
$.Dispatch('stateUpdate').publish({'category': category, 'stateName':stateName}); $.Dispatch('stateUpdate').publish({'category': category, 'stateName':stateName});
if(save) Engine.saveGame(); if(save) Engine.saveGame();
}, },
getCategory: function(stateName){ getCategory: function(stateName){
var firstOB = stateName.indexOf('['); var firstOB = stateName.indexOf('[');
var firstDot = stateName.indexOf('.'); var firstDot = stateName.indexOf('.');
var cutoff = null; var cutoff = null;
if(firstOB == -1 || firstDot == -1){ if(firstOB == -1 || firstDot == -1){
cutoff = firstOB > firstDot ? firstOB : firstDot; cutoff = firstOB > firstDot ? firstOB : firstDot;
} else { } else {
cutoff = firstOB < firstDot ? firstOB : firstDot; cutoff = firstOB < firstDot ? firstOB : firstDot;
} }
if (cutoff == -1){ if (cutoff == -1){
return stateName; return stateName;
} else { } else {
return stateName.substr(0,cutoff); return stateName.substr(0,cutoff);
} }
}, },
//Use this function to make old save games compatible with new version //Use this function to make old save games compatible with new version
updateOldState: function(){ updateOldState: function(){
var version = $SM.get('version'); var version = $SM.get('version');
if(typeof version != 'number') version = 1.0; if(typeof version != 'number') version = 1.0;
if(version == 1.0) { if(version == 1.0) {
// v1.1 introduced the Lodge, so get rid of lodgeless hunters // v1.1 introduced the Lodge, so get rid of lodgeless hunters
$SM.remove('outside.workers.hunter', true); $SM.remove('outside.workers.hunter', true);
$SM.remove('income.hunter', true); $SM.remove('income.hunter', true);
Engine.log('upgraded save to v1.1'); Engine.log('upgraded save to v1.1');
version = 1.1; version = 1.1;
}; };
if(version == 1.1) { if(version == 1.1) {
//v1.2 added the Swamp to the map, so add it to already generated maps //v1.2 added the Swamp to the map, so add it to already generated maps
if($SM.get('world')) { if($SM.get('world')) {
World.placeLandmark(15, World.RADIUS * 1.5, World.TILE.SWAMP, $SM.get('world.map')); World.placeLandmark(15, World.RADIUS * 1.5, World.TILE.SWAMP, $SM.get('world.map'));
} }
Engine.log('upgraded save to v1.2'); Engine.log('upgraded save to v1.2');
version = 1.2; version = 1.2;
}; };
if(version == 1.2) { if(version == 1.2) {
//StateManager added, so move data to new locations //StateManager added, so move data to new locations
$SM.remove('room.fire'); $SM.remove('room.fire');
$SM.remove('room.temperature'); $SM.remove('room.temperature');
$SM.remove('room.buttons'); $SM.remove('room.buttons');
if($SM.get('room')){ if($SM.get('room')){
$SM.set('features.location.room', true); $SM.set('features.location.room', true);
$SM.set('game.builder.level', $SM.get('room.builder')); $SM.set('game.builder.level', $SM.get('room.builder'));
$SM.remove('room'); $SM.remove('room');
}; };
if($SM.get('outside')){ if($SM.get('outside')){
$SM.set('features.location.outside', true); $SM.set('features.location.outside', true);
$SM.set('game.population', $SM.get('outside.population')); $SM.set('game.population', $SM.get('outside.population'));
$SM.set('game.buildings', $SM.get('outside.buildings')); $SM.set('game.buildings', $SM.get('outside.buildings'));
$SM.set('game.workers', $SM.get('outside.workers')); $SM.set('game.workers', $SM.get('outside.workers'));
$SM.set('game.outside.seenForest', $SM.get('outside.seenForest')); $SM.set('game.outside.seenForest', $SM.get('outside.seenForest'));
$SM.remove('outside'); $SM.remove('outside');
}; };
if($SM.get('world')){ if($SM.get('world')){
$SM.set('features.location.world', true); $SM.set('features.location.world', true);
$SM.set('game.world.map', $SM.get('world.map')); $SM.set('game.world.map', $SM.get('world.map'));
$SM.set('game.world.mask', $SM.get('world.mask')); $SM.set('game.world.mask', $SM.get('world.mask'));
$SM.set('starved', $SM.get('character.starved', true)); $SM.set('starved', $SM.get('character.starved', true));
$SM.set('dehydrated', $SM.get('character.dehydrated', true)); $SM.set('dehydrated', $SM.get('character.dehydrated', true));
$SM.remove('world'); $SM.remove('world');
$SM.remove('starved'); $SM.remove('starved');
$SM.remove('dehydrated'); $SM.remove('dehydrated');
}; };
if($SM.get('ship')){ if($SM.get('ship')){
$SM.set('features.location.spaceShip', true); $SM.set('features.location.spaceShip', true);
$SM.set('game.spaceShip.hull', $SM.get('ship.hull', true)); $SM.set('game.spaceShip.hull', $SM.get('ship.hull', true));
$SM.set('game.spaceShip.thrusters', $SM.get('ship.thrusters', true)); $SM.set('game.spaceShip.thrusters', $SM.get('ship.thrusters', true));
$SM.set('game.spaceShip.seenWarning', $SM.get('ship.seenWarning')); $SM.set('game.spaceShip.seenWarning', $SM.get('ship.seenWarning'));
$SM.set('game.spaceShip.seenShip', $SM.get('ship.seenShip')); $SM.set('game.spaceShip.seenShip', $SM.get('ship.seenShip'));
$SM.remove('ship'); $SM.remove('ship');
}; };
if($SM.get('punches')){ if($SM.get('punches')){
$SM.set('character.punches', $SM.get('punches')); $SM.set('character.punches', $SM.get('punches'));
$SM.remove('punches'); $SM.remove('punches');
}; };
if($SM.get('perks')){ if($SM.get('perks')){
$SM.set('character.perks', $SM.get('perks')); $SM.set('character.perks', $SM.get('perks'));
$SM.remove('perks'); $SM.remove('perks');
}; };
if($SM.get('thieves')){ if($SM.get('thieves')){
$SM.set('game.thieves', $SM.get('thieves')); $SM.set('game.thieves', $SM.get('thieves'));
$SM.remove('thieves'); $SM.remove('thieves');
}; };
if($SM.get('stolen')){ if($SM.get('stolen')){
$SM.set('game.stolen', $SM.get('stolen')); $SM.set('game.stolen', $SM.get('stolen'));
$SM.remove('stolen'); $SM.remove('stolen');
}; };
if($SM.get('cityCleared')){ if($SM.get('cityCleared')){
$SM.set('character.cityCleared', $SM.get('cityCleared')); $SM.set('character.cityCleared', $SM.get('cityCleared'));
$SM.remove('cityCleared'); $SM.remove('cityCleared');
}; };
$SM.set('version', 1.3); $SM.set('version', 1.3);
}; };
}, },
/****************************************************************** /******************************************************************
* Start of specific state functions * Start of specific state functions
******************************************************************/ ******************************************************************/
//PERKS //PERKS
addPerk: function(name) { addPerk: function(name) {
$SM.set('character.perks["'+name+'"]', true); $SM.set('character.perks["'+name+'"]', true);
Notifications.notify(null, Engine.Perks[name].notify); Notifications.notify(null, Engine.Perks[name].notify);
}, },
hasPerk: function(name) { hasPerk: function(name) {
return $SM.get('character.perks["'+name+'"]'); return $SM.get('character.perks["'+name+'"]');
}, },
//INCOME //INCOME
setIncome: function(source, options) { setIncome: function(source, options) {
var existing = $SM.get('income["'+source+'"]'); var existing = $SM.get('income["'+source+'"]');
if(typeof existing != 'undefined') { if(typeof existing != 'undefined') {
options.timeLeft = existing.timeLeft; options.timeLeft = existing.timeLeft;
} }
$SM.set('income["'+source+'"]', options); $SM.set('income["'+source+'"]', options);
}, },
getIncome: function(source) { getIncome: function(source) {
var existing = $SM.get('income["'+source+'"]'); var existing = $SM.get('income["'+source+'"]');
if(typeof existing != 'undefined') { if(typeof existing != 'undefined') {
return existing; return existing;
} }
return {}; return {};
}, },
collectIncome: function() { collectIncome: function() {
var changed = false; var changed = false;
if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) { if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) {
for(var source in $SM.get('income')) { for(var source in $SM.get('income')) {
var income = $SM.get('income["'+source+'"]'); var income = $SM.get('income["'+source+'"]');
if(typeof income.timeLeft != 'number') if(typeof income.timeLeft != 'number')
{ {
income.timeLeft = 0; income.timeLeft = 0;
} }
income.timeLeft--; income.timeLeft--;
if(income.timeLeft <= 0) { if(income.timeLeft <= 0) {
Engine.log('collection income from ' + source); Engine.log('collection income from ' + source);
if(source == 'thieves') $SM.addStolen(income.stores); if(source == 'thieves') $SM.addStolen(income.stores);
var cost = income.stores; var cost = income.stores;
var ok = true; var ok = true;
if (source != 'thieves') { if (source != 'thieves') {
for (var k in cost) { for (var k in cost) {
var have = $SM.get('stores["' + k + '"]', true); var have = $SM.get('stores["' + k + '"]', true);
if (have + cost[k] < 0) { if (have + cost[k] < 0) {
ok = false; ok = false;
break; break;
} }
} }
} }
if(ok){ if(ok){
$SM.addM('stores', income.stores, true); $SM.addM('stores', income.stores, true);
} }
changed = true; changed = true;
if(typeof income.delay == 'number') { if(typeof income.delay == 'number') {
income.timeLeft = income.delay; income.timeLeft = income.delay;
} }
} }
} }
} }
if(changed){ if(changed){
$SM.fireUpdate('income', true); $SM.fireUpdate('income', true);
}; };
Engine._incomeTimeout = setTimeout($SM.collectIncome, 1000); Engine._incomeTimeout = setTimeout($SM.collectIncome, 1000);
}, },
//Thieves //Thieves
addStolen: function(stores) { addStolen: function(stores) {
for(var k in stores) { for(var k in stores) {
var old = $SM.get('stores["'+k+'"]', true); var old = $SM.get('stores["'+k+'"]', true);
var short = old + stores[k]; var short = old + stores[k];
//if they would steal more than actually owned //if they would steal more than actually owned
if(short < 0){ if(short < 0){
$SM.add('game.stolen["'+k+'"]', (stores[k] * -1) + short); $SM.add('game.stolen["'+k+'"]', (stores[k] * -1) + short);
} else { } else {
$SM.add('game.stolen["'+k+'"]', stores[k] * -1); $SM.add('game.stolen["'+k+'"]', stores[k] * -1);
} }
}; };
}, },
startThieves: function() { startThieves: function() {
$SM.set('game.thieves', 1); $SM.set('game.thieves', 1);
$SM.setIncome('thieves', { $SM.setIncome('thieves', {
delay: 10, delay: 10,
stores: { stores: {
'wood': -10, 'wood': -10,
'fur': -5, 'fur': -5,
'meat': -5 'meat': -5
} }
}); });
}, },
//Misc //Misc
num: function(name, craftable) { num: function(name, craftable) {
switch(craftable.type) { switch(craftable.type) {
case 'good': case 'good':
case 'tool': case 'tool':
case 'weapon': case 'weapon':
case 'upgrade': case 'upgrade':
return $SM.get('stores["'+name+'"]', true); return $SM.get('stores["'+name+'"]', true);
case 'building': case 'building':
return $SM.get('game.buildings["'+name+'"]', true); return $SM.get('game.buildings["'+name+'"]', true);
} }
}, },
handleStateUpdates: function(e){ handleStateUpdates: function(e){
} }
}; };
//alias //alias
var $SM = StateManager; var $SM = StateManager;