mirror of
https://github.com/doublespeakgames/adarkroom.git
synced 2026-06-28 15:22:30 +08:00
Expansion (#707)
This additional content explores the aftermath of an event in The Ensign. A large dungeon, The Executioner, reveals the fate of one of the Wanderers’ most powerful weapons though multiple wings, each ending with a unique boss encounter. The fabricator allows the player to craft powerful items out of alien alloy, introducing new combat mechanics.
This commit is contained in:
+14
-1
@@ -52,6 +52,14 @@ div#stores {
|
|||||||
border: 1px solid #EEE;
|
border: 1px solid #EEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#blueprints:before {
|
||||||
|
background: #272823;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#blueprints {
|
||||||
|
border: 1px solid #EEE;
|
||||||
|
}
|
||||||
|
|
||||||
div#weapons:before {
|
div#weapons:before {
|
||||||
background: #272823;
|
background: #272823;
|
||||||
}
|
}
|
||||||
@@ -173,10 +181,15 @@ body.noMask #buttons > .button {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.endGame {
|
.endGame, .outro {
|
||||||
color:#272823;
|
color:#272823;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#wait-btn {
|
||||||
|
border-color: black;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
#theEnd {
|
#theEnd {
|
||||||
color: #272823;
|
color: #272823;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
div#fabricateButtons {
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#fabricateButtons::before {
|
||||||
|
content: attr(data-legend);
|
||||||
|
position: relative;
|
||||||
|
top: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#blueprints::before {
|
||||||
|
content: attr(data-legend);
|
||||||
|
position: absolute;
|
||||||
|
top: -13px;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#blueprints {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 237px;
|
||||||
|
border: 1px solid black;
|
||||||
|
cursor: default;
|
||||||
|
padding: 5px 10px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.blueprintRow {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.blueprintRow .row_key {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
+51
-4
@@ -46,9 +46,9 @@ div#wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div#saveNotify {
|
div#saveNotify {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
top: 20px;
|
top: 10px;
|
||||||
right: 0px;
|
right: 20px;
|
||||||
background: white;
|
background: white;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ span.customSelectOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.headerButton {
|
div.headerButton {
|
||||||
font-size: 18px;
|
font-size: 17px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
float: left;
|
float: left;
|
||||||
border-left: 1px solid black;
|
border-left: 1px solid black;
|
||||||
@@ -561,6 +561,53 @@ body.noMask #description {
|
|||||||
margin-left: -50%;
|
margin-left: -50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fighter.shield > .label::before {
|
||||||
|
content: '(';
|
||||||
|
position: absolute;
|
||||||
|
left: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.shield > .label::after {
|
||||||
|
content: ')';
|
||||||
|
position: absolute;
|
||||||
|
right: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.energised > .label {
|
||||||
|
font-size: 2em;
|
||||||
|
font-style: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.meditation > .label {
|
||||||
|
font-size: 1.5em;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes exploding {
|
||||||
|
0% { transform: translate(0, 0); }
|
||||||
|
25% { transform: translate(-10px, 0); }
|
||||||
|
75% { transform: translate(10px, 0); }
|
||||||
|
100% { transform: translate(0, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.exploding > .label {
|
||||||
|
animation: exploding 200ms linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.venomous > .label {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-style: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.enraged > .label {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fighter.boost > .label {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
#description .bullet {
|
#description .bullet {
|
||||||
padding: 0px 20px 0px 20px;
|
padding: 0px 20px 0px 20px;
|
||||||
bottom: 25px;
|
bottom: 25px;
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#outfitting:before ,div#perks:before {
|
div#outfitting:before, div#perks:before {
|
||||||
content: attr(data-legend);
|
content: attr(data-legend);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -13px;
|
top: -13px;
|
||||||
|
|||||||
@@ -137,6 +137,19 @@
|
|||||||
padding-top:10%;
|
padding-top:10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.outroContainer {
|
||||||
|
padding-top:10%;
|
||||||
|
width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outro {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #FFF;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.endGame {
|
.endGame {
|
||||||
font-size:48px;
|
font-size:48px;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
@@ -152,3 +165,10 @@
|
|||||||
.endGameOption:hover {
|
.endGameOption:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#wait-btn {
|
||||||
|
border-color: #fff;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0 auto;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|||||||
+5
-2
@@ -59,7 +59,8 @@
|
|||||||
<script src="script/world.js"></script>
|
<script src="script/world.js"></script>
|
||||||
<script src="script/path.js"></script>
|
<script src="script/path.js"></script>
|
||||||
<script src="script/ship.js"></script>
|
<script src="script/ship.js"></script>
|
||||||
<script src="script/space.js"></script>
|
<script src="script/space.js"></script>
|
||||||
|
<script src="script/fabricator.js"></script>
|
||||||
<script src="script/prestige.js"></script>
|
<script src="script/prestige.js"></script>
|
||||||
<script src="script/scoring.js"></script>
|
<script src="script/scoring.js"></script>
|
||||||
<!-- Event modules -->
|
<!-- Event modules -->
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
<script src="script/events/encounters.js"></script>
|
<script src="script/events/encounters.js"></script>
|
||||||
<script src="script/events/setpieces.js"></script>
|
<script src="script/events/setpieces.js"></script>
|
||||||
<script src="script/events/marketing.js"></script>
|
<script src="script/events/marketing.js"></script>
|
||||||
|
<script src="script/events/executioner.js"></script>
|
||||||
|
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
var oldIE = false;
|
var oldIE = false;
|
||||||
@@ -83,7 +85,8 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="css/path.css" />
|
<link rel="stylesheet" type="text/css" href="css/path.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/world.css" />
|
<link rel="stylesheet" type="text/css" href="css/world.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/ship.css" />
|
<link rel="stylesheet" type="text/css" href="css/ship.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/space.css" />
|
<link rel="stylesheet" type="text/css" href="css/space.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/fabricator.css" />
|
||||||
|
|
||||||
<script src="script/localization.js"></script>
|
<script src="script/localization.js"></script>
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
|
|||||||
+5
-1
@@ -20,7 +20,8 @@ var Button = {
|
|||||||
})
|
})
|
||||||
.data("handler", typeof options.click == 'function' ? options.click : function() { Engine.log("click"); })
|
.data("handler", typeof options.click == 'function' ? options.click : function() { Engine.log("click"); })
|
||||||
.data("remaining", 0)
|
.data("remaining", 0)
|
||||||
.data("cooldown", typeof options.cooldown == 'number' ? options.cooldown : 0);
|
.data("cooldown", typeof options.cooldown == 'number' ? options.cooldown : 0)
|
||||||
|
.data('boosted', options.boosted ?? (() => false));
|
||||||
|
|
||||||
el.append($("<div>").addClass('cooldown'));
|
el.append($("<div>").addClass('cooldown'));
|
||||||
|
|
||||||
@@ -68,6 +69,9 @@ var Button = {
|
|||||||
|
|
||||||
cooldown: function(btn, option) {
|
cooldown: function(btn, option) {
|
||||||
var cd = btn.data("cooldown");
|
var cd = btn.data("cooldown");
|
||||||
|
if (btn.data('boosted')()) {
|
||||||
|
cd /= 2;
|
||||||
|
}
|
||||||
var id = 'cooldown.'+ btn.attr('id');
|
var id = 'cooldown.'+ btn.attr('id');
|
||||||
if(cd > 0) {
|
if(cd > 0) {
|
||||||
if(typeof option == 'number') {
|
if(typeof option == 'number') {
|
||||||
|
|||||||
+791
-789
File diff suppressed because it is too large
Load Diff
+352
-74
@@ -8,8 +8,18 @@ var Events = {
|
|||||||
_FIGHT_SPEED: 100,
|
_FIGHT_SPEED: 100,
|
||||||
_EAT_COOLDOWN: 5,
|
_EAT_COOLDOWN: 5,
|
||||||
_MEDS_COOLDOWN: 7,
|
_MEDS_COOLDOWN: 7,
|
||||||
|
_HYPO_COOLDOWN: 7,
|
||||||
|
_SHIELD_COOLDOWN: 10,
|
||||||
|
_STIM_COOLDOWN: 10,
|
||||||
_LEAVE_COOLDOWN: 1,
|
_LEAVE_COOLDOWN: 1,
|
||||||
STUN_DURATION: 4000,
|
STUN_DURATION: 4000,
|
||||||
|
ENERGISE_MULTIPLIER: 4,
|
||||||
|
EXPLOSION_DURATION: 3000,
|
||||||
|
ENRAGE_DURATION: 4000,
|
||||||
|
MEDITATE_DURATION: 5000,
|
||||||
|
BOOST_DURATION: 3000,
|
||||||
|
BOOST_DAMAGE: 10,
|
||||||
|
DOT_TICK: 1000,
|
||||||
BLINK_INTERVAL: false,
|
BLINK_INTERVAL: false,
|
||||||
init: function(options) {
|
init: function(options) {
|
||||||
this.options = $.extend(
|
this.options = $.extend(
|
||||||
@@ -133,11 +143,59 @@ var Events = {
|
|||||||
if((Path.outfit['medicine'] || 0) !== 0) {
|
if((Path.outfit['medicine'] || 0) !== 0) {
|
||||||
Events.createUseMedsButton().appendTo(healBtns);
|
Events.createUseMedsButton().appendTo(healBtns);
|
||||||
}
|
}
|
||||||
|
if((Path.outfit['hypo'] || 0) !== 0) {
|
||||||
|
Events.createUseHypoButton().appendTo(healBtns);
|
||||||
|
}
|
||||||
|
if ((Path.outfit['stim'] ?? 0) > 0) {
|
||||||
|
Events.createStimButton().appendTo(healBtns);
|
||||||
|
}
|
||||||
|
if($SM.get('stores["kinetic armour"]', true) > 0) {
|
||||||
|
Events.createShieldButton().appendTo(healBtns);
|
||||||
|
}
|
||||||
$('<div>').addClass('clear').appendTo(healBtns);
|
$('<div>').addClass('clear').appendTo(healBtns);
|
||||||
Events.setHeal(healBtns);
|
Events.setHeal(healBtns);
|
||||||
|
|
||||||
// Set up the enemy attack timer
|
// Set up the enemy attack timers
|
||||||
Events._enemyAttackTimer = Engine.setInterval(Events.enemyAttack, scene.attackDelay * 1000);
|
Events.startEnemyAttacks();
|
||||||
|
Events._specialTimers = (scene.specials ?? []).map(s => Engine.setInterval(
|
||||||
|
() => {
|
||||||
|
const enemy = $('#enemy');
|
||||||
|
const text = s.action(enemy);
|
||||||
|
Events.updateFighterDiv(enemy);
|
||||||
|
if (text) {
|
||||||
|
Events.drawFloatText(text, $('.hp', enemy))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
s.delay * 1000
|
||||||
|
));
|
||||||
|
},
|
||||||
|
|
||||||
|
startEnemyAttacks: (delay) => {
|
||||||
|
clearInterval(Events._enemyAttackTimer);
|
||||||
|
const scene = Events.activeEvent().scenes[Events.activeScene];
|
||||||
|
Events._enemyAttackTimer = Engine.setInterval(Events.enemyAttack, (delay ?? scene.attackDelay) * 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
setStatus: (fighter, status) => {
|
||||||
|
fighter.data('status', status);
|
||||||
|
if (status === 'enraged' && fighter.attr('id') === 'enemy') {
|
||||||
|
Events.startEnemyAttacks(0.5);
|
||||||
|
setTimeout(() => {
|
||||||
|
fighter.data('status', 'none');
|
||||||
|
Events.startEnemyAttacks();
|
||||||
|
}, Events.ENRAGE_DURATION);
|
||||||
|
}
|
||||||
|
if (status === 'meditation') {
|
||||||
|
Events._meditateDmg = 0;
|
||||||
|
setTimeout(() => {
|
||||||
|
fighter.data('status', 'none');
|
||||||
|
}, Events.MEDITATE_DURATION);
|
||||||
|
}
|
||||||
|
if (status === 'boost') {
|
||||||
|
setTimeout(() => {
|
||||||
|
fighter.data('status', 'none');
|
||||||
|
}, Events.BOOST_DURATION);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setPause: function(btn, state){
|
setPause: function(btn, state){
|
||||||
@@ -261,6 +319,43 @@ var Events = {
|
|||||||
return btn;
|
return btn;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createUseHypoButton: function(cooldown) {
|
||||||
|
if (cooldown == null) {
|
||||||
|
cooldown = Events._HYPO_COOLDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
var btn = new Button.Button({
|
||||||
|
id: 'hypo',
|
||||||
|
text: _('use hypo'),
|
||||||
|
cooldown: cooldown,
|
||||||
|
click: Events.useHypo,
|
||||||
|
cost: { 'hypo': 1 }
|
||||||
|
});
|
||||||
|
|
||||||
|
if((Path.outfit['hypo'] ?? 0) > 0) {
|
||||||
|
Button.setDisabled(btn, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn;
|
||||||
|
},
|
||||||
|
|
||||||
|
createShieldButton: function() {
|
||||||
|
var btn = new Button.Button({
|
||||||
|
id: 'shld',
|
||||||
|
text: _('shield'),
|
||||||
|
cooldown: Events._SHIELD_COOLDOWN,
|
||||||
|
click: Events.useShield
|
||||||
|
});
|
||||||
|
return btn;
|
||||||
|
},
|
||||||
|
|
||||||
|
createStimButton: () => new Button.Button({
|
||||||
|
id: 'use-stim',
|
||||||
|
text: _('boost'),
|
||||||
|
cooldown: Events._STIM_COOLDOWN,
|
||||||
|
click: Events.useStim
|
||||||
|
}),
|
||||||
|
|
||||||
createAttackButton: function(weaponName) {
|
createAttackButton: function(weaponName) {
|
||||||
var weapon = World.Weapons[weaponName];
|
var weapon = World.Weapons[weaponName];
|
||||||
var cd = weapon.cooldown;
|
var cd = weapon.cooldown;
|
||||||
@@ -270,10 +365,11 @@ var Events = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var btn = new Button.Button({
|
var btn = new Button.Button({
|
||||||
id: 'attack_' + weaponName.replace(' ', '-'),
|
id: 'attack_' + weaponName.replace(/ /g, '-'),
|
||||||
text: weapon.verb,
|
text: weapon.verb,
|
||||||
cooldown: cd,
|
cooldown: cd,
|
||||||
click: Events.useWeapon,
|
click: Events.useWeapon,
|
||||||
|
boosted: () => $('#wanderer').data('status') === 'boost',
|
||||||
cost: weapon.cost
|
cost: weapon.cost
|
||||||
});
|
});
|
||||||
if(typeof weapon.damage == 'number' && weapon.damage > 0) {
|
if(typeof weapon.damage == 'number' && weapon.damage > 0) {
|
||||||
@@ -290,15 +386,16 @@ var Events = {
|
|||||||
return btn;
|
return btn;
|
||||||
},
|
},
|
||||||
|
|
||||||
drawFloatText: function(text, parent) {
|
drawFloatText: function(text, parent, cb) {
|
||||||
$('<div>').text(text).addClass('damageText').appendTo(parent).animate({
|
$('<div>').text(text).addClass('damageText').appendTo(parent).animate({
|
||||||
'bottom': '50px',
|
'bottom': '70px',
|
||||||
'opacity': '0'
|
'opacity': '0'
|
||||||
},
|
},
|
||||||
300,
|
700,
|
||||||
'linear',
|
'linear',
|
||||||
function() {
|
function() {
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
|
cb && cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -309,7 +406,8 @@ var Events = {
|
|||||||
healBtns = healBtns.children('.button');
|
healBtns = healBtns.children('.button');
|
||||||
var canHeal = (World.health < World.getMaxHealth());
|
var canHeal = (World.health < World.getMaxHealth());
|
||||||
healBtns.each(function(i){
|
healBtns.each(function(i){
|
||||||
Button.setDisabled($(this), !canHeal);
|
const btn = $(this);
|
||||||
|
Button.setDisabled(btn, !canHeal && btn.attr('id') !== 'shld');
|
||||||
});
|
});
|
||||||
return canHeal;
|
return canHeal;
|
||||||
},
|
},
|
||||||
@@ -348,9 +446,27 @@ var Events = {
|
|||||||
AudioEngine.playSound(AudioLibrary.USE_MEDS);
|
AudioEngine.playSound(AudioLibrary.USE_MEDS);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
useHypo: btn => {
|
||||||
|
Events.doHeal('hypo', World.hypoHeal(), btn);
|
||||||
|
AudioEngine.playSound(AudioLibrary.USE_MEDS);
|
||||||
|
},
|
||||||
|
|
||||||
|
useShield: btn => {
|
||||||
|
const player = $('#wanderer');
|
||||||
|
player.data('status', 'shield');
|
||||||
|
Events.updateFighterDiv(player);
|
||||||
|
},
|
||||||
|
|
||||||
|
useStim: btn => {
|
||||||
|
const player = $('#wanderer');
|
||||||
|
player.data('status', 'boost');
|
||||||
|
Events.dotDamage(player, Events.BOOST_DAMAGE);
|
||||||
|
Events.updateFighterDiv(player);
|
||||||
|
},
|
||||||
|
|
||||||
useWeapon: function(btn) {
|
useWeapon: function(btn) {
|
||||||
if(Events.activeEvent()) {
|
if(Events.activeEvent()) {
|
||||||
var weaponName = btn.attr('id').substring(7).replace('-', ' ');
|
var weaponName = btn.attr('id').substring(7).replace(/-/g, ' ');
|
||||||
var weapon = World.Weapons[weaponName];
|
var weapon = World.Weapons[weaponName];
|
||||||
if(weapon.type == 'unarmed') {
|
if(weapon.type == 'unarmed') {
|
||||||
if(!$SM.get('character.punches')) $SM.set('character.punches', 0);
|
if(!$SM.get('character.punches')) $SM.set('character.punches', 0);
|
||||||
@@ -436,29 +552,103 @@ var Events = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attackFn($('#wanderer'), dmg, function() {
|
attackFn($('#wanderer'), dmg, function() {
|
||||||
if($('#enemy').data('hp') <= 0 && !Events.won) {
|
const enemy = $('#enemy');
|
||||||
|
const enemyHp = enemy.data('hp');
|
||||||
|
const scene = Events.activeEvent().scenes[Events.activeScene];
|
||||||
|
const atHealth = scene.atHealth ?? {};
|
||||||
|
const explosion = scene.explosion;
|
||||||
|
|
||||||
|
for (const [k, action] of Object.entries(atHealth)) {
|
||||||
|
const hpThreshold = Number(k);
|
||||||
|
if (enemyHp <= hpThreshold && enemyHp + dmg > hpThreshold) {
|
||||||
|
action(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemyHp <= 0 && !Events.won) {
|
||||||
// Success!
|
// Success!
|
||||||
Events.winFight();
|
if (explosion) {
|
||||||
|
Events.explode(enemy, $('#wanderer'), explosion);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Events.winFight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
damage: function(fighter, enemy, dmg, type) {
|
explode: (enemy, player, dmg) => {
|
||||||
|
Events.clearTimeouts();
|
||||||
|
enemy.addClass('exploding');
|
||||||
|
setTimeout(() => {
|
||||||
|
enemy.removeClass('exploding');
|
||||||
|
$('.label', enemy).text('*');
|
||||||
|
Events.damage(enemy, player, dmg, 'ranged', () => {
|
||||||
|
if (!Events.checkPlayerDeath()) {
|
||||||
|
Events.winFight();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, Events.EXPLOSION_DURATION);
|
||||||
|
},
|
||||||
|
|
||||||
|
dotDamage: (target, dmg) => {
|
||||||
|
const hp = Math.max(0, target.data('hp') - dmg);
|
||||||
|
target.data('hp', hp);
|
||||||
|
if(target.attr('id') == 'wanderer') {
|
||||||
|
World.setHp(hp);
|
||||||
|
Events.setHeal();
|
||||||
|
Events.checkPlayerDeath();
|
||||||
|
}
|
||||||
|
else if(hp <= 0 && !Events.won) {
|
||||||
|
Events.winFight();
|
||||||
|
}
|
||||||
|
Events.updateFighterDiv(target);
|
||||||
|
Events.drawFloatText(`-${dmg}`, $('.hp', target));
|
||||||
|
},
|
||||||
|
|
||||||
|
damage: function(fighter, enemy, dmg, type, cb) {
|
||||||
var enemyHp = enemy.data('hp');
|
var enemyHp = enemy.data('hp');
|
||||||
|
const maxHp = enemy.data('maxHp');
|
||||||
var msg = "";
|
var msg = "";
|
||||||
|
const shielded = enemy.data('status') === 'shield';
|
||||||
|
const energised = fighter.data('status') === 'energised';
|
||||||
|
const venomous = fighter.data('status') === 'venomous';
|
||||||
|
const meditating = enemy.data('status') === 'meditation';
|
||||||
if(typeof dmg == 'number') {
|
if(typeof dmg == 'number') {
|
||||||
if(dmg < 0) {
|
if(dmg < 0) {
|
||||||
msg = _('miss');
|
msg = _('miss');
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
} else {
|
} else {
|
||||||
msg = '-' + dmg;
|
if (energised) {
|
||||||
enemyHp = ((enemyHp - dmg) < 0) ? 0 : (enemyHp - dmg);
|
dmg *= this.ENERGISE_MULTIPLIER;
|
||||||
enemy.data('hp', enemyHp);
|
|
||||||
if(fighter.attr('id') == 'enemy') {
|
|
||||||
World.setHp(enemyHp);
|
|
||||||
Events.setHeal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meditating) {
|
||||||
|
Events._meditateDmg = (Events._meditateDmg ?? 0) + dmg;
|
||||||
|
msg = dmg;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = (shielded ? '+' : '-') + dmg;
|
||||||
|
enemyHp = Math.min(maxHp, Math.max(0, enemyHp + (shielded ? dmg : -dmg)));
|
||||||
|
enemy.data('hp', enemyHp);
|
||||||
|
if(fighter.attr('id') == 'enemy') {
|
||||||
|
World.setHp(enemyHp);
|
||||||
|
Events.setHeal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (venomous && !shielded) {
|
||||||
|
Events._dotTimer = setInterval(() => {
|
||||||
|
Events.dotDamage(enemy, Math.floor(dmg / 2));
|
||||||
|
}, Events.DOT_TICK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shielded) {
|
||||||
|
// shields break in one hit
|
||||||
|
enemy.data('status', 'none');
|
||||||
|
}
|
||||||
|
|
||||||
Events.updateFighterDiv(enemy);
|
Events.updateFighterDiv(enemy);
|
||||||
|
|
||||||
// play variation audio for weapon type
|
// play variation audio for weapon type
|
||||||
@@ -478,11 +668,18 @@ var Events = {
|
|||||||
} else {
|
} else {
|
||||||
if(dmg == 'stun') {
|
if(dmg == 'stun') {
|
||||||
msg = _('stunned');
|
msg = _('stunned');
|
||||||
enemy.data('stunned', Events.STUN_DURATION);
|
enemy.data('stunned', true);
|
||||||
|
setTimeout(() => enemy.data('stunned', false), Events.STUN_DURATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.drawFloatText(msg, $('.hp', enemy));
|
if (energised || venomous) {
|
||||||
|
// attack buffs only applies to one hit
|
||||||
|
fighter.data('status', 'none');
|
||||||
|
Events.updateFighterDiv(fighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Events.drawFloatText(msg, $('.hp', enemy), cb);
|
||||||
},
|
},
|
||||||
|
|
||||||
animateMelee: function(fighter, dmg, callback) {
|
animateMelee: function(fighter, dmg, callback) {
|
||||||
@@ -533,32 +730,47 @@ var Events = {
|
|||||||
// Events.togglePause($('#pause'),'auto');
|
// Events.togglePause($('#pause'),'auto');
|
||||||
|
|
||||||
var scene = Events.activeEvent().scenes[Events.activeScene];
|
var scene = Events.activeEvent().scenes[Events.activeScene];
|
||||||
|
const enemy = $('#enemy');
|
||||||
|
const stunned = enemy.data('stunned');
|
||||||
|
const meditating = enemy.data('status') === 'meditation';
|
||||||
|
|
||||||
if(!$('#enemy').data('stunned')) {
|
if(!stunned && !meditating) {
|
||||||
var toHit = scene.hit;
|
var toHit = scene.hit;
|
||||||
toHit *= $SM.hasPerk('evasive') ? 0.8 : 1;
|
toHit *= $SM.hasPerk('evasive') ? 0.8 : 1;
|
||||||
var dmg = -1;
|
var dmg = -1;
|
||||||
if(Math.random() <= toHit) {
|
if ((Events._meditateDmg ?? 0) > 0) {
|
||||||
|
dmg = Events._meditateDmg;
|
||||||
|
Events._meditateDmg = 0;
|
||||||
|
}
|
||||||
|
else if(Math.random() <= toHit) {
|
||||||
dmg = scene.damage;
|
dmg = scene.damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
var attackFn = scene.ranged ? Events.animateRanged : Events.animateMelee;
|
var attackFn = scene.ranged ? Events.animateRanged : Events.animateMelee;
|
||||||
|
|
||||||
attackFn($('#enemy'), dmg, function() {
|
attackFn($('#enemy'), dmg, Events.checkPlayerDeath);
|
||||||
if($('#wanderer').data('hp') <= 0) {
|
|
||||||
// Failure!
|
|
||||||
clearTimeout(Events._enemyAttackTimer);
|
|
||||||
Events.endEvent();
|
|
||||||
World.die();
|
|
||||||
AudioEngine.playSound(AudioLibrary.LOSE_FIGHT);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkPlayerDeath: () => {
|
||||||
|
if($('#wanderer').data('hp') <= 0) {
|
||||||
|
Events.clearTimeouts();
|
||||||
|
Events.endEvent();
|
||||||
|
World.die();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
clearTimeouts: () => {
|
||||||
|
clearTimeout(Events._enemyAttackTimer);
|
||||||
|
Events._specialTimers.forEach(clearTimeout);
|
||||||
|
clearTimeout(Events._dotTimer);
|
||||||
|
},
|
||||||
|
|
||||||
endFight: function() {
|
endFight: function() {
|
||||||
Events.fought = true;
|
Events.fought = true;
|
||||||
clearTimeout(Events._enemyAttackTimer);
|
Events.clearTimeouts();
|
||||||
Events.removePause($('#pause'), 'end');
|
Events.removePause($('#pause'), 'end');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -605,6 +817,9 @@ var Events = {
|
|||||||
if((Path.outfit['medicine'] || 0) !== 0) {
|
if((Path.outfit['medicine'] || 0) !== 0) {
|
||||||
Events.createUseMedsButton(0).appendTo(healBtns);
|
Events.createUseMedsButton(0).appendTo(healBtns);
|
||||||
}
|
}
|
||||||
|
if (Path.outfit['hypo'] ?? 0 > 0) {
|
||||||
|
Events.createUseHypoButton(0).appendTo(healBtns);
|
||||||
|
}
|
||||||
$('<div>').addClass('clear').appendTo(healBtns);
|
$('<div>').addClass('clear').appendTo(healBtns);
|
||||||
Events.setHeal(healBtns);
|
Events.setHeal(healBtns);
|
||||||
}
|
}
|
||||||
@@ -623,7 +838,7 @@ var Events = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
drawDrop:function(btn) {
|
drawDrop:function(btn) {
|
||||||
var name = btn.attr('id').substring(5).replace('-', ' ');
|
var name = btn.attr('id').substring(5).replace(/-/g, ' ');
|
||||||
var needsAppend = false;
|
var needsAppend = false;
|
||||||
var weight = Path.getWeight(name);
|
var weight = Path.getWeight(name);
|
||||||
var freeSpace = Path.getFreeSpace();
|
var freeSpace = Path.getFreeSpace();
|
||||||
@@ -647,7 +862,7 @@ var Events = {
|
|||||||
numToDrop = Path.outfit[k];
|
numToDrop = Path.outfit[k];
|
||||||
}
|
}
|
||||||
if(numToDrop > 0) {
|
if(numToDrop > 0) {
|
||||||
var dropRow = $('<div>').attr('id', 'drop_' + k.replace(' ', '-'))
|
var dropRow = $('<div>').attr('id', 'drop_' + k.replace(/ /g, '-'))
|
||||||
.text(_(k) + ' x' + numToDrop)
|
.text(_(k) + ' x' + numToDrop)
|
||||||
.data('thing', k)
|
.data('thing', k)
|
||||||
.data('num', numToDrop)
|
.data('num', numToDrop)
|
||||||
@@ -679,7 +894,7 @@ var Events = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
drawLootRow: function(name, num){
|
drawLootRow: function(name, num){
|
||||||
var id = name.replace(' ', '-');
|
var id = name.replace(/ /g, '-');
|
||||||
var lootRow = $('<div>').attr('id','loot_' + id).data('item', name).addClass('lootRow');
|
var lootRow = $('<div>').attr('id','loot_' + id).data('item', name).addClass('lootRow');
|
||||||
var take = new Button.Button({
|
var take = new Button.Button({
|
||||||
id: 'take_' + id,
|
id: 'take_' + id,
|
||||||
@@ -790,7 +1005,7 @@ var Events = {
|
|||||||
var btn = $(this);
|
var btn = $(this);
|
||||||
var target = btn.closest('.button');
|
var target = btn.closest('.button');
|
||||||
var thing = btn.data('thing');
|
var thing = btn.data('thing');
|
||||||
var id = 'take_' + thing.replace(' ', '-');
|
var id = 'take_' + thing.replace(/ /g, '-');
|
||||||
var num = btn.data('num');
|
var num = btn.data('num');
|
||||||
var lootButtons = $('#lootButtons');
|
var lootButtons = $('#lootButtons');
|
||||||
Engine.log('dropping ' + num + ' ' + thing);
|
Engine.log('dropping ' + num + ' ' + thing);
|
||||||
@@ -810,7 +1025,7 @@ var Events = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getLoot: function(btn, stateSkipButtonSet) {
|
getLoot: function(btn, stateSkipButtonSet) {
|
||||||
var name = btn.attr('id').substring(5).replace('-', ' ');
|
var name = btn.attr('id').substring(5).replace(/-/g, ' ');
|
||||||
if(btn.data('numLeft') > 0) {
|
if(btn.data('numLeft') > 0) {
|
||||||
var skipButtonSet = stateSkipButtonSet || false;
|
var skipButtonSet = stateSkipButtonSet || false;
|
||||||
var weight = Path.getWeight(name);
|
var weight = Path.getWeight(name);
|
||||||
@@ -867,13 +1082,21 @@ var Events = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
createFighterDiv: function(chara, hp, maxhp) {
|
createFighterDiv: function(chara, hp, maxhp) {
|
||||||
var fighter = $('<div>').addClass('fighter').text(_(chara)).data('hp', hp).data('maxHp', maxhp).data('refname',chara);
|
var fighter = $('<div>')
|
||||||
|
.addClass('fighter')
|
||||||
|
.data('hp', hp)
|
||||||
|
.data('maxHp', maxhp)
|
||||||
|
.data('refname',chara);
|
||||||
|
$('<div>').addClass('label').text(_(chara)).appendTo(fighter);
|
||||||
$('<div>').addClass('hp').text(hp+'/'+maxhp).appendTo(fighter);
|
$('<div>').addClass('hp').text(hp+'/'+maxhp).appendTo(fighter);
|
||||||
return fighter;
|
return fighter;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateFighterDiv: function(fighter) {
|
updateFighterDiv: function(fighter) {
|
||||||
$('.hp', fighter).text(fighter.data('hp') + '/' + fighter.data('maxHp'));
|
$('.hp', fighter).text(fighter.data('hp') + '/' + fighter.data('maxHp'));
|
||||||
|
const status = fighter.data('status');
|
||||||
|
const hasStatus = status && status !== 'none';
|
||||||
|
fighter.attr('class', `fighter${hasStatus ? ` ${status}` : ''}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
startStory: function(scene) {
|
startStory: function(scene) {
|
||||||
@@ -912,13 +1135,19 @@ var Events = {
|
|||||||
var btnsList = [];
|
var btnsList = [];
|
||||||
for(var id in scene.buttons) {
|
for(var id in scene.buttons) {
|
||||||
var info = scene.buttons[id];
|
var info = scene.buttons[id];
|
||||||
var b = new Button.Button({
|
const cost = {
|
||||||
id: id,
|
...info.cost
|
||||||
text: info.text,
|
};
|
||||||
cost: info.cost,
|
if (Path.outfit && Path.outfit['glowstone']) {
|
||||||
click: Events.buttonClick,
|
delete cost.torch;
|
||||||
cooldown: info.cooldown
|
}
|
||||||
}).appendTo(btns);
|
var b = new Button.Button({
|
||||||
|
id,
|
||||||
|
text: info.text,
|
||||||
|
cost,
|
||||||
|
click: Events.buttonClick,
|
||||||
|
cooldown: info.cooldown
|
||||||
|
}).appendTo(btns);
|
||||||
if(typeof info.available == 'function' && !info.available()) {
|
if(typeof info.available == 'function' && !info.available()) {
|
||||||
Button.setDisabled(b, true);
|
Button.setDisabled(b, true);
|
||||||
}
|
}
|
||||||
@@ -932,6 +1161,17 @@ var Events = {
|
|||||||
return (btnsList.length == 1) ? btnsList[0] : false;
|
return (btnsList.length == 1) ? btnsList[0] : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getQuantity: function(store) {
|
||||||
|
if (store === 'water') {
|
||||||
|
return World.water;
|
||||||
|
}
|
||||||
|
if (store === 'hp') {
|
||||||
|
return World.health;
|
||||||
|
}
|
||||||
|
var num = Engine.activeModule == World ? Path.outfit[store] : $SM.get('stores["'+store+'"]', true);
|
||||||
|
return isNaN(num) || num < 0 ? 0 : num;
|
||||||
|
},
|
||||||
|
|
||||||
updateButtons: function() {
|
updateButtons: function() {
|
||||||
var btns = Events.activeEvent().scenes[Events.activeScene].buttons;
|
var btns = Events.activeEvent().scenes[Events.activeScene].buttons;
|
||||||
for(var bId in btns) {
|
for(var bId in btns) {
|
||||||
@@ -940,11 +1180,16 @@ var Events = {
|
|||||||
if(typeof b.available == 'function' && !b.available()) {
|
if(typeof b.available == 'function' && !b.available()) {
|
||||||
Button.setDisabled(btnEl, true);
|
Button.setDisabled(btnEl, true);
|
||||||
} else if(b.cost) {
|
} else if(b.cost) {
|
||||||
|
const cost = {
|
||||||
|
...b.cost
|
||||||
|
};
|
||||||
|
if (Path.outfit && Path.outfit['glowstone']) {
|
||||||
|
delete cost.torch;
|
||||||
|
}
|
||||||
var disabled = false;
|
var disabled = false;
|
||||||
for(var store in b.cost) {
|
for(var store in cost) {
|
||||||
var num = Engine.activeModule == World ? Path.outfit[store] : $SM.get('stores["'+store+'"]', true);
|
var num = Events.getQuantity(store);
|
||||||
if(typeof num != 'number') num = 0;
|
if(num < cost[store]) {
|
||||||
if(num < b.cost[store]) {
|
|
||||||
// Too expensive
|
// Too expensive
|
||||||
disabled = true;
|
disabled = true;
|
||||||
break;
|
break;
|
||||||
@@ -960,14 +1205,27 @@ var Events = {
|
|||||||
// Cost
|
// Cost
|
||||||
var costMod = {};
|
var costMod = {};
|
||||||
if(info.cost) {
|
if(info.cost) {
|
||||||
for(var store in info.cost) {
|
const cost = {
|
||||||
var num = Engine.activeModule == World ? Path.outfit[store] : $SM.get('stores["'+store+'"]', true);
|
...info.cost
|
||||||
if(typeof num != 'number') num = 0;
|
};
|
||||||
if(num < info.cost[store]) {
|
if (Path.outfit && Path.outfit['glowstone']) {
|
||||||
|
delete cost.torch;
|
||||||
|
}
|
||||||
|
for(var store in cost) {
|
||||||
|
var num = Events.getQuantity(store);
|
||||||
|
if(num < cost[store]) {
|
||||||
// Too expensive
|
// Too expensive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
costMod[store] = -info.cost[store];
|
if (store === 'water') {
|
||||||
|
World.setWater(World.water - cost[store]);
|
||||||
|
}
|
||||||
|
else if (store === 'hp') {
|
||||||
|
World.setHp(World.hp - cost[store]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
costMod[store] = -cost[store];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(Engine.activeModule == World) {
|
if(Engine.activeModule == World) {
|
||||||
for(var k in costMod) {
|
for(var k in costMod) {
|
||||||
@@ -1002,8 +1260,16 @@ var Events = {
|
|||||||
if (info.link) {
|
if (info.link) {
|
||||||
Events.endEvent();
|
Events.endEvent();
|
||||||
window.open(info.link);
|
window.open(info.link);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next Event
|
||||||
|
if (info.nextEvent) {
|
||||||
|
const eventData = Events.Setpieces[info.nextEvent] || Events.Executioner[info.nextEvent];
|
||||||
|
Events.switchEvent(eventData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Next Scene
|
// Next Scene
|
||||||
if(info.nextScene) {
|
if(info.nextScene) {
|
||||||
if(info.nextScene == 'end') {
|
if(info.nextScene == 'end') {
|
||||||
@@ -1104,27 +1370,39 @@ var Events = {
|
|||||||
return Events.activeEvent().eventPanel;
|
return Events.activeEvent().eventPanel;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
switchEvent: event => {
|
||||||
|
if (!event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Events.eventPanel().remove();
|
||||||
|
Events.activeEvent().eventPanel = null;
|
||||||
|
Events.eventStack.shift();
|
||||||
|
Events.startEvent(event);
|
||||||
|
},
|
||||||
|
|
||||||
startEvent: function(event, options) {
|
startEvent: function(event, options) {
|
||||||
if(event) {
|
if(!event) {
|
||||||
Engine.event('game event', 'event');
|
return;
|
||||||
Engine.keyLock = true;
|
}
|
||||||
Engine.tabNavigation = false;
|
event.audio && AudioEngine.playEventMusic(event.audio);
|
||||||
Button.saveCooldown = false;
|
Engine.event('game event', 'event');
|
||||||
Events.eventStack.unshift(event);
|
Engine.keyLock = true;
|
||||||
event.eventPanel = $('<div>').attr('id', 'event').addClass('eventPanel').css('opacity', '0');
|
Engine.tabNavigation = false;
|
||||||
if(options != null && options.width != null) {
|
Button.saveCooldown = false;
|
||||||
Events.eventPanel().css('width', options.width);
|
Events.eventStack.unshift(event);
|
||||||
}
|
event.eventPanel = $('<div>').attr('id', 'event').addClass('eventPanel').css('opacity', '0');
|
||||||
$('<div>').addClass('eventTitle').text(Events.activeEvent().title).appendTo(Events.eventPanel());
|
if(options != null && options.width != null) {
|
||||||
$('<div>').attr('id', 'description').appendTo(Events.eventPanel());
|
Events.eventPanel().css('width', options.width);
|
||||||
$('<div>').attr('id', 'buttons').appendTo(Events.eventPanel());
|
}
|
||||||
Events.loadScene('start');
|
$('<div>').addClass('eventTitle').text(Events.activeEvent().title).appendTo(Events.eventPanel());
|
||||||
$('div#wrapper').append(Events.eventPanel());
|
$('<div>').attr('id', 'description').appendTo(Events.eventPanel());
|
||||||
Events.eventPanel().animate({opacity: 1}, Events._PANEL_FADE, 'linear');
|
$('<div>').attr('id', 'buttons').appendTo(Events.eventPanel());
|
||||||
var currentSceneInformation = Events.activeEvent().scenes[Events.activeScene];
|
Events.loadScene('start');
|
||||||
if (currentSceneInformation.blink) {
|
$('div#wrapper').append(Events.eventPanel());
|
||||||
Events.blinkTitle();
|
Events.eventPanel().animate({opacity: 1}, Events._PANEL_FADE, 'linear');
|
||||||
}
|
var currentSceneInformation = Events.activeEvent().scenes[Events.activeScene];
|
||||||
|
if (currentSceneInformation.blink) {
|
||||||
|
Events.blinkTitle();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,244 @@
|
|||||||
|
/**
|
||||||
|
* Module that registers the fabricator functionality
|
||||||
|
*/
|
||||||
|
const Fabricator = {
|
||||||
|
_STORES_OFFSET: 0,
|
||||||
|
name: _('Fabricator'),
|
||||||
|
Craftables: {
|
||||||
|
'energy blade': {
|
||||||
|
name: _('energy blade'),
|
||||||
|
type: 'weapon',
|
||||||
|
buildMsg: _("the blade hums, charged particles sparking and fizzing."),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'fluid recycler': {
|
||||||
|
name: _('fluid recycler'),
|
||||||
|
type: 'upgrade',
|
||||||
|
maximum: 1,
|
||||||
|
buildMsg: _('water out, water in. waste not, want not.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 2
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'cargo drone': {
|
||||||
|
name: _('cargo drone'),
|
||||||
|
type: 'upgrade',
|
||||||
|
maximum: 1,
|
||||||
|
buildMsg: _('the workhorse of the wanderer fleet.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 2
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'kinetic armour': {
|
||||||
|
name: _('kinetic armour'),
|
||||||
|
type: 'upgrade',
|
||||||
|
maximum: 1,
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _('wanderer soldiers succeed by subverting the enemy\'s rage.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 2
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'disruptor': {
|
||||||
|
name: _('disruptor'),
|
||||||
|
type: 'weapon',
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _("somtimes it is best not to fight."),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'hypo': {
|
||||||
|
name: _('hypo'),
|
||||||
|
type: 'tool',
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _('a handful of hypos. life in a vial.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
}),
|
||||||
|
quantity: 5
|
||||||
|
},
|
||||||
|
'stim': {
|
||||||
|
name: _('stim'),
|
||||||
|
type: 'tool',
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _('sometimes it is best to fight without restraint.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'plasma rifle': {
|
||||||
|
name: _('plasma rifle'),
|
||||||
|
type: 'weapon',
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _("the peak of wanderer weapons technology, sleek and deadly."),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'glowstone': {
|
||||||
|
name: _('glow stone'),
|
||||||
|
type: 'tool',
|
||||||
|
blueprintRequired: true,
|
||||||
|
buildMsg: _('a smooth, perfect sphere. its light is inextinguishable.'),
|
||||||
|
cost: () => ({
|
||||||
|
'alien alloy': 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init: () => {
|
||||||
|
|
||||||
|
if (!$SM.get('features.location.fabricator')) {
|
||||||
|
$SM.set('features.location.fabricator', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Fabricator tab
|
||||||
|
Fabricator.tab = Header.addLocation(_("A Whirring Fabricator"), "fabricator", Fabricator, 'ship');
|
||||||
|
|
||||||
|
// Create the Fabricator panel
|
||||||
|
Fabricator.panel = $('<div>').attr('id', "fabricatorPanel")
|
||||||
|
.addClass('location');
|
||||||
|
if (Ship.panel) {
|
||||||
|
Fabricator.panel.insertBefore(Ship.panel);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Fabricator.panel.appendTo('div#locationSlider');
|
||||||
|
}
|
||||||
|
|
||||||
|
$.Dispatch('stateUpdate').subscribe(() => {
|
||||||
|
Fabricator.updateBuildButtons();
|
||||||
|
Fabricator.updateBlueprints();
|
||||||
|
});
|
||||||
|
|
||||||
|
Engine.updateSlider();
|
||||||
|
Fabricator.updateBuildButtons();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onArrival: transition_diff => {
|
||||||
|
Fabricator.setTitle();
|
||||||
|
Fabricator.updateBlueprints(true);
|
||||||
|
|
||||||
|
if(!$SM.get('game.fabricator.seen')) {
|
||||||
|
Notifications.notify(Fabricator, _('the familiar hum of wanderer machinery coming to life. finally, real tools.'));
|
||||||
|
$SM.set('game.fabricator.seen', true);
|
||||||
|
}
|
||||||
|
AudioEngine.playBackgroundMusic(AudioLibrary.MUSIC_SHIP);
|
||||||
|
|
||||||
|
Engine.moveStoresView(null, transition_diff);
|
||||||
|
},
|
||||||
|
|
||||||
|
setTitle: () => {
|
||||||
|
if(Engine.activeModule == Fabricator) {
|
||||||
|
document.title = _("A Whirring Fabricator");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateBuildButtons: () => {
|
||||||
|
let section = $('#fabricateButtons');
|
||||||
|
let needsAppend = false;
|
||||||
|
if (section.length === 0) {
|
||||||
|
section = $('<div>').attr({ 'id': 'fabricateButtons', 'data-legend': _('fabricate:') }).css('opacity', 0);
|
||||||
|
needsAppend = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [ key, value ] of Object.entries(Fabricator.Craftables)) {
|
||||||
|
const max = $SM.num(key, value) + 1 > value.maximum;
|
||||||
|
if (!value.button) {
|
||||||
|
if (Fabricator.canFabricate(key)) {
|
||||||
|
const name = _(value.name) + ((value.quantity ?? 1) > 1 ? ` (x${value.quantity})` : '');
|
||||||
|
value.button = new Button.Button({
|
||||||
|
id: 'fabricate_' + key,
|
||||||
|
cost: value.cost(),
|
||||||
|
text: name,
|
||||||
|
click: Fabricator.fabricate,
|
||||||
|
width: '150px',
|
||||||
|
ttPos: section.children().length > 10 ? 'top right' : 'bottom right'
|
||||||
|
}).css('opacity', 0).attr('fabricateThing', key).appendTo(section).animate({ opacity: 1 }, 300, 'linear');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// refresh the tooltip
|
||||||
|
const costTooltip = $('.tooltip', value.button);
|
||||||
|
costTooltip.empty();
|
||||||
|
const cost = value.cost();
|
||||||
|
for (const [ resource, num ] of Object.entries(cost)) {
|
||||||
|
$("<div>").addClass('row_key').text(_(resource)).appendTo(costTooltip);
|
||||||
|
$("<div>").addClass('row_val').text(num).appendTo(costTooltip);
|
||||||
|
}
|
||||||
|
if (max && value.maxMsg && !value.button.hasClass('disabled')) {
|
||||||
|
Notifications.notify(Fabricator, value.maxMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (max) {
|
||||||
|
Button.setDisabled(value.button, true);
|
||||||
|
} else {
|
||||||
|
Button.setDisabled(value.button, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsAppend && section.children().length > 0) {
|
||||||
|
section.appendTo(Fabricator.panel).animate({ opacity: 1 }, 300, 'linear');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateBlueprints: ignoreStores => {
|
||||||
|
if(!$SM.get('character.blueprints')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let blueprints = $('#blueprints');
|
||||||
|
let needsAppend = false;
|
||||||
|
if(blueprints.length === 0) {
|
||||||
|
needsAppend = true;
|
||||||
|
blueprints = $('<div>').attr({'id': 'blueprints', 'data-legend': _('blueprints')});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const k in $SM.get('character.blueprints')) {
|
||||||
|
const id = 'blueprint_' + k.replace(/ /g, '-');
|
||||||
|
let r = $('#' + id);
|
||||||
|
if($SM.get(`character.blueprints["${k}"]`) && r.length === 0) {
|
||||||
|
r = $('<div>').attr('id', id).addClass('blueprintRow').appendTo(blueprints);
|
||||||
|
$('<div>').addClass('row_key').text(_(k)).appendTo(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(needsAppend && blueprints.children().length > 0) {
|
||||||
|
blueprints.prependTo(Fabricator.panel);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
canFabricate: itemKey =>
|
||||||
|
!Fabricator.Craftables[itemKey].blueprintRequired ||
|
||||||
|
$SM.get(`character.blueprints['${itemKey}']`),
|
||||||
|
|
||||||
|
fabricate: button => {
|
||||||
|
const thing = $(button).attr('fabricateThing');
|
||||||
|
const craftable = Fabricator.Craftables[thing];
|
||||||
|
const numThings = Math.min(0, $SM.get(`stores['${thing}']`, true));
|
||||||
|
|
||||||
|
if (craftable.maximum <= numThings) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const storeMod = {};
|
||||||
|
const cost = craftable.cost();
|
||||||
|
for (const [ key, value ] of Object.entries(cost)) {
|
||||||
|
const have = $SM.get(`stores['${key}']`, true);
|
||||||
|
if (have < value) {
|
||||||
|
Notifications.notify(Fabricator, _(`not enough ${key}`));
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
storeMod[key] = have - value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$SM.setM('stores', storeMod);
|
||||||
|
$SM.add(`stores['${thing}']`, craftable.quantity ?? 1);
|
||||||
|
|
||||||
|
Notifications.notify(Fabricator, craftable.buildMsg);
|
||||||
|
AudioEngine.playSound(AudioLibrary.CRAFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
+10
-4
@@ -16,13 +16,19 @@ var Header = {
|
|||||||
return $('div#header div.headerButton').length > 1;
|
return $('div#header div.headerButton').length > 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
addLocation: function(text, id, module) {
|
addLocation: function(text, id, module, before) {
|
||||||
return $('<div>').attr('id', "location_" + id)
|
const toAdd = $('<div>').attr('id', "location_" + id)
|
||||||
.addClass('headerButton')
|
.addClass('headerButton')
|
||||||
.text(text).click(function() {
|
.text(text).click(function() {
|
||||||
if(Header.canTravel()) {
|
if(Header.canTravel()) {
|
||||||
Engine.travelTo(module);
|
Engine.travelTo(module);
|
||||||
}
|
}
|
||||||
}).appendTo($('div#header'));
|
});
|
||||||
|
|
||||||
|
if (before && $(`#location_${before}`).length > 0) {
|
||||||
|
return toAdd.insertBefore(`#location_${before}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toAdd.appendTo($('div#header'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -661,37 +661,5 @@ var Outside = {
|
|||||||
Outside.updateWorkersView();
|
Outside.updateWorkersView();
|
||||||
Outside.updateVillageIncome();
|
Outside.updateVillageIncome();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
scrollSidebar: function(direction, reset) {
|
|
||||||
|
|
||||||
if( typeof reset != "undefined" ){
|
|
||||||
$('#village').css('top', '0px');
|
|
||||||
$('#storesContainer').css('top', '224px');
|
|
||||||
Outside._STORES_OFFSET = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var momentum = 10;
|
|
||||||
|
|
||||||
// If they hit up, we scroll everything down
|
|
||||||
if( direction == 'up' )
|
|
||||||
momentum = momentum * -1;
|
|
||||||
|
|
||||||
/* Let's stop scrolling if the top or bottom bound is in the viewport, based on direction */
|
|
||||||
if( direction == 'down' && inView( direction, $('#village') ) ){
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}else if( direction == 'up' && inView( direction, $('#storesContainer') ) ){
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollByX( $('#village'), momentum );
|
|
||||||
scrollByX( $('#storesContainer'), momentum );
|
|
||||||
Outside._STORES_OFFSET += momentum;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-35
@@ -10,7 +10,8 @@ var Path = {
|
|||||||
'bullets': 0.1,
|
'bullets': 0.1,
|
||||||
'energy cell': 0.2,
|
'energy cell': 0.2,
|
||||||
'laser rifle': 5,
|
'laser rifle': 5,
|
||||||
'bolas': 0.5
|
'plasma rifle': 5,
|
||||||
|
'bolas': 0.5,
|
||||||
},
|
},
|
||||||
|
|
||||||
name: 'Path',
|
name: 'Path',
|
||||||
@@ -67,7 +68,9 @@ var Path = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCapacity: function() {
|
getCapacity: function() {
|
||||||
if($SM.get('stores.convoy', true) > 0) {
|
if($SM.get('stores["cargo drone"]', true) > 0) {
|
||||||
|
return Path.DEFAULT_BAG_SPACE + 100;
|
||||||
|
} else if($SM.get('stores.convoy', true) > 0) {
|
||||||
return Path.DEFAULT_BAG_SPACE + 60;
|
return Path.DEFAULT_BAG_SPACE + 60;
|
||||||
} else if($SM.get('stores.wagon', true) > 0) {
|
} else if($SM.get('stores.wagon', true) > 0) {
|
||||||
return Path.DEFAULT_BAG_SPACE + 30;
|
return Path.DEFAULT_BAG_SPACE + 30;
|
||||||
@@ -98,7 +101,7 @@ var Path = {
|
|||||||
var needsAppend = false;
|
var needsAppend = false;
|
||||||
if(perks.length === 0) {
|
if(perks.length === 0) {
|
||||||
needsAppend = true;
|
needsAppend = true;
|
||||||
perks = $('<div>').attr({'id': 'perks', 'data-legend': _('perks:')});
|
perks = $('<div>').attr({'id': 'perks', 'data-legend': _('perks')});
|
||||||
}
|
}
|
||||||
for(var k in $SM.get('character.perks')) {
|
for(var k in $SM.get('character.perks')) {
|
||||||
var id = 'perk_' + k.replace(' ', '-');
|
var id = 'perk_' + k.replace(' ', '-');
|
||||||
@@ -129,7 +132,9 @@ var Path = {
|
|||||||
|
|
||||||
// Add the armour row
|
// Add the armour row
|
||||||
var armour = _("none");
|
var armour = _("none");
|
||||||
if($SM.get('stores["s armour"]', true) > 0)
|
if($SM.get('stores["kinetic armour"]', true) > 0)
|
||||||
|
armour = _("kinetic");
|
||||||
|
else if($SM.get('stores["s armour"]', true) > 0)
|
||||||
armour = _("steel");
|
armour = _("steel");
|
||||||
else if($SM.get('stores["i armour"]', true) > 0)
|
else if($SM.get('stores["i armour"]', true) > 0)
|
||||||
armour = _("iron");
|
armour = _("iron");
|
||||||
@@ -169,7 +174,7 @@ var Path = {
|
|||||||
'bayonet': {type: 'weapon' },
|
'bayonet': {type: 'weapon' },
|
||||||
'charm': {type: 'tool'},
|
'charm': {type: 'tool'},
|
||||||
'medicine': {type: 'tool', desc: _('restores') + ' ' + World.MEDS_HEAL + ' ' + _('hp') }
|
'medicine': {type: 'tool', desc: _('restores') + ' ' + World.MEDS_HEAL + ' ' + _('hp') }
|
||||||
}, Room.Craftables);
|
}, Room.Craftables, Fabricator.Craftables);
|
||||||
|
|
||||||
for(var k in carryable) {
|
for(var k in carryable) {
|
||||||
var lk = _(k);
|
var lk = _(k);
|
||||||
@@ -329,35 +334,5 @@ var Path = {
|
|||||||
} else if(e.category == 'income' && Engine.activeModule == Path){
|
} else if(e.category == 'income' && Engine.activeModule == Path){
|
||||||
Path.updateOutfitting();
|
Path.updateOutfitting();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
scrollSidebar: function(direction, reset){
|
|
||||||
|
|
||||||
if( typeof reset != "undefined" ){
|
|
||||||
$('#perks').css('top', '0px');
|
|
||||||
$('#storesContainer').css('top', '206px');
|
|
||||||
Path._STORES_OFFSET = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var momentum = 10;
|
|
||||||
|
|
||||||
if( direction == 'up' )
|
|
||||||
momentum = momentum * -1;
|
|
||||||
|
|
||||||
if( direction == 'down' && inView( direction, $('#perks') ) ){
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}else if( direction == 'up' && inView( direction, $('#storesContainer') ) ){
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollByX( $('#perks'), momentum );
|
|
||||||
scrollByX( $('#storesContainer'), momentum );
|
|
||||||
Path._STORES_OFFSET += momentum;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+13
-9
@@ -826,15 +826,19 @@ var Room = {
|
|||||||
}
|
}
|
||||||
for (var k in $SM.get('stores')) {
|
for (var k in $SM.get('stores')) {
|
||||||
|
|
||||||
var type = null;
|
if (k.indexOf('blueprint') > 0) {
|
||||||
if (Room.Craftables[k]) {
|
// don't show blueprints
|
||||||
type = Room.Craftables[k].type;
|
continue;
|
||||||
} else if (Room.TradeGoods[k]) {
|
|
||||||
type = Room.TradeGoods[k].type;
|
|
||||||
} else if (Room.MiscItems[k]) {
|
|
||||||
type = Room.MiscItems[k].type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const good =
|
||||||
|
Room.Craftables[k] ||
|
||||||
|
Room.TradeGoods[k] ||
|
||||||
|
Room.TradeGoods[k] ||
|
||||||
|
Room.MiscItems[k] ||
|
||||||
|
Fabricator.Craftables[k];
|
||||||
|
const type = good ? good.type : null;
|
||||||
|
|
||||||
var location;
|
var location;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'upgrade':
|
case 'upgrade':
|
||||||
@@ -854,7 +858,7 @@ var Room = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var id = "row_" + k.replace(' ', '-');
|
var id = "row_" + k.replace(/ /g, '-');
|
||||||
var row = $('div#' + id, location);
|
var row = $('div#' + id, location);
|
||||||
var num = $SM.get('stores["' + k + '"]');
|
var num = $SM.get('stores["' + k + '"]');
|
||||||
|
|
||||||
@@ -1139,7 +1143,7 @@ var Room = {
|
|||||||
if (Room.craftUnlocked(k)) {
|
if (Room.craftUnlocked(k)) {
|
||||||
var loc = Room.needsWorkshop(craftable.type) ? craftSection : buildSection;
|
var loc = Room.needsWorkshop(craftable.type) ? craftSection : buildSection;
|
||||||
craftable.button = new Button.Button({
|
craftable.button = new Button.Button({
|
||||||
id: 'build_' + k,
|
id: 'build_' + k.replace(/ /g, '-'),
|
||||||
cost: craftable.cost(),
|
cost: craftable.cost(),
|
||||||
text: _(k),
|
text: _(k),
|
||||||
click: Room.build,
|
click: Room.build,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ var Score = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fullScore = fullScore + $SM.get('stores["alien alloy"]', true) * 10;
|
fullScore = fullScore + $SM.get('stores["alien alloy"]', true) * 10;
|
||||||
|
fullScore = fullScore + $SM.get('stores["fleet beacon"]', true) * 500;
|
||||||
fullScore = fullScore + Ship.getMaxHull() * 50;
|
fullScore = fullScore + Ship.getMaxHull() * 50;
|
||||||
return Math.floor(fullScore);
|
return Math.floor(fullScore);
|
||||||
},
|
},
|
||||||
|
|||||||
+119
-55
@@ -437,63 +437,13 @@ var Space = {
|
|||||||
Engine.GAME_OVER = true;
|
Engine.GAME_OVER = true;
|
||||||
Score.save();
|
Score.save();
|
||||||
Prestige.save();
|
Prestige.save();
|
||||||
|
|
||||||
$('<center>')
|
|
||||||
.addClass('centerCont')
|
|
||||||
.appendTo('body');
|
|
||||||
$('<span>')
|
|
||||||
.addClass('endGame')
|
|
||||||
.text(_('score for this game: {0}', Score.calculateScore()))
|
|
||||||
.appendTo('.centerCont')
|
|
||||||
.animate({opacity:1},1500);
|
|
||||||
$('<br />')
|
|
||||||
.appendTo('.centerCont');
|
|
||||||
$('<span>')
|
|
||||||
.addClass('endGame')
|
|
||||||
.text(_('total score: {0}', Prestige.get().score))
|
|
||||||
.appendTo('.centerCont')
|
|
||||||
.animate({opacity:1},1500);
|
|
||||||
$('<br />')
|
|
||||||
.appendTo('.centerCont');
|
|
||||||
$('<br />')
|
|
||||||
.appendTo('.centerCont');
|
|
||||||
$('#starsContainer').remove();
|
$('#starsContainer').remove();
|
||||||
$('#content, #notifications').remove();
|
$('#content, #notifications').remove();
|
||||||
$('<span>')
|
Space.showExpansionEnding().then(() => {
|
||||||
.addClass('endGame endGameOption')
|
Space.showEndingOptions();
|
||||||
.text(_('restart.'))
|
Engine.options = {};
|
||||||
.click(Engine.confirmDelete)
|
Engine.deleteSave(true);
|
||||||
.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);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
@@ -501,6 +451,120 @@ var Space = {
|
|||||||
}, 2000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showExpansionEnding: () => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (!$SM.get('stores["fleet beacon"]')) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const c = $('<div>')
|
||||||
|
.addClass('outroContainer')
|
||||||
|
.appendTo('body');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('outro')
|
||||||
|
.html('the beacon pulses gently as the ship glides through space.<br>coordinates are locked. nothing to do but wait.')
|
||||||
|
.appendTo(c)
|
||||||
|
.animate({ opacity: 1}, 500);
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('outro')
|
||||||
|
.html('the beacon glows a solid blue, and then goes dim. the ship slows.<br>gradually, the vast wanderer homefleet comes into view.<br>massive worldships drift unnaturally through clouds of debris, scarred and dead.')
|
||||||
|
.appendTo(c)
|
||||||
|
.animate({ opacity: 1}, 500);
|
||||||
|
}, 7000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('outro')
|
||||||
|
.text('the air is running out.')
|
||||||
|
.appendTo(c)
|
||||||
|
.animate({ opacity: 1}, 500);
|
||||||
|
}, 14000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('outro')
|
||||||
|
.text('the capsule is cold.')
|
||||||
|
.appendTo(c)
|
||||||
|
.animate({ opacity: 1}, 500);
|
||||||
|
}, 17000);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
Button.Button({
|
||||||
|
id: 'wait-btn',
|
||||||
|
text: _('wait'),
|
||||||
|
click: (btn) => {
|
||||||
|
btn.addClass('disabled');
|
||||||
|
c.animate({ opacity: 0 }, 5000, 'linear', () => {
|
||||||
|
c.remove();
|
||||||
|
setTimeout(resolve, 3000);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).animate({ opacity: 1 }, 500).appendTo(c);
|
||||||
|
}, 19500)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
showEndingOptions: () => {
|
||||||
|
$('<center>')
|
||||||
|
.addClass('centerCont')
|
||||||
|
.appendTo('body');
|
||||||
|
$('<span>')
|
||||||
|
.addClass('endGame')
|
||||||
|
.text(_('score for this game: {0}', Score.calculateScore()))
|
||||||
|
.appendTo('.centerCont')
|
||||||
|
.animate({opacity:1},1500);
|
||||||
|
$('<br />')
|
||||||
|
.appendTo('.centerCont');
|
||||||
|
$('<span>')
|
||||||
|
.addClass('endGame')
|
||||||
|
.text(_('total score: {0}', Prestige.get().score))
|
||||||
|
.appendTo('.centerCont')
|
||||||
|
.animate({opacity:1},1500);
|
||||||
|
$('<br />')
|
||||||
|
.appendTo('.centerCont');
|
||||||
|
$('<br />')
|
||||||
|
.appendTo('.centerCont');
|
||||||
|
$('<span>')
|
||||||
|
.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);
|
||||||
|
},
|
||||||
|
|
||||||
keyDown: function(event) {
|
keyDown: function(event) {
|
||||||
switch(event.which) {
|
switch(event.which) {
|
||||||
|
|||||||
+1107
-1031
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user