Merge pull request #592 from doublespeakgames/master

merge pull
This commit is contained in:
Michael Townsend
2017-10-02 14:50:45 -04:00
committed by GitHub
91 changed files with 62348 additions and 23554 deletions
+61 -20
View File
@@ -7,12 +7,12 @@ var Button = {
if(typeof options.click == 'function') {
this.data_handler = options.click;
}
var el = $('<div>')
.attr('id', typeof(options.id) != 'undefined' ? options.id : "BTN_" + Engine.getGuid())
.addClass('button')
.text(typeof(options.text) != 'undefined' ? options.text : "button")
.click(function() {
.click(function() {
if(!$(this).hasClass('disabled')) {
Button.cooldown($(this));
$(this).data("handler")($(this));
@@ -21,9 +21,12 @@ var Button = {
.data("handler", typeof options.click == 'function' ? options.click : function() { Engine.log("click"); })
.data("remaining", 0)
.data("cooldown", typeof options.cooldown == 'number' ? options.cooldown : 0);
el.append($("<div>").addClass('cooldown'));
// waiting for expiry of residual cooldown detected in state
Button.cooldown(el, 'state');
if(options.cost) {
var ttPos = options.ttPos ? options.ttPos : "bottom right";
var costTooltip = $('<div>').addClass('tooltip ' + ttPos);
@@ -35,14 +38,16 @@ var Button = {
costTooltip.appendTo(el);
}
}
if(options.width) {
el.css('width', options.width);
}
return el;
},
saveCooldown: true,
setDisabled: function(btn, disabled) {
if(btn) {
if(!disabled && !btn.data('onCooldown')) {
@@ -53,34 +58,70 @@ var Button = {
btn.data('disabled', disabled);
}
},
isDisabled: function(btn) {
if(btn) {
return btn.data('disabled') === true;
}
return false;
},
cooldown: function(btn) {
cooldown: function(btn, option) {
var cd = btn.data("cooldown");
var id = 'cooldown.'+ btn.attr('id');
if(cd > 0) {
$('div.cooldown', btn).stop(true, true).width("100%").animate({width: '0%'}, cd * 1000, 'linear', function() {
var b = $(this).closest('.button');
b.data('onCooldown', false);
if(!b.data('disabled')) {
b.removeClass('disabled');
}
if(typeof option == 'number') {
cd = option;
}
// param "start" takes value from cooldown time if not specified
var start, left;
switch(option){
// a switch will allow for several uses of cooldown function
case 'state':
if(!$SM.get(id)){
return;
}
start = Math.min($SM.get(id), cd);
left = (start / cd).toFixed(4);
break;
default:
start = cd;
left = 1;
}
Button.clearCooldown(btn);
if(Button.saveCooldown){
$SM.set(id,start);
// residual value is measured in seconds
// saves program performance
btn.data('countdown', Engine.setInterval(function(){
$SM.set(id, $SM.get(id, true) - 0.5, true);
},500));
}
var time = start;
if (Engine.options.doubleTime){
time /= 2;
}
$('div.cooldown', btn).width(left * 100 +"%").animate({width: '0%'}, time * 1000, 'linear', function() {
Button.clearCooldown(btn, true);
});
btn.addClass('disabled');
btn.data('onCooldown', true);
}
},
clearCooldown: function(btn) {
$('div.cooldown', btn).stop(true, true);
clearCooldown: function(btn, cooldownEnded) {
var ended = cooldownEnded || false;
if(!ended){
$('div.cooldown', btn).stop(true, true);
}
btn.data('onCooldown', false);
if(btn.data('countdown')){
window.clearInterval(btn.data('countdown'));
$SM.remove('cooldown.'+ btn.attr('id'));
btn.removeData('countdown');
}
if(!btn.data('disabled')) {
btn.removeClass('disabled');
}
}
};
};
+2 -2
View File
@@ -121,7 +121,7 @@
onChoose: function () {
DropboxConnector.log('Save to slot ' + n + ' initiated');
// timeout prevents error due to fade out animation of the previous event
window.setTimeout(function () {
Engine.setTimeout(function () {
DropboxConnector.log('Save to slot ' + n);
DropboxConnector.saveGameToDropbox(n, DropboxConnector.savedtoDropboxEvent);
}, 1000);
@@ -150,7 +150,7 @@
onChoose: function () {
DropboxConnector.log('Load from slot ' + n + ' initiated');
// timeout prevents error due to fade out animation of the previous event
window.setTimeout(function () {
Engine.setTimeout(function () {
DropboxConnector.log('Load from slot ' + n);
DropboxConnector.loadGameFromDropbox(n);
}, 1000);
+203 -118
View File
@@ -1,15 +1,15 @@
(function() {
var Engine = window.Engine = {
SITE_URL: encodeURIComponent("http://adarkroom.doublespeakgames.com"),
VERSION: 1.3,
MAX_STORE: 99999999999999,
SAVE_DISPLAY: 30 * 1000,
GAME_OVER: false,
//object event types
topics: {},
Perks: {
'boxer': {
name: _('boxer'),
@@ -69,7 +69,7 @@
notify: _('learned to make the most of food')
}
},
options: {
state: null,
debug: false,
@@ -77,7 +77,7 @@
dropbox: false,
doubleTime: false
},
init: function(options) {
this.options = $.extend(
this.options,
@@ -85,31 +85,31 @@
);
this._debug = this.options.debug;
this._log = this.options.log;
// Check for HTML5 support
if(!Engine.browserValid()) {
window.location = 'browserWarning.html';
}
// Check for mobile
if(Engine.isMobile()) {
window.location = 'mobileWarning.html';
}
Engine.disableSelection();
if(this.options.state != null) {
window.State = this.options.state;
} else {
Engine.loadGame();
}
$('<div>').attr('id', 'locationSlider').appendTo('#main');
var menu = $('<div>')
.addClass('menu')
.appendTo('body');
if(typeof langs != 'undefined'){
var customSelect = $('<span>')
.addClass('customSelect')
@@ -123,7 +123,7 @@
$('<li>')
.text("language.")
.appendTo(optionsList);
$.each(langs, function(name,display){
$('<li>')
.text(display)
@@ -133,6 +133,12 @@
});
}
$('<span>')
.addClass('appStore menuBtn')
.text(_('get the app.'))
.click(Engine.getApp)
.appendTo(menu);
$('<span>')
.addClass('lightsOff menuBtn')
.text(_('lights off.'))
@@ -140,15 +146,9 @@
.appendTo(menu);
$('<span>')
.addClass('menuBtn')
.addClass('hyper menuBtn')
.text(_('hyper.'))
.click(function(){
Engine.options.doubleTime = !Engine.options.doubleTime;
if(Engine.options.doubleTime)
$(this).text(_('classic.'));
else
$(this).text(_('hyper.'));
})
.click(Engine.confirmHyperMode)
.appendTo(menu);
$('<span>')
@@ -156,7 +156,7 @@
.text(_('restart.'))
.click(Engine.confirmDelete)
.appendTo(menu);
$('<span>')
.addClass('menuBtn')
.text(_('share.'))
@@ -178,19 +178,13 @@
.click(Engine.Dropbox.startDropbox)
.appendTo(menu);
}
$('<span>')
.addClass('menuBtn')
.text(_('app store.'))
.click(function() { window.open('https://itunes.apple.com/us/app/a-dark-room/id736683061'); })
.appendTo(menu);
$('<span>')
.addClass('menuBtn')
.text(_('github.'))
.click(function() { window.open('https://github.com/Continuities/adarkroom'); })
.click(function() { window.open('https://github.com/doublespeakgames/adarkroom'); })
.appendTo(menu);
// Register keypress handlers
$('body').off('keydown').keydown(Engine.keyDown);
$('body').off('keyup').keyup(Engine.keyUp);
@@ -201,7 +195,7 @@
swipeElement.on('swiperight', Engine.swipeRight);
swipeElement.on('swipeup', Engine.swipeUp);
swipeElement.on('swipedown', Engine.swipeDown);
// subscribe to stateUpdates
$.Dispatch('stateUpdate').subscribe(Engine.handleStateUpdates);
@@ -209,7 +203,7 @@
Notifications.init();
Events.init();
Room.init();
if(typeof $SM.get('stores.wood') != 'undefined') {
Outside.init();
}
@@ -219,20 +213,28 @@
if($SM.get('features.location.spaceShip')) {
Ship.init();
}
if($SM.get('config.lightsOff', true)){
Engine.turnLightsOff();
}
if($SM.get('config.hyperMode', true)){
Engine.triggerHyperMode();
}
Engine.saveLanguage();
Engine.travelTo(Room);
},
browserValid: function() {
return ( location.search.indexOf( 'ignorebrowser=true' ) >= 0 || ( typeof Storage != 'undefined' && !oldIE ) );
},
isMobile: function() {
return ( location.search.indexOf( 'ignorebrowser=true' ) < 0 && /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test( navigator.userAgent ) );
},
saveGame: function() {
if(typeof Storage != 'undefined' && localStorage) {
if(Engine._saveTimer != null) {
@@ -245,7 +247,7 @@
localStorage.gameState = JSON.stringify(State);
}
},
loadGame: function() {
try {
var savedState = JSON.parse(localStorage.gameState);
@@ -260,7 +262,7 @@
Engine.event('progress', 'new game');
}
},
exportImport: function() {
Events.startEvent({
title: _('Export / Import'),
@@ -273,7 +275,7 @@
buttons: {
'export': {
text: _('export'),
onChoose: Engine.export64
nextScene: {1: 'inputExport'}
},
'import': {
text: _('import'),
@@ -285,6 +287,19 @@
}
}
},
'inputExport': {
text: [_('save this.')],
textarea: Engine.export64(),
onLoad: function() { Engine.event('progress', 'export'); },
readonly: true,
buttons: {
'done': {
text: _('got it'),
nextScene: 'end',
onChoose: Engine.disableSelection
}
}
},
'confirm': {
text: [
_('are you sure?'),
@@ -299,7 +314,7 @@
},
'no': {
text: _('no'),
nextScene: 'end'
nextScene: {1: 'start'}
}
}
},
@@ -333,29 +348,12 @@
export64: function() {
Engine.saveGame();
var string64 = Engine.generateExport64();
Engine.enableSelection();
Events.startEvent({
title: _('Export'),
scenes: {
start: {
text: [_('save this.')],
textarea: string64,
readonly: true,
buttons: {
'done': {
text: _('got it'),
nextScene: 'end',
onChoose: Engine.disableSelection
}
}
}
}
});
Engine.autoSelect('#description textarea');
return Engine.generateExport64();
},
import64: function(string64) {
Engine.event('progress', 'import');
Engine.disableSelection();
string64 = string64.replace(/\s/g, '');
string64 = string64.replace(/\./g, '');
@@ -370,7 +368,7 @@
ga('send', 'event', cat, act);
}
},
confirmDelete: function() {
Events.startEvent({
title: _('Restart?'),
@@ -392,7 +390,7 @@
}
});
},
deleteSave: function(noReload) {
if(typeof Storage != 'undefined' && localStorage) {
var prestige = Prestige.get();
@@ -404,7 +402,38 @@
location.reload();
}
},
getApp: function() {
Events.startEvent({
title: _('Get the App'),
scenes: {
start: {
text: [_('bring the room with you.')],
buttons: {
'ios': {
text: _('ios'),
nextScene: 'end',
onChoose: function () {
window.open('https://itunes.apple.com/app/apple-store/id736683061?pt=2073437&ct=adrproper&mt=8');
}
},
'android': {
text: _('android'),
nextScene: 'end',
onChoose: function() {
window.open('https://play.google.com/store/apps/details?id=com.yourcompany.adarkroom');
}
},
'close': {
text: _('close'),
nextScene: 'end'
}
}
}
}
});
},
share: function() {
Events.startEvent({
title: _('Share'),
@@ -470,22 +499,61 @@
}
return false;
},
turnLightsOff: function() {
var darkCss = Engine.findStylesheet('darkenLights');
if (darkCss == null) {
$('head').append('<link rel="stylesheet" href="css/dark.css" type="text/css" title="darkenLights" />');
$('.lightsOff').text(_('lights on.'));
$SM.set('config.lightsOff', true, true);
} else if (darkCss.disabled) {
darkCss.disabled = false;
$('.lightsOff').text(_('lights on.'));
$SM.set('config.lightsOff', true,true);
} else {
$("#darkenLights").attr("disabled", "disabled");
darkCss.disabled = true;
$('.lightsOff').text(_('lights off.'));
$SM.set('config.lightsOff', false, true);
}
},
confirmHyperMode: function(){
if (!Engine.options.doubleTime) {
Events.startEvent({
title: _('Go Hyper?'),
scenes: {
start: {
text: [_('turning hyper mode speeds up the game to x2 speed. do you want to do that?')],
buttons: {
'yes': {
text: _('yes'),
nextScene: 'end',
onChoose: Engine.triggerHyperMode
},
'no': {
text: _('no'),
nextScene: 'end'
}
}
}
}
});
} else {
Engine.triggerHyperMode();
}
},
triggerHyperMode: function() {
Engine.options.doubleTime = !Engine.options.doubleTime;
if(Engine.options.doubleTime)
$('.hyper').text(_('classic.'));
else
$('.hyper').text(_('hyper.'));
$SM.set('config.hyperMode', Engine.options.doubleTime, false);
},
// Gets a guid
getGuid: function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
@@ -493,9 +561,9 @@
return v.toString(16);
});
},
activeModule: null,
travelTo: function(module) {
if(Engine.activeModule != module) {
var currentIndex = Engine.activeModule ? $('.location').index(Engine.activeModule.panel) : 1;
@@ -512,10 +580,6 @@
// FIXME Why does this work if there's an animation queue...?
stores.animate({right: -(panelIndex * 700) + 'px'}, 300 * diff);
}
Engine.activeModule = module;
module.onArrival(diff);
if(Engine.activeModule == Room || Engine.activeModule == Path) {
// Don't fade out the weapons if we're switching to a module
@@ -529,8 +593,10 @@
$('div#weapons').animate({opacity: 1}, 300);
}
Engine.activeModule = module;
module.onArrival(diff);
Notifications.printQueue(module);
}
},
@@ -557,33 +623,37 @@
top: top_container.height() + 26 + 'px'
},
{
queue: false,
queue: false,
duration: 300 * transition_diff
});
}
},
log: function(msg) {
if(this._log) {
console.log(msg);
}
},
updateSlider: function() {
var slider = $('#locationSlider');
slider.width((slider.children().length * 700) + 'px');
},
updateOuterSlider: function() {
var slider = $('#outerSlider');
slider.width((slider.children().length * 700) + 'px');
},
getIncomeMsg: function(num, delay) {
return _("{0} per {1}s", (num > 0 ? "+" : "") + num, delay);
//return (num > 0 ? "+" : "") + num + " per " + delay + "s";
},
keyLock: false,
tabNavigation: true,
restoreNavigation: false,
keyDown: function(e) {
e = e || window.event;
if(!Engine.keyPressed && !Engine.keyLock) {
@@ -594,14 +664,12 @@
}
return jQuery.inArray(e.keycode, [37,38,39,40]) < 0;
},
keyUp: function(e) {
Engine.pressed = false;
if(Engine.activeModule.keyUp) {
Engine.activeModule.keyUp(e);
}
else
{
} else {
switch(e.which) {
case 38: // Up
case 87:
@@ -619,33 +687,40 @@
break;
case 37: // Left
case 65:
if(Engine.activeModule == Ship && Path.tab)
Engine.travelTo(Path);
else if(Engine.activeModule == Path && Outside.tab){
Engine.activeModule.scrollSidebar('left', true);
Engine.travelTo(Outside);
}else if(Engine.activeModule == Outside && Room.tab){
Engine.activeModule.scrollSidebar('left', true);
Engine.travelTo(Room);
if(Engine.tabNavigation){
if(Engine.activeModule == Ship && Path.tab)
Engine.travelTo(Path);
else if(Engine.activeModule == Path && Outside.tab){
Engine.activeModule.scrollSidebar('left', true);
Engine.travelTo(Outside);
}else if(Engine.activeModule == Outside && Room.tab){
Engine.activeModule.scrollSidebar('left', true);
Engine.travelTo(Room);
}
}
Engine.log('left');
break;
case 39: // Right
case 68:
if(Engine.activeModule == Room && Outside.tab)
Engine.travelTo(Outside);
else if(Engine.activeModule == Outside && Path.tab){
Engine.activeModule.scrollSidebar('right', true);
Engine.travelTo(Path);
}else if(Engine.activeModule == Path && Ship.tab){
Engine.activeModule.scrollSidebar('right', true);
Engine.travelTo(Ship);
if(Engine.tabNavigation){
if(Engine.activeModule == Room && Outside.tab)
Engine.travelTo(Outside);
else if(Engine.activeModule == Outside && Path.tab){
Engine.activeModule.scrollSidebar('right', true);
Engine.travelTo(Path);
}else if(Engine.activeModule == Path && Ship.tab){
Engine.activeModule.scrollSidebar('right', true);
Engine.travelTo(Ship);
}
}
Engine.log('right');
break;
}
}
if(Engine.restoreNavigation){
Engine.tabNavigation = true;
Engine.restoreNavigation = false;
}
return false;
},
@@ -682,15 +757,15 @@
document.onselectstart = eventPassthrough;
document.onmousedown = eventPassthrough;
},
autoSelect: function(selector) {
$(selector).focus().select();
},
handleStateUpdates: function(e){
},
switchLanguage: function(dom){
var lang = $(dom).data("language");
if(document.location.href.search(/[\?\&]lang=[a-z_]+/) != -1){
@@ -699,14 +774,24 @@
document.location.href = document.location.href + ( (document.location.href.search(/\?/) != -1 )?"&":"?") + "lang="+lang;
}
},
saveLanguage: function(){
var lang = decodeURIComponent((new RegExp('[?|&]lang=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
var lang = decodeURIComponent((new RegExp('[?|&]lang=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
if(lang && typeof Storage != 'undefined' && localStorage) {
localStorage.lang = lang;
}
},
setInterval: function(callback, interval, skipDouble){
if( Engine.options.doubleTime && !skipDouble ){
Engine.log('Double time, cutting interval in half');
interval /= 2;
}
return setInterval(callback, interval);
},
setTimeout: function(callback, timeout, skipDouble){
if( Engine.options.doubleTime && !skipDouble ){
@@ -732,32 +817,32 @@
function inView(dir, elem){
var scTop = $('#main').offset().top;
var scBot = scTop + $('#main').height();
var scTop = $('#main').offset().top;
var scBot = scTop + $('#main').height();
var elTop = elem.offset().top;
var elBot = elTop + elem.height();
var elTop = elem.offset().top;
var elBot = elTop + elem.height();
if( dir == 'up' ){
// STOP MOVING IF BOTTOM OF ELEMENT IS VISIBLE IN SCREEN
return ( elBot < scBot );
}else if( dir == 'down' ){
return ( elTop > scTop );
}else{
return ( ( elBot <= scBot ) && ( elTop >= scTop ) );
}
if( dir == 'up' ){
// STOP MOVING IF BOTTOM OF ELEMENT IS VISIBLE IN SCREEN
return ( elBot < scBot );
}else if( dir == 'down' ){
return ( elTop > scTop );
}else{
return ( ( elBot <= scBot ) && ( elTop >= scTop ) );
}
}
function scrollByX(elem, x){
var elTop = parseInt( elem.css('top'), 10 );
elem.css( 'top', ( elTop + x ) + "px" );
var elTop = parseInt( elem.css('top'), 10 );
elem.css( 'top', ( elTop + x ) + "px" );
}
//create jQuery Callbacks() to handle object events
//create jQuery Callbacks() to handle object events
$.Dispatch = function( id ) {
var callbacks, topic = id && Engine.topics[ id ];
if ( !topic ) {
+549 -251
View File
File diff suppressed because it is too large Load Diff
+23 -23
View File
@@ -14,7 +14,7 @@ Events.Encounters = [
enemy: 'snarling beast',
enemyName: _('snarling beast'),
deathMessage: _('the snarling beast is dead'),
chara: 'B',
chara: 'R',
damage: 1,
hit: 0.8,
attackDelay: 1,
@@ -51,7 +51,7 @@ Events.Encounters = [
enemy: 'gaunt man',
enemyName: _('gaunt man'),
deathMessage: _('the gaunt man is dead'),
chara: 'G',
chara: 'E',
damage: 2,
hit: 0.8,
attackDelay: 2,
@@ -88,7 +88,7 @@ Events.Encounters = [
enemy: 'strange bird',
enemyName: _('strange bird'),
deathMessage: _('the strange bird is dead'),
chara: 'B',
chara: 'R',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -123,10 +123,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'shivering man',
enemyName: _('shivering man'),
enemy: 'shivering man',
enemyName: _('shivering man'),
deathMessage: _('the shivering man is dead'),
chara: 'S',
chara: 'E',
damage: 5,
hit: 0.5,
attackDelay: 1,
@@ -165,10 +165,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'man-eater',
enemyName: _('man-eater'),
enemy: 'man-eater',
enemyName: _('man-eater'),
deathMessage: _('the man-eater is dead'),
chara: 'E',
chara: 'T',
damage: 3,
hit: 0.8,
attackDelay: 1,
@@ -202,10 +202,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'scavenger',
enemyName: _('scavenger'),
enemy: 'scavenger',
enemyName: _('scavenger'),
deathMessage: _('the scavenger is dead'),
chara: 'S',
chara: 'E',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -244,10 +244,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'lizard',
enemyName: _('lizard'),
enemy: 'lizard',
enemyName: _('lizard'),
deathMessage: _('the lizard is dead'),
chara: 'L',
chara: 'T',
damage: 5,
hit: 0.8,
attackDelay: 2,
@@ -282,10 +282,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'feral terror',
enemyName: _('feral terror'),
enemy: 'feral terror',
enemyName: _('feral terror'),
deathMessage: _('the feral terror is dead'),
chara: 'F',
chara: 'T',
damage: 6,
hit: 0.8,
attackDelay: 1,
@@ -319,8 +319,8 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'soldier',
enemyName: _('soldier'),
enemy: 'soldier',
enemyName: _('soldier'),
deathMessage: _('the soldier is dead'),
ranged: true,
chara: 'D',
@@ -362,10 +362,10 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'sniper',
enemyName: _('sniper'),
enemy: 'sniper',
enemyName: _('sniper'),
deathMessage: _('the sniper is dead'),
chara: 'S',
chara: 'D',
damage: 15,
hit: 0.8,
attackDelay: 4,
+19 -10
View File
@@ -37,6 +37,7 @@ Events.Outside = [
_('the tracks disappear after just a few minutes.'),
_('the forest is silent.')
],
notification: _('nothing was found'),
buttons: {
'end': {
text: _('go home'),
@@ -49,6 +50,7 @@ Events.Outside = [
_('not far from the village lies a large beast, its fur matted with blood.'),
_('it puts up little resistance before the knife.')
],
notification: _('there was a beast. it\'s dead now'),
reward: {
fur: 100,
meat: 100,
@@ -63,10 +65,10 @@ Events.Outside = [
}
}
},
{
{ /* Hut fire */
title: _('Fire'),
isAvailable: function() {
return Engine.activeModule == Outside && $SM.get('game.buildings["hut"]', true) > 0 && $SM.get('game.population', true) > 5;
return Engine.activeModule == Outside && $SM.get('game.buildings["hut"]', true) > 0 && $SM.get('game.population', true) > 50;
},
scenes: {
'start': {
@@ -77,10 +79,7 @@ Events.Outside = [
notification: _('a fire has started'),
blink: true,
onLoad: function() {
var population = $SM.get('game.population', true);
var huts = $SM.get('game.buildings["hut"]', true);
$SM.set('game.buildings["hut"]', (huts - 1));
Outside.killVillagers(4);
Outside.destroyHuts(1);
},
buttons: {
'mourn': {
@@ -103,7 +102,7 @@ Events.Outside = [
_('a sickness is spreading through the village.'),
_('medicine is needed immediately.')
],
notification: _('some villagers are ill'),
blink: true,
buttons: {
'heal': {
@@ -121,6 +120,7 @@ Events.Outside = [
text: [
_('the sickness is cured in time.')
],
notification: _('sufferers are healed'),
buttons: {
'end': {
text: _('go home'),
@@ -134,8 +134,9 @@ Events.Outside = [
_('the days are spent with burials.'),
_('the nights are rent with screams.')
],
notification: _('sufferers are left to die'),
onLoad: function() {
var numKilled = Math.floor(Math.random() * 20) + 1;
var numKilled = Math.floor(Math.random() * Math.floor($SM.get('game.population', true)/2)) + 1;
Outside.killVillagers(numKilled);
},
buttons: {
@@ -147,7 +148,7 @@ Events.Outside = [
}
}
},
{ /* Plague */
title: _('Plague'),
isAvailable: function() {
@@ -159,6 +160,7 @@ Events.Outside = [
_('a terrible plague is fast spreading through the village.'),
_('medicine is needed immediately.')
],
notification: _('a plague afflicts the village'),
blink: true,
buttons: {
/* Because there is a serious need for medicine, the price is raised. */
@@ -185,6 +187,7 @@ Events.Outside = [
_('only a few die.'),
_('the rest bury them.')
],
notification: _('epidemic is eradicated eventually'),
onLoad: function() {
var numKilled = Math.floor(Math.random() * 5) + 2;
Outside.killVillagers(numKilled);
@@ -202,6 +205,7 @@ Events.Outside = [
_('the nights are rent with screams.'),
_('the only hope is a quick death.')
],
notification: _('population is almost exterminated'),
onLoad: function() {
var numKilled = Math.floor(Math.random() * 80) + 10;
Outside.killVillagers(numKilled);
@@ -228,6 +232,7 @@ Events.Outside = [
_('the fight is short and bloody, but the beasts are repelled.'),
_('the villagers retreat to mourn the dead.')
],
notification: _('wild beasts attack the villagers'),
onLoad: function() {
var numKilled = Math.floor(Math.random() * 10) + 1;
Outside.killVillagers(numKilled);
@@ -241,6 +246,7 @@ Events.Outside = [
buttons: {
'end': {
text: _('go home'),
notification: _('predators become prey. price is unfair'),
nextScene: 'end'
}
}
@@ -260,6 +266,7 @@ Events.Outside = [
_('well armed men charge out of the forest, firing into the crowd.'),
_('after a skirmish they are driven away, but not without losses.')
],
notification: _('troops storm the village'),
onLoad: function() {
var numKilled = Math.floor(Math.random() * 40) + 1;
Outside.killVillagers(numKilled);
@@ -268,15 +275,17 @@ Events.Outside = [
bullets: 10,
'cured meat': 50
},
blink: true,
buttons: {
'end': {
text: _('go home'),
notification: _('warfare is bloodthirsty'),
nextScene: 'end'
}
}
}
}
}
];
+111 -37
View File
@@ -39,9 +39,8 @@ Events.Room = [
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: Path.openPath
},
notification: _('the old compass is dented and dusty, but it looks to work.')
},
'goodbye': {
text: _('say goodbye'),
nextScene: 'end'
@@ -49,7 +48,7 @@ Events.Room = [
}
}
}
},
},
{ /* Noises Outside -- gain wood/fur */
title: _('Noises'),
isAvailable: function() {
@@ -258,7 +257,63 @@ Events.Room = [
}
}
},
{/* The Shady Builder */
title: _('The Shady Builder'),
isAvailable: function() {
return Engine.activeModule == Room && $SM.get('game.buildings["hut"]', true) >= 5 && $SM.get('game.buildings["hut"]', true) < 20;
},
scenes: {
'start':{
text: [
_('a shady builder passes through'),
_('says he can build you a hut for less wood')
],
notification: _('a shady builder passes through'),
buttons: {
'build': {
text: _('300 wood'),
cost: { 'wood' : 300 },
nextScene: {0.6: 'steal', 1: 'build'}
},
'deny': {
text: _('say goodbye'),
nextScene: 'end'
}
}
},
'steal': {
text:[
_("the shady builder has made off with your wood")
],
notification: _('the shady builder has made off with your wood'),
buttons: {
'end': {
text: _('go home'),
nextScene: 'end'
}
}
},
'build': {
text:[
_("the shady builder builds a hut")
],
notification: _('the shady builder builds a hut'),
onLoad: function() {
var n = $SM.get('game.buildings["hut"]', true);
if(n < 20){
$SM.set('game.buildings["hut"]',n+1);
}
},
buttons: {
'end': {
text: _('go home'),
nextScene: 'end'
}
}
}
}
},
{ /* Mysterious Wanderer -- wood gambling */
title: _('The Mysterious Wanderer'),
isAvailable: function() {
@@ -273,15 +328,15 @@ Events.Room = [
notification: _('a mysterious wanderer arrives'),
blink: true,
buttons: {
'100wood': {
'wood100': {
text: _('give 100'),
cost: {wood: 100},
nextScene: { 1: '100wood'}
nextScene: { 1: 'wood100'}
},
'500wood': {
'wood500': {
text: _('give 500'),
cost: {wood: 500},
nextScene: { 1: '500wood' }
nextScene: { 1: 'wood500' }
},
'deny': {
text: _('turn him away'),
@@ -289,16 +344,20 @@ Events.Room = [
}
}
},
'100wood': {
'wood100': {
text: [
_('the wanderer leaves, cart loaded with wood')
],
action: function(inputDelay) {
var delay = inputDelay || false;
Events.saveDelay(function() {
$SM.add('stores.wood', 300);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with wood.'));
}, 'Room[4].scenes.wood100.action', delay);
},
onLoad: function() {
if(Math.random() < 0.5) {
Engine.setTimeout(function() {
$SM.add('stores.wood', 300);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with wood.'));
}, 60 * 1000);
this.action(60);
}
},
buttons: {
@@ -308,16 +367,20 @@ Events.Room = [
}
}
},
'500wood': {
'wood500': {
text: [
_('the wanderer leaves, cart loaded with wood')
],
action: function(inputDelay) {
var delay = inputDelay || false;
Events.saveDelay(function() {
$SM.add('stores.wood', 1500);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with wood.'));
}, 'Room[4].scenes.wood500.action', delay);
},
onLoad: function() {
if(Math.random() < 0.3) {
Engine.setTimeout(function() {
$SM.add('stores.wood', 1500);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with wood.'));
}, 60 * 1000);
this.action(60);
}
},
buttons: {
@@ -329,7 +392,7 @@ Events.Room = [
}
}
},
{ /* Mysterious Wanderer -- fur gambling */
title: _('The Mysterious Wanderer'),
isAvailable: function() {
@@ -344,15 +407,15 @@ Events.Room = [
notification: _('a mysterious wanderer arrives'),
blink: true,
buttons: {
'100fur': {
'fur100': {
text: _('give 100'),
cost: {fur: 100},
nextScene: { 1: '100fur'}
nextScene: { 1: 'fur100'}
},
'500fur': {
'fur500': {
text: _('give 500'),
cost: {fur: 500},
nextScene: { 1: '500fur' }
nextScene: { 1: 'fur500' }
},
'deny': {
text: _('turn her away'),
@@ -360,16 +423,20 @@ Events.Room = [
}
}
},
'100fur': {
'fur100': {
text: [
_('the wanderer leaves, cart loaded with furs')
],
action: function(inputDelay) {
var delay = inputDelay || false;
Events.saveDelay(function() {
$SM.add('stores.fur', 300);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with furs.'));
}, 'Room[5].scenes.fur100.action', delay);
},
onLoad: function() {
if(Math.random() < 0.5) {
Engine.setTimeout(function() {
$SM.add('stores.fur', 300);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with furs.'));
}, 60 * 1000);
this.action(60);
}
},
buttons: {
@@ -379,16 +446,20 @@ Events.Room = [
}
}
},
'500fur': {
'fur500': {
text: [
_('the wanderer leaves, cart loaded with furs')
],
action: function(inputDelay) {
var delay = inputDelay || false;
Events.saveDelay(function() {
$SM.add('stores.fur', 1500);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with furs.'));
}, 'Room[5].scenes.fur500.action', delay);
},
onLoad: function() {
if(Math.random() < 0.3) {
Engine.setTimeout(function() {
$SM.add('stores.fur', 1500);
Notifications.notify(Room, _('the mysterious wanderer returns, cart piled high with furs.'));
}, 60 * 1000);
this.action(60);
}
},
buttons: {
@@ -400,7 +471,7 @@ Events.Room = [
}
}
},
{ /* The Scout -- Map Merchant */
title: _('The Scout'),
isAvailable: function() {
@@ -418,6 +489,9 @@ Events.Room = [
'buyMap': {
text: _('buy map'),
cost: { 'fur': 200, 'scales': 10 },
available: function() {
return !World.seenAll;
},
notification: _('the map uncovers a bit of the world'),
onChoose: World.applyMap
},
@@ -439,7 +513,7 @@ Events.Room = [
}
}
},
{ /* The Wandering Master */
title: _('The Master'),
isAvailable: function() {
@@ -512,7 +586,7 @@ Events.Room = [
}
}
},
{ /* The Sick Man */
title: _('The Sick Man'),
isAvailable: function() {
+49 -49
View File
@@ -112,7 +112,7 @@ Events.Setpieces = {
'a1': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 1,
hit: 0.8,
attackDelay: 1,
@@ -257,7 +257,7 @@ Events.Setpieces = {
'b3': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 1,
hit: 0.8,
attackDelay: 1,
@@ -291,7 +291,7 @@ Events.Setpieces = {
'b4': {
combat: true,
enemy: 'cave lizard',
chara: 'L',
chara: 'R',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -325,7 +325,7 @@ Events.Setpieces = {
'c1': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -359,7 +359,7 @@ Events.Setpieces = {
'c2': {
combat: true,
enemy: 'lizard',
chara: 'L',
chara: 'T',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -560,7 +560,7 @@ Events.Setpieces = {
'a2': {
combat: true,
enemy: 'thug',
chara: 'T',
chara: 'E',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -655,7 +655,7 @@ Events.Setpieces = {
'b2': {
combat: true,
enemy: 'scavenger',
chara: 'S',
chara: 'E',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -694,7 +694,7 @@ Events.Setpieces = {
'b3': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 3,
hit: 0.8,
attackDelay: 1,
@@ -768,7 +768,7 @@ Events.Setpieces = {
'b5': {
combat: true,
enemy: 'madman',
chara: 'M',
chara: 'E',
damage: 6,
hit: 0.3,
attackDelay: 1,
@@ -807,7 +807,7 @@ Events.Setpieces = {
'c1': {
combat: true,
enemy: 'thug',
chara: 'T',
chara: 'E',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -846,7 +846,7 @@ Events.Setpieces = {
'c2': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 3,
hit: 0.8,
attackDelay: 1,
@@ -897,7 +897,7 @@ Events.Setpieces = {
'c4': {
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 4,
hit: 0.8,
attackDelay: 1,
@@ -949,14 +949,14 @@ Events.Setpieces = {
_('a small basket of food is hidden under a park bench, with a note attached.'),
_("can't read the words.")
],
loot: {
'cured meat': {
min: 1,
max: 5,
chance: 1
}
},
buttons: {
loot: {
'cured meat': {
min: 1,
max: 5,
chance: 1
}
},
buttons: {
'continue': {
text: _('continue'),
cooldown: Events._LEAVE_COOLDOWN,
@@ -972,7 +972,7 @@ Events.Setpieces = {
'd1': {
combat: true,
enemy: 'scavenger',
chara: 'S',
chara: 'E',
damage: 5,
hit: 0.8,
attackDelay: 2,
@@ -1011,7 +1011,7 @@ Events.Setpieces = {
'd2': {
combat: true,
enemy: 'vigilante',
chara: 'V',
chara: 'D',
damage: 6,
hit: 0.8,
attackDelay: 2,
@@ -1258,10 +1258,10 @@ Events.Setpieces = {
},
'a1': {
text:[
_('the streets are empty.'),
_('the air is filled with dust, driven relentlessly by the hard winds.')
_('the streets are empty.'),
_('the air is filled with dust, driven relentlessly by the hard winds.')
],
buttons: {
buttons: {
'continue': {
text: _('continue'),
nextScene: {0.5: 'b1', 1: 'b2'}
@@ -1274,8 +1274,8 @@ Events.Setpieces = {
},
'a2': {
text:[
_('orange traffic cones are set across the street, faded and cracked.'),
_('lights flash through the alleys between buildings.')
_('orange traffic cones are set across the street, faded and cracked.'),
_('lights flash through the alleys between buildings.')
],
buttons: {
'continue': {
@@ -1341,7 +1341,7 @@ Events.Setpieces = {
combat: true,
notification: _('a huge lizard scrambles up out of the darkness of an old metro station.'),
enemy: 'lizard',
chara: 'L',
chara: 'R',
damage: 5,
hit: 0.8,
attackDelay: 2,
@@ -1380,7 +1380,7 @@ Events.Setpieces = {
notification: _('the shot echoes in the empty street.'),
combat: true,
enemy: 'sniper',
chara: 'S',
chara: 'D',
damage: 15,
hit: 0.8,
attackDelay: 4,
@@ -1460,7 +1460,7 @@ Events.Setpieces = {
notification: _('a frail man stands defiantly, blocking the path.'),
combat: true,
enemy: 'frail man',
chara: 'M',
chara: 'E',
damage: 1,
hit: 0.8,
attackDelay: 2,
@@ -1536,7 +1536,7 @@ Events.Setpieces = {
notification: _('an old man bursts through a door, wielding a scalpel.'),
combat: true,
enemy: 'old man',
chara: 'M',
chara: 'E',
damage: 3,
hit: 0.5,
attackDelay: 2,
@@ -1575,7 +1575,7 @@ Events.Setpieces = {
notification: _('a thug is waiting on the other side of the wall.'),
combat: true,
enemy: 'thug',
chara: 'T',
chara: 'E',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -1615,7 +1615,7 @@ Events.Setpieces = {
notification: _('a snarling beast jumps out from behind a car.'),
combat: true,
enemy: 'beast',
chara: 'B',
chara: 'R',
damage: 2,
hit: 0.8,
attackDelay: 1,
@@ -1834,7 +1834,7 @@ Events.Setpieces = {
combat: true,
enemy: 'squatters',
plural: true,
chara: 'SSS',
chara: 'EEE',
damage: 2,
hit: 0.7,
attackDelay: 0.5,
@@ -1875,7 +1875,7 @@ Events.Setpieces = {
combat: true,
enemy: 'lizards',
plural: true,
chara: 'LLL',
chara: 'RRR',
damage: 4,
hit: 0.7,
attackDelay: 0.7,
@@ -1940,7 +1940,7 @@ Events.Setpieces = {
notification: _('a large bird nests at the top of the stairs.'),
combat: true,
enemy: 'bird',
chara: 'B',
chara: 'R',
damage: 5,
hit: 0.7,
attackDelay: 1,
@@ -2047,8 +2047,8 @@ Events.Setpieces = {
notification: _('a large man attacks, waving a bayonet.'),
combat: true,
enemy: 'veteran',
chara: 'V',
damage: 3,
chara: 'D',
damage: 6,
hit: 0.8,
attackDelay: 2,
health: 45,
@@ -2123,7 +2123,7 @@ Events.Setpieces = {
notification: _('a masked soldier rounds the corner, gun drawn'),
combat: true,
enemy: 'commando',
chara: 'C',
chara: 'D',
ranged: true,
damage: 3,
hit: 0.9,
@@ -2165,7 +2165,7 @@ Events.Setpieces = {
combat: true,
enemy: 'squatters',
plural: true,
chara: 'SSS',
chara: 'EEE',
damage: 2,
hit: 0.7,
attackDelay: 0.5,
@@ -2200,7 +2200,7 @@ Events.Setpieces = {
notification: _('a youth lashes out with a tree branch.'),
combat: true,
enemy: 'youth',
chara: 'Y',
chara: 'E',
damage: 2,
hit: 0.7,
attackDelay: 1,
@@ -2235,7 +2235,7 @@ Events.Setpieces = {
notification: _('a squatter stands firmly in the doorway of a small hut.'),
combat: true,
enemy: 'squatter',
chara: 'S',
chara: 'E',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -2270,7 +2270,7 @@ Events.Setpieces = {
notification: _('behind the door, a deformed figure awakes and attacks.'),
combat: true,
enemy: 'deformed',
chara: 'D',
chara: 'T',
damage: 8,
hit: 0.6,
attackDelay: 2,
@@ -3011,7 +3011,7 @@ Events.Setpieces = {
'occupied': {
combat: true,
enemy: 'squatter',
chara: 'S',
chara: 'E',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -3255,7 +3255,7 @@ Events.Setpieces = {
'a3': {
combat: true,
enemy: 'veteran',
chara: 'V',
chara: 'D',
damage: 10,
hit: 0.8,
attackDelay: 2,
@@ -3324,7 +3324,7 @@ Events.Setpieces = {
'a1': {
combat: true,
enemy: 'man',
chara: 'M',
chara: 'E',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -3358,7 +3358,7 @@ Events.Setpieces = {
'a2': {
combat: true,
enemy: 'man',
chara: 'M',
chara: 'E',
damage: 3,
hit: 0.8,
attackDelay: 2,
@@ -3392,7 +3392,7 @@ Events.Setpieces = {
'a3': {
combat: true,
enemy: 'chief',
chara: 'C',
chara: 'D',
damage: 5,
hit: 0.8,
attackDelay: 2,
@@ -3468,7 +3468,7 @@ Events.Setpieces = {
'enter': {
combat: true,
enemy: 'beastly matriarch',
chara: 'M',
chara: 'T',
damage: 4,
hit: 0.8,
attackDelay: 2,
+1 -16
View File
@@ -65,20 +65,5 @@
_('the compass points southwest')
];
delete keywords;
//translate text in css by overriding attributes
$("<style>").text('\
div#stores:before{ content: \''+ _("stores") + '\'}\
div#weapons:before{ content: \''+ _("weapons") + '\'}\
div#buildBtns:before{ content: \''+ _("build:") + '\'}\
div#craftBtns:before{ content: \''+ _("craft:") + '\'}\
div#buyBtns:before{ content: \''+ _("buy:") + '\'}\
div#outfitting:before{ content: \''+ _("supplies:") + '\'}\
div#perks:before{ content: \''+ _("perks:") + '\'}\
div#lootButtons:before { content: \''+ _("take:") + '\'}\
div#dropMenu:before { content: \''+ _("drop:") + '\'}\
div#village.noHuts:before { content: \'' + _("forest") + '\'}\
div#village:before { content: \'' + _("village") + '\'}\
').appendTo($('head'));
keywords = null;
})();
+59 -27
View File
@@ -8,6 +8,7 @@ var Outside = {
_GATHER_DELAY: 60,
_TRAPS_DELAY: 90,
_POP_DELAY: [0.5, 3],
_HUT_ROOM: 4,
_INCOME: {
'gatherer': {
@@ -158,6 +159,7 @@ var Outside = {
this.updateVillage();
Outside.updateWorkersView();
Outside.updateVillageIncome();
Engine.updateSlider();
@@ -169,10 +171,12 @@ var Outside = {
cooldown: Outside._GATHER_DELAY,
width: '80px'
}).appendTo('div#outsidePanel');
Outside.updateTrapButton();
},
getMaxPopulation: function() {
return $SM.get('game.buildings["hut"]', true) * 4;
return $SM.get('game.buildings["hut"]', true) * Outside._HUT_ROOM;
},
increasePopulation: function() {
@@ -218,6 +222,36 @@ var Outside = {
}
},
destroyHuts: function(num, allowEmpty) {
var dead = 0;
for(var i = 0; i < num; i++){
var population = $SM.get('game.population', true);
var rate = population / Outside._HUT_ROOM;
var full = Math.floor(rate);
// by default this is used to destroy full or half-full huts
// pass allowEmpty to include empty huts in the armageddon
var huts = (allowEmpty) ? $SM.get('game.buildings["hut"]', true) : Math.ceil(rate);
if(!huts) {
break;
}
// random can be 0 but not 1; however, 0 as a target is useless
var target = Math.floor(Math.random() * huts) + 1;
var inhabitants = 0;
if(target <= full){
inhabitants = Outside._HUT_ROOM;
} else if(target == full + 1){
inhabitants = population % Outside._HUT_ROOM;
}
$SM.set('game.buildings["hut"]', ($SM.get('game.buildings["hut"]') - 1));
if(inhabitants){
Outside.killVillagers(inhabitants);
dead += inhabitants;
}
}
// this method returns the total number of victims, for further actions
return dead;
},
schedulePopIncrease: function() {
var nextIncrease = Math.floor(Math.random()*(Outside._POP_DELAY[1] - Outside._POP_DELAY[0])) + Outside._POP_DELAY[0];
Engine.log('next population increase scheduled in ' + nextIncrease + ' minutes');
@@ -241,6 +275,7 @@ var Outside = {
var gatherer = $('div#workers_row_gatherer', workers);
for(var k in $SM.get('game.workers')) {
var lk = _(k);
var workerCount = $SM.get('game.workers["'+k+'"]');
var row = $('div#workers_row_' + k.replace(' ', '-'), workers);
if(row.length === 0) {
@@ -249,23 +284,19 @@ var Outside = {
var curPrev = null;
workers.children().each(function(i) {
var child = $(this);
var cName = child.attr('id').substring(12).replace('-', ' ');
var cName = child.children('.row_key').text();
if(cName != 'gatherer') {
if(cName < k && (curPrev == null || cName > curPrev)) {
curPrev = cName;
if(cName < lk) {
curPrev = child.attr('id');
}
}
});
if(curPrev == null && gatherer.length === 0) {
row.prependTo(workers);
}
else if(curPrev == null)
{
} else if(curPrev == null) {
row.insertAfter(gatherer);
}
else
{
row.insertAfter(workers.find('#workers_row_' + curPrev.replace(' ', '-')));
} else {
row.insertAfter(workers.find('#'+ curPrev));
}
} else {
@@ -323,9 +354,9 @@ var Outside = {
$('<span>').text(num).appendTo(val);
if(key != 'gatherer') {
$('<div>').addClass('upManyBtn').appendTo(val).click([10], Outside.increaseWorker);
$('<div>').addClass('upBtn').appendTo(val).click([1], Outside.increaseWorker);
$('<div>').addClass('dnBtn').appendTo(val).click([1], Outside.decreaseWorker);
$('<div>').addClass('upManyBtn').appendTo(val).click([10], Outside.increaseWorker);
$('<div>').addClass('dnManyBtn').appendTo(val).click([10], Outside.decreaseWorker);
}
@@ -363,26 +394,27 @@ var Outside = {
updateVillageRow: function(name, num, village) {
var id = 'building_row_' + name.replace(' ', '-');
var lname = _(name);
var row = $('div#' + id, village);
if(row.length === 0 && num > 0) {
row = $('<div>').attr('id', id).addClass('storeRow');
$('<div>').addClass('row_key').text(_(name)).appendTo(row);
$('<div>').addClass('row_key').text(lname).appendTo(row);
$('<div>').addClass('row_val').text(num).appendTo(row);
$('<div>').addClass('clear').appendTo(row);
var curPrev = null;
village.children().each(function(i) {
var child = $(this);
if(child.attr('id') != 'population') {
var cName = child.attr('id').substring(13).replace('-', ' ');
if(cName < name && (curPrev == null || cName > curPrev)) {
curPrev = cName;
var cName = child.children('.row_key').text();
if(cName < lname) {
curPrev = child.attr('id');
}
}
});
if(curPrev == null) {
row.prependTo(village);
} else {
row.insertAfter('#building_row_' + curPrev.replace(' ', '-'));
row.insertAfter('#' + curPrev);
}
} else if(num > 0) {
$('div#' + row.attr('id') + ' > div.row_val', village).text(num);
@@ -422,14 +454,14 @@ var Outside = {
var hasPeeps;
if($SM.get('game.buildings["hut"]', true) === 0) {
hasPeeps = false;
village.addClass('noHuts');
village.attr('data-legend', _('forest'));
} else {
hasPeeps = true;
village.removeClass('noHuts');
village.attr('data-legend', _('village'));
}
if(needsAppend && village.children().length > 1) {
village.appendTo('#outsidePanel');
village.prependTo('#outsidePanel');
village.animate({opacity:1}, 300, 'linear');
}
@@ -585,16 +617,16 @@ var Outside = {
}
}
}
/// TRANSLATORS : Mind the whitespace at the end.
/// TRANSLATORS : Mind the whitespace at the end.
var s = _('the traps contain ');
for(var i = 0, len = msg.length; i < len; i++) {
if(len > 1 && i > 0 && i < len - 1) {
for(var l = 0, len = msg.length; l < len; l++) {
if(len > 1 && l > 0 && l < len - 1) {
s += ", ";
} else if(len > 1 && i == len - 1) {
/// TRANSLATORS : Mind the whitespaces at the beginning and end.
} else if(len > 1 && l == len - 1) {
/// TRANSLATORS : Mind the whitespaces at the beginning and end.
s += _(" and ");
}
s += msg[i];
s += msg[l];
}
var baitUsed = numBait < numTraps ? numBait : numTraps;
@@ -611,7 +643,7 @@ var Outside = {
Outside.updateVillage();
Outside.updateWorkersView();
Outside.updateVillageIncome();
};
}
},
scrollSidebar: function(direction, reset) {
+49 -35
View File
@@ -34,7 +34,7 @@ var Path = {
.appendTo('div#locationSlider');
// Add the outfitting area
var outfitting = $('<div>').attr('id', 'outfitting').appendTo(this.panel);
var outfitting = $('<div>').attr({'id': 'outfitting', 'data-legend': _('supplies:')}).appendTo(this.panel);
$('<div>').attr('id', 'bagspace').appendTo(outfitting);
// Add the embark button
@@ -99,7 +99,7 @@ var Path = {
var needsAppend = false;
if(perks.length === 0) {
needsAppend = true;
perks = $('<div>').attr('id', 'perks');
perks = $('<div>').attr({'id': 'perks', 'data-legend': _('perks:')});
}
for(var k in $SM.get('character.perks')) {
var id = 'perk_' + k.replace(' ', '-');
@@ -112,7 +112,7 @@ var Path = {
}
if(needsAppend && perks.children().length > 0) {
perks.appendTo(Path.panel);
perks.prependTo(Path.panel);
}
if(!ignoreStores && Engine.activeModule === Path) {
@@ -157,55 +157,56 @@ var Path = {
$('.row_val', wRow).text(World.getMaxWater());
}
var space = Path.getFreeSpace();
var total = 0;
var currentBagCapacity = 0;
// Add the non-craftables to the craftables
var carryable = $.extend({
'cured meat': { type: 'tool' },
'bullets': { type: 'tool' },
'cured meat': { type: 'tool', desc: 'restores '+ World.MEAT_HEAL + ' hp' },
'bullets': { type: 'tool', desc: 'use with rifle' },
'grenade': {type: 'weapon' },
'bolas': {type: 'weapon' },
'laser rifle': {type: 'weapon' },
'energy cell': {type: 'tool' },
'energy cell': {type: 'tool', desc: 'use with laser rifle' },
'bayonet': {type: 'weapon' },
'charm': {type: 'tool'},
'medicine': {type: 'tool'}
'medicine': {type: 'tool', desc: 'restores ' + World.MEDS_HEAL + ' hp' }
}, Room.Craftables);
for(var k in carryable) {
var lk = _(k);
var store = carryable[k];
var have = $SM.get('stores["'+k+'"]');
var num = Path.outfit[k];
num = typeof num == 'number' ? num : 0;
if (have < num) { num = have; }
var numAvailable = $SM.get('stores["'+k+'"]', true);
if (have !== undefined) {
if (have < num) { num = have; }
$SM.set(k, num, true);
}
var row = $('div#outfit_row_' + k.replace(' ', '-'), outfit);
if((store.type == 'tool' || store.type == 'weapon') && have > 0) {
total += num * Path.getWeight(k);
currentBagCapacity += num * Path.getWeight(k);
if(row.length === 0) {
row = Path.createOutfittingRow(k, num, store.name);
row = Path.createOutfittingRow(k, num, store, store.name);
var curPrev = null;
outfit.children().each(function(i) {
var child = $(this);
if(child.attr('id').indexOf('outfit_row_') === 0) {
var cName = child.attr('id').substring(11).replace('-', ' ');
if(cName < k && (curPrev == null || cName > curPrev)) {
curPrev = cName;
var cName = child.children('.row_key').text();
if(cName < lk) {
curPrev = child.attr('id');
}
}
});
if(curPrev == null) {
row.insertAfter(wRow);
}
else
{
row.insertAfter(outfit.find('#outfit_row_' + curPrev.replace(' ', '-')));
} else {
row.insertAfter(outfit.find('#' + curPrev));
}
} else {
$('div#' + row.attr('id') + ' > div.row_val > span', outfit).text(num);
$('div#' + row.attr('id') + ' .tooltip .numAvailable', outfit).text(numAvailable - num);
$('div#' + row.attr('id') + ' .tooltip .numAvailable', outfit).text(have - num);
}
if(num === 0) {
$('.dnBtn', row).addClass('disabled');
@@ -214,10 +215,10 @@ var Path = {
$('.dnBtn', row).removeClass('disabled');
$('.dnManyBtn', row).removeClass('disabled');
}
if(num >= numAvailable || space < Path.getWeight(k)) {
if(num == have || space < Path.getWeight(k)) {
$('.upBtn', row).addClass('disabled');
$('.upManyBtn', row).addClass('disabled');
} else if(space >= Path.getWeight(k)) {
} else {
$('.upBtn', row).removeClass('disabled');
$('.upManyBtn', row).removeClass('disabled');
}
@@ -225,21 +226,27 @@ var Path = {
row.remove();
}
}
Path.updateBagSpace(currentBagCapacity);
},
updateBagSpace: function(currentBagCapacity) {
// Update bagspace
$('#bagspace').text(_('free {0}/{1}', Math.floor(Path.getCapacity() - total) , Path.getCapacity()));
$('#bagspace').text(_('free {0}/{1}', Math.floor(Path.getCapacity() - currentBagCapacity) , Path.getCapacity()));
if(Path.outfit['cured meat'] > 0) {
Button.setDisabled($('#embarkButton'), false);
} else {
Button.setDisabled($('#embarkButton'), true);
}
},
createOutfittingRow: function(key, num, name) {
if(!name) name = _(key);
createOutfittingRow: function(key, num, store) {
if(!store.name) store.name = _(key);
var row = $('<div>').attr('id', 'outfit_row_' + key.replace(' ', '-')).addClass('outfitRow').attr('key',key);
$('<div>').addClass('row_key').text(name).appendTo(row);
$('<div>').addClass('row_key').text(store.name).appendTo(row);
var val = $('<div>').addClass('row_val').appendTo(row);
$('<span>').text(num).appendTo(val);
@@ -251,6 +258,14 @@ var Path = {
var numAvailable = $SM.get('stores["'+key+'"]', true);
var tt = $('<div>').addClass('tooltip bottom right').appendTo(row);
if(store.type == 'weapon') {
$('<div>').addClass('row_key').text(_('damage')).appendTo(tt);
$('<div>').addClass('row_val').text(World.getDamage(key)).appendTo(tt);
} else if(store.type == 'tool' && store.desc != "undefined") {
$('<div>').addClass('row_key').text(store.desc).appendTo(tt);
}
$('<div>').addClass('row_key').text(_('weight')).appendTo(tt);
$('<div>').addClass('row_val').text(Path.getWeight(key)).appendTo(tt);
$('<div>').addClass('row_key').text(_('available')).appendTo(tt);
@@ -267,8 +282,7 @@ var Path = {
if(Path.getFreeSpace() >= Path.getWeight(supply) && cur < $SM.get('stores["'+supply+'"]', true)) {
var maxExtraByWeight = Math.floor(Path.getFreeSpace() / Path.getWeight(supply));
var maxExtraByStore = $SM.get('stores["'+supply+'"]', true) - cur;
var maxExtraByBtn = btn.data;
Path.outfit[supply] = cur + Math.min(maxExtraByBtn, Math.min(maxExtraByWeight, maxExtraByStore));
Path.outfit[supply] = cur + Math.min(btn.data, maxExtraByWeight, maxExtraByStore);
$SM.set('outfit['+supply+']', Path.outfit[supply]);
Path.updateOutfitting();
}
@@ -290,7 +304,6 @@ var Path = {
Path.setTitle();
Path.updateOutfitting();
Path.updatePerks(true);
$SM.set('outfit', Path.outfit);
Engine.moveStoresView($('#perks'), transition_diff);
},
@@ -303,7 +316,6 @@ var Path = {
for(var k in Path.outfit) {
$SM.add('stores["'+k+'"]', -Path.outfit[k]);
}
$SM.remove('outfit');
World.onArrival();
$('#outerSlider').animate({left: '-700px'}, 300);
Engine.activeModule = World;
@@ -312,7 +324,9 @@ var Path = {
handleStateUpdates: function(e){
if(e.category == 'character' && e.stateName.indexOf('character.perks') === 0 && Engine.activeModule == Path){
Path.updatePerks();
};
} else if(e.category == 'income' && Engine.activeModule == Path){
Path.updateOutfitting();
}
},
scrollSidebar: function(direction, reset){
@@ -327,7 +341,7 @@ var Path = {
var momentum = 10;
if( direction == 'up' )
momentum = momentum * -1
momentum = momentum * -1;
if( direction == 'down' && inView( direction, $('#perks') ) ){
+96 -42
View File
@@ -437,7 +437,7 @@ var Room = {
}
},
'compass': {
type: 'upgrade',
type: 'special',
maximum: 1,
cost: function() {
return {
@@ -462,6 +462,8 @@ var Room = {
options
);
Room.pathDiscovery = Boolean($SM.get('stores["compass"]'));
if(Engine._debug) {
this._ROOM_WARM_DELAY = 5000;
this._BUILDER_STATE_DELAY = 5000;
@@ -511,7 +513,7 @@ var Room = {
}).appendTo('div#roomPanel');
// Create the stores container
$('<div>').attr('id', 'storesContainer').appendTo('div#roomPanel');
$('<div>').attr('id', 'storesContainer').prependTo('div#roomPanel');
//subscribe to stateUpdates
$.Dispatch('stateUpdate').subscribe(Room.handleStateUpdates);
@@ -748,17 +750,33 @@ var Room = {
updateStoresView: function() {
var stores = $('div#stores');
var resources = $('div#resources');
var special = $('div#special');
var weapons = $('div#weapons');
var needsAppend = false, wNeedsAppend = false, newRow = false;
var needsAppend = false, rNeedsAppend = false, sNeedsAppend = false, wNeedsAppend = false, newRow = false;
if(stores.length === 0) {
stores = $('<div>').attr({
id: 'stores'
'id': 'stores',
'data-legend': _('stores')
}).css('opacity', 0);
needsAppend = true;
}
if(resources.length === 0) {
resources = $('<div>').attr({
id: 'resources'
}).css('opacity', 0);
rNeedsAppend = true;
}
if(special.length === 0) {
special = $('<div>').attr({
id: 'special'
}).css('opacity', 0);
sNeedsAppend = true;
}
if(weapons.length === 0) {
weapons = $('<div>').attr({
id: 'weapons'
'id': 'weapons',
'data-legend': _('weapons')
}).css('opacity', 0);
wNeedsAppend = true;
}
@@ -778,11 +796,17 @@ var Room = {
case 'upgrade':
// Don't display upgrades on the Room screen
continue;
case 'building':
// Don't display buildings either
continue;
case 'weapon':
location = weapons;
break;
case 'special':
location = special;
break;
default:
location = stores;
location = resources;
break;
}
@@ -797,37 +821,48 @@ var Room = {
$SM.set('stores["'+k+'"]', 0);
}
var lk = _(k);
// thieves?
if(typeof $SM.get('game.thieves') == 'undefined' && num > 5000 && $SM.get('features.location.world')) {
$SM.startThieves();
}
if(row.length === 0 && num > 0) {
if(row.length === 0) {
row = $('<div>').attr('id', id).addClass('storeRow');
$('<div>').addClass('row_key').text(_(k)).appendTo(row);
$('<div>').addClass('row_key').text(lk).appendTo(row);
$('<div>').addClass('row_val').text(Math.floor(num)).appendTo(row);
$('<div>').addClass('clear').appendTo(row);
var curPrev = null;
location.children().each(function(i) {
var child = $(this);
var cName = child.attr('id').substring(4).replace('-', ' ');
if(cName < k && (curPrev == null || cName > curPrev)) {
curPrev = cName;
var cName = child.children('.row_key').text();
if(cName < lk) {
curPrev = child.attr('id');
}
});
if(curPrev == null) {
row.prependTo(location);
} else {
row.insertAfter(location.find('#row_' + curPrev.replace(' ', '-')));
row.insertAfter(location.find('#' + curPrev));
}
newRow = true;
} else if(num>= 0){
} else {
$('div#' + row.attr('id') + ' > div.row_val', location).text(Math.floor(num));
}
}
if(rNeedsAppend && resources.children().length > 0) {
resources.prependTo(stores);
resources.animate({opacity: 1}, 300, 'linear');
}
if(needsAppend && stores.children().length > 0) {
if(sNeedsAppend && special.children().length > 0) {
special.appendTo(stores);
special.animate({opacity: 1}, 300, 'linear');
}
if(needsAppend && stores.find('div.storeRow').length > 0) {
stores.appendTo('div#storesContainer');
stores.animate({opacity: 1}, 300, 'linear');
}
@@ -844,15 +879,22 @@ var Room = {
if($("div#outsidePanel").length) {
Outside.updateVillage();
}
if($SM.get('stores.compass') && !Room.pathDiscovery){
Room.pathDiscovery = true;
Path.openPath();
}
},
updateIncomeView: function() {
var stores = $('div#stores');
var stores = $('div#resources');
var totalIncome = {};
if(stores.length === 0 || typeof $SM.get('income') == 'undefined') return;
$('div.storeRow', stores).each(function(index, el) {
el = $(el);
$('div.tooltip', el).remove();
var tt = $('<div>').addClass('tooltip bottom right');
var ttPos = index > 10 ? 'top right' : 'bottom right';
var tt = $('<div>').addClass('tooltip ' + ttPos);
var storeName = el.attr('id').substring(4).replace('-', ' ');
for(var incomeSource in $SM.get('income')) {
var income = $SM.get('income["'+incomeSource+'"]');
@@ -863,10 +905,18 @@ var Room = {
.addClass('row_val')
.text(Engine.getIncomeMsg(income.stores[store], income.delay))
.appendTo(tt);
if (!totalIncome[store] || totalIncome[store].income === undefined) {
totalIncome[store] = { income: 0 };
}
totalIncome[store].income += Number(income.stores[store]);
totalIncome[store].delay = income.delay;
}
}
}
if(tt.children().length > 0) {
var total = totalIncome[storeName].income;
$('<div>').addClass('total row_key').text(_('total')).appendTo(tt);
$('<div>').addClass('total row_val').text(Engine.getIncomeMsg(total, totalIncome[storeName].delay)).appendTo(tt);
tt.appendTo(el);
}
});
@@ -897,10 +947,6 @@ var Room = {
Notifications.notify(Room, good.buildMsg);
$SM.add('stores["'+thing+'"]', 1);
if(thing == 'compass') {
Path.openPath();
}
},
build: function(buildBtn) {
@@ -1009,21 +1055,21 @@ var Room = {
var buildSection = $('#buildBtns');
var needsAppend = false;
if(buildSection.length === 0) {
buildSection = $('<div>').attr('id', 'buildBtns').css('opacity', 0);
buildSection = $('<div>').attr({'id': 'buildBtns', 'data-legend': _('build:')}).css('opacity', 0);
needsAppend = true;
}
var craftSection = $('#craftBtns');
var cNeedsAppend = false;
if(craftSection.length === 0 && $SM.get('game.buildings["workshop"]', true) > 0) {
craftSection = $('<div>').attr('id', 'craftBtns').css('opacity', 0);
craftSection = $('<div>').attr({'id': 'craftBtns', 'data-legend': _('craft:')}).css('opacity', 0);
cNeedsAppend = true;
}
var buySection = $('#buyBtns');
var bNeedsAppend = false;
if(buySection.length === 0 && $SM.get('game.buildings["trading post"]', true) > 0) {
buySection = $('<div>').attr('id', 'buyBtns').css('opacity', 0);
buySection = $('<div>').attr({'id': 'buyBtns', 'data-legend': _('buy:')}).css('opacity', 0);
bNeedsAppend = true;
}
@@ -1047,9 +1093,9 @@ var Room = {
var costTooltip = $('.tooltip', craftable.button);
costTooltip.empty();
var cost = craftable.cost();
for(var k in cost) {
$("<div>").addClass('row_key').text(_(k)).appendTo(costTooltip);
$("<div>").addClass('row_val').text(cost[k]).appendTo(costTooltip);
for(var c in cost) {
$("<div>").addClass('row_key').text(_(c)).appendTo(costTooltip);
$("<div>").addClass('row_val').text(cost[c]).appendTo(costTooltip);
}
if(max && !craftable.button.hasClass('disabled')) {
Notifications.notify(Room, craftable.maxMsg);
@@ -1062,33 +1108,34 @@ var Room = {
}
}
for(var k in Room.TradeGoods) {
good = Room.TradeGoods[k];
var max = $SM.num(k, good) + 1 > good.maximum;
for(var g in Room.TradeGoods) {
good = Room.TradeGoods[g];
var goodsMax = $SM.num(g, good) + 1 > good.maximum;
if(good.button == null) {
if(Room.buyUnlocked(k)) {
if(Room.buyUnlocked(g)) {
good.button = new Button.Button({
id: 'build_' + k,
id: 'build_' + g,
cost: good.cost(),
text: _(k),
text: _(g),
click: Room.buy,
width: '80px'
}).css('opacity', 0).attr('buildThing', k).appendTo(buySection).animate({opacity:1}, 300, 'linear');
width: '80px',
ttPos: buySection.children().length > 10 ? 'top right' : 'bottom right'
}).css('opacity', 0).attr('buildThing', g).appendTo(buySection).animate({opacity:1}, 300, 'linear');
}
} else {
// refresh the tooltip
var costTooltip = $('.tooltip', good.button);
costTooltip.empty();
var cost = good.cost();
for(var k in cost) {
$("<div>").addClass('row_key').text(_(k)).appendTo(costTooltip);
$("<div>").addClass('row_val').text(cost[k]).appendTo(costTooltip);
var goodsCostTooltip = $('.tooltip', good.button);
goodsCostTooltip.empty();
var goodCost = good.cost();
for(var gc in goodCost) {
$("<div>").addClass('row_key').text(_(gc)).appendTo(goodsCostTooltip);
$("<div>").addClass('row_val').text(goodCost[gc]).appendTo(goodsCostTooltip);
}
if(max && !good.button.hasClass('disabled')) {
if(goodsMax && !good.button.hasClass('disabled')) {
Notifications.notify(Room, good.maxMsg);
}
}
if(max) {
if(goodsMax) {
Button.setDisabled(good.button, true);
} else {
Button.setDisabled(good.button, false);
@@ -1106,6 +1153,13 @@ var Room = {
}
},
compassTooltip: function(direction){
var ttPos = $('div#resources').children().length > 10 ? 'top right' : 'bottom right';
var tt = $('<div>').addClass('tooltip ' + ttPos);
$('<div>').addClass('row_key').text(_('the compass points '+ direction)).appendTo(tt);
tt.appendTo($('#row_compass'));
},
handleStateUpdates: function(e){
if(e.category == 'stores'){
Room.updateStoresView();
+1 -1
View File
@@ -13,7 +13,7 @@ var Score = {
var fullScore = 0;
var factor = [1, 1.5, 1, 2, 2, 3, 3, 2, 2, 2, 2, 1.5, 1,
1, 10, 30, 50, 100, 150, 150, 3, 3, 5, 4]
1, 10, 30, 50, 100, 150, 150, 3, 3, 5, 4];
for(var i = 0; i< factor.length; i++){
fullScore += scoreUnadded[i] * factor[i];
}
+2 -2
View File
@@ -97,7 +97,7 @@ var Ship = {
setTitle: function() {
if(Engine.activeModule == this) {
document.title = "An Old Starship";
document.title = _("An Old Starship");
}
},
@@ -171,4 +171,4 @@ var Ship = {
handleStateUpdates: function(e){
}
};
};
+32 -5
View File
@@ -171,7 +171,7 @@ var Space = {
}
if(!Space.done) {
Engine.setTimeout(Space.createAsteroid, 1000 - (Space.altitude * 10));
Engine.setTimeout(Space.createAsteroid, 1000 - (Space.altitude * 10), true);
}
}
},
@@ -271,7 +271,7 @@ var Space = {
$('#spacePanel, .menu, select.menuBtn').animate({color: '#272823'}, 500, 'linear');
else
$('#spacePanel, .menu, select.menuBtn').animate({color: 'white'}, 500, 'linear');
}, Space.FTB_SPEED / 2);
}, Space.FTB_SPEED / 2, true);
Space.createAsteroid();
},
@@ -377,8 +377,8 @@ var Space = {
clearTimeout(Events._eventTimeout);
clearTimeout(Room._fireTimer);
clearTimeout(Room._tempTimer);
for(var k in Room.Craftables) {
Room.Craftables[k].button = null;
for(var j in Room.Craftables) {
Room.Craftables[j].button = null;
}
for(var k in Room.TradeGoods) {
Room.TradeGoods[k].button = null;
@@ -443,11 +443,38 @@ var Space = {
$('#starsContainer').remove();
$('#content, #notifications').remove();
$('<span>')
.addClass('endGame endGameRestart')
.addClass('endGame endGameOption')
.text(_('restart.'))
.click(Engine.confirmDelete)
.appendTo('.centerCont')
.animate({opacity:1},1500);
$('<br />')
.appendTo('.centerCont');
$('<br />')
.appendTo('.centerCont');
$('<span>')
.addClass('endGame')
.text(_('expanded story. alternate ending. behind the scenes commentary. get the app.'))
.appendTo('.centerCont')
.animate({opacity:1}, 1500);
$('<br />')
.appendTo('.centerCont');
$('<br />')
.appendTo('.centerCont');
$('<span>')
.addClass('endGame endGameOption')
.text(_('iOS.'))
.click(function() { window.open('https://itunes.apple.com/app/apple-store/id736683061?pt=2073437&ct=gameover&mt=8'); })
.appendTo('.centerCont')
.animate({opacity:1},1500);
$('<br />')
.appendTo('.centerCont');
$('<span>')
.addClass('endGame endGameOption')
.text(_('android.'))
.click(function() { window.open('https://play.google.com/store/apps/details?id=com.yourcompany.adarkroom'); })
.appendTo('.centerCont')
.animate({opacity:1},1500);
Engine.options = {};
Engine.deleteSave(true);
}
+90 -71
View File
@@ -1,60 +1,63 @@
/*
* 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
'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
'previous', // prestige, score, trophies (in future), achievements (again, not yet), etc
'outfit' // used to temporarily store the items to be taken on the path
'game', // mostly location related: fire temp, workers, population, world map, etc
'playStats', // anything play related: play time, loads, 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
'config',
'wait', // mysterious wanderers are coming back
'cooldown' // residual values for cooldown buttons
];
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
$.Dispatch('stateUpdate').subscribe($SM.handleStateUpdates);
},
//create all parents and then set state
createState: function(stateName, value) {
var words = stateName.split(/[.\[\]'"]+/);
//for some reason there are sometimes empty strings
for (var i = 0; i < words.length; i++) {
if (words[i] === '') {
words.splice(i, 1);
i--;
for (var j = 0; j < words.length; j++) {
if (words[j] === '') {
words.splice(j, 1);
j--;
}
}
var obj = State;
@@ -67,51 +70,51 @@ var StateManager = {
obj[words[i]] = value;
return obj;
},
//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.createState(stateName, 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) {
$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;
@@ -119,7 +122,7 @@ var StateManager = {
//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);
//check for NaN (old != old) and non number values
if(old != old){
Engine.log('WARNING: '+stateName+' was corrupted (NaN). Resetting to 0.');
@@ -131,52 +134,52 @@ var StateManager = {
} 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);
//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;
},
//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
setget: function(stateName, value, noEvent){
$SM.set(stateName, value, noEvent);
return eval('('+$SM.buildPath(stateName)+')');
},
remove: function(stateName, noEvent) {
var whichState = $SM.buildPath(stateName);
try{
@@ -190,21 +193,36 @@ var StateManager = {
$SM.fireUpdate(stateName);
}
},
removeBranch: function(stateName, noEvent) {
for(var i in $SM.get(stateName)){
if(typeof $SM.get(stateName)[i] == 'object'){
$SM.removeBranch(stateName +'["'+ i +'"]');
}
}
if($.isEmptyObject($SM.get(stateName))){
$SM.remove(stateName);
}
if(!noEvent){
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){
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});
if(save) Engine.saveGame();
},
getCategory: function(stateName){
var firstOB = stateName.indexOf('[');
var firstDot = stateName.indexOf('.');
@@ -220,7 +238,7 @@ var StateManager = {
return stateName.substr(0,cutoff);
}
},
//Use this function to make old save games compatible with new version
updateOldState: function(){
var version = $SM.get('version');
@@ -299,7 +317,7 @@ var StateManager = {
$SM.set('version', 1.3);
}
},
/******************************************************************
* Start of specific state functions
******************************************************************/
@@ -308,11 +326,11 @@ var StateManager = {
$SM.set('character.perks["'+name+'"]', true);
Notifications.notify(null, Engine.Perks[name].notify);
},
hasPerk: function(name) {
return $SM.get('character.perks["'+name+'"]');
},
//INCOME
setIncome: function(source, options) {
var existing = $SM.get('income["'+source+'"]');
@@ -321,7 +339,7 @@ var StateManager = {
}
$SM.set('income["'+source+'"]', options);
},
getIncome: function(source) {
var existing = $SM.get('income["'+source+'"]');
if(typeof existing != 'undefined') {
@@ -329,7 +347,7 @@ var StateManager = {
}
return {};
},
collectIncome: function() {
var changed = false;
if(typeof $SM.get('income') != 'undefined' && Engine.activeModule != Space) {
@@ -340,21 +358,21 @@ var StateManager = {
income.timeLeft = 0;
}
income.timeLeft--;
if(income.timeLeft <= 0) {
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 ok = true;
if (source != 'thieves') {
for (var k in cost) {
var have = $SM.get('stores["' + k + '"]', true);
if (have + cost[k] < 0) {
ok = false;
break;
}
}
for (var k in cost) {
var have = $SM.get('stores["' + k + '"]', true);
if (have + cost[k] < 0) {
ok = false;
break;
}
}
}
if(ok){
@@ -370,9 +388,9 @@ var StateManager = {
if(changed){
$SM.fireUpdate('income', true);
}
Engine._incomeTimeout = setTimeout($SM.collectIncome, 1000);
Engine._incomeTimeout = Engine.setTimeout($SM.collectIncome, 1000);
},
//Thieves
addStolen: function(stores) {
for(var k in stores) {
@@ -386,7 +404,7 @@ var StateManager = {
}
}
},
startThieves: function() {
$SM.set('game.thieves', 1);
$SM.setIncome('thieves', {
@@ -398,7 +416,7 @@ var StateManager = {
}
});
},
//Misc
num: function(name, craftable) {
switch(craftable.type) {
@@ -406,15 +424,16 @@ var StateManager = {
case 'tool':
case 'weapon':
case 'upgrade':
case 'special':
return $SM.get('stores["'+name+'"]', true);
case 'building':
return $SM.get('game.buildings["'+name+'"]', true);
}
},
handleStateUpdates: function(e){
}
}
};
//alias
+179 -103
View File
@@ -1,5 +1,5 @@
var World = {
RADIUS: 30,
VILLAGE_POS: [30, 30],
TILE: {
@@ -40,7 +40,7 @@ var World = {
SOUTH: [ 0, 1],
WEST: [-1, 0],
EAST: [ 1, 0],
Weapons: {
'fists': {
verb: _('punch'),
@@ -101,7 +101,7 @@ var World = {
cost: { 'bolas': 1 }
}
},
name: 'World',
options: {}, // Nothing for now
init: function(options) {
@@ -109,12 +109,12 @@ var World = {
this.options,
options
);
// Setup probabilities. Sum must equal 1.
World.TILE_PROBS[World.TILE.FOREST] = 0.15;
World.TILE_PROBS[World.TILE.FIELD] = 0.35;
World.TILE_PROBS[World.TILE.BARRENS] = 0.5;
// Setpiece definitions
World.LANDMARKS[World.TILE.OUTPOST] = { num: 0, minRadius: 0, maxRadius: 0, scene: 'outpost', label: _('An&nbsp;Outpost') };
World.LANDMARKS[World.TILE.IRON_MINE] = { num: 1, minRadius: 5, maxRadius: 5, scene: 'ironmine', label: _('Iron&nbsp;Mine') };
@@ -128,12 +128,12 @@ var World = {
World.LANDMARKS[World.TILE.BOREHOLE] = { num: 10, minRadius: 15, maxRadius: World.RADIUS * 1.5, scene: 'borehole', label: _('A&nbsp;Borehole')};
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')};
// Only add the cache if there is prestige data
if($SM.get('previous.stores')) {
World.LANDMARKS[World.TILE.CACHE] = { num: 1, minRadius: 10, maxRadius: World.RADIUS * 1.5, scene: 'cache', label: _('A&nbsp;Destroyed&nbsp;Village')};
}
if(typeof $SM.get('features.location.world') == 'undefined') {
$SM.set('features.location.world', true);
$SM.setM('game.world', {
@@ -141,31 +141,40 @@ var World = {
mask: World.newMask()
});
}
// Create the World panel
this.panel = $('<div>').attr('id', "worldPanel").addClass('location').appendTo('#outerSlider');
// Create the shrink wrapper
var outer = $('<div>').attr('id', 'worldOuter').appendTo(this.panel);
// Create the bag panel
$('<div>').attr('id', 'bagspace-world').append($('<div>')).appendTo(outer);
$('<div>').attr('id', 'backpackTitle').appendTo(outer);
$('<div>').attr('id', 'backpackSpace').appendTo(outer);
$('<div>').attr('id', 'healthCounter').appendTo(outer);
Engine.updateOuterSlider();
// Map the ship and show compass tooltip
World.ship = World.mapSearch(World.TILE.SHIP,$SM.get('game.world.map'),1);
World.dir = World.compassDir(World.ship[0]);
// compass tooltip text
Room.compassTooltip(World.dir);
// Check if everything has been seen
World.testMap();
//subscribe to stateUpdates
$.Dispatch('stateUpdate').subscribe(World.handleStateUpdates);
},
clearDungeon: function() {
Engine.event('progress', 'dungeon cleared');
World.state.map[World.curPos[0]][World.curPos[1]] = World.TILE.OUTPOST;
World.drawRoad();
},
drawRoad: function() {
var findClosestRoad = function(startPos) {
// We'll search in a spiral to find the closest road tile
@@ -220,7 +229,7 @@ var World = {
xIntersect = closestRoad[0] + xDist;
yIntersect = closestRoad[1];
}
for(var x = 0; x < Math.abs(xDist); x++) {
if(World.isTerrain(World.state.map[closestRoad[0] + (xDir*x)][yIntersect])) {
World.state.map[closestRoad[0] + (xDir*x)][yIntersect] = World.TILE.ROAD;
@@ -233,14 +242,14 @@ var World = {
}
World.drawMap();
},
updateSupplies: function() {
var supplies = $('div#bagspace-world > div');
if(!Path.outfit) {
Path.outfit = {};
}
// Add water
var water = $('div#supply_water');
if(World.water > 0 && water.length === 0) {
@@ -251,7 +260,7 @@ var World = {
} else {
water.remove();
}
var total = 0;
for(var k in Path.outfit) {
var item = $('div#supply_' + k.replace(' ', '-'), supplies);
@@ -272,18 +281,18 @@ var World = {
item.remove();
}
}
// Update label
var t = _('pockets');
if($SM.get('stores.rucksack', true) > 0) {
t = _('rucksack');
}
$('#backpackTitle').text(t);
// Update bagspace
$('#backpackSpace').text(_('free {0}/{1}', Math.floor(Path.getCapacity() - total) , Path.getCapacity()));
},
setWater: function(w) {
World.water = w;
if(World.water > World.getMaxWater()) {
@@ -291,7 +300,7 @@ var World = {
}
World.updateSupplies();
},
setHp: function(hp) {
if(typeof hp == 'number' && !isNaN(hp)) {
World.health = hp;
@@ -301,35 +310,35 @@ var World = {
$('#healthCounter').text(_('hp: {0}/{1}', World.health , World.getMaxHealth()));
}
},
createItemDiv: function(name, num) {
var div = $('<div>').attr('id', 'supply_' + name.replace(' ', '-'))
.addClass('supplyItem')
.text(_('{0}:{1}',_(name), num));
return div;
},
moveNorth: function() {
Engine.log('North');
if(World.curPos[1] > 0) World.move(World.NORTH);
},
moveSouth: function() {
Engine.log('South');
if(World.curPos[1] < World.RADIUS * 2) World.move(World.SOUTH);
},
moveWest: function() {
Engine.log('West');
if(World.curPos[0] > 0) World.move(World.WEST);
},
moveEast: function() {
Engine.log('East');
if(World.curPos[0] < World.RADIUS * 2) World.move(World.EAST);
},
move: function(direction) {
var oldTile = World.state.map[World.curPos[0]][World.curPos[1]];
World.curPos[0] += direction[0];
@@ -346,7 +355,7 @@ var World = {
}
}
},
keyDown: function(event) {
switch(event.which) {
case 38: // Up
@@ -406,14 +415,14 @@ var World = {
World.moveEast();
}
},
checkDanger: function() {
World.danger = typeof World.danger == 'undefined' ? false: World.danger;
if(!World.danger) {
if($SM.get('stores["i armour"]', true) === 0 && World.getDistance() >= 8) {
World.danger = true;
return true;
}
}
if($SM.get('stores["s armour"]', true) === 0 && World.getDistance() >= 18) {
World.danger = true;
return true;
@@ -430,7 +439,7 @@ var World = {
}
return false;
},
useSupplies: function() {
World.foodMove++;
World.waterMove++;
@@ -495,15 +504,15 @@ var World = {
}
return true;
},
meatHeal: function() {
return World.MEAT_HEAL * ($SM.hasPerk('gastronome') ? 2 : 1);
},
medsHeal: function() {
return World.MEDS_HEAL;
},
checkFight: function() {
World.fightMove = typeof World.fightMove == 'number' ? World.fightMove : 0;
World.fightMove++;
@@ -516,7 +525,7 @@ var World = {
}
}
},
doSpace: function() {
var curTile = World.state.map[World.curPos[0]][World.curPos[1]];
@@ -532,17 +541,21 @@ var World = {
}
}
},
getDistance: function(from, to) {
from = from || World.curPos;
to = to || World.VILLAGE_POS;
return Math.abs(from[0] - to[0]) + Math.abs(from[1] - to[1]);
},
getTerrain: function() {
return World.state.map[World.curPos[0]][World.curPos[1]];
},
getDamage: function(thing) {
return World.Weapons[thing].damage;
},
narrateMove: function(oldTile, newTile) {
var msg = null;
switch(oldTile) {
@@ -581,7 +594,7 @@ var World = {
Notifications.notify(World, msg);
}
},
newMask: function() {
var mask = new Array(World.RADIUS * 2 + 1);
for(var i = 0; i <= World.RADIUS * 2; i++) {
@@ -590,33 +603,56 @@ var World = {
World.lightMap(World.RADIUS, World.RADIUS, mask);
return mask;
},
lightMap: function(x, y, mask) {
var r = World.LIGHT_RADIUS;
r *= $SM.hasPerk('scout') ? 2 : 1;
World.uncoverMap(x, y, r, mask);
return mask;
},
uncoverMap: function(x, y, r, mask) {
mask[x][y] = true;
for(var i = -r; i <= r; i++) {
for(var j = -r + Math.abs(i); j <= r - Math.abs(i); j++) {
if(y + j >= 0 && y + j <= World.RADIUS * 2 &&
x + i <= World.RADIUS * 2 &&
if(y + j >= 0 && y + j <= World.RADIUS * 2 &&
x + i <= World.RADIUS * 2 &&
x + i >= 0) {
mask[x+i][y+j] = true;
}
}
}
},
applyMap: function() {
var x = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
var y = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
World.uncoverMap(x, y, 5, $SM.get('game.world.mask'));
testMap: function() {
if(!World.seenAll) {
var dark;
var mask = $SM.get('game.world.mask');
loop:
for(var i = 0; i < mask.length; i++) {
for(var j = 0; j < mask[i].length; j++) {
if(!mask[i][j]) {
dark = true;
break loop;
}
}
}
World.seenAll = !dark;
}
},
applyMap: function() {
if(!World.seenAll){
var x,y,mask = $SM.get('game.world.mask');
do {
x = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
y = Math.floor(Math.random() * (World.RADIUS * 2) + 1);
} while (mask[x][y]);
World.uncoverMap(x, y, 5, mask);
}
World.testMap();
},
generateMap: function() {
var map = new Array(World.RADIUS * 2 + 1);
for(var i = 0; i <= World.RADIUS * 2; i++) {
@@ -641,36 +677,70 @@ var World = {
x = World.RADIUS - r;
y = World.RADIUS + (7 * r) - t;
}
map[x][y] = World.chooseTile(x, y, map);
}
}
// Place landmarks
for(var k in World.LANDMARKS) {
var landmark = World.LANDMARKS[k];
for(var i = 0; i < landmark.num; i++) {
for(var l = 0; l < landmark.num; l++) {
var pos = World.placeLandmark(landmark.minRadius, landmark.maxRadius, k, map);
if(k == World.TILE.SHIP) {
var dx = pos[0] - World.RADIUS, dy = pos[1] - World.RADIUS;
var horz = dx < 0 ? 'west' : 'east';
var vert = dy < 0 ? 'north' : 'south';
if(Math.abs(dx) / 2 > Math.abs(dy)) {
World.dir = horz;
} else if(Math.abs(dy) / 2 > Math.abs(dx)){
World.dir = vert;
} else {
World.dir = vert + horz;
}
}
return map;
},
mapSearch: function(target,map,required){
var max = World.LANDMARKS[target].num;
if(!max){
// this restrict the research to numerable landmarks
return null;
}
// restrict research if only a fixed number (usually 1) is required
max = (required) ? Math.min(required,max) : max;
var index = 0;
var targets = [];
search: // label for coordinate research
for(var i = 0; i <= World.RADIUS * 2; i++){
for(var j = 0; j <= World.RADIUS * 2; j++){
if(map[i][j].charAt(0) === target){
// search result is stored as an object;
// items are listed as they appear in the map, tl-br
// each item has relative coordinates and a compass-type direction
targets[index] = {
x : i - World.RADIUS,
y : j - World.RADIUS,
};
index++;
if(index === max){
// optimisation: stop the research if maximum number of items has been reached
break search;
}
}
}
}
return map;
return targets;
},
compassDir: function(pos){
var dir = '';
var horz = pos.x < 0 ? 'west' : 'east';
var vert = pos.y < 0 ? 'north' : 'south';
if(Math.abs(pos.x) / 2 > Math.abs(pos.y)) {
dir = horz;
} else if(Math.abs(pos.y) / 2 > Math.abs(pos.x)){
dir = vert;
} else {
dir = vert + horz;
}
return dir;
},
placeLandmark: function(minRadius, maxRadius, landmark, map) {
var x = World.RADIUS, y = World.RADIUS;
while(!World.isTerrain(map[x][y])) {
var r = Math.floor(Math.random() * (maxRadius - minRadius)) + minRadius;
@@ -688,20 +758,20 @@ var World = {
map[x][y] = landmark;
return [x, y];
},
isTerrain: function(tile) {
return tile == World.TILE.FOREST || tile == World.TILE.FIELD || tile == World.TILE.BARRENS;
},
chooseTile: function(x, y, map) {
var adjacent = [
y > 0 ? map[x][y-1] : null,
y < World.RADIUS * 2 ? map[x][y+1] : null,
x < World.RADIUS * 2 ? map[x+1][y] : null,
x > 0 ? map[x-1][y] : null
];
var chances = {};
var nonSticky = 1;
for(var i in adjacent) {
@@ -724,34 +794,34 @@ var World = {
chances[tile] = cur;
}
}
var list = [];
for(var t in chances) {
list.push(chances[t] + '' + t);
for(var j in chances) {
list.push(chances[j] + '' + j);
}
list.sort(function(a, b) {
var n1 = parseFloat(a.substring(0, a.length - 1));
var n2 = parseFloat(b.substring(0, b.length - 1));
return n2 - n1;
});
var c = 0;
var r = Math.random();
for(var i in list) {
var prob = list[i];
for(var l in list) {
var prob = list[l];
c += parseFloat(prob.substring(0,prob.length - 1));
if(r < c) {
return prob.charAt(prob.length - 1);
}
}
return World.TILE.BARRENS;
},
markVisited: function(x, y) {
World.state.map[x][y] = World.state.map[x][y] + '!';
},
drawMap: function() {
var map = $('#map');
if(map.length === 0) {
@@ -800,7 +870,7 @@ var World = {
}
map.html(mapString);
},
die: function() {
if(!World.dead) {
World.dead = true;
@@ -811,6 +881,7 @@ var World = {
Notifications.notify(World, _('the world fades'));
World.state = null;
Path.outfit = {};
$SM.remove('outfit');
$('#outerSlider').animate({opacity: '0'}, 600, 'linear', function() {
$('#outerSlider').css('left', '0px');
$('#locationSlider').css('left', '0px');
@@ -818,19 +889,22 @@ var World = {
Engine.activeModule = Room;
$('div.headerButton').removeClass('selected');
Room.tab.addClass('selected');
Engine.setTimeout(function(){
Room.onArrival();
Engine.setTimeout(function(){
Room.onArrival();
$('#outerSlider').animate({opacity:'1'}, 600, 'linear');
Button.cooldown($('#embarkButton'));
Engine.keyLock = false;
Engine.tabNavigation = true;
}, 2000, true);
});
}
},
goHome: function() {
// Home safe! Commit the changes.
$SM.setM('game.world', World.state);
World.testMap();
if(World.state.sulphurmine && $SM.get('game.buildings["sulphur mine"]', true) === 0) {
$SM.add('game.buildings["sulphur mine"]', 1);
Engine.event('progress', 'sulphur mine');
@@ -848,30 +922,29 @@ var World = {
Engine.event('progress', 'ship');
}
World.state = null;
// Clear the embark cooldown
var btn = Button.clearCooldown($('#embarkButton'));
if(Path.outfit['cured meat'] > 0) {
Button.setDisabled(btn, false);
Button.setDisabled($('#embarkButton'), false);
}
for(var k in Path.outfit) {
$SM.add('stores["'+k+'"]', Path.outfit[k]);
if(World.leaveItAtHome(k)) {
Path.outfit[k] = 0;
}
}
$('#outerSlider').animate({left: '0px'}, 300);
Engine.activeModule = Path;
Path.onArrival();
Engine.restoreNavigation = true;
},
leaveItAtHome: function(thing) {
return thing != 'cured meat' && thing != 'bullets' && thing != 'energy cell' && thing != 'charm' && thing != 'medicine' &&
typeof World.Weapons[thing] == 'undefined' && typeof Room.Craftables[thing] == 'undefined';
},
getMaxHealth: function() {
if($SM.get('stores["s armour"]', true) > 0) {
return World.BASE_HEALTH + 35;
@@ -882,14 +955,14 @@ var World = {
}
return World.BASE_HEALTH;
},
getHitChance: function() {
if($SM.hasPerk('precise')) {
return World.BASE_HIT_CHANCE + 0.1;
}
return World.BASE_HIT_CHANCE;
},
getMaxWater: function() {
if($SM.get('stores["water tank"]', true) > 0) {
return World.BASE_WATER + 50;
@@ -900,22 +973,25 @@ var World = {
}
return World.BASE_WATER;
},
outpostUsed: function(x, y) {
x = typeof x == 'number' ? x : World.curPos[0];
y = typeof y == 'number' ? y : World.curPos[1];
var used = World.usedOutposts[x + ',' + y];
return typeof used != 'undefined' && used === true;
},
useOutpost: function() {
Notifications.notify(null, _('water replenished'));
World.setWater(World.getMaxWater());
// Mark this outpost as used
World.usedOutposts[World.curPos[0] + ',' + World.curPos[1]] = true;
},
onArrival: function() {
Engine.tabNavigation = false;
// Clear the embark cooldown
Button.clearCooldown($('#embarkButton'));
Engine.keyLock = false;
// Explore in a temporary world-state. We'll commit the changes if you return home safe.
World.state = $.extend(true, {}, $SM.get('game.world'));
@@ -934,16 +1010,16 @@ var World = {
World.updateSupplies();
$('#bagspace-world').width($('#map').width());
},
setTitle: function() {
document.title = _('A Barren World');
},
copyPos: function(pos) {
return [pos[0], pos[1]];
},
handleStateUpdates: function(e){
}
};