Merge pull request #16 from doublespeakgames/master

Massive update 2015-06-27
This commit is contained in:
Andrea Rendine
2015-06-27 18:19:09 +02:00
23 changed files with 3743 additions and 301 deletions
+21 -22
View File
@@ -7,32 +7,31 @@ a minimalist text adventure game for your browser
[Click to play](http://adarkroom.doublespeakgames.com)
<table>
<tr><th colspan=4>Available Languages</tr>
<tr>
<th colspan=2>Available Languages
<td><a href="http://adarkroom.doublespeakgames.com/?lang=zh_cn">Chinese</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=en">English</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=fr">French</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=de">German</a></td>
</tr>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=zh_cn">Chinese</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=en">English</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=it">Italian</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ja">Japanese</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ko">Korean</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=nb">Norwegian</a></td>
</tr>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=fr">French</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=de">German</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pl">Polish</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pt">Portuguese</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ru">Russian</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=es">Spanish</a></td>
</tr>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=it">Italian</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ja">Japanese</a>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ko">Korean</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=nb">Norwegian</a>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pl">Polish</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pt">Portuguese</a>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=ru">Russian</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=es">Spanish</a>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=sv">Swedish</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=tr">Turkish</a>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=uk">Ukrainian</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=vi">Vietnamese</a>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=sv">Swedish</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=tr">Turkish</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=uk">Ukrainian</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=vi">Vietnamese</a></td>
</tr>
</table>
or play the latest on [GitHub](http://doublespeakgames.github.io/adarkroom)
+19
View File
@@ -0,0 +1,19 @@
Contributing to A Dark Room
===========
Hello and welcome, contributors both new, and old.
Like most projects on GitHub, A Dark Room is open source, and thrives off contributions from members of the community. We appreciate any pull requests or issues that you may open in the project, no matter the size.
<br><hr>
Before contributing to the project, there are a few things you should look over to ensure your contribution is done correctly.
Most of the projects code is written in JavaScript. We would prefer all submitted JavaScript be [JSHint](http://jshint.com/) compliant.
> "JSHint is a community-driven tool to detect errors and potential problems in JavaScript code and to enforce your team's coding conventions."
<br><br><br>
Before opening a new issue, try to check the projects [issues](https://github.com/doublespeakgames/adarkroom/issues) or [wiki](https://github.com/doublespeakgames/adarkroom/wiki).
Doing so will help prevent needless double issues.
<br>Most of the time you will be able to find what you are looking for in one of those places. If not, please open an issue and describe your problem with as much detail as possible.
Lastly, be nice, patient, open to new ideas, and have some fun!
+1 -1
View File
@@ -31,7 +31,7 @@ div#saveNotify {
}
div.tooltip {
background-color: #111;
background-color: #171813;
border: 1px solid black;
box-shadow: -1px 3px 2px #111;
}
+6 -6
View File
@@ -83,12 +83,12 @@ div#header {
span.customSelectOptions {
margin: 0;
width: 80px;
width: 120px;
}
.customSelectOptions > ul {
max-height: 20px;
width: 80px;
width: 120px;
overflow: hidden;
-webkit-transition: max-height 1s;
transition: max-height 1s;
@@ -101,7 +101,7 @@ span.customSelectOptions {
}
.customSelectOptions > ul:hover {
max-height: 400px;
max-height: 450px;
}
.customSelectOptions > ul > li {
@@ -258,7 +258,7 @@ div.button div.cooldown {
.upBtn, .dnBtn, .upManyBtn, .dnManyBtn {
position: absolute;
width: 14px;
height: 15px;
height: 12px;
cursor: pointer;
}
@@ -288,7 +288,7 @@ div.button div.cooldown {
content: " ";
height: 0;
width: 0;
bottom: 4px;
bottom: 2px;
}
.upBtn:after, .upManyBtn:after {
@@ -318,7 +318,7 @@ div.button div.cooldown {
content: " ";
height: 0;
width: 0;
top: 4px;
top: 2px;
}
/* Overall size of buttons controlled by this style
+2 -6
View File
@@ -22,15 +22,11 @@ div#population {
div#village:before {
position: absolute;
background: white;
content: "village";
content: attr(data-legend);
left: 8px;
top: -13px;
}
div#village.noHuts:before {
content: "forest";
}
div#workers {
position:absolute;
top: -4px;
@@ -61,4 +57,4 @@ div#workers {
div.storeRow div.tooltip {
width: 160px;
}
}
+3 -10
View File
@@ -6,9 +6,9 @@
padding: 5px 10px;
}
div#outfitting:before {
div#outfitting:before ,div#perks:before {
content: attr(data-legend);
position: absolute;
content: "supplies";
top: -13px;
background-color: white;
}
@@ -50,17 +50,10 @@ div#perks {
width: 200px;
}
div#perks:before {
position: absolute;
content: "perks";
top: -13px;
background-color: white;
}
div.perkRow {
position: relative;
}
div.perkRow .row_key {
float: none;
}
}
+10 -30
View File
@@ -4,8 +4,8 @@ div#buildBtns {
left: 0px;
}
div#buildBtns:before {
content: "build:";
div#buildBtns:before, div#craftBtns:before, div#buyBtns:before {
content: attr(data-legend);
position: relative;
top: -5px;
}
@@ -16,30 +16,26 @@ div#craftBtns {
left: 150px;
}
div#craftBtns:before {
content: "craft:";
position: relative;
top: -5px;
}
div#buyBtns {
position: absolute;
top: 50px;
left: 300px;
}
div#buyBtns:before {
content: "buy:";
position: relative;
top: -5px;
}
div#storesContainer {
position: absolute;
top: 0px;
right: 0px;
}
div#stores:before, div#weapons:before {
position: absolute;
background: white;
content: attr(data-legend);
left: 8px;
top: -13px;
}
div#stores {
position: relative;
z-index:10;
@@ -53,14 +49,6 @@ div.storeRow {
position: relative;
}
div#stores:before {
position: absolute;
background: white;
content: "stores";
left: 8px;
top: -13px;
}
div#weapons {
margin-top: 15px;
position: relative;
@@ -70,11 +58,3 @@ div#weapons {
padding: 5px 10px;
width: 200px;
}
div#weapons:before {
position: absolute;
background: white;
content: "weapons";
left: 8px;
top: -13px;
}
+1 -1
View File
@@ -872,7 +872,7 @@ msgstr "ein handelsposten würde tauschgeschäfte fördern"
msgid ""
"now the nomads have a place to set up shop, they might stick around a while"
msgstr ""
"jetzt haben die nomaden einen ort zum handeln, sie bleiben villeicht eine "
"jetzt haben die nomaden einen ort zum handeln, sie bleiben vielleicht eine "
"weile"
#: script/room.js:94
+1
View File
@@ -9,6 +9,7 @@ var langs = {
'nb':'norsk',
'pl':'polski',
'pt':'português',
'pt_br':'português (brasil)',
'ru':'русский',
'sv':'svenska',
'tr':'türkçe',
+3
View File
@@ -0,0 +1,3 @@
.button{width: 100px !important;}
#outsidePanel .button{width: 115px !important;}
.eventPanel .button {width: 122px !important;}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+54 -41
View File
@@ -275,7 +275,7 @@
buttons: {
'export': {
text: _('export'),
onChoose: Engine.export64
nextScene: {1: 'inputExport'}
},
'import': {
text: _('import'),
@@ -287,6 +287,18 @@
}
}
},
'inputExport': {
text: [_('save this.')],
textarea: Engine.export64(),
readonly: true,
buttons: {
'done': {
text: _('got it'),
nextScene: 'end',
onChoose: Engine.disableSelection
}
}
},
'confirm': {
text: [
_('are you sure?'),
@@ -301,7 +313,7 @@
},
'no': {
text: _('no'),
nextScene: 'end'
nextScene: {1: 'start'}
}
}
},
@@ -335,26 +347,8 @@
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) {
@@ -599,6 +593,10 @@
//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) {
@@ -614,9 +612,7 @@
Engine.pressed = false;
if(Engine.activeModule.keyUp) {
Engine.activeModule.keyUp(e);
}
else
{
} else {
switch(e.which) {
case 38: // Up
case 87:
@@ -634,33 +630,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;
},
@@ -722,6 +725,16 @@
}
},
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 ){
+254 -91
View File
@@ -31,10 +31,14 @@ var Events = {
//subscribe to stateUpdates
$.Dispatch('stateUpdate').subscribe(Events.handleStateUpdates);
//check for stored delayed events
Events.initDelay();
},
options: {}, // Nothing for now
delayState: 'wait',
activeScene: null,
loadScene: function(name) {
@@ -215,6 +219,8 @@ var Events = {
w.data('hp', hp);
Events.updateFighterDiv(w);
Events.drawFloatText('+' + World.meatHeal(), '#wanderer .hp');
var takeETbutton = Events.setTakeAll();
Events.canLeave(takeETbutton);
}
}
},
@@ -237,6 +243,8 @@ var Events = {
w.data('hp', hp);
Events.updateFighterDiv(w);
Events.drawFloatText('+' + World.medsHeal(), '#wanderer .hp');
var takeETbutton = Events.setTakeAll();
Events.canLeave(takeETbutton);
}
}
},
@@ -448,23 +456,23 @@ var Events = {
Engine.setTimeout(function() {
try {
var scene = Events.activeEvent().scenes[Events.activeScene];
var leaveBtn = false;
var desc = $('#description', Events.eventPanel());
var btns = $('#buttons', Events.eventPanel());
desc.empty();
btns.empty();
$('<div>').text(scene.deathMessage).appendTo(desc);
Events.drawLoot(scene.loot);
var takeETbtn = Events.drawLoot(scene.loot);
if(scene.buttons) {
// Draw the buttons
Events.drawButtons(scene);
leaveBtn = Events.drawButtons(scene);
} else {
Button.cooldown(new Button.Button({
leaveBtn = new Button.Button({
id: 'leaveBtn',
cooldown: Events._LEAVE_COOLDOWN,
click: function() {
var scene = Events.activeEvent().scenes[Events.activeScene];
if(scene.nextScene && scene.nextScene != 'end') {
Events.loadScene(scene.nextScene);
} else {
@@ -472,13 +480,15 @@ var Events = {
}
},
text: _('leave')
}).appendTo(btns));
});
Button.cooldown(leaveBtn.appendTo(btns));
Events.createEatMeatButton(0).appendTo(btns);
if((Path.outfit['medicine'] || 0) !== 0) {
Events.createUseMedsButton(0).appendTo(btns);
}
}
Events.allowLeave(takeETbtn, leaveBtn);
} catch(e) {
// It is possible to die and win if the timing is perfect. Just let it fail.
}
@@ -486,106 +496,212 @@ var Events = {
});
},
drawDrop:function(btn) {
var name = btn.attr('id').substring(5).replace('-', ' ');
var needsAppend = false;
var weight = Path.getWeight(name);
var freeSpace = Path.getFreeSpace();
if(weight > freeSpace) {
// Draw the drop menu
Engine.log('drop menu');
if($('#dropMenu').length){
var dropMenu = $('#dropMenu');
$('#dropMenu').empty();
} else {
var dropMenu = $('<div>').attr({'id': 'dropMenu', 'data-legend': _('drop:')});
needsAppend = true;
}
for(var k in Path.outfit) {
if(name == k) continue;
var itemWeight = Path.getWeight(k);
if(itemWeight > 0) {
var numToDrop = Math.ceil((weight - freeSpace) / itemWeight);
if(numToDrop > Path.outfit[k]) {
numToDrop = Path.outfit[k];
}
if(numToDrop > 0) {
var dropRow = $('<div>').attr('id', 'drop_' + k.replace(' ', '-'))
.text(_(k) + ' x' + numToDrop)
.data('thing', k)
.data('num', numToDrop)
.click(Events.dropStuff)
.mouseenter(function(e){
e.stopPropagation();
});
dropRow.appendTo(dropMenu);
}
}
}
$('<div>').attr('id','no_drop')
.text(_('nothing'))
.mouseenter(function(e){
e.stopPropagation();
})
.click(function(e){
e.stopPropagation();
dropMenu.remove();
})
.appendTo(dropMenu);
if(needsAppend){
dropMenu.appendTo(btn);
}
btn.one("mouseleave", function() {
$('#dropMenu').remove();
});
}
},
drawLootRow: function(name, num){
var id = name.replace(' ', '-');
var lootRow = $('<div>').attr('id','loot_' + id).data('item', name).addClass('lootRow');
var take = new Button.Button({
id: 'take_' + id,
text: _(name) + ' [' + num + ']',
click: Events.getLoot
}).addClass('lootTake').data('numLeft', num).appendTo(lootRow);
take.mouseenter(function(){
Events.drawDrop(take);
});
var takeall = new Button.Button({
id: 'all_take_' + id,
text: _('take') + ' ',
click: Events.takeAll
}).addClass('lootTakeAll').appendTo(lootRow);
$('<span>').insertBefore(takeall.children('.cooldown'));
$('<div>').addClass('clear').appendTo(lootRow);
return lootRow;
},
drawLoot: function(lootList) {
var desc = $('#description', Events.eventPanel());
var lootButtons = $('<div>').attr('id', 'lootButtons');
var lootButtons = $('<div>').attr({'id': 'lootButtons', 'data-legend': _('take:')});
for(var k in lootList) {
var loot = lootList[k];
if(Math.random() < loot.chance) {
var num = Math.floor(Math.random() * (loot.max - loot.min)) + loot.min;
new Button.Button({
id: 'loot_' + k.replace(' ', '-'),
text: _(k) + ' [' + num + ']',
click: Events.getLoot
}).data('numLeft', num).appendTo(lootButtons);
var lootRow = Events.drawLootRow(k, num);
lootRow.appendTo(lootButtons);
}
}
$('<div>').addClass('clear').appendTo(lootButtons);
if(lootButtons.children().length > 1) {
lootButtons.appendTo(desc);
var takeAll = new Button.Button({
id: 'loot_take_all',
text: _('take all'),
click: Events.takeAllLoot
}).addClass('take-all-button').appendTo(lootButtons);
lootButtons.appendTo(desc);
if(lootButtons.children().length > 0) {
var takeETrow = $('<div>').addClass('takeETrow');
var takeET = new Button.Button({
id: 'loot_takeEverything',
text: '',
click: Events.takeEverything
}).appendTo(takeETrow);
$('<span>').insertBefore(takeET.children('.cooldown'));
$('<div>').addClass('clear').appendTo(takeETrow);
takeETrow.appendTo(lootButtons);
Events.setTakeAll(lootButtons);
} else {
var noLoot = $('<div>').addClass('noLoot').text( _('nothing to take') );
noLoot.appendTo(lootButtons);
}
return takeET || false;
},
setTakeAll: function(lootButtons){
var lootButtons = lootButtons || $('#lootButtons');
var canTakeSomething = false;
var free = Path.getFreeSpace();
var takeETbutton = lootButtons.find('#loot_takeEverything');
lootButtons.children('.lootRow').each(function(i){
var name = $(this).data('item');
var take = $(this).children('.lootTake').first();
var takeAll = $(this).children('.lootTakeAll').first();
var numLeft = take.data('numLeft');
var num = Math.min(Math.floor(Path.getFreeSpace() / Path.getWeight(name)), numLeft);
takeAll.data('numLeft', num);
free -= numLeft * Path.getWeight(name);
if(num > 0){
takeAll.removeClass('disabled');
canTakeSomething = true;
} else {
takeAll.addClass('disabled');
}
if(num < numLeft){
takeAll.children('span').first().text(num);
} else {
takeAll.children('span').first().text(_('all'));
}
});
if(canTakeSomething){
takeETbutton.removeClass('disabled');
} else {
takeETbutton.addClass('disabled');
}
takeETbutton.data('canTakeEverything', (free >= 0) ? true : false);
return takeETbutton;
},
allowLeave: function(takeETbtn, leaveBtn){
if(takeETbtn){
if(leaveBtn){
takeETbtn.data('leaveBtn', leaveBtn);
}
Events.canLeave(takeETbtn);
}
},
takeAllLoot: function(){
var stoppedEarly = false;
$('#lootButtons')
.children('.button')
.each(function(){
if( $(this).hasClass('take-all-button') ) {
return;
}
var weight = $(this).data('numLeft') * Path.getWeight($(this).attr('id').substring(5).replace('-', ' '));
while( $(this).data('numLeft') > 0 && weight < Path.getFreeSpace() ){
$(this).click();
}
if(weight > Path.getFreeSpace()){
stoppedEarly = true;
return;
}
});
if( !stoppedEarly ){
$('#leave').click();
$('#leaveBtn').click();
canLeave: function(btn){
var basetext = _('take everything');
var textbox = btn.children('span');
var takeAndLeave = (btn.data('leaveBtn')) ? btn.data('canTakeEverything') : false;
if(takeAndLeave){
textbox.text( basetext + _(' and ') + _('leave') );
btn.data('canLeave', true);
} else {
textbox.text( basetext );
btn.data('canLeave', false)
}
},
dropStuff: function(e) {
e.stopPropagation();
var btn = $(this);
var target = btn.closest('.button');
var thing = btn.data('thing');
var id = 'take_' + thing.replace(' ', '-');
var num = btn.data('num');
var lootButtons = $('#lootButtons');
Engine.log('dropping ' + num + ' ' + thing);
var lootBtn = $('#loot_' + thing.replace(' ', '-'), lootButtons);
var lootBtn = $('#' + id, lootButtons);
if(lootBtn.length > 0) {
var curNum = lootBtn.data('numLeft');
curNum += num;
lootBtn.text(_(thing) + ' [' + curNum + ']').data('numLeft', curNum);
} else {
new Button.Button({
id: 'loot_' + thing.replace(' ', '-'),
text: _(thing) + ' [' + num + ']',
click: Events.getLoot
}).data('numLeft', num).insertBefore($('.clear', lootButtons));
var lootRow = Events.drawLootRow(thing, num);
lootRow.insertBefore($('.takeETrow', lootButtons));
}
Path.outfit[thing] -= num;
Events.getLoot(btn.closest('.button'));
Events.getLoot(target);
World.updateSupplies();
},
getLoot: function(btn) {
getLoot: function(btn, skipButtonSet) {
var name = btn.attr('id').substring(5).replace('-', ' ');
if(btn.data('numLeft') > 0) {
var skipButtonSet = skipButtonSet || false;
var weight = Path.getWeight(name);
var freeSpace = Path.getFreeSpace();
if(weight <= freeSpace) {
var num = btn.data('numLeft');
num--;
btn.data('numLeft', num);
// #dropMenu gets removed by this.
btn.text(_(name) + ' [' + num + ']');
if(num === 0) {
Button.setDisabled(btn);
btn.animate({'opacity':0}, 300, 'linear', function() {
$(this).remove();
$(this).parent().remove();
if($('#lootButtons').children().length == 1) {
$('#lootButtons').remove();
}
});
} else {
// #dropMenu gets removed by this.
btn.text(_(name) + ' [' + num + ']');
}
var curNum = Path.outfit[name];
curNum = typeof curNum == 'number' ? curNum : 0;
@@ -593,39 +709,33 @@ var Events = {
Path.outfit[name] = curNum;
World.updateSupplies();
// Update weight and free space variables so we can decide
// whether or not to bring up/update the drop menu.
weight = Path.getWeight(name);
freeSpace = Path.getFreeSpace();
}
if(weight > freeSpace && btn.data('numLeft') > 0) {
// Draw the drop menu
Engine.log('drop menu');
$('#dropMenu').remove();
var dropMenu = $('<div>').attr('id', 'dropMenu');
for(var k in Path.outfit) {
var itemWeight = Path.getWeight(k);
if(itemWeight > 0) {
var numToDrop = Math.ceil((weight - freeSpace) / itemWeight);
if(numToDrop > Path.outfit[k]) {
numToDrop = Path.outfit[k];
}
if(numToDrop > 0) {
var dropRow = $('<div>').attr('id', 'drop_' + k.replace(' ', '-'))
.text(_(k) + ' x' + numToDrop)
.data('thing', k)
.data('num', numToDrop)
.click(Events.dropStuff);
dropRow.appendTo(dropMenu);
}
}
if(!skipButtonSet){
Events.setTakeAll();
}
dropMenu.appendTo(btn);
btn.one("mouseleave", function() {
$('#dropMenu').remove();
});
}
if(!skipButtonSet){
Events.drawDrop(btn);
}
}
},
takeAll: function(btn){
var target = $('#'+ btn.attr('id').substring(4));
for(var k = 0; k < btn.data('numLeft'); k++){
Events.getLoot(target, true);
}
Events.setTakeAll();
},
takeEverything: function(btn){
$('#lootButtons').children('.lootRow').each(function(i){
var target = $(this).children('.lootTakeAll').first();
if(!target.hasClass('disabled')){
Events.takeAll(target);
}
});
if(btn.data('canLeave')){
btn.data('leaveBtn').click();
}
},
@@ -642,6 +752,7 @@ var Events = {
startStory: function(scene) {
// Write the text
var desc = $('#description', Events.eventPanel());
var leaveBtn = false;
for(var i in scene.text) {
$('<div>').text(scene.text[i]).appendTo(desc);
}
@@ -651,19 +762,23 @@ var Events = {
if(scene.readonly) {
ta.attr('readonly', true);
}
Engine.autoSelect('#description textarea');
}
// Draw any loot
if(scene.loot) {
Events.drawLoot(scene.loot);
var takeETbtn = Events.drawLoot(scene.loot);
}
// Draw the buttons
Events.drawButtons(scene);
leaveBtn = Events.drawButtons(scene);
Events.allowLeave(takeETbtn, leaveBtn);
},
drawButtons: function(scene) {
var btns = $('#buttons', Events.eventPanel());
var btnsList = [];
for(var id in scene.buttons) {
var info = scene.buttons[id];
var b = new Button.Button({
@@ -679,9 +794,11 @@ var Events = {
if(typeof info.cooldown == 'number') {
Button.cooldown(b);
}
btnsList.push(b);
}
Events.updateButtons();
return (btnsList.length == 1) ? btnsList[0] : false;
},
updateButtons: function() {
@@ -837,6 +954,7 @@ var Events = {
if(event) {
Engine.event('game event', 'event');
Engine.keyLock = true;
Engine.tabNavigation = false;
Events.eventStack.unshift(event);
event.eventPanel = $('<div>').attr('id', 'event').addClass('eventPanel').css('opacity', '0');
if(options != null && options.width != null) {
@@ -869,6 +987,7 @@ var Events = {
Events.eventStack.shift();
Engine.log(Events.eventStack.length + ' events remaining');
Engine.keyLock = false;
Engine.tabNavigation = true;
if (Events.BLINK_INTERVAL) {
Events.stopTitleBlink();
}
@@ -881,5 +1000,49 @@ var Events = {
if((e.category == 'stores' || e.category == 'income') && Events.activeEvent() != null){
Events.updateButtons();
}
},
initDelay: function(){
if($SM.get(Events.delayState)){
Events.recallDelay(Events.delayState, Events);
}
},
recallDelay: function(stateName, target){
var state = $SM.get(stateName);
for(var i in state){
if(typeof(state[i]) == 'object'){
Events.recallDelay(stateName +'["'+ i +'"]', target[i]);
} else {
if(typeof target[i] == 'function'){
target[i]();
} else {
$SM.remove(stateName)
}
}
}
if($.isEmptyObject(state)){
$SM.remove(stateName);
}
},
saveDelay: function(action, stateName, delay){
var state = Events.delayState + '.' + stateName;
if(delay){
$SM.set(state, delay);
} else {
var delay = $SM.get(state, true)
}
var time = Engine.setInterval(function(){
// update state every half second
$SM.set(state, ($SM.get(state) - 0.5), true);
}, 500);
Engine.setTimeout(function(){
// outcome realizes. erase countdown
window.clearInterval(time);
$SM.remove(state);
$SM.removeBranch(Events.delayState);
action();
}, delay * 1000);
}
};
+14 -14
View File
@@ -123,8 +123,8 @@ 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: 'E',
damage: 5,
@@ -165,8 +165,8 @@ 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: 'T',
damage: 3,
@@ -202,8 +202,8 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'scavenger',
enemyName: _('scavenger'),
enemy: 'scavenger',
enemyName: _('scavenger'),
deathMessage: _('the scavenger is dead'),
chara: 'E',
damage: 4,
@@ -244,8 +244,8 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'lizard',
enemyName: _('lizard'),
enemy: 'lizard',
enemyName: _('lizard'),
deathMessage: _('the lizard is dead'),
chara: 'T',
damage: 5,
@@ -282,8 +282,8 @@ 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: 'T',
damage: 6,
@@ -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,8 +362,8 @@ Events.Encounters = [
scenes: {
'start': {
combat: true,
enemy: 'sniper',
enemyName: _('sniper'),
enemy: 'sniper',
enemyName: _('sniper'),
deathMessage: _('the sniper is dead'),
chara: 'D',
damage: 15,
+15 -7
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,7 +65,7 @@ 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;
@@ -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: {
@@ -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);
@@ -273,6 +280,7 @@ Events.Outside = [
buttons: {
'end': {
text: _('go home'),
notification: _('warfare is bloodthirsty'),
nextScene: 'end'
}
}
+44 -28
View File
@@ -273,15 +273,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 +289,20 @@ Events.Room = [
}
}
},
'100wood': {
'wood100': {
text: [
_('the wanderer leaves, cart loaded with wood')
],
action: function(delay) {
var delay = delay || 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 +312,20 @@ Events.Room = [
}
}
},
'500wood': {
'wood500': {
text: [
_('the wanderer leaves, cart loaded with wood')
],
action: function(delay) {
var delay = delay || 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: {
@@ -344,15 +352,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 +368,20 @@ Events.Room = [
}
}
},
'100fur': {
'fur100': {
text: [
_('the wanderer leaves, cart loaded with furs')
],
action: function(delay) {
var delay = delay || false;
Events.saveDelay(function() {
$SM.add('stores.wood', 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 +391,20 @@ Events.Room = [
}
}
},
'500fur': {
'fur500': {
text: [
_('the wanderer leaves, cart loaded with furs')
],
action: function(delay) {
var delay = delay || false;
Events.saveDelay(function() {
$SM.add('stores.wood', 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: {
-15
View File
@@ -66,19 +66,4 @@
];
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'));
})();
+42 -14
View File
@@ -8,6 +8,7 @@ var Outside = {
_GATHER_DELAY: 60,
_TRAPS_DELAY: 90,
_POP_DELAY: [0.5, 3],
_HUT_ROOM: 4,
_INCOME: {
'gatherer': {
@@ -173,7 +174,7 @@ var Outside = {
},
getMaxPopulation: function() {
return $SM.get('game.buildings["hut"]', true) * 4;
return $SM.get('game.buildings["hut"]', true) * Outside._HUT_ROOM;
},
increasePopulation: function() {
@@ -219,6 +220,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');
@@ -242,6 +273,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) {
@@ -250,23 +282,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 {
@@ -324,9 +352,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);
}
@@ -424,10 +452,10 @@ 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) {
+8 -9
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(' ', '-');
@@ -174,6 +174,7 @@ var Path = {
}, 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];
@@ -190,18 +191,16 @@ var Path = {
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);
+7 -5
View File
@@ -752,13 +752,15 @@ var Room = {
var needsAppend = 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(weapons.length === 0) {
weapons = $('<div>').attr({
id: 'weapons'
'id': 'weapons',
'data-legend': _('weapons')
}).css('opacity', 0);
wNeedsAppend = true;
}
@@ -1010,21 +1012,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;
}
+17 -1
View File
@@ -37,7 +37,8 @@ var StateManager = {
'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'
'config',
'wait' // mysterious wanderers are coming back
];
for(var which in cats) {
@@ -192,6 +193,21 @@ var StateManager = {
}
},
removeBranch(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){
+3
View File
@@ -823,6 +823,7 @@ var World = {
$('#outerSlider').animate({opacity:'1'}, 600, 'linear');
Button.cooldown($('#embarkButton'));
Engine.keyLock = false;
Engine.tabNavigation = true;
}, 2000, true);
});
}
@@ -865,6 +866,7 @@ var World = {
$('#outerSlider').animate({left: '0px'}, 300);
Engine.activeModule = Path;
Path.onArrival();
Engine.restoreNavigation = true;
},
leaveItAtHome: function(thing) {
@@ -916,6 +918,7 @@ var World = {
},
onArrival: function() {
Engine.tabNavigation = false;
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'));