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
+1
View File
@@ -2,3 +2,4 @@
*.TODO
*.mo
*.swp
.idea
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>A Dark Room</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>
+35 -12
View File
@@ -6,17 +6,40 @@ a minimalist text adventure game for your browser
[Click to play](http://adarkroom.doublespeakgames.com)
Available | Languages
--------- | ---------
[Chinese](http://adarkroom.doublespeakgames.com/?lang=zh_cn) | [English](http://adarkroom.doublespeakgames.com/?lang=en)
[French](http://adarkroom.doublespeakgames.com/?lang=fr) | [German](http://adarkroom.doublespeakgames.com/?lang=de)
[Italian](http://adarkroom.doublespeakgames.com/?lang=it) | [Japanese](http://adarkroom.doublespeakgames.com/?lang=ja)
[Korean](http://adarkroom.doublespeakgames.com/?lang=ko) | [Norwegian](http://adarkroom.doublespeakgames.com/?lang=nb)
[Polish](http://adarkroom.doublespeakgames.com/?lang=pl) | [Portuguese](http://adarkroom.doublespeakgames.com/?lang=pt)
[Russian](http://adarkroom.doublespeakgames.com/?lang=ru) | [Spanish](http://adarkroom.doublespeakgames.com/?lang=es)
[Swedish](http://adarkroom.doublespeakgames.com/?lang=sv) | [Turkish](http://adarkroom.doublespeakgames.com/?lang=tr)
[Ukrainian](http://adarkroom.doublespeakgames.com/?lang=uk) | [Vietnamese] (http://adarkroom.doublespeakgames.com/?lang=vi)
<table>
<tr><th colspan=4>Available Languages</tr>
<tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=zh_cn">Chinese (Simplified)</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=zh_tw">Chinese (Traditional)</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>
</tr><tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=de">German</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=el">Greek</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=id">Indonesian</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=it">Italian</a></td>
</tr><tr>
<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>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pl">Polish</a></td>
</tr><tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pt">Portuguese</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=pt_br">Portuguese (Brazil)</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=sv">Swedish</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=th">Thai</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>
</tr><tr>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=vi">Vietnamese</a></td>
<td><a href="http://adarkroom.doublespeakgames.com/?lang=lt_LT">Lithuanian</a></td>
</tr>
</table>
or play the latest on [GitHub](http://continuities.github.io/adarkroom)
or play the latest on [GitHub](http://doublespeakgames.github.io/adarkroom)
[![app store](http://i.imgur.com/M6jlJQH.png)](https://itunes.apple.com/us/app/a-dark-room/id736683061)
<a href="https://itunes.apple.com/us/app/a-dark-room/id736683061"><img src="http://i.imgur.com/DMdnDYq.png" height="50"></a>
<a href="https://play.google.com/store/apps/details?id=com.yourcompany.adarkroom"><img src="http://i.imgur.com/bLWWj4r.png" height="50"></a>
+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
@@ -27,7 +27,7 @@ div#saveNotify {
}
div.tooltip {
background-color: #111;
background-color: #171813;
border: 1px solid black;
box-shadow: -1px 3px 2px #111;
}
+43 -24
View File
@@ -69,6 +69,7 @@ div#header {
right: 10px;
bottom: 10px;
color: #666;
z-index: 10;
}
.menu span {
@@ -83,12 +84,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;
@@ -100,7 +101,7 @@ span.customSelectOptions {
}
.customSelectOptions > ul:hover {
max-height: 400px;
max-height: 600px;
}
.customSelectOptions > ul > li {
@@ -126,6 +127,10 @@ span.customSelectOptions {
text-decoration: underline;
}
.menu .appStore {
font-weight: bold;
}
div.headerButton {
font-size: 18px;
cursor: pointer;
@@ -181,6 +186,10 @@ div.row_val {
float: right;
}
div.total {
font-weight: bold;
}
/* Notifications */
div#notifications {
@@ -257,7 +266,7 @@ div.button div.cooldown {
.upBtn, .dnBtn, .upManyBtn, .dnManyBtn {
position: absolute;
width: 14px;
height: 15px;
height: 12px;
cursor: pointer;
}
@@ -266,7 +275,7 @@ div.button div.cooldown {
}
.upManyBtn, .dnManyBtn {
right: -11px;
right: -15px;
}
.upBtn.disabled, .dnBtn.disabled, .upManyBtn.disabled, .dnManyBtn.disabled {
@@ -274,11 +283,11 @@ div.button div.cooldown {
}
.upBtn {
top: -2px;
top: -3px;
}
.upManyBtn {
top: -2px;
top: -3px;
}
.upBtn:after, .upBtn:before, .upManyBtn:after, .upManyBtn:before {
@@ -287,7 +296,7 @@ div.button div.cooldown {
content: " ";
height: 0;
width: 0;
bottom: 4px;
bottom: 2px;
}
.upBtn:after, .upManyBtn:after {
@@ -317,27 +326,33 @@ div.button div.cooldown {
content: " ";
height: 0;
width: 0;
top: 4px;
top: 2px;
}
/* Overall size of buttons controlled by this style
border-width and margin-left should be the same. */
.upBtn:before, .dnBtn:before, .upManyBtn:before, .dnManyBtn:before {
border-width: 6px;
left: 50%;
margin-left: -6px;
}
/* Thickness of up/down button lines controlled by this style.
border-width and margin-left should be the same.
Thickness = :before.border-width minus :after.border-width */
.upBtn:after, .dnBtn:after {
border-width: 4px;
left: 50%;
margin-left: -4px;
}
/* See comment on .upBtn:after, .dnBtn:after */
.upManyBtn:after, .dnManyBtn:after {
border-width: 3px;
left: 50%;
margin-left: -3px;
}
.upBtn:before, .dnBtn:before, .upManyBtn:before, .dnManyBtn:before {
border-width: 5px;
left: 50%;
margin-left: -5px;
}
.upManyBtn:after, .dnManyBtn:after {
border-width: 2px;
left: 50%;
margin-left: -2px;
}
.dnBtn:after, .dnManyBtn:after {
border-color: white transparent transparent;
}
@@ -501,6 +516,10 @@ body.noMask #description {
padding-bottom: 20px;
}
.take-all-button {
float: none;
}
#buttons > .button {
margin: 0 5px 5px;
margin-right: 15px;
@@ -544,12 +563,12 @@ body.noMask #description {
#lootButtons {
padding-bottom: 0px !important;
margin: 20px 0 0 5px;
margin: 20px 0 5px 0;
position: relative;
}
#lootButtons:before {
content: "take:";
content: attr(data-legend);
position: absolute;
top: -25px;
left: 0px;
@@ -567,7 +586,7 @@ body.noMask #description {
}
#dropMenu:before {
content: "drop:";
content: attr(data-legend);
border-bottom: 1px solid black;
display: block;
margin-bottom: 5px;
+1 -5
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;
+2 -9
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,13 +50,6 @@ div#perks {
width: 200px;
}
div#perks:before {
position: absolute;
content: "perks";
top: -13px;
background-color: white;
}
div.perkRow {
position: relative;
}
+11 -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,32 +16,29 @@ 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;
border: 1px solid black;
cursor: default;
padding: 5px 10px;
@@ -52,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;
@@ -69,11 +58,3 @@ div#weapons {
padding: 5px 10px;
width: 200px;
}
div#weapons:before {
position: absolute;
background: white;
content: "weapons";
left: 8px;
top: -13px;
}
+2 -2
View File
@@ -144,11 +144,11 @@
position:relative;
}
.endGameRestart {
.endGameOption {
font-size: 32px;
cursor: pointer;
}
.endGameRestart:hover {
.endGameOption:hover {
text-decoration: underline;
}
BIN
View File
Binary file not shown.
+4 -4
View File
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/CreativeWork">
<html itemscope itemtype="https://schema.org/CreativeWork">
<head>
<meta charset="UTF-8"/>
<!--
@@ -8,7 +8,7 @@
A minimalist text adventure by Michael Townsend and all his friends.
Inspired by Candy Box (http://candies.aniwey.net/)
Contribute on GitHub! (https://github.com/Continuities/adarkroom/)
Contribute on GitHub! (https://github.com/doublespeakgames/adarkroom/)
-->
<title>A Dark Room</title>
<meta itemprop="description" name="description" property="og:description" content="A minimalist text adventure">
@@ -16,7 +16,7 @@
<meta itemprop="name" property="og:title" content="A Dark Room" />
<link rel="shortcut icon" href="favicon.ico" />
<link rel="image_src" href="img/adr.png" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://www.dropbox.com/static/api/dropbox-datastores-1.1-latest.js" type="text/javascript"></script>
<script>
if(!window.jQuery) {
@@ -90,7 +90,7 @@
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','http://www.google-analytics.com/analytics.js','ga');
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41314886-1', 'doublespeakgames.com');
ga('send', 'pageview');
+911 -813
View File
File diff suppressed because it is too large Load Diff
+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
+3313
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1703 -1591
View File
File diff suppressed because it is too large Load Diff
+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
+3477
View File
File diff suppressed because it is too large Load Diff
+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
+3304
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+2810 -1840
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -1,3 +1,18 @@
.button{width: 100px !important;}
#outsidePanel .button{width: 115px !important;}
.eventPanel .button {width: 122px !important;}
#lootButtons:before {
content: "prendre :" !important;
}
#dropMenu:before {
content: "déposer :" !important;
}
#hullRow {
width: 80px !important;
}
div#workers {
width: 160px !important;
}
div.button div.tooltip {
width: 120px !important;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+2935 -1941
View File
File diff suppressed because it is too large Load Diff
+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
+3554
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1063 -944
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+927 -809
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1423 -1296
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -1,18 +1,26 @@
var langs = {
'de':'deutsch',
'el':'ελληνικά',
'en':'english',
'eo':'esperanto',
'es':'español',
'fr':'français',
'id':'bahasa indonesia',
'it':'italiano',
'lv':'latviešu valoda',
'ja':'日本語',
'ko':'한국어',
'nb':'norsk',
'pl':'polski',
'lt_LT':'lietuvių',
'pt':'português',
'pt_br':'português (brasil)',
'ru':'русский',
'sv':'svenska',
'th':'ไทย',
'tr':'türkçe',
'uk':'українська',
'vi':'tiếng việt',
'zh_cn':'简体中文'
'zh_cn':'简体中文',
'zh_tw':'繁體中文'
};
+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
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+3308
View File
File diff suppressed because it is too large Load Diff
+926 -798
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
.button{width: 100px !important;}
#outsidePanel .button{width: 115px !important;}
.eventPanel .button {width: 122px !important;}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1824 -1587
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+934 -798
View File
File diff suppressed because it is too large Load Diff
+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
+1 -1
View File
File diff suppressed because one or more lines are too long
+2886 -2514
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+2531 -1542
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
.button{width: 120px !important;}
#outsidePanel .button{width: 115px !important;}
.eventPanel .button {width: 122px !important;}
+307
View File
@@ -0,0 +1,307 @@
_.setTranslation({"water tank": "ถังน้ำ", "all":"ทุกอย่าง",
"use meds": "ใช้ยา", "Fire": "ไฟไหม้","a fire rampages through one of the huts, destroying it.":"ไฟไหม้ออกจากห้อง ลุกลามและเผาทำลายกระท่อมหลังหนึ่งในหมู่บ้าน",
"all residents in the hut perished in the fire.": "ทุกคนที่อาศัยในบ้านหลังนั้นเสียชีวิตในเปลวไฟ", "mourn":"ไว้อาลัย", "nothing to take":"ไม่มีอะไรให้เก็บ",
"the room is {0}": "ในห้อง {0}", "take everything":"เก็บทุกอย่าง",
"punch twice as fast, and with even more force": "ต่อยด้วยความรวดเร็วเป็นสองเท่า และรุนแรงมากยิ่งขึ้นไปอีก", "a fire has started": "เกิดไฟไหม้",
"some villagers have died": "ชาวบ้านบางส่วนเสียชีวิตในเปลวไฟ",
"charm": "เครื่องราง", "The Nomad": "ผู้เร่ร่อน",
"more traps won't help now": "มีกับดักมากไปกว่านี้ก็คงไม่ช่วยอะไรแล้ว",
"only a few die.": "มีไม่กี่คนเท่านั้นที่เสียชีวิต", "total": "รวม",
"the compass points east": "เข็มทิศชี้ไปทางตะวันออก",
"the bodies of the wanderers that lived here are still visible in the flames.": "ยังคงเห็นร่างของผู้ดินทางที่อาศัยอยู่ที่นี่ในเปลวไฟ",
"the walls are scorched from an old battle.": "กำแพงถูกเผาทำลาย เป็นสัญลักษณ์ของการต่อสู้ในอดีต","there was a beast. it's dead now": "มีสัตว์ร้ายในป่า เราสังหารมันลงแล้ว",
"convoy": "ผู้คุ้มกัน", "buy medicine": "ซื้อยา",
"not enough fur": "มีขนสัตว์ไม่เพียงพอ",
"a masked soldier rounds the corner, gun drawn": "ทหารใต้หน้ากากปรากฏตัวขึ้นในมุมหนึ่ง ปืนชี้มาตรงหน้า",
"a huge hole is cut deep into the earth, evidence of the past harvest.": "หลุมขนาดใหญ่ตัดลึกลงไปในหน้าดิน ร่องรอยของการเก็บเกี่ยวในครั้งก่อน",
"it puts up little resistance before the knife.": "มันไม่สู้คมมีดมากนัก",
"the body of a wanderer lies in a small cavern.": "ร่างของผู้เดินทางทอดกายอยู่ในโพรงหลุม",
"a shivering man approaches and attacks with surprising strength": "ชายตัวสั่นเทิมโจนเข้ามา และโจมตีด้วยความรุนแรงอย่างไม่น่าเชื่อ",
"steel's stronger than iron": "เหล็กกล้าแข็งแกร่งกว่าเหล็กทั่ว ๆ ไป",
"A Strange Bird": "นกประหลาด",
"not enough alien alloy": "มีโลหะต่างดาวไม่เพียงพอ", "not enough wood": "มีไม้ไม่เพียงพอ", "street above the subway platform is blown away.": "พื้นถนนเหนือทางรถไฟใต้ดึงถูกระเบิดออกไป",
"the soldier is dead": "ทหารเสียชีวิต",
"error while saving to dropbox datastorage": "มีอะไรบางอย่างผิดพลาดกับการเก็บข้อมูลใน dropbox",
"the footsteps stop.": "เสียงฝีเท้าสงบลง",
"sniper": "พลซุ่มยิง",
"the coal mine is clear of dangers": "เหมืองถ่านหินปลอดภัยสำหรับคนงานแล้ว",
"the warped man lies dead.": "คนวิปริตได้ตายลงแล้ว",
"something's in the store room": "มีอะไรบางอย่างอยู่ในห้องเก็บของ",
"unfathomable destruction to fuel wanderer hungers.": "การทำลายอย่างไม่สิ้นสุดที่เต็มเห็นความกระหายหยากของผู้เดินทาง",
"embark": "ออกเดินทาง", "scout": "ผู้สำรวจ", "facebook": "facebook",
"the trees yield to dry grass. the yellowed brush rustles in the wind.": "ต้นไม้หายไปจากบริเวณ เหลือแต่ผืนหญ้าแห้ง พุ่มไม้สีเหลืองเสียดสีกันเองตามสายลม",
"save.": "save.", "total score: {0}": "คะแนนรวม: {0}",
"learned to make the most of food": "เรียนรู้การกินอาหารอย่างคุ้มค่า",
"blast": "ยิงลำแสง",
"the sky is grey and the wind blows relentlessly": "ท้องฟ้าเป็นสีเทา ลมพัดกระหน่ำแรง",
"supplies:": "เสบียง:", "the feral terror is dead": "อสูรจรจัดถูกสังหาร",
"the tracks disappear after just a few minutes.": "รอยเท้าหายไปหลังจากตามได้ไม่นานนัก",
"a safe place in the wilds.": "ที่หลบภัยกลางถิ่นกันดาร", "fur": "ขนสัตว์",
"beneath the wanderer's rags, clutched in one of its many hands, a glint of steel.": "มีประกายแสงของโลหะอยู่ใต้ผ้าคลุม มันถูกกอดกุมเอาไว้โดยมือทั้งหลายของผู้เดินทาง",
"buy scales": "ซื้อเกล็ดประหลาด", "mild": "เริ่มอุ่น",
"the hunting lodge stands in the forest, a ways out of town": "ซุ้มพรานถูกสร้างขึ้น ไกลออกไปจากตัวเมือง",
"leave": "ออก", "the convoy can haul mostly everything": "ผู้คุ้มกันสามารถช่วยขนของได้แทบทุกอย่าง",
"learned to strike faster without weapons": "เรียนรู้ที่จะจู่โจมได้เร็วขึ้นโดยไม่ใช้อาวุธ",
"an old house remains here, once white siding yellowed and peeling.": "บ้านหลังเก่ากรุตั้งอยู่ที่นี่ สภาพทรุดโทรมเกินบูรณะ",
"ignore them": "เพิกเฉยเสีย",
"willing to talk about it, for a price.": "ยินที่ที่จะพูดคุยเรื่องดังกล่าว ด้วยราคาที่สมเหตุสมผล",
"a beast, wilder than imagining, erupts out of the foliage": "สัตว์อสูรหน้าตาผิดเพี้ยนเกินจินตนาการโจนตัวออกมาจากสุมทุมพุ่มไม้",
"go home": "กลับบ้าน", "the soldier steps out from between the buildings, rifle raised.": "ทหารก้าวเท้าออกมาจากตรอก ยกปืนขึ้นประทับบ่า",
"force": "พลัง", "the rickety cart will carry more wood from the forest": "รถเข็นจะช่วยให้เก็บไม้จากป่าได้มากขึ้น",
"a ragged stranger stumbles through the door and collapses in the corner": "คนแปลกหน้าในเศษผ้าคลุมเก่า ๆ เดินเข้ามาทางประตูและล้มลงตรงมุมห้อง",
"not enough leather": "มีหนังฟอกไม่เพียงพอ", "the fight is short and bloody, but the beasts are repelled.": "การต่อสู้เป็นไปอย่างรวดเร็วและดุเดือด สัตว์ประหลาดถูกขับไล่ไปได้", "the wood is running out": "ไม้ฟืนเริ่มเหลือน้อยลงเต็มที่", "restart.": "restart.",
"rot's been to work on it, and some of the pieces are missing.": "ดูเหมือนมันจะเริ่มผุพัง และมีหลายชิ้นส่วนที่ยังขาดหายไป",
"workshop's finally ready. builder's excited to get to it": "โรงงานถูกตั้งขึ้นในที่สุด ผู้สร้างดูจะดีใจกว่าใครเพื่อนเป็นพิเศษ",
"a trading post would make commerce easier": "ท่าสินค้าจะทำให้การซื้อขายงายขึ้นมาก", "not enough steel": "มีเหล็กกล้าไม่พอ",
"perks:": "ความสามารถพิเศษ:", "the torch goes out": "คบไฟมอดลง", "saved.": "saved.",
"after a skirmish they are driven away, but not without losses.": "หลังจากการปะทะ พวกมันก็ถูกขับไล่ออกไป แต่ก็ด้วยราคาที่เจ็บปวด",
"the military is already set up at the mine's entrance.": "ดูเหมือนว่ากองทหารได้ตั้งค่ายอยู่หน้าเหมืองมาสักพักแล้ว",
"tannery goes up quick, on the edge of the village": "โรงฟอกหนังถูกตั้งไว้ที่ปลายของหมู่บ้าน",
"learned to fight quite effectively without weapons": "เรียนรู้ที่จะต่อสู้เมื่อไม่มีอาวุธ",
"charred bodies litter the ground.": "ซากศพไหม้เกรียมกระจัดกระจายตามพื้น",
"someone throws a stone.": "มีใครบางคนโยนก้อนหินมา",
"leaves a pile of small teeth behind.": "ทิ้งกองเขี้ยวประหลาดเอาไว้",
"leave city": "ออกจากเมือง", "not enough scales": "มีเกล็ดไม่เพียงพอ",
"someone has locked and barricaded the door to this operating theatre.": "ใครบางคนได้ลั่นกลอนและตั้งเครื่องกีดขวางอยู่ทั่วโรงละคร",
"leave cave": "ออกจากถ้ำ", "hp: {0}/{1}": "hp: {0}/{1}",
"a lone frog sits in the muck, silently.": "กบตัวใหญ่นั่งอยู่ในตมเงียบ ๆ ",
"the steel is strong, and the blade true.": "โลหะแข็งแรงดี และใบดาบก็คมกริบ",
"a shame to let what he'd found go to waste.": "คงไม่ดีถ้าจะให้ของที่เขาอุตส่าห์เหลือไว้มาทิ้งไว้เสียเปล่า",
"learned how to ignore the hunger": "เรียนรู้ที่จะเพิกเฉยต่อความหิวโหย",
"punch": "ชก", "water": "น้ำ", "desert rat": "ชาวทะเลทราย", "explore": "สำรวจ",
"a pack of snarling beasts pours out of the trees.": "ฝูงสัตว์ร้ายโถมออกมาจากต้นไม้รอบ ๆ ",
"punches do even more damage.": "กำปั้นสร้างความเสียหายให้กับศัตรูมากยิ่งขึ้น", "roaring": "ลุกโชติช่วง", "gatherer": "คนเก็บฟืน",
"the people back away, avoiding eye contact.": "ผู้คนค่อย ๆ ถอยออกไป พยายามหลบสายตา",
"A Huge Borehole": "หลุมอุกกาบาตยักษ์",
"a bundle of sticks lies just beyond the threshold, wrapped in coarse furs.": "มีกิ่งไม้วางอยู่ที่เชิงประตู พันไว้ด้วยขนสัตว์",
"builder says she could make finer things, if she had the tools": "ผู้สร้างบอกว่าเธอสามารถสร้างของที่ประณีตกว่านี้ก็ได้ ถ้าเธอมีอุปกรณ์ครบ",
"soldier": "ทหาร", "learn scouting": "เรียนรู้วิชาสำรวจ", "share.": "share.", "choose one slot to save to": "เลือกช่องที่ต้องการบันทึก.",
"A Murky Swamp": "บึง", "iron sword": "ดาบเหล็ก", "builder says she can make traps to catch any creatures might still be alive out there": "ผู้สร้างบอกว่าเธอน่าจะประกอบกับดักง่าย ๆ ไว้จับสัตว์ที่อาจจะอยู่ข้างนอกนั่นได้",
"the grasses thin. soon, only dust remains.": "หญ้าเริ่มบางลงจากบริเวณ เหลือเพียงแต่ฝุ่นทราย",
"a shot rings out, from somewhere in the long grass": "เสียงปืนดังขึ้นจากบางแห่งในพงหญ้า",
"a wall of gnarled trees rises from the dust. their branches twist into a skeletal canopy overhead.": "ถึงชายป่า ต้นไม้บิดเบี้ยวแทงขึ้นมาจากพื้นฝุ่น กิ่งใบประกอบกันเหมือนซี่โครงน่าขยะแขยง", "gather wood": "เก็บไม้",
"with a little effort, it might fly again.": "คงต้องทุ่มแรงนิดหน่อยถ้าจะให้มันบินขึ้นอีกครั้ง",
"A Scavenger": "คนเก็บขยะ", "picking the bones finds some useful trinkets.": "เจอของเล็ก ๆ น้อย ๆ ที่น่าจะเอามาใช้งานได้ในโครงกระดูก",
"the shell of an abandoned hospital looms ahead.": "ศากโรงพยาบาลร้างอยู่ตรงหน้า",
"the villagers hang the thief high in front of the store room.": "ชาวบ้านแขวนคอพวกโจรเหนือขื่อห้องเก้บของ",
"eye for an eye seems fair.": "ตาต่อตา ฟันต่อฟัน คงจะยุติธรรมที่สุดแล้ว", "an old man bursts through a door, wielding a scalpel.": "ชายชราโจนออกมาจากประตู ในมือถือมีดผ่าตัด", "1 medicine": "1 ยารักษา", "the small military outpost is well supplied.": "ป้อมทหารเล็ก ๆ ดูเหมือนจะมีจุเสบียงไว้เต็มที่",
"the clinic has been ransacked.": "คลินิกถูกรื้อค้นจนทั่ว", "drop:": "drop:",
"leaves some scraps of cloth behind.": "ทิ้งเศษผ้าเอาไว้เล็กน้อย", "are you sure?": "คุณแน่ใจหรือไม่?",
"charcutier": "คนตากเนื้อ", "a military perimeter is set up around the mine.": "ค่ายทหารถูกสร้างขึ้น ล้อมรอบด้วยกับระเบิด",
"trading post": "ท่าสินค้า", "a wanderer arrives with an empty cart. says if she leaves with furs, she'll be back with more.": "ผู้เดินทางมาเยี่ยมเยือนพร้อมกับรถเข็น เธอบอกว่าถ้าเธอมีขนสัตว์ให้ยืมสักหน่อย เธอจะเอากลับมาคืนด้วยจำนวนที่มากขึ้น", "in exchange, the wanderer offers his wisdom.": "เพื่อเป็นการแลกเปลี่ยน ผู้เดินทางเสนอความรู้ของเขาเป็นการตอบแทน", "sulphur miner": "เหมืองกำมะถัน",
"a small basket of food is hidden under a park bench, with a note attached.": "ตะกร้าอาหารถูกซ่อนอยู่ใต้เก้าอี้ในสวนสาธารณะ พร้อมกับข้อความสั้น ๆ", "warm": "อุ่น", "the sound of gunfire carries on the wind.": "เสียงยิงปืนดังขึ้นมาตามสายลม", "stoke fire": "เติมฟืน", "lift off": "ปล่อยยาน",
"shoot": "ยิงปืน", "none": "ไม่มี", "leave town": "ออกจากเมือง", "most of the windows at ground level are busted anyway.": "หน้าต่างชั้นล่างถูกพังออกมา",
"a strange looking bird speeds across the plains": "นกหน้าตาประหลาดโฉบมาตามทุ่งราบ", "linger": "รออยู่ต่อ", "take": "เก็บ", "connect game to dropbox local storage": "เชื่อมต่อเกมเข้ากับ dropbox", "strange bird": "นกประหลาด", "if the code is invalid, all data will be lost.": "ถ้าใส่รหัสผิดพลาด ข้อมูลทั้งหมดจะหลายไป", "A Feral Terror": "อสูรจรจัด", "can't see what's inside.": "มองไม่เห็นว่าข้างในมีอะไร", "a large beast charges out of the dark": "สัตว์ตัวใหญ่โจนออกมาจากความมืด", "salvage": "รื้อของ", "grenade": "ระเบิดมือ",
"the stranger in the corner stops shivering. her breathing calms.": "คนแปลกหน้าที่มุมห้องหยุดสั่นลง เธอเริ่มหายใจอย่างสงบ",
"a small suburb lays ahead, empty houses scorched and peeling.": "หมู่บ้านชานเมืองเล็ก ๆ อยู่ตรงหน้า มีร่องรอยของการถูกเผาและทำลาย",
"a wanderer arrives with an empty cart. says if he leaves with wood, he'll be back with more.": "ผู้เดินทางมาเยี่ยมเยือนพร้อมกับรถเข็น เขาบอกว่าถ้าเขามีไม้ให้ยืมสักหน่อย เขาจะเอากลับมาคืนด้วยจำนวนที่มากขึ้น", "gaunt man": "คนผอมแห้ง",
"a squat building up ahead.": "มีอาคารขนาดย่อม ๆ อยู่ข้างหน้า",
"a thug moves out of the shadows.": "นักเลงโผล่ออกมาจากเงามืด", "An Outpost": "ค่าย",
"there's not much, but some useful things can still be found.": "พบของมีประโยชน์บางอย่าง แม้จะไม่มากนักก็ตาม", " and ": " และ ",
"an improvised shop is set up on the sidewalk.": "เพิงร้านค้าเล็ก ๆ ถูกตั้งขึ้นข้างทาง", "cured meat": "เนื้อแห้ง",
"builder puts up a hut, out in the forest. says word will get around.": "ผู้สร้างตั้งกระท่อมเล็ก ๆ ที่ชายป่า เธอบอกว่าข่าวเรื่องที่พักจะกระจายออกไป",
"learned how not to be seen": "เรียนรู้ที่จะไม่ถูกมองเห็น", "punches do more damage": "หมัดสร้างความเสียหายมากขึน",
"some traps have been destroyed": "กับดักบางส่วนถูกทำลาย", "castoff from the mammoth drills can still be found by the edges of the precipice.": "พบชิ้นโลหะประหลาดในกระบอกสว่านขนาดใหญ่", "well armed men charge out of the forest, firing into the crowd.": "กลุ่มคนติดอาวุธอย่างดีระดมเข้ามาจากทางป่าและยิงเข้ามา", "deep in the swamp is a moss-covered cabin.": "ลึกเข้าไปในบึง กระท่อมเล็ก ๆ ตั้งอยู่โดดเดี่ยว",
"app store.": "app store.", "An Old Starship": "ยานอวกาศเก่า", "ignore it": "เพิกเฉยเสีย", "hot": "ร้อน",
"upgrade engine": "เสริมเครื่องยนต์", "forest": "ป่า", "give 500": "ให้ไป 500", "A Dark Room": "ห้องมืด", "a battle was fought here, long ago.": "มีการต่อสู้ในบริเวณนี้เมื่อนานมาแล้ว", "builder says leather could be useful. says the villagers could make it.": "ผู้สร้างบอกว่าหนังฟอกน่าจะมีประโยชน์ พวกชาวบ้านน่าจะทำกันได้", "craft:": "สร้าง:", "Iron&nbsp;Mine": "เหมืองเหล็ก", "coal mine": "เหมืองถ่านหิน", "bits of meat": "เศษเนื้อ","safer here.":"ทีนี่ปลอดภัยดี",
"scavengers must have gotten to this place already.": "พวกเก็บซากคงเข้ามารื้อที่นี่ไปแล้ว",
"the remains of an old camp sits just inside the cave.": "มีเศษซากของค่ายพักแรมเก่า ๆ ในถ้ำ", "The&nbsp;Village": "หมู่บ้าน", "snarling beast": "สัตว์ร้าย", "soldiers patrol the perimeter, rifles slung over their shoulders.": "ทหารลาดตระเวนอยู่ในบริเวณนี้ ปืนยาวสะพายพาดบ่า",
"a swarm of rats rushes up the tunnel.": "ฝูงของหนูโจนเข้ามาจากโพรง",
"faces, darkened by soot and blood, stare out from crooked huts.": "ใบหน้าที่เปื้อนคราบเลือดและดินโคลนมองออกมาจากกระท่อม",
"strange noises can be heard through the walls": "เสียงประหลาดลอดผ่านเข้ามาทางกำแพง", "coal": "ถ่านหิน",
"Stratosphere": "Stratosphere", "man-eater": "อสูรกินคน", "can't tell what they're up to.": "ไม่รู้เหมือนกันว่าพวกนั้นต้องการอะไร",
"enter": "เข้าไป", "a destroyed village lies in the dust.": "หมู่บ้านที่ถูกเผาทำลายจมลงในกองเถ้า", "Ship": "ยาน",
"better avoid conflict in the wild": "คงจะต้องหลีกเลี่ยงการต่อสู้ในป่า", "talk": "พูดคุย", "another beast, draw by the noise, leaps out of a copse of trees.": "สัตว์ป่าอีกตัวที่ถูกดึงดูดมาด้วยเสียง โจนออกมาจากโคนต้นไม้", "A Soldier": "ทหาร",
"the man expresses his thanks and hobbles off.": "ชายคนนั้นแสดงท่าทางขอบคุณก่อนจะเดินกะโผลกกะเผลกออกไป",
"battered technology from both sides lays dormant on the blasted landscape.": "อาวุธผุพังจากทั้งสองฝ่ายวางอยู่นิ่ง ๆ บนผืนดินแห้งกร้าว",
"the villagers haul a filthy man out of the store room.": "ชาวบ้านขนชายท่าทางสกปรกออกมาจากห้องเก็บของ", "strips of meat are hung up to dry in this ward.": "แผ่นเนื้อจะถูกตากไว้ที่นี่", "the familiar curves of a wanderer vessel rise up out of the dust and ash. ": "ยานหน้าตาคุ้นเคยของผู้เดินทางผุดขึ้นมาจากกองเถ้าและฝุ่น", "all the work of a previous generation is here.": "การก่อสร้างของรุ่นก่อน ๆ นั้นอยู่ที่นี่", "cold": "หนาวเย็น", "the iron mine is clear of dangers": "เหมืองเหล็กปลอดภัยแล้ว", "the military presence has been cleared.": "กองทหารถูกเก็บกวาดจากบริเวณ", "A&nbsp;Crashed&nbsp;Starship": "ซากยานอวกาศ", "the fire is {0}": "ไฟ {0}", "A Lonely Hut": "กระท่อมเดียวดาย", "buy teeth": "ซื้อเขี้ยว",
"a small supply cache is hidden at the back of the cave.": "กล่องเก็บของเล็ก ๆ ถูกซ่อนไว้ที่ปลายถ้ำ",
"iron's stronger than leather": "เหล็กทนทานกว่าหนังสัตว์", "bedrolls, torn and blackened, lay beneath a thin layer of dust.": "มีถุงนอนฉีกขาดและไหม้เกรียม วางอยู่ใต้ชั้นบาง ๆ ของฝุ่น", "dodge attacks more effectively": "หลบการโจมตีได้ดีขั้น", "hull: ": "เกราะหุ้ม:",
"a madman attacks, screeching.": "ชายคุ้มคลั่งโจนเข้ามาโจมตี กรีดร้องเสียงดัง", "thieves": "โจร",
"the towers that haven't crumbled jut from the landscape like the ribcage of some ancient beast.": "หอคอยที่ไม่ได้ล้มลง สร้างภาพทิวทัศน์เหมือนซี่โครงของสัตว์ยักษ์โบราณ", "lights off.": "lights off.", "someone had been stockpiling loot here.": "ใครบางคนเอาสมบัติของตนมาเก็บไว้ที่นี่",
"learned to look ahead": "เรียนรู้ที่จะมองให้ไกลออกไป", "the mine is now safe for workers.": "เหมืองปลอดภัยสำหรับคนงานแล้ว",
"Coal&nbsp;Mine": "เหมืองถ่าน", "empty corridors.": "ระเบียงว่างเปล่า", "save to slot": "ช่องบันทึก",
"the owner stands by, stoic.": "เจ้าของที่ยืนอยู่นิ่ง ๆ อย่างสุขุม", "hunter": "พราน", "strips of meat hang drying by the side of the street.": "แผ่นเนื้อถูกวางตากไว้ข้างทางเดิน", "more squatters are crowding around now.": "คนจรจัดเริ่มรวมตัวกันมารอบ ๆ ",
"some weird glowing boxes he picked up on his travels.": "กล่องเรื่องแสงหน้าตาประหลาดที่เขาเก้บมาได้ระหว่างเดินทาง",
"a panicked scavenger bursts through the door, screaming.": "คนเก็บเศษซากโจนเข้ามาจากประตู กรีดร้องเสียงดัง", "give 50": "ให้ไป 50",
"wagon": "เกวียน", "An&nbsp;Old&nbsp;House": "บ้านเก่า", "a soldier, alerted, opens fire.": "ทหารรู้สึกถึงผู้บุกรุก ทาบปืนพร้อมยิงทันที",
"meat": "เนื้อ", "the tunnel opens up at another platform.": "โพรงเปิดขึ้นมาจากอีกเพิงหนึ่ง", "a terrible plague is fast spreading through the village.": "โรคระบาดกระจายไปอย่างรวดเร็วทั่วหมู่บ้าน", "the gaunt man is dead": "ชายผอมแห้งเสียชีวิต", "bone spear": "หอกกระดูก", "trap": "กับดัก",
"the street ahead glows with firelight.": "ถนนตรงหน้าสว่างไสวไปด้วยเปลวไฟ", "armourer": "ช่างอาวุธ",
"a large shanty town sprawls across the streets.": "เมืองสลัมขนาดใหญ่แผ่ไปทั่วถนน",
"the shell of a burned out car blocks the entrance.": "โครงของซากรถไม้ ๆ ปิดทางเข้าเอาไว้",
"a small group arrives, all dust and bones.": "กลุ่มคนเล็ก ๆ เดินทางมาถึง ผอมแห้งหิวโซ", "A&nbsp;Ruined&nbsp;City": "ซากเมือง",
"weight": "น้ำหนัก", "torch": "คบไฟ", "The Thief": "โจร", "not enough cloth": "มีเศษผ้าไม่เพียงพอ",
"a youth lashes out with a tree branch.": "เด็กหนุ่มคนหนึ่งโจนออกมาพร้อมกิ่งไม้",
"the rest of the hospital is empty.": "ที่อื่น ๆ ในโรงพยาบาลนั้นว่างเปล่า", "connect": "เชื่อมต่อ",
"learned to be where they're not": "เรียนรู้ที่จะหลบหลีกอันตราย", "go twice as far without eating": "เดินทางได้ไกลขึ้นโดยไม่กินอาหาร",
"scavenger'd been looking for supplies in here, it seems.": "ดูเหมือนพวกเก็บซากขยะจะเคยเข้ามาหาของที่นี่",
"there's nothing else here.": "ไม่มีอะไรอยู่เลย", "the plague is kept from spreading.": "โรคระบาดถูกหยุดไว้ได้",
"the cask holds enough water for longer expeditions": "กระบอกน้ำเก็บน้ำไว้ได้สำหรับการเดินทางระยะยาว",
"check traps": "ตรวจดูกับดัก", "Plague": "โรคระบาด", "medicine": "ยา", "the old man had a small cache of interesting items.": "ชายแก่มีของที่น่าสนใจติดตัวมาด้วย", "tannery": "โรงฟอกหนัง", "lob": "ขว้างระเบิด", "no more room for huts.": "ไม่มีที่สำหรับกระท่อมแล้ว", "a plague afflicts the village":"เกิดโรคร้ายขึ้นในหมู่บ้าน",
"they took what they came for, and left.": "พวกมันมาเอาของที่พวกมันมองหา แล้วก็จากไป",
"through the large gymnasium doors, footsteps can be heard.": "ได้ยินเสียงฝีเท้าผ่านประตูของโรงยิม","epidemic is eradicated eventually":"โรคร้ายได้หยุดลงในที่สุด",
"a large creature attacks, claws freshly bloodied": "สัตว์ประหลาดขนาดใหญ่เข้ามาโจมตี กรงเล็บของมันยังคงเปื้อนเลือดสด ๆ อยู่",
"a green cross barely visible behind grimy windows.": "มองผ่านหน้าต่างเปรอะฝุ่น มองเห็นเพียงกางเขนสีเขียวจาง ๆ ",
"a sick man hobbles up": "ชายทางทางป่วยกระเพลกเข้ามา", "An&nbsp;Abandoned&nbsp;Town": "เมืองร้าง", "cart": "รถเข็น",
"might be things worth having still inside.": "อาจจะยังมีของมีค่าอยู่ข้างใน", "the wood has run out": "ฟืนเริ่มเหลือน้อยเต้มที่",
"The Master": "ผู้สั่งสอน", "thrust": "เสียบ", "water replenished": "น้ำถูกเติมจนเต็ม", "a soldier opens fire from across the desert": "ทหารยิงปืนเข้ามาใส่จากอีกฟากของเนินทราย", "go twice as far without drinking": "เดินทางได้ไกลขึ้นโดยไม่ดื่มน้ำ",
"the tentacular horror is defeated.": "ปราบสัตว์ประหลาดหนวดยาวลงได้", "an overturned caravan is spread across the pockmarked street.": "คาราวานสินค้าคว่ำลงบนถนน", "the villagers retreat to mourn the dead.": "ชาวบ้านล่าถอยกลับมาเพื่อทำพิธีให้กับผู้ตาย",
"A Modest Village": "หมู่บ้านทั่วไป", "A Damp Cave": "ถ้ำชื้นแฉะ", "swing": "ฟาด", "alien alloy": "โลหะต่างดาว", "export or import save data, for backing up": "ส่งหรือรับข้อมูลเกม สำหรับการเก็บรักษา", "smokehouse": "โรงรมเนื้อ", "vague shapes move, just out of sight.": "ร่างราง ๆ เคลื่อนไหวออกไปจากสายตา", "Wanderer": "ผู้เดินทาง", "the earth here is split, as if bearing an ancient wound": "แผ่นดินตรงนี้แยกออก ราวกับว่าเป็นแผลเปิดจากกาลก่อน", "the compass points southeast": "เข็มทิศชี้ไปยังตะวันออกเฉียงใต้", "barbarian": "คนเถื่อน", "the wanderer leaves, cart loaded with furs": "ผู้เดินทางจากไปด้วยรถเข็มที่เต็มไปด้วยขนสัตว์", "there are still supplies inside.": "ยังมีของบางอย่างหลงเหลืออยู่ข้างใน", "traps are more effective with bait.": "กับดักจะมีผลลัพท์ดียิ่งขึ้นเมื่อมีเหยื่อล่อ", "rusted chainlink is pulled across an alleyway.": "โซ่เกรอสนิมถูกลากผ่านตรอกทางเดิน", "a sickness is spreading through the village.": "โรคประหลาดเริ่มแพร่ไปในหมู่บ้าน", "tangle": "รวบตัว", "miss": "พลาดเป้า",
"the meat has run out": "ไม่มีเนื้อเหลืออยู่แล้ว",
"a beast charges out of a ransacked classroom.": "สัตว์ป่าโจนออกมาจากห้องเรียน",
"lucky that the natives can't work the mechanisms.": "โชคดีที่พวกพื้นเมืองไม่สามารถใช้เครื่องยนต์กลไกเหล่านี้ได้", "A&nbsp;Murky&nbsp;Swamp": "บึง",
"just as deadly now as they were then.": "อันตรายเหมือนอย่างที่เคยเป็นเมื่อก่อน", "builder just shivers": "ผู้สร้างเริ่มรู้สึกเย็น", "a second soldier joins the fight.": "ทหารคนที่สองเข้ามาเสริมกำลัง", "attack": "โจมตี", "go inside": "เข้าไปข้างใน",
"turn her away": "ไล่เธอไป", "dropbox.": "dropbox.", "reinforce hull": "เสริมเกราะหุ้ม", "not enough wood to get the fire going": "มีไม้ไม่พอสำหรับต่อไฟ",
"a stranger arrives in the night": "คนแปลกหน้าเข้ามาอาศัยในเวลาค่ำ", "hut": "กระท่อม", "trapper": "ผู้ดักสัตว์", "a battered highway sign stands guard at the entrance to this once-great city.": "ป้ายบอกทางตั้งตระหง่านอยู่หน้าเมืองใหญ่ที่เคยรุ่งเรืองแห่งนี้", "rifle": "ปืนยาว", "sulphur": "กำมะถัน", "steel": "เหล็กกล้า",
"the stranger is standing by the fire. she says she can help. says she builds things.": "หญิงสาวแปลกหน้านั่งอยู่ข้างกองไฟ เธอบอกว่าเธอสามารถช่วยสร้างสิ่งต่าง ๆ ได้",
"the sickness is cured in time.": "โรคร้ายได้รับการรักษาทันเวลา",
"the only hope is a quick death.": "ความหวังเดียวคือการตายอย่างไม่ทรมาน",
"score for this game: {0}": "คะแนนในรอบนี้: {0}", "the lizard is dead": "กิ้งกาถูกสังหาร", "iron": "เหล็ก", "fires burn in the courtyard beyond.": "ไฟลุกท่วมในสนามตรงหน้า", "builder": "ผู้สร้าง",
"a large creature lunges, muscles rippling in the torchlight": "สัตว์ร้ายตัวใหญ่โจนออกมา กล้ามเนื้อและผิวหนังของมันสะท้อนแสงจากคบไฟ", "something's causing a commotion a ways down the road.": "มีเสียงดังเอะอะมาจากฝั่งหนึ่งของถนน", "the stranger shivers, and mumbles quietly. her words are unintelligible.": "หญิงแปลกหน้าตัวสั่นเทิม กระซิบกระซาบอะไรบางอย่างไม่เป็นภาษา", "A Firelit Room": "ห้องแสงไฟ",
"some wood is missing.": "ไม้บางส่วนหายไป", "The Beggar": "ขอทาน", "Troposphere": "Troposphere", "ripe for the picking.": "พร้อมให้เก็บเกี่ยว", "A&nbsp;Destroyed&nbsp;Village": "ซากหมู่บ้าน", "coal miner": "เหมืองถ่าน", "not enough teeth": "มีเขี้ยวไม่เพียงพอ", "all he has are some scales.": "เชามีเพียงแค่เกล็ดประหลาดติดตัวเท่านั้น",
"learned to predict their movement": "เรียนรู้ที่จะคาดการณ์การเคลื่อนไหวศัตรูล่วงหน้า",
"the nights are rent with screams.": "คำคืนนั้นเต็มไปด้วยเสียงร้องโหยหวน", "the scavenger is dead": "คนเก็บขยะถูกสังหาร", "a nomad shuffles into view, laden with makeshift bags bound with rough twine.": "ผู้เร่ร่อนเดินทางมายังที่พักพร้อมกับถุงหนังขนาดใหญ่มัดด้วยเชือกหยาบ ๆ ",
"a convoy lurches in, equal parts worry and hope.": "ผู้คุ้มกันโจนเข้ามาอย่างกล้า ๆ กลัว ๆ", "the map uncovers a bit of the world": "แผนที่เปิดเผยบางส่วนของดินแดน",
"the shot echoes in the empty street.": "เสียงปืนดังลั่นขึ้นบนถนนร้าง", "the sounds stop.": "เสียงนั้นหยุดลง", "rucksack": "ถุงหนัง", "the towers of a decaying city dominate the skyline": "ตึกสูงของเมืองที่ผุพังปรากฏขึ้นที่ขอบฟ้า",
"lights on.": "lights on.",
"a torch to keep the dark away": "คบไฟใช้ขับไล่ความมืด",
"some good stuff woven into its nest.": "มีของดีหลาย ๆ อย่างพันเกี่ยวเป็นรังของมันขึ้นมา", "starvation sets in": "ความหิวโหยเริ่มคุกคามเข้ามา",
"the sniper is dead": "สังหารพลซุ่มยิงสำเร็จ", "nothing": "ไม่มีอะไร",
"say his folk have been skimming the supplies.": "บอกว่าคนของเขากำลังพยายามหาเครื่องใช้และเสบียง", "Restart?": "เริ่มเกมใหม่?", "this is irreversible.": "การกระทำนี้ไม่สามารถย้อนกลับได้",
"the town's booming. word does get around.": "เมืองเริ่มคึกคักขึ้นมาก ผู้คนบอกกันปากต่อปากถึงเมืองนี้", "Dropbox connection": "เชื่อมต่อกับ Dropbox",
"arms and munitions, relics from the war, are neatly arranged on the store-room floor.": "อาวุธยุทโธปกรณ์สำหรับสงคราม ถูกวางอย่างประณีตในห้องเก็บของ",
"iron miner": "เหมืองเหล็ก", "give 100": "ให้ไป 100",
"Export": "Export", "the operating theatre has a lot of curious equipment.": "โรงละครมีของหลายอย่างที่น่าสนใจอย่างมาก", "A Sniper": "พลซุ่มยิง",
"the mysterious wanderer returns, cart piled high with wood.": "ผู้เดินทางลึกลับกลับมาที่นี่ รถเข็นพูนสูงไปด้วยไม้", "a snarling beast jumps out from behind a car.": "สัตว์ร้ายกระโดดออกมาจากหลังซากรถ", "precise": "ความแม่นยำ",
"looks like a camp of sorts up ahead.": "ดูเหมือนจะมีค่ายอะไรสักอย่างข้างหน้า", "bait": "เหยื่อล่อ", "The Sulphur Mine": "เหมืองกำมะถัน", "stunned": "มึนงง",
"a thief is caught": "โจรถูกจับไว้ได้", "a beggar arrives.": "ขอทานเดินทางมายังที่พัก",
"the strange bird is dead": "สังหารนกประหลาด", "*** EVENT ***": "*** เหตุการณ์พิเศษ ***", "the grass thrashes wildly as a huge lizard pushes through": "พงหญ้าเหวี่ยงไปมาอย่างรวดเร็วเมื่อกิ้งก่ายักษ์โจนออกมา", "medicine is needed immediately.": "ต้องการยาอย่างเร่งด่วน", "A Crashed Ship": "ซากยาน",
"the town lies abandoned, its citizens long dead": "เมืองถูกทิ้งร้าง ประชากรคงเสียชีวิตกันหมดแล้ว", "give 1 medicine": "ให้ยาไป 1",
"the old compass is dented and dusty, but it looks to work.": "เข็มทิศเก่ามีหน้าปัดเบี้ยวและขึ้นสนิม แต่ยังดูเหมือนจะใช้งานได้อยู่", "wood": "ไม้",
"A Forgotten Battlefield": "สนามรบที่ถูกลืม",
"the trees are gone. parched earth and blowing dust are poor replacements.": "ต้นไม้หายไปจากสายตา พื้นดินแห้งผากและลมพัดแรงเข้ามาแทนที่",
"lodge": "ซุ้มพราน", "the debris is denser here.": "ซากปรักหักพังเริ่มกีดขวางทางมากขึ้นในบริเวณนี้", "a scout stops for the night": "ผู้สำรวจแวะมาพักที่นี่", "a gunshot rings through the trees.": "เสียงปืนลังลั่นทั่วท้องถนน",
"pop ": "ประชากร ", "somewhere above the debris cloud, the wanderer fleet hovers. been on this rock too long.": "บนท้องฟ้า ยานลำหนึ่งของผู้เดินทางลอยขึ้นไป ดูเหมือนเราจะอยู่บนหินโง่ ๆ นี่นานไปเสียแล้ว", "iron mine": "เหมืองเหล็ก", "freezing": "หนาวเหน็บ",
"the world fades": "สิ่งรอบ ๆ ตัวเริ่มจางลงช้า ๆ", "some of the traps have been torn apart.": "กับดักส่วนหนึ่งถูกทำลาย", "not enough iron": "มีเหล็กไม่พอ",
"compass": "เข็มทิศ", "successfully saved to dropbox datastorage": "บันทึกลงใน dropbox สำเร็จ",
"builder says it'd be useful to have a steady source of bullets": "ผู้สร้างบอกว่าถ้าเราสามารถผลิตกระสุนได้เองก็คงจะดี", "a mysterious wanderer arrives": "ผู้เดินทางลึกลับปรากฏตัวขึ้น", "An Old House": "บ้านเก่า ๆ",
"bleached bones are strewn about the entrance. many, deeply scored with jagged grooves.": "โครงกระดูกกองเรี่ยรายหน้าทางเข้า บางชิ้นมีร่องรอยของการขูดขีดอย่างชัดเจน",
"as soon as the door is open a little bit, hundreds of tentacles erupt.": "เมื่อเปิดประตูออก หนวดประหลาดก็พุ่งส่วนออกมาทันที", "leather": "หนังฟอก",
"a sound comes from the tunnel, just ahead.": "มีเสียงอะไรบางอย่างดังมาจากข้างในของโพรง",
"investigate": "ตรวจดู", "the cave narrows a few feet in.": "ถ้ำเริ่มแคบลงเมื่อเดินลึกเข้าไป", "sword is sharp. good protection out in the wilds.": "ดาบมีคม เหมาะสำหรับการป้องกันตัวในป่า", "orange traffic cones are set across the street, faded and cracked.": "มีกรวยจลาจรอู่ข้างถนน สีของมันเลือนไปเกือบหมด",
"a large man attacks, waving a bayonet.": "ชายร่างใหญ่เข้ามาโจมตี เหวี่ยงดาบปลายปืนไปมา",
"the air is filled with dust, driven relentlessly by the hard winds.": "ละอองฝุ่งปนเปื้อนในอากาศ พัดไหวไปมาตามลม", "A&nbsp;Damp&nbsp;Cave": "ถ้าชื้นแฉะ",
"a gaunt man approaches, a crazed look in his eye": "ชายร่างผอมเกร็งวิ่งเข้ามา มีแววตาของความบ้าคลั่ง", "A Military Raid": "กองทหารโจมตี",
"the walls are moist and moss-covered": "ผนังมีน้ำไหลแลลชื้น ปกคลุมด้วยมอส",
"a giant lizard shambles forward": "กิ้งก่ายักษ์คืบคลานเข้ามา", "close": "ปิด",
"some medicine abandoned in the drawers.": "มียาเล็กน้อยถูกทิ้งไว้ในตู้",
"strange scales": "เกล็ดประหลาด", "bayonet": "ดาบปลายปืน",
"learned to throw punches with purpose": "เรียนรู้ที่จะต่อยอย่างมีจุดมุ่งหมาย",
"a shack stands at the center of the village.": "มีเพิงไม้ตั้งอยู่กล้าหมู่บ้าน",
"spare him": "ไว้ชีวิตเขา", "he smiles warmly and asks for lodgings for the night.": "เขายิ้มให้น้อย ๆ และขออาศัยอยู่ที่นี่สักคืน", "stealthy": "ซ่อนตัว", "the sulphur mine is clear of dangers": "เหมืองกำมะถันปลอดภัยสำหรับคนงานแล้ว",
"weapons": "อาวุธ", "the man is thankful.": "ชายคนนั้นขอบคุณ",
"broken streetlights stand, rusting. light hasn't graced this place in a long time.": "เสาไฟตั้งตระหง่าน สนิมเกาะกรัง คงจะไม่มีแสงไฟแตะที่แห่งนี้อยู่นานพอดู",
"shares what he knows about sneaking before he goes.": "เขามอบความรู้เกี่ยวกับการซ่อนตัวก่อนจากไป", "import": "Import", "available": "มีอยู่",
"A Shivering Man": "คนตัวสั่น", "the rest bury them.": "ส่วนที่เหลือก็ฝั่งพวกมันไป",
"smoldering": "คุกรุ่น", "the young settler was carrying a canvas sack.": "ผู้ตั้งรกรากหอบถุงผ้าใบมาด้วย",
"the ground is littered with small teeth": "บนพื้นมีเขี้ยวเล็ก ๆ กระจัดกระจายเต็มไปหมด", "the nest of a large animal lies at the back of the cave.": "ที่สุดปลายถ้ำมีรังของสัตว์ขนาดใหญ่อยู่", "A Tiny Village": "หมู่บ้านเล็ก ๆ ", "a tribe of elderly squatters is camped out in this ward.": "ชนเผ่าที่มีแต่คนชราปักหลักอาศัยอยู่ในหอผู้ป่วยแห่งนี้", "your are connected to dropbox with account / email ": "คุณเชื่อมต่อกับ dropbox", "Mesosphere": "Mesosphere",
"agree": "ตกลง", "the double doors creak endlessly in the wind.": "ประตูเปิดแง้มออกมีเสียงออดแอดตามลม", "not much here.": "ไม่มีอะไรอยู่แถวนี้",
"got it": "เข้าใจแล้ว", "choose one slot to load from": "เลือกช่องที่ต้องการโหลดบันทึก", "a cave lizard attacks": "กิ้งก่าถ้ำเข้าจู่โจม",
"men mill about, weapons at the ready.": "ผู้คนหรี่ตรงเข้ามา ยกอาวุธขึ้นพร้อมโจมตี", "l armour": "เกราะหนัง", "steelworks": "โรงหลอมโลหะ",
"A Ruined City": "ซากเมือง", "Noises": "เสียง", "can't tell what left it here.": "ไม่รู้ว่าใครทิ้งมันเอาไว้", "trees loom on the horizon. grasses gradually yield to a forest floor of dry branches and fallen leaves.": "ต้นไม้เริ่มปรากฏให้เห็น ทุ่งหญ้ารอบ ๆ ตัวจากไป เหลือแต่พื้นบนป่าที่มีใบไม้กิ้งไม้แห้งระเกะระกะ",
"a man stands over a dead wanderer. notices he's not alone.": "ชายคนหนึ่งยืนอยู่ข้างศพของผู้เดินทาง รับรู้ได้ว่าเขาไม่ได้อยู่เพียงลำพัง", "village": "หมู่บ้าน",
"cancel": "ยกเลิก", "put the save code here.": "ใส่รหัสบันทึกลงที่นี่", "hang him": "แขวนคอเขาซะ",
"inside, the remains of its victims are everywhere.": "มีซากศพของเหยื่อที่ถูกมันสังหารระเกะระกะภายใน", "this spear's not elegant, but it's pretty good at stabbing": "หอกเล่มนี้อาจไม่สวยงามนัก แต่ถ้าใช้แทงล่ะก็เชื่อมือได้เลย", "the forest is silent.": "ในป่าเงียบสงัด", "A&nbsp;Borehole": "หลุมอุกกาบาต",
"the night is silent.": "คำคืนนี้เงียบสงัด", "never go thirsty again": "ไม่ต้องทนหิวน้ำอีกต่อไป", "a small cache of supplies is tucked inside a rusting locker.": "กล่องเสบียงถูกยัดเอาไว้ในตู้สนิมเขรอะ", "learned to love the dry air": "เรียนรู้ที่จะรักอากาศแห้ง ๆ ", "workshop": "โรงงาน",
"A Barren World": "โลกที่รกร้างว่างเปล่า", "see farther": "มองเห็นได้ไกลขึ้น", "bolas": "บ่วงบาศก์", "the ground is littered with scraps of cloth": "เศษผ้าวางกระจัดกระจายเต็มพื้น", "The Coal Mine": "เหมืองถ่านหิน", "a huge lizard scrambles up out of the darkness of an old metro station.": "กิ้งก่ายักษ์ตะกายขึ้นมาจากสถานีรถไฟใต้ดินเก่า", "more voices can be heard ahead.": "เสียงต่าง ๆ ยังคงดังอยู่ข้างหน้า",
"A Large Village": "หมู่บ้านขนาดใหญ่", "precision": "ความแม่นยำ", "A Deserted Town": "เมืองร้าง", "the sickness spreads through the village.": "ไข้หวัดกระจายไปทั่วหมู่บ้าน", "won't say from where he came, but it's clear that he's not staying.": "ไม่ยอมบอกว่าเขามาจากที่ไหน แต่ที่แน่ ๆ เขาคงอยู่ที่นี่ไม่นาน",
"the crowd surges forward.": "กลุ่มคนโถมมาข้างหน้า", "the wanderer takes the charm and nods slowly.": "ผู้เดินทางรับเครื่องรางเอาไว้แล้วผงกศีรษะช้า ๆ ",
"the mysterious wanderer returns, cart piled high with furs.": "ผู้เดินทางลึกลับกลับมาพร้อมกับรถเข็มที่พูนไปด้วยแผ่นหนัง", "armoury": "โรงอาวุธ",
"searching the bodies yields a few supplies.": "มีเสบียงติดมากับซากศพเล็กน้อย",
"the torchlight casts a flickering glow down the hallway.": "คบไฟส่องแสงราง ๆ ไปตามทางเดิน", "Export / Import": "Export / Import",
"steelworker": "ช่างโลหะ", "the man-eater is dead": "ตัวกินคนถูกสังหาร", "learned to swing weapons with force": "เรียนรู้ที่จะซัดอาวุธเต็มกำลัง",
"the remaining settlers flee from the violence, their belongings forgotten.": "ผู้ตั้งถิ่นฐานหนีไปเมื่อเห็นการปะทะ ลืมของบางอย่างเอาไว้",
"a crudely made charm": "เครื่องรางที่แกะขึ้นอย่างหยาบ ๆ ", "cask": "กระติกน้ำ", "engine:": "เครื่องยนต์",
"the streets are empty.": "ถนนว่างเปล่า", "lizard": "กิ้งก่า", "Sulphur&nbsp;Mine": "เหมืองกำมะถัน", "export or import save data to dropbox datastorage": "export หรือ import บันทึกเกมด้วย dropbox", "the house has been ransacked.": "บ้านหลังนี้ถูกรื้อค้นจนเกลี้ยง",
"a thug is waiting on the other side of the wall.": "พวกนักเลงรออยู่ในอีกฟากของกำแพง", "the metallic tang of wanderer afterburner hangs in the air.": "มีกลิ่นโลหะของเครื่องยนต์ยานผู้เดินทางลอยอยู่ในอากาศจาง ๆ ", "large prints lead away, into the forest.": "รอยเท้าขนาดใหญ่นำทางเข้าไปในป่า",
"a startled beast defends its home": "สัตว์ป่าพยายามป้องกันดินแดนของตน", "there is nothing else here.": "ไม่มีอะไรอยู่แถวนี้อีกแล้ว",
"his time here, now, is his penance.": "เวลาที่เหลือของเขา ติดอยู่ที่นี่เพื่อเป็นการสำนักบาปในอดีต", "where the windows of the schoolhouse aren't shattered, they're blackened with soot.": "จุดที่หน้าต่างของโรงเรียนไม่แตกออก ก็ถูกปกคลุมด้วยเขม่าดำ", "hull:": "เกราะหุ้ม:", "scavenger": "คนเก็บขยะ",
"unarmed master": "ปรมาจารย์หมัดเปล่า", "the man says he's grateful. says he won't come around any more.": "ชายผู้นั้นขอบคุณ และกล่าวว่าเขาจะไม่มารบกวนอีก",
"laser rifle": "ปืนเลเซอร์", "sulphur mine": "เหมืองกำมะถัน", "buy compass": "ซื้อเข็มทิศ", "buy map": "ซื้อแผนที่", "scratching noises can be heard from the store room.": "มีเสียงขีดข่วนดังขึ้นมาจากห้องเก็บของ", "steel sword": "ดาบเหล็กกล้า", "descend": "ลงไป",
"asks for any spare furs to keep him warm at night.": "ขอเศษขนสัตว์เหลือ ๆ เพื่อห่มคลายหนาวให้กับเขาเอง", "A Raucous Village": "หมู่บ้านยิ่งใหญ่",
"the beggar expresses his thanks.": "ขอทานแสดงความขอบคุณ", "carrying more means longer expeditions to the wilds": "เก็บของได้มากขึ้นหมายถึงสำรวจได้นานขึ้น", "free {0}/{1}": "ที่ว่าง {0}/{1}", "Room": "ห้อง", "a swamp festers in the stagnant air.": "บึงมีกลิ่นฉุนกึกลอยละล่องอยู่ในอากาศรอบ ๆ ", "rotting reeds rise out of the swampy earth.": "ต้นกกเน่าเปื่อยลอยคว้างอยู่กลางน้ำโคลน",
"armoury's done, welcoming back the weapons of the past.": "โรงอาวุธสร้างขึ้นอย่างสมบูรณ์ พร้อมใช้งาน", "eat meat": "กินเนื้อ",
"slow metabolism": "เผาผลาญช้า", "camp fires burn by the entrance to the mine.": "มีกองไฟอยู่หน้าทางเข้าเหมือง", "the mouth of the cave is wide and dark.": "ปากถ้ำเปิดกว้างแต่มืดสนิท", "builder's not sure he's to be trusted.": "ผู้สร้างไม่เชื่อว่าผู้มาเยือนจะไว้ใจได้", "evasion": "หลบหลีก",
"buy bait": "ซื้อเหยื่อล่อ", "a pack of lizards rounds the corner.": "ฝูงกิ้งก่าล้อมทางหนีเอาไว้", "light fire": "จุดไฟ",
"waterskin": "ถุงใส่น้ำ", "scattered teeth": "เขี้ยวที่กระจัดกระจาย", "the door hangs open.": "ประตูเปิดอ้าเอาไว้", "buy:": "ซื้อ:", "load": "load",
"track them": "ตามรอยไป", "stores": "เก็บ", "now the nomads have a place to set up shop, they might stick around a while": "ทีนี้ผู้เร่ร่อนก็มีร้านเป็นของตนเอง พวกเขาน่าจะอยู่นานขึ้น", "A Dusty Path": "เส้นทางเปรอะฝุ่น", "armour": "ชุดเกราะ", "A Man-Eater": "ตัวกินคน",
"bring your friends.": "พาเพื่อนไปด้วย", "the compass points south": "เข็มทิศชี้ไปทางทิศใต้",
"the compass points north": "เข็มทิศชี้ไปทางทิศเหนือ", "The Sick Man": "คนป่วย", "yes": "ใช่", "martial artist": "นักสู้มือเปล่า",
"the traps contain ": "ในกับดักมี : ", "the old tower seems mostly intact.": "หอคอยใหญ่ ดูภายนอกสมบูรณ์ดี", "scales": "เกล็ด",
"bird must have liked shiney things.": "พวกนกน่าจะชอบของสะท้อนแสง", "the path leads to an abandoned mine": "เส้นทางนี้นำไปสู่เหมืองร้าง",
"the compass points northeast": "เข็มทิศชี้ไปทางทิศตะวันออกเฉียงเหนือ", "the camp is still, save for the crackling of the fires.": "ค่ายเงียบสงบดี มีเพียงเสียงของเปลวไฟและฟืนเป็นครั้งคราว", "he begs for medicine.": "เขามาขอยา", "save": "บันทึก",
"this waterskin'll hold a bit of water, at least": "อย่างน้อยถุงน้ำก็ยังเก็บน้ำมากกว่าไม่มีอะไรเลย", "turn him away": "ไล่เขาไป",
"the people here were broken a long time ago.": "ผู้คนที่นี่ไม่สามารถทำอะไรได้เป็นชิ้นเป็นอันมานานมากแล้ว", "a grizzled soldier attacks, waving a bayonet.": "ทหารท่าทางดุดันพุ่งเข้ามาโจมตี โบกดาบปลายปืนไปมา", "shivering man": "คนตัวสั่น", "The Mysterious Wanderer": "ผู้เดินทางลึกลับ", "A Huge Lizard": "กิ้งก่ายักษ์",
"boxer": "นักมวย", "a man joins the fight": "ชายคนหนึ่งเข้ามาร่วมวงด้วย", "An&nbsp;Outpost": "ค่ายพักแรม", "not enough meat": "มีเนื้อไม่พอ",
"some weird metal he picked up on his travels.": "โลหะประหลาดที่เขาเก้บมาได้จากการเดินทาง", "something's in there.": "มีอะไรบางอย่างข้างใน",
"restore more health when eating": "ฟื้นฟูพลังชีวิตมากขึ้นจากอาหาร", "A Snarling Beast": "สัตว์ร้าย", "Share": "Share",
"a haze falls over the village as the steelworks fires up": "หมอกควันปกคลุมหมู่บ้าน โรงเหล็กถูกสร้างขึ้นอย่างสมบูรณ์", "a large bird nests at the top of the stairs.": "มีรังนกขนาดใหญ่อยู่บนบันได", "an old wanderer sits inside, in a seeming trance.": "ผู้เดินทางชรานั่งอยู่ข้างใน ดูเหมือนกำลังครุ่นคิดเหม่อลอย",
"builder says the villagers could make steel, given the tools": "ผู้สร้างบอกว่าชาวบ้านสามารถสร้างเหล็กได้ ถ้ามีอุปกรณ์ให้", "continue": "ไปต่อ",
"there is no more water": "ไม่มีน้ำเหลืออยู่แล้ว", "flickering": "พริ้วไหว", "only the chief remains.": "มีเพียงหัวหน้าใหญ่เท่านั้นที่เหลืออยู่",
"go back inside": "กลับเข้าไปข้างใน", "a few items are scattered on the ground.": "มีของจำนวนหนึ่งระเกะระกะบนพื้น", "save this.": "เก็บเอาไว้",
"this old mine is not abandoned": "ดูเหมือนเหมืองเก่าจะไม่รกร้างซะทีเดียว", "a fight, maybe.": "คงจะต้องสู้", "behind the door, a deformed figure awakes and attacks.": "หลังบานประตู มีร่างประหลาดตื่นขึ้นมาและเข้าจู่โจมทันที", "twitter": "twitter", "baited trap": "กับดักติดเหยื่อ", "dead": "ดับมอด",
"the torch sputters and dies in the damp air": "คบไฟค่อย ๆ ดับมอดลงจากความชื้นในอากาศ", "export": "export",
"a few belongings rest against the walls.": "ของเหลือ ๆ บางอย่างพาดไว้กับผนัง", "not far from the village lies a large beast, its fur matted with blood.": "ไม่ไกลนักจากหมู่บ้าน มีสัตว์ร้ายที่ขนเปรอะไปด้วยเลือด", "an old iron mine sits here, tools abandoned and left to rust.": "มีเหมืองเหล็กเก่าที่นี่ อุปกรณ์ต่าง ๆ ถูกทิ้งเอาไว้ให้สนิมเกาะเฉย ๆ ", "but there is a cache of medicine under the floorboards.": "แต่ว่ามีกล่องเก็บยาอยู่ใต้พื้นอีกที",
"only dust and stains remain.": "เหลือเพียงฝุ่นเกรอะและคราบสนิม", "s armour": "เกราะเหล็กกล้า", "say he should be strung up as an example.": "เขาควรถูกแขวนคอเอาไว้เพื่อไม่ให้เป็นเยี่ยงอย่าง", "collected scraps spread across the floor like they fell from heaven.": "เศษซากกระจายเต็มพื้นราวกับว่ามันร่วมมาจากฟ้า",
"the darkness is absolute": "ความมืดไม่อาจหยั่งถึง", "A Ruined Trap": "ซากกับดัก", "not enough coal": "มีถ่านหินไม่พอ",
"ambushed on the street.": "ถูกซุ่มโจมตีบนถนน", "worth killing for, it seems.": "เหมือนจะมีค่าพอที่จะยอมตายแทน", "slash": "ฟัน",
"builder says she can make a cart for carrying wood": "ผู้สร้างบอกว่าเธอสามารถสร้างรถเข็นเพื่อช่วยขนไม้ได้",
"leather's not strong. better than rags, though.": "หนังสัตว์ไม่ทนทานนัก แต่ก็ยังดีกว่าเศษผ้าเก่า ๆ", "builder stokes the fire": "ผู้ก่อสร้างเติมฟืนให้กับไฟ", "say goodbye": "บอกลา", "A Silent Forest": "ป่าเงียบงัน", "builder's not sure she's to be trusted.": "ผู้สร้างไม่เชื่อใจเธอเท่าไรนัก",
"an old case is wedged behind a rock, covered in a thick layer of dust.": "กล่องเก่า ๆ ซุกอยู่ใต้กองหิน ปกคลุมด้วยฝุ่นหนาเตอะ",
"the point is made. in the next few days, the missing supplies are returned.": "ไม่กี่วันต่อมา เสบียงก็ถูกนำมาคืนด้วยความหวาดกลัว",
"a frail man stands defiantly, blocking the path.": "ชายท่าทางผอมแห้งพยายามขวางทางเอาไว้", "the plague rips through the village.": "โรคระบาดกระจายไปทั่วหมู่บ้าน", "an old wanderer arrives.": "ผู้เดินทางชรามาถึงที่พัก", "scavenger had a small camp in the school.": "พวกเก็บขยะตั้งค่ายในโรงเรียน",
"the compass points southwest": "เข็มทิศชี้ไปทางตะวันตกเฉียงใต้", "the wanderer leaves, cart loaded with wood": "ผู้เดินทางจากได้พร้อมกับรถเข็นที่จุไปด้วยไม้",
"Dropbox Export / Import": "Dropbox Export / Import", "maybe some useful stuff in the rubble.": "อาจจะมีของมีประโยชน์ติดอยู่หลังซากปรักหักพัง",
"google+": "google+", "ok": "โอเค", "a man hobbles up, coughing.": "ชายคนหนึ่งกระเพลกเข้ามา ไอเสียงดัง", "i armour": "เกราะเหล็ก",
"The Scout": "ผู้สำรวจ", "leaves a pile of small scales behind.": "ทิ้งกองเกล็ดประหลาดเล็ก ๆ เอาไว้", "pockets": "กระเป๋า", "stab": "แทง",
"time to move on.": "ได้เวลาไปต่อแล้ว", "the ground is littered with small scales": "มีเศษเกล็ดประหลาดกระจายเต็มพื้น", "not enough ": "มีไม่พอ",
"the stench of rot and death fills the operating theatres.": "กลิ่นเน่าเสียและซากศพลอยคลุ้งในโรงละคร", "burning": "ยังคงติดอยู่", "they must be here for a reason.": "พวกมันมาที่นี่เพื่ออะไรบางอย่าง", "a nomad arrives, looking to trade": "ผู้เร่ร่อนแวะผ่านมา ต้องการแลกเปลี่ยนอะไรสักอย่าง", "black powder and bullets, like the old days.": "ดินดำและกระสุน เหมือนในวันเก่า ๆ ", "restart the game?": "ต้องการเริ่มเกมใหม่หรือไม่?", "gastronome": "นักชิม",
"load from slot": "load จากช่อง", "energy cell": "เซลล์พลังงาน", "inside the hut, a child cries.": "มีเสียงเด็กร้องไห้ในกระท่อม",
"the compass points west": "เข็มทิศชี้ไปทางตะวันตก", "always worked before, at least.": "อย่างน้อยก็ใช้ได้เมื่อก่อน", "a scavenger draws close, hoping for an easy score": "คนเก็บขยะค่อย ๆ เคลื่อนที่เข้ามา หวังจะโจมตีทีเผลอ", "Sickness": "ไข้หวัด", "still a few drops of water in the old well.": "ยังมีน้ำเหลือบ้างในบ่อ",
"build:": "สร้าง:", "feral terror": "อสูรจรจัด", "signout": "signout", "A Beast Attack": "สัตว์ป่าเข้าโจมตี",
"Ready to Leave?": "พร้อมจะไปจากที่นี่หรือยัง?", "the house is abandoned, but not yet picked over.": "บ้านถูกทิ้งร้าง แต่ยังมีของบางอยากทิ้งไว้อยู่",
"time to get out of this place. won't be coming back.": "ได้เวลาไปจากที่นี่แล้ว เราจะไม่หันหลังกลับมาอีก", "the compass points northwest": "เข็มทิศชี้ไปทางตะวันตกเฉียงเหนือ", "the thirst becomes unbearable": "ความกระหายน้ำชักเกินจะทนไหว", "a beggar arrives": "ขอทานมาถึงที่พัก",
"a beast stands alone in an overgrown park.": "สัตว์ตัวหนึ่งยืนอยู่เดียวดายท่ามกลางสวนสาธารณะที่กลายเป็นป่ารกชัฏ", "he leaves a reward.": "เขาทิ้งของขวัญเอาไว้",
"nothing but downcast eyes.": "ไม่มีอะไรเหลืออยู่นอกจากความเศร้าโศก", "the scout says she's been all over.": "ผู้สำรวจบอกว่าเธอเดินทางไปทั่วทิศบนดาวนี้",
"the small settlement has clearly been burning a while.": "ที่แห่งนี้ถูกเผาทำลายมานานพอสมควร", "cloth": "ผ้า", "a second soldier opens fire.": "ทหารคนต่อมายิงปืนเข้ามาสมทบ", "dangerous to be this far from the village without proper protection": "เรามาไกลเกินไปจากหมู่บ้าน อันตรายมากหากไม่มีเครื่องป้องกันที่ดี",
"squeeze": "เบียดเข้าไป", "a pristine medicine cabinet at the end of a hallway.": "ยาที่อยู่ในสภาพสมบูรณ์เก็บอยู่ในตู้ที่สุดทางเดิน",
"scraps of fur": "เศษขนสัตว์", "a scavenger waits just inside the door.": "คนเก็บขยะรออยู่หลังประตู",
"the wind howls outside": "ลมพัดแรงข้างนอก", "the wagon can carry a lot of supplies": "เกวียนสามารถเก็บของได้จำนวนมาก",
"A&nbsp;Battlefield": "สนามรบ", "more soldiers will be on their way.": "ทหารอีกกลุ่มกำลังจะตามมาสมทบ",
"the shivering man is dead": "คนตัวสั่นเสียชีวิต", "builder finishes the smokehouse. she looks hungry.": "สร้างโรงรมควันสำเร็จ ผู้สร้างแสดงอาการหิวอย่างชัดเจน",
"the barrens break at a sea of dying grass, swaying in the arid breeze.": "พื้นดินเริ่มกลับมามีหญ้าปกคลุมบาง ๆ พริ้วไหวตามแรงลม",
"a snarling beast leaps out of the underbrush": "สัตว์ร้ายโจนออกมาจากพงหญ้า", "the place has been swept clean by scavengers.": "ที่นี่โดนกวาดเรียบโดยพวกเก็บเศษขยะ", "A Destroyed Village": "ซากหมู่บ้าน", "land blows more often": "โจมตีถูกเป้าได้แม่นยำขึ้น", "Space": "อวกาศ",
"it's been picked over by scavengers, but there's still some things worth taking.": "ที่นี่ถูกกวาดไปโดยพวกเก็บขยะ แต่น่าจะมีอะไรเหลืออยู่บ้าง",
"Thermosphere": "Thermosphere", "5 medicine": "ยารักษา 5 ", "do nothing": "ไม่สนใจ", "A Gaunt Man": "คนผอมแห้ง",
"Outside": "ภายนอก", "the snarling beast is dead": "สัตว์ร้ายถูกสังหาร", "bodies and supplies from both sides litter the ground.": "ซากศพและเสีบยงกระจัดกระจายเต็มพื้น", "the remains of an old house stand as a monument to simpler times": "เศษซากของบ้านเก่า ๆ ตั้งตระหง่าย เป็นสักญลักษณ์ของวันเก่า ๆ",
"a squatter stands firmly in the doorway of a small hut.": "ผู้อาศัยยืนกันบานประตูของกระท่อมเล็ก ๆ ", "lights flash through the alleys between buildings.": "ไฟสว่างวาบผ่านตรอกเล็ก ๆ ข้างอาคาร", "no": "ไม่", "{0} per {1}s": "{0} ต่อ {1}วินาที", "a weathered family takes up in one of the huts.": "ครอบครัวเล็ก ๆ เข้ามาอยู่อาศัยในกระท่อม", "run": "หนี", "Exosphere": "Exosphere",
"he speaks of once leading the great fleets to fresh worlds.": "เขากล่าวว่าครั้งหนึ่งตนเคยนำกองยานของผุ้เดินทางไปสู่โลกที่อุดมสมบูรณ์",
"builder says there are more wanderers. says they'll work, too.": "ผู้สร้างบอกว่ามีผู้เดินทางอีกมากอาศัยอยู่ในดินแดนนี้ พวกเขาพร้อมจะทำงานหากมีที่พัก",
"evasive": "หลบหลีก", "an old wanderer arrives": "ผู้เดินทางชรามาถึงที่พัก", "through the walls, shuffling noises can be heard.": "มีเสียงเบา ๆ ผ่านมาทางกำแพง", "melee weapons deal more damage": "อาวุธระยะประชิดโจมตีแรงขึ้น", "the compass points ": "เข็มทิศชี้ไปยัง",
"lets some light down into the dusty haze.": "แสงส่องผ่านหมอกควันจาง ๆ ", "the man swallows the medicine eagerly": "ชายคนนั้นกินยาอย่างเร่งรีบ",
"the days are spent with burials.": "ทุกคนไว้อาลัยที่สุสานกันทั้งวัน", "more traps to catch more creatures": "กับดักมากขึ้น จับสัตว์มากขึ้น",
"a man charges down the hall, a rusty blade in his hand": "ชายคนหนึ่งวิ่งเข้ามาในโถงทางเดิน มีดขึ้นสนิมอยู่ในกำมือ",
"it contains travelling gear, and a few trinkets.": "มีอุปกรณ์การเดินทางและของเล็ก ๆ น้อย ๆ ปนอยู่", "bullets": "กระสุน",
"the light from the fire spills from the windows, out into the dark": "แสงสว่างจากกองไฟส่องออกมาจากหน้าต่าง เข้าไปในความมืดมิด",
"tell him to leave": "ไล่เขาไป", "dry brush and dead branches litter the forest floor": "กิ่งไม้และใบไม้แห้ง ๆ เกลื่อนพื้นป่าไปหมด",
"tattered cloth": "ผ้าขาด ๆ ", "can't read the words.": "อ่านอะไรไม่ออกสักคำ", "tanner": "คนฟอกหนัง",
"should cure the meat, or it'll spoil. builder says she can fix something up.": "น่าจะตากเนื้อเอาไว้บ้าง ไม่เช่นนั้นมันจะเน่าไป",
"or migrating computers": "หรือย้ายเครื่อง", "water:{0}": "น้ำ:{0}", "still time to rescue a few supplies.": "ยังมีเวลาเก้บของเล็กน้อย",
"teeth": "เขี้ยว", "villagers could help hunt, given the means": "ชาวบ้านสามารถช่วยล่าสัตว์ได้ ถ้ามีเครื่องมือ", "the beast is dead.": "ฆ่าสัตว์ป่าได้สำเร็จ",
"feral howls echo out of the darkness.": "อสูรจรจัดหอนขึ้นมาในความมืด", "The Iron Mine": "เหมืองเหล็ก", "wild beasts attack the villagers": "สัตว์ป่าโจมตีหมู่บ้าน",
"predators become prey. price is unfair": "ผู้ล่ากลับกลายเป็นเหยื่อ ความสูยเสียไม่อาจคาดเดา"
,"troops storm the village": "ทหารบุกรุกหมู่บ้าน","warefare is bloodthristy":"สงครามนองเลือด..","nothing was found":"ไม่เจออะไรเลย"
});
+3402
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+2897 -1942
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+2872 -1857
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+925 -798
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+2462 -1528
View File
File diff suppressed because it is too large Load Diff
+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
+2 -2
View File
@@ -63,7 +63,7 @@
return target;
}
if (target in translation == false)
if (target in translation === false)
{
if (dynoTrans != null)
{
@@ -79,7 +79,7 @@
}
return result;
};
}
window._ = translate;
+44 -20
View File
@@ -1,34 +1,58 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>A Dark Room</title>
<style>
body {
background-color: #000000;
color: #FFFFFF;
background-color: #000000;
color: #FFFFFF;
line-height: 1.5;
font-size: 22px;
display: flex;
flex-direction: column;
justify-content: center;
}
a {
color: #FFFFFF;
color: #FFFFFF;
}
p {
margin: 10px 20px;
text-align: center;
}
.logo {
width: 100%;
}
.store {
width: 90%;
}
.storeLink {
text-align: center;
}
div {
width: 100%;
margin: auto;
text-align: center;
margin-top: 20px;
}
div {
width: 960px;
margin: auto;
text-align: center;
margin-top: 20px;
}
</style>
</head>
<body>
<center>
<img src="img/Logo1.jpg" />
<div>
<strong>
A Dark Room isn't really mobile-friendly, and it requires arrow keys.<br/>
Sorry about that!<br/>
</strong><br/>
Of course you can <a href='index.html?ignorebrowser=true'>play anyway</a>, but it probably won't work!<br/><br/>
A Dark Room is now native on iOS! Get it on the <a href="https://itunes.apple.com/us/app/a-dark-room/id736683061?mt=8">App Store</a>.
</div>
</center>
<img class="logo" src="img/Logo1.jpg" />
<p>
A Dark Room isn't mobile-friendly, and it requires arrow keys.
<br>
Sorry about that!
</p>
<p>
There are native apps, though! Get them now!
</p>
<a class="storeLink" href="https://itunes.apple.com/app/apple-store/id736683061?pt=2073437&ct=mobilesplash&mt=8">
<img class="store" src="http://i.imgur.com/DMdnDYq.png" alt="App Store">
</a>
<a class="storeLink" href = "https://play.google.com/store/apps/details?id=com.yourcompany.adarkroom&hl=en">
<img class="store" src="http://i.imgur.com/bLWWj4r.png" alt="Google Play">
</a>
</body>
</html>
+50 -9
View File
@@ -24,6 +24,9 @@ var Button = {
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);
@@ -43,6 +46,8 @@ var Button = {
return el;
},
saveCooldown: true,
setDisabled: function(btn, disabled) {
if(btn) {
if(!disabled && !btn.data('onCooldown')) {
@@ -61,24 +66,60 @@ var Button = {
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);
+159 -74
View File
@@ -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>')
@@ -179,16 +179,10 @@
.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
@@ -220,6 +214,14 @@
Ship.init();
}
if($SM.get('config.lightsOff', true)){
Engine.turnLightsOff();
}
if($SM.get('config.hyperMode', true)){
Engine.triggerHyperMode();
}
Engine.saveLanguage();
Engine.travelTo(Room);
@@ -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, '');
@@ -405,6 +403,37 @@
}
},
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'),
@@ -476,16 +505,55 @@
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) {
@@ -513,10 +581,6 @@
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
// where we're going to keep showing them anyway.
@@ -529,6 +593,8 @@
$('div#weapons').animate({opacity: 1}, 300);
}
Engine.activeModule = module;
module.onArrival(diff);
Notifications.printQueue(module);
}
@@ -584,6 +650,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) {
@@ -599,9 +669,7 @@
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;
},
@@ -707,6 +782,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 ){
@@ -732,27 +817,27 @@
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" );
}
+464 -166
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) {
@@ -42,11 +46,6 @@ var Events = {
Events.activeScene = name;
var scene = Events.activeEvent().scenes[name];
// Scene reward
if(scene.reward) {
$SM.addM('stores', scene.reward);
}
// onLoad
if(scene.onLoad) {
scene.onLoad();
@@ -57,6 +56,11 @@ var Events = {
Notifications.notify(null, scene.notification);
}
// Scene reward
if(scene.reward) {
$SM.addM('stores', scene.reward);
}
$('#description', Events.eventPanel()).empty();
$('#buttons', Events.eventPanel()).empty();
if(scene.combat) {
@@ -68,20 +72,36 @@ var Events = {
startCombat: function(scene) {
Engine.event('game event', 'combat');
Events.won = false;
Events.fought = false;
var desc = $('#description', Events.eventPanel());
$('<div>').text(scene.notification).appendTo(desc);
// Draw the wanderer
Events.createFighterDiv('@', World.health, World.getMaxHealth()).attr('id', 'wanderer').appendTo(desc);
// Draw pause button
/* Disable for now, because it doesn't work and looks weird
var pauseBox = $('<div>').attr('id', 'pauseButton').appendTo(desc);
var pause = new Button.Button({
id: 'pause',
text: '',
cooldown: Events._PAUSE_COOLDOWN,
click: Events.togglePause
}).appendTo(pauseBox);
$('<span>').addClass('text').insertBefore(pause.children('.cooldown'));
$('<div>').addClass('clear').appendTo(pauseBox);
Events.setPause(pause, 'set');
Events.removePause(pause, 'set');
*/
var fightBox = $('<div>').attr('id', 'fight').appendTo(desc);
// Draw the wanderer
Events.createFighterDiv('@', World.health, World.getMaxHealth()).attr('id', 'wanderer').appendTo(fightBox);
// Draw the enemy
Events.createFighterDiv(scene.chara, scene.health, scene.health).attr('id', 'enemy').appendTo(desc);
Events.createFighterDiv(scene.chara, scene.health, scene.health).attr('id', 'enemy').appendTo(fightBox);
// Draw the action buttons
var btns = $('#buttons', Events.eventPanel());
var attackBtns = $('<div>').appendTo(btns).attr('id','attackButtons');
var numWeapons = 0;
for(var k in World.Weapons) {
var weapon = World.Weapons[k];
@@ -99,21 +119,106 @@ var Events = {
}
}
numWeapons++;
Events.createAttackButton(k).appendTo(btns);
Events.createAttackButton(k).appendTo(attackBtns);
}
}
if(numWeapons === 0) {
// No weapons? You can punch stuff!
Events.createAttackButton('fists').prependTo(btns);
Events.createAttackButton('fists').prependTo(attackBtns);
}
$('<div>').addClass('clear').appendTo(attackBtns);
Events.createEatMeatButton().appendTo(btns);
var healBtns = $('<div>').appendTo(btns).attr('id','healButtons');
Events.createEatMeatButton().appendTo(healBtns);
if((Path.outfit['medicine'] || 0) !== 0) {
Events.createUseMedsButton().appendTo(btns);
Events.createUseMedsButton().appendTo(healBtns);
}
$('<div>').addClass('clear').appendTo(healBtns);
Events.setHeal(healBtns);
// Set up the enemy attack timer
Events._enemyAttackTimer = Engine.setTimeout(Events.enemyAttack, scene.attackDelay * 1000);
Events._enemyAttackTimer = Engine.setInterval(Events.enemyAttack, scene.attackDelay * 1000);
},
setPause: function(btn, state){
if(!btn) {
btn = $('#pause');
}
var event = btn.closest('#event');
var string, log;
if(state == 'set') {
string = 'start.';
log = 'loaded';
} else {
string = 'resume.';
log = 'paused';
}
btn.children('.text').first().text( _(string) );
Events.paused = (state == 'auto') ? 'auto' : true;
event.addClass('paused');
Button.clearCooldown(btn);
$('#buttons').find('.button').each(function(i){
if($(this).data('onCooldown')){
$(this).children('.cooldown').stop(true,false);
}
});
Engine.log('fight '+ log +'.');
},
removePause: function(btn, state){
if(!btn) {
btn = $('#pause');
}
var event = btn.closest('#event');
var log, time, target;
if(state == 'auto' && Events.paused != 'auto') {
return;
}
switch(state){
case 'set':
Button.cooldown(btn, Events._LEAVE_COOLDOWN);
log = 'started';
time = Events._LEAVE_COOLDOWN * 1000;
target = $();
break;
case 'end':
Button.setDisabled(btn, true);
log = 'ended';
time = Events._FIGHT_SPEED;
target = $();
break;
case 'auto':
Button.cooldown(btn);
/* falls through */
default:
log = 'resumed';
time = Events._PAUSE_COOLDOWN * 1000;
target = $('#buttons').find('.button');
break;
}
Engine.setTimeout(function(){
btn.children('.text').first().text( _('pause.') );
Events.paused = false;
event.removeClass('paused');
target.each(function(i){
if($(this).data('onCooldown')){
Button.cooldown($(this), 'pause');
}
});
Engine.log('Event '+ log);
}, time);
},
togglePause: function(btn, auto){
if(!btn) {
btn = $('#pause');
}
if((auto) && (document.hasFocus() == !Events.paused)) {
return;
}
var f = (Events.paused) ? Events.removePause : Events.setPause;
var state = (auto) ? 'auto' : false;
f(btn, state);
},
createEatMeatButton: function(cooldown) {
@@ -197,48 +302,48 @@ var Events = {
});
},
eatMeat: function() {
if(Path.outfit['cured meat'] > 0) {
Path.outfit['cured meat']--;
setHeal: function(healBtns) {
if(!healBtns){
healBtns = $('#healButtons');
}
healBtns = healBtns.children('.button');
var canHeal = (World.health < World.getMaxHealth());
healBtns.each(function(i){
Button.setDisabled($(this), !canHeal);
});
return canHeal;
},
doHeal: function(healing, cured, btn) {
if(Path.outfit[healing] > 0) {
Path.outfit[healing]--;
World.updateSupplies();
if(Path.outfit['cured meat'] === 0) {
Button.setDisabled($('#eat'), true);
if(Path.outfit[healing] === 0) {
Button.setDisabled(btn, true);
}
var hp = World.health;
hp += World.meatHeal();
hp = hp > World.getMaxHealth() ? World.getMaxHealth() : hp;
var hp = World.health + cured;
hp = Math.min(World.getMaxHealth(),hp);
World.setHp(hp);
Events.setHeal();
if(Events.activeEvent()) {
var w = $('#wanderer');
w.data('hp', hp);
Events.updateFighterDiv(w);
Events.drawFloatText('+' + World.meatHeal(), '#wanderer .hp');
Events.drawFloatText('+' + cured, '#wanderer .hp');
var takeETbutton = Events.setTakeAll();
Events.canLeave(takeETbutton);
}
}
},
useMeds: function() {
if(Path.outfit['medicine'] > 0) {
Path.outfit['medicine']--;
World.updateSupplies();
if(Path.outfit['medicine'] === 0) {
Button.setDisabled($('#meds'), true);
}
eatMeat: function(btn) {
Events.doHeal('cured meat', World.meatHeal(), btn);
},
var hp = World.health;
hp += World.medsHeal();
hp = hp > World.getMaxHealth() ? World.getMaxHealth() : hp;
World.setHp(hp);
if(Events.activeEvent()) {
var w = $('#wanderer');
w.data('hp', hp);
Events.updateFighterDiv(w);
Events.drawFloatText('+' + World.medsHeal(), '#wanderer .hp');
}
}
useMeds: function(btn) {
Events.doHeal('medicine', World.medsHeal(), btn);
},
useWeapon: function(btn) {
@@ -269,8 +374,8 @@ var Events = {
out = true;
}
}
for(var k in mod) {
Path.outfit[k] += mod[k];
for(var m in mod) {
Path.outfit[m] += mod[m];
}
if(out) {
Button.setDisabled(btn, true);
@@ -322,6 +427,33 @@ var Events = {
}
},
damage: function(fighter, enemy, dmg) {
var enemyHp = enemy.data('hp');
var msg = "";
if(typeof dmg == 'number') {
if(dmg < 0) {
msg = _('miss');
dmg = 0;
} else {
msg = '-' + dmg;
enemyHp = ((enemyHp - dmg) < 0) ? 0 : (enemyHp - dmg);
enemy.data('hp', enemyHp);
if(fighter.attr('id') == 'enemy') {
World.setHp(enemyHp);
Events.setHeal();
}
Events.updateFighterDiv(enemy);
}
} else {
if(dmg == 'stun') {
msg = _('stunned');
enemy.data('stunned', Events.STUN_DURATION);
}
}
Events.drawFloatText(msg, $('.hp', enemy));
},
animateMelee: function(fighter, dmg, callback) {
var start, end, enemy;
if(fighter.attr('id') == 'wanderer') {
@@ -335,32 +467,8 @@ var Events = {
}
fighter.stop(true, true).animate(start, Events._FIGHT_SPEED, function() {
var enemyHp = enemy.data('hp');
var msg = "";
if(typeof dmg == 'number') {
if(dmg < 0) {
msg = _('miss');
dmg = 0;
} else {
msg = '-' + dmg;
enemyHp = ((enemyHp - dmg) < 0) ? 0 : (enemyHp - dmg);
enemy.data('hp', enemyHp);
if(fighter.attr('id') == 'enemy') {
World.setHp(enemyHp);
}
Events.updateFighterDiv(enemy);
}
} else {
if(dmg == 'stun') {
msg = _('stunned');
enemy.data('stunned', true);
Engine.setTimeout(function() {
enemy.data('stunned', false);
}, Events.STUN_DURATION);
}
}
Events.drawFloatText(msg, $('.hp', enemy));
Events.damage(fighter, enemy, dmg);
$(this).animate(end, Events._FIGHT_SPEED, callback);
});
@@ -379,33 +487,9 @@ var Events = {
}
$('<div>').css(start).addClass('bullet').text('o').appendTo('#description')
.animate(end, Events._FIGHT_SPEED * 2, 'linear', function() {
var enemyHp = enemy.data('hp');
var msg = "";
if(typeof dmg == 'number') {
if(dmg < 0) {
msg = _('miss');
dmg = 0;
} else {
msg = '-' + dmg;
enemyHp = ((enemyHp - dmg) < 0) ? 0 : (enemyHp - dmg);
enemy.data('hp', enemyHp);
if(fighter.attr('id') == 'enemy') {
World.setHp(enemyHp);
}
Events.updateFighterDiv(enemy);
}
} else {
if(dmg == 'stun') {
msg = _('stunned');
enemy.data('stunned', true);
Engine.setTimeout(function() {
enemy.data('stunned', false);
}, Events.STUN_DURATION);
}
}
.animate(end, Events._FIGHT_SPEED * 2, 'linear', function() {
Events.drawFloatText(msg, $('.hp', enemy));
Events.damage(fighter, enemy, dmg);
$(this).remove();
if(typeof callback == 'function') {
@@ -415,6 +499,7 @@ var Events = {
},
enemyAttack: function() {
// Events.togglePause($('#pause'),'auto');
var scene = Events.activeEvent().scenes[Events.activeScene];
@@ -437,34 +522,41 @@ var Events = {
}
});
}
},
Events._enemyAttackTimer = Engine.setTimeout(Events.enemyAttack, scene.attackDelay * 1000);
endFight: function() {
Events.fought = true;
clearTimeout(Events._enemyAttackTimer);
Events.removePause($('#pause'), 'end');
},
winFight: function() {
Events.won = true;
clearTimeout(Events._enemyAttackTimer);
$('#enemy').animate({opacity: 0}, 300, 'linear', function() {
Engine.setTimeout(function() {
try {
Engine.setTimeout(function() {
if(Events.fought) {
return;
}
Events.endFight();
$('#enemy').animate({opacity: 0}, 300, 'linear', function() {
Engine.setTimeout(function() {
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);
var exitBtns = $('<div>').appendTo(btns).attr('id','exitButtons');
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,85 +564,238 @@ var Events = {
}
},
text: _('leave')
}).appendTo(btns));
});
Button.cooldown(leaveBtn.appendTo(exitBtns));
Events.createEatMeatButton(0).appendTo(btns);
var healBtns = $('<div>').appendTo(btns).attr('id','healButtons');
Events.createEatMeatButton(0).appendTo(healBtns);
if((Path.outfit['medicine'] || 0) !== 0) {
Events.createUseMedsButton(0).appendTo(btns);
Events.createUseMedsButton(0).appendTo(healBtns);
}
$('<div>').addClass('clear').appendTo(healBtns);
Events.setHeal(healBtns);
}
$('<div>').addClass('clear').appendTo(exitBtns);
Events.allowLeave(takeETbtn, leaveBtn);
}, 1000, true);
});
}, Events._FIGHT_SPEED);
},
loseFight: function(){
Events.endFight();
Events.endEvent();
World.die();
},
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');
var dropMenu;
if($('#dropMenu').length){
dropMenu = $('#dropMenu');
$('#dropMenu').empty();
} else {
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);
}
} catch(e) {
// It is possible to die and win if the timing is perfect. Just let it fail.
}
}, 1000, true);
}
$('<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);
lootButtons.appendTo(desc);
var takeET = null;
if(lootButtons.children().length > 0) {
var takeETrow = $('<div>').addClass('takeETrow');
takeET = new Button.Button({
id: 'loot_takeEverything',
text: '',
cooldown: Events._LEAVE_COOLDOWN,
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){
if(!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'));
}
});
Button.setDisabled(takeETbutton, !canTakeSomething);
takeETbutton.data('canTakeEverything', (free >= 0) ? true : false);
return takeETbutton;
},
allowLeave: function(takeETbtn, leaveBtn){
if(takeETbtn){
if(leaveBtn){
takeETbtn.data('leaveBtn', leaveBtn);
}
Events.canLeave(takeETbtn);
}
},
canLeave: function(btn){
var basetext = (btn.data('canTakeEverything')) ? _('take everything') : _('take all you can');
var textbox = btn.children('span');
var takeAndLeave = (btn.data('leaveBtn')) ? btn.data('canTakeEverything') : false;
var text = _(basetext);
if(takeAndLeave){
Button.cooldown(btn);
text += _(' and ') + btn.data('leaveBtn').text();
}
textbox.text( text );
btn.data('canLeave', takeAndLeave);
},
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, stateSkipButtonSet) {
var name = btn.attr('id').substring(5).replace('-', ' ');
if(btn.data('numLeft') > 0) {
var skipButtonSet = stateSkipButtonSet || 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;
@@ -558,39 +803,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();
}
},
@@ -607,6 +846,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);
}
@@ -616,19 +856,27 @@ var Events = {
if(scene.readonly) {
ta.attr('readonly', true);
}
Engine.autoSelect('#description textarea');
}
// Draw any loot
var takeETbtn;
if(scene.loot) {
Events.drawLoot(scene.loot);
takeETbtn = Events.drawLoot(scene.loot);
}
// Draw the buttons
Events.drawButtons(scene);
var exitBtns = $('<div>').attr('id','exitButtons').appendTo($('#buttons', Events.eventPanel()));
leaveBtn = Events.drawButtons(scene);
$('<div>').addClass('clear').appendTo(exitBtns);
Events.allowLeave(takeETbtn, leaveBtn);
},
drawButtons: function(scene) {
var btns = $('#buttons', Events.eventPanel());
var btns = $('#exitButtons', Events.eventPanel());
var btnsList = [];
for(var id in scene.buttons) {
var info = scene.buttons[id];
var b = new Button.Button({
@@ -644,9 +892,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() {
@@ -802,6 +1052,8 @@ var Events = {
if(event) {
Engine.event('game event', 'event');
Engine.keyLock = true;
Engine.tabNavigation = false;
Button.saveCooldown = false;
Events.eventStack.unshift(event);
event.eventPanel = $('<div>').attr('id', 'event').addClass('eventPanel').css('opacity', '0');
if(options != null && options.width != null) {
@@ -834,6 +1086,8 @@ var Events = {
Events.eventStack.shift();
Engine.log(Events.eventStack.length + ' events remaining');
Engine.keyLock = false;
Engine.tabNavigation = true;
Button.saveCooldown = true;
if (Events.BLINK_INTERVAL) {
Events.stopTitleBlink();
}
@@ -846,5 +1100,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 {
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);
}
};
+9 -9
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,
@@ -126,7 +126,7 @@ Events.Encounters = [
enemy: 'shivering man',
enemyName: _('shivering man'),
deathMessage: _('the shivering man is dead'),
chara: 'S',
chara: 'E',
damage: 5,
hit: 0.5,
attackDelay: 1,
@@ -168,7 +168,7 @@ Events.Encounters = [
enemy: 'man-eater',
enemyName: _('man-eater'),
deathMessage: _('the man-eater is dead'),
chara: 'E',
chara: 'T',
damage: 3,
hit: 0.8,
attackDelay: 1,
@@ -205,7 +205,7 @@ Events.Encounters = [
enemy: 'scavenger',
enemyName: _('scavenger'),
deathMessage: _('the scavenger is dead'),
chara: 'S',
chara: 'E',
damage: 4,
hit: 0.8,
attackDelay: 2,
@@ -247,7 +247,7 @@ Events.Encounters = [
enemy: 'lizard',
enemyName: _('lizard'),
deathMessage: _('the lizard is dead'),
chara: 'L',
chara: 'T',
damage: 5,
hit: 0.8,
attackDelay: 2,
@@ -285,7 +285,7 @@ Events.Encounters = [
enemy: 'feral terror',
enemyName: _('feral terror'),
deathMessage: _('the feral terror is dead'),
chara: 'F',
chara: 'T',
damage: 6,
hit: 0.8,
attackDelay: 1,
@@ -365,7 +365,7 @@ Events.Encounters = [
enemy: 'sniper',
enemyName: _('sniper'),
deathMessage: _('the sniper is dead'),
chara: 'S',
chara: 'D',
damage: 15,
hit: 0.8,
attackDelay: 4,
+17 -8
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: {
@@ -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,10 +280,12 @@ Events.Outside = [
buttons: {
'end': {
text: _('go home'),
notification: _('warfare is bloodthirsty'),
nextScene: 'end'
}
}
}
}
}
];
+104 -30
View File
@@ -39,8 +39,7 @@ 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'),
@@ -258,6 +257,62 @@ 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'),
@@ -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: {
@@ -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: {
@@ -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
},
+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) {
+47 -33
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');
}
@@ -226,20 +227,26 @@ var Path = {
}
}
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(needsAppend && stores.children().length > 0) {
if(rNeedsAppend && resources.children().length > 0) {
resources.prependTo(stores);
resources.animate({opacity: 1}, 300, 'linear');
}
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];
}
+1 -1
View File
@@ -97,7 +97,7 @@ var Ship = {
setTitle: function() {
if(Engine.activeModule == this) {
document.title = "An Old Starship";
document.title = _("An Old Starship");
}
},
+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);
}
+40 -21
View File
@@ -28,15 +28,18 @@ var StateManager = {
//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) {
@@ -51,10 +54,10 @@ var StateManager = {
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;
@@ -191,6 +194,21 @@ var StateManager = {
}
},
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){
@@ -200,7 +218,7 @@ var StateManager = {
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();
},
@@ -343,18 +361,18 @@ var StateManager = {
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,7 +388,7 @@ var StateManager = {
if(changed){
$SM.fireUpdate('income', true);
}
Engine._incomeTimeout = setTimeout($SM.collectIncome, 1000);
Engine._incomeTimeout = Engine.setTimeout($SM.collectIncome, 1000);
},
//Thieves
@@ -406,6 +424,7 @@ 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);
+99 -23
View File
@@ -156,6 +156,15 @@ var World = {
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);
},
@@ -543,6 +552,10 @@ var World = {
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) {
@@ -611,10 +624,33 @@ var World = {
}
},
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() {
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'));
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() {
@@ -649,26 +685,60 @@ var World = {
// 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 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;
@@ -726,8 +796,8 @@ var World = {
}
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));
@@ -737,8 +807,8 @@ var World = {
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);
@@ -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');
@@ -823,6 +894,7 @@ var World = {
$('#outerSlider').animate({opacity:'1'}, 600, 'linear');
Button.cooldown($('#embarkButton'));
Engine.keyLock = false;
Engine.tabNavigation = true;
}, 2000, true);
});
}
@@ -831,6 +903,8 @@ var World = {
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');
@@ -849,10 +923,8 @@ var World = {
}
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) {
@@ -865,6 +937,7 @@ var World = {
$('#outerSlider').animate({left: '0px'}, 300);
Engine.activeModule = Path;
Path.onArrival();
Engine.restoreNavigation = true;
},
leaveItAtHome: function(thing) {
@@ -916,6 +989,9 @@ var World = {
},
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'));