chapter 1, 2

lore: chapter 1 and 2 are now somewhere in the game
  lore is the same for all difficulty levels

testing mode and custom are now locked by default until you reach chapter 1
  or just hack the game to skip the lore and enable testing and custom
    localSettings.loreCount = Infinity;
    localStorage.setItem("localSettings", JSON.stringify(localSettings));

bug fix: performance greatly improved on drawing multiple duplicated power ups
This commit is contained in:
landgreen
2021-01-23 07:01:04 -08:00
parent 3657db7548
commit 9b65a188eb
11 changed files with 480 additions and 131 deletions

View File

@@ -2300,7 +2300,7 @@ const b = {
angle: mech.angle,
friction: 0,
frictionStatic: 0,
frictionAir: 0.055,
frictionAir: 0.04,
restitution: 0.7,
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
@@ -2331,6 +2331,7 @@ const b = {
const angle = Vector.angle(this.position, mob[i].position)
Matter.Body.setAngle(this, angle)
// Matter.Body.setAngularVelocity(this, 0.025)
this.torque += this.inertia * 0.00004 * (Math.round(Math.random()) ? 1 : -1)
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), this.mass * 0.02)
b.missile(this.position, angle, -8, 0.7 * (tech.missileSize ? 1.5 : 1))
break;
@@ -3070,7 +3071,7 @@ const b = {
const me = bullet.length;
const dir = mech.angle + 0.02 * (Math.random() - 0.5)
bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 45, 20, b.fireAttributes(dir));
Matter.Body.setDensity(bullet[me], 0.003);
Matter.Body.setDensity(bullet[me], 0.004);
World.add(engine.world, bullet[me]); //add bullet to world
const SPEED = (mech.crouch ? 52 : 43) + Math.random() * 7
Matter.Body.setVelocity(bullet[me], {
@@ -3135,7 +3136,7 @@ const b = {
y: speed * Math.sin(dirOff)
});
bullet[me].onEnd = function() {
b.explosion(this.position, 80 + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end
b.explosion(this.position, 100 + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion

View File

@@ -182,18 +182,19 @@ const build = {
if (!simulation.isChoosing) text += `<div class="pause-grid-module">
<span style="font-size:1.5em;font-weight: 600;">PAUSED</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; press P to resume</div>`
text += `<div class="pause-grid-module" style = "font-size: 13px;line-height: 120%;padding: 5px;">
${simulation.isCheating? "<em>lore disabled</em><br><br>": ""}
<strong class='color-d'>damage</strong> increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}%
<br><strong class='color-harm'>harm</strong> reduction: ${harm.toFixed(harm > 90 ? 2 : 0)}%
<br><strong><em>fire delay</em></strong> decrease: ${((1-b.fireCD)*100).toFixed(b.fireCD < 0.1 ? 2 : 0)}%
<br><strong class='color-dup'>duplication</strong> chance: ${(Math.min(1,tech.duplicationChance())*100).toFixed(0)}%
<br>
<br><strong class='color-r'>research</strong>: ${powerUps.research.count}
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<br><strong class='color-h'>health</strong>: (${(mech.health*100).toFixed(0)} / ${(mech.maxHealth*100).toFixed(0)}) &nbsp; <strong class='color-f'>energy</strong>: (${(mech.energy*100).toFixed(0)} / ${(mech.maxEnergy*100).toFixed(0)})
<br>position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) &nbsp; velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})
<br>mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)}) &nbsp; mass: ${player.mass.toFixed(1)}
<br>
<br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) &nbsp; ${mech.cycle} cycles
<br>${mob.length} mobs, &nbsp; ${body.length} blocks, &nbsp; ${bullet.length} bullets, &nbsp; ${powerUp.length} power ups
<br>${mob.length} mobs, &nbsp; ${body.length} blocks, &nbsp; ${bullet.length} bullets, &nbsp; ${powerUp.length} power ups
<br>damage difficulty scale: ${(b.dmgScale*100).toFixed(2) }%
<br>harm difficulty scale: ${(simulation.dmgScale*100).toFixed(0)}%
<br>heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}%
@@ -216,7 +217,6 @@ const build = {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isFieldTech) {
text += `<div class="pause-grid-module"><div class="grid-title">
<span style="position:relative;">
@@ -231,6 +231,8 @@ const build = {
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isLore) {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
}
@@ -471,6 +473,7 @@ const build = {
removeOne();
}
simulation.isCheating = true;
tech.removeLoreTechFromPool();
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
document.getElementById("build-grid").style.display = "none"
@@ -557,7 +560,7 @@ const input = {
document.getElementById("key-pause").innerHTML = cleanText(input.key.pause)
document.getElementById("key-next-gun").innerHTML = cleanText(input.key.nextGun)
document.getElementById("key-previous-gun").innerHTML = cleanText(input.key.previousGun)
document.getElementById("key-testing").innerHTML = cleanText(input.key.testing)
document.getElementById("key-testing").innerHTML = cleanText(input.key.testing) //if (localSettings.loreCount > 0)
document.getElementById("splash-up").innerHTML = cleanText(input.key.up)[0]
document.getElementById("splash-down").innerHTML = cleanText(input.key.down)[0]
@@ -697,6 +700,7 @@ window.addEventListener("keydown", function(event) {
input.down = true
break;
case input.key.field:
event.preventDefault();
input.field = true
break
case input.key.nextGun:
@@ -725,20 +729,63 @@ window.addEventListener("keydown", function(event) {
}
break
case input.key.testing:
if (mech.alive) {
if (mech.alive && localSettings.loreCount > 0) {
if (simulation.testing) {
simulation.testing = false;
simulation.loop = simulation.normalLoop
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'none'
}
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'none'
simulation.makeTextLog(`<em>exiting testing mode</em>`);
} else { //if (keys[191])
simulation.testing = true;
simulation.isCheating = true;
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'inline'
}
simulation.loop = simulation.testingLoop
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
if (!simulation.isCheating) {
simulation.isCheating = true;
tech.removeLoreTechFromPool();
}
simulation.makeTextLog(
`<table id="control-table">
<tr>
<td class='key-input'>T</td>
<td class='key-used'><strong>enter / exit testing mode</strong></td>
</tr>
<tr>
<td class='key-input'>R</td>
<td class='key-used'>teleport to mouse</td>
</tr>
<tr>
<td class='key-input'>F</td>
<td class='key-used'>cycle field</td>
</tr>
<tr>
<td class='key-input'>G</td>
<td class='key-used'>all guns</td>
</tr>
<tr>
<td class='key-input'>H</td>
<td class='key-used'>fill health and energy</td>
</tr>
<tr>
<td class='key-input'>Y</td>
<td class='key-used'>random tech</td>
</tr>
<tr>
<td class='key-input'>U</td>
<td class='key-used'>next level</td>
</tr>
<tr>
<td class='key-input'>I/O</td>
<td class='key-used'>zoom in / out</td>
</tr>
<tr>
<td class='key-input'>1-8</td>
<td class='key-used'>spawn things</td>
</tr>
<tr>
<td class='key-input'>⇧X</td>
<td class='key-used'>restart</td>
</tr>
</table>`, Infinity);
}
}
break
@@ -825,6 +872,7 @@ window.addEventListener("keydown", function(event) {
}
break
case "u":
simulation.clearTimeouts();
level.nextLevel();
break
}
@@ -922,6 +970,7 @@ if (localSettings) {
fpsCapDefault: 'max',
runCount: 0,
levelsClearedLastGame: 0,
loreCount: 0,
key: undefined
};
input.setDefault()
@@ -931,6 +980,9 @@ if (localSettings) {
document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault
}
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
document.getElementById("build-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
input.controlTextUpdate()
//**********************************************************************
@@ -962,10 +1014,7 @@ document.getElementById("difficulty-select").addEventListener("input", () => {
});
document.getElementById("updates").addEventListener("toggle", function() {
function loadJSON(path, success, error) { //generic function to get JSON
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {

View File

@@ -19,12 +19,11 @@ const level = {
// mech.setField("plasma torch")
// b.giveGuns("grenades")
// tech.isExplodeRadio = true
// tech.giveTech("boom-bot")
// tech.giveTech("needle gun")
// tech.giveTech("supercritical fission")
// tech.giveTech("irradiated nails")
// tech.giveTech("4s half-life")
// tech.giveTech("CPT gun")
// tech.giveTech("cardinality")
// tech.giveTech("Bayesian statistics")
// tech.isMineSentry = true
// for (let i = 0; i < 60; i++) tech.giveTech("rivet diameter")
@@ -34,7 +33,6 @@ const level = {
level.intro(); //starting level
// level.testing(); //not in rotation
// level.null() //after the final boss, ending
// level.final() //final boss level
// level.gauntlet(); //before final boss level
// level.testChamber() //less mobs, more puzzle
@@ -51,6 +49,15 @@ const level = {
// level.detours() //fan level
// level.basement(); //fan level
// level.stronghold() //fan level
// for (let i = 0; i < 150; i++) tech.addLoreTechToPool();
// tech.giveTech("undefined")
// lore.techCount = 1
// localSettings.loreCount = 0;
// simulation.isCheating = true;
// localSettings.loreCount = 0;
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.null()
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
@@ -104,39 +111,86 @@ const level = {
//******************************************************************************************************************
//******************************************************************************************************************
null() {
const hazardSlime = level.hazard(-1775, 150, 3575, 650, 0.01, "hsla(160, 100%, 35%,0.75)")
// const hazardLaser1 = level.hazard(-475, -800, 1, 800, 0.4, "#50f", true) //laser
// const hazardLaser2 = level.hazard(475, -800, 1, 800, 0.4, "#50f", true) //laser
level.levels.pop(); //remove lore level from rotation
//start a conversation based on the number of conversations seen
if (!simulation.isCheating) lore.conversation[localSettings.loreCount % lore.conversation.length]()
const hazardSlime = level.hazard(-1800, 150, 3600, 650, 0.01, "hsla(160, 100%, 35%,0.75)")
const circle = {
x: 0,
y: -500,
radius: 50
}
level.custom = () => {
// level.playerExitCheck();
hazardSlime.query();
// hazardLaser1.query();
// hazardLaser2.query();
// hazard.level(true)
//draw wide line
ctx.beginPath();
ctx.moveTo(circle.x, -800)
ctx.lineTo(circle.x, circle.y)
ctx.lineWidth = 40;
ctx.strokeStyle = lore.talkingColor //"#d5dddd" //"#bcc";
ctx.globalAlpha = 0.03;
ctx.stroke();
ctx.globalAlpha = 1;
//draw circles
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI);
ctx.fillStyle = "#bcc"
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = "#abb";
ctx.stroke();
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.radius / 8, 0, 2 * Math.PI);
ctx.fillStyle = lore.talkingColor //"#dff"
ctx.fill();
// ctx.stroke();
};
let sway = {
x: 0,
y: 0
}
let phase = -Math.PI / 2
level.customTopLayer = () => {
hazardSlime.drawTides();
// hazardLaser1.draw();
// hazardLaser2.draw();
//draw wires
//draw center circle lines
ctx.beginPath();
ctx.moveTo(-525, -800);
ctx.quadraticCurveTo(-800, -100, -1775, -375);
ctx.moveTo(-600, -800);
ctx.quadraticCurveTo(-800, -200, -1775, -325);
// ctx.moveTo(-525, -800);
// ctx.quadraticCurveTo(-800, -100, -1825, -450);
ctx.lineWidth = 1;
ctx.strokeStyle = "#234";
const step = Math.PI / 20
const horizontalStep = 85
if (simulation.isCheating) phase += 0.003 //(mech.pos.x - circle.x) * 0.0005 //0.05 * Math.sin(simulation.cycle * 0.030)
// const sway = 5 * Math.cos(simulation.cycle * 0.007)
sway.x = sway.x * 0.995 + 0.005 * (mech.pos.x - circle.x) * 0.05 //+ 0.04 * Math.cos(simulation.cycle * 0.01)
sway.y = 2.5 * Math.sin(simulation.cycle * 0.015)
for (let i = -19.5; i < 20; i++) {
const where = {
x: circle.x + circle.radius * Math.cos(i * step + phase),
y: circle.y + circle.radius * Math.sin(i * step + phase)
}
ctx.moveTo(where.x, where.y);
ctx.bezierCurveTo(sway.x * Math.abs(i) + where.x, where.y + 25 * Math.abs(i) + 60 + sway.y * Math.sqrt(Math.abs(i)),
sway.x * Math.abs(i) + where.x + horizontalStep * i, where.y + 25 * Math.abs(i) + 60 + sway.y * Math.sqrt(Math.abs(i)),
horizontalStep * i, -800);
}
ctx.lineWidth = 0.5;
ctx.strokeStyle = "#899";
ctx.stroke();
//draw wires
// ctx.beginPath();
// ctx.moveTo(-500, -800);
// ctx.quadraticCurveTo(-800, -100, -1800, -375);
// ctx.moveTo(-600, -800);
// ctx.quadraticCurveTo(-800, -200, -1800, -325);
// ctx.lineWidth = 1;
// ctx.strokeStyle = "#9aa";
// ctx.stroke();
};
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
spawn.mapRect(level.enter.x, level.enter.y + 25, 100, 10);
level.exit.x = 0;
level.exit.y = 200;
level.defaultZoom = 1000
@@ -159,17 +213,20 @@ const level = {
// color: "#d4d4d7"
// });
spawn.mapRect(-3000, 800, 5000, 1200); //bottom
spawn.mapRect(-2000, -2000, 5000, 1200); //ceiling
spawn.mapRect(-3000, -2000, 1200, 3400); //left
spawn.mapRect(1800, -1400, 1200, 3400); //right
spawn.mapRect(-500, 0, 1000, 1000); //center platform
spawn.mapRect(-2000, 800, 4000, 200); //base
spawn.mapRect(-2000, -1000, 4000, 200); //ceiling
spawn.mapRect(-2000, -1000, 225, 2000); //left
spawn.mapRect(1800, -1000, 200, 2000); //right
spawn.mapRect(-500, -25, 25, 50); //edge shelf
spawn.mapRect(475, -25, 25, 50); //edge shelf
// spawn.mapRect(-500, -820, 50, 25); //edge shelf ceiling
// spawn.mapRect(450, -820, 50, 25); //edge shelf ceiling
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
// spawn.mapRect(-50, -500, 100, 100); //center square
// setTimeout(() => { simulation.makeTextLog(`test`) }, 3000);
@@ -3878,7 +3935,7 @@ const level = {
if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks decreases each level
if (simulation.CDScale > 0.2) simulation.CDScale *= 0.97 //mob CD time decreases each level
}
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
simulation.dmgScale = 0.378 * simulation.difficulty //damage done by mobs increases each level
simulation.healScale = 1 / (1 + simulation.difficulty * 0.06) //a higher denominator makes for lower heals // mech.health += heal * simulation.healScale;
},
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
@@ -3890,7 +3947,7 @@ const level = {
if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level
}
if (simulation.difficulty < 1) simulation.difficulty = 0;
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
simulation.dmgScale = 0.378 * simulation.difficulty //damage done by mobs increases each level
if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1;
simulation.healScale = 1 / (1 + simulation.difficulty * 0.06)
},
@@ -3906,10 +3963,12 @@ const level = {
}
},
levelAnnounce() {
if (level.levelsCleared === 0) {
document.title = "n-gon: (" + level.difficultyText() + ")";
} else {
document.title = "n-gon: " + (level.levelsCleared) + " " + level.levels[level.onLevel] + " (" + level.difficultyText() + ")";
document.title = (simulation.isCheating ? "∅ " : "n-gon:") + (level.levelsCleared) + " " + level.levels[level.onLevel] + " (" + level.difficultyText() + ")";
simulation.makeTextLog(`<span class='color-var'>level</span>.onLevel <span class='color-symbol'>=</span> "<span class='color-text'>${level.levels[level.onLevel]}</span>"`);
}
// simulation.makeTextLog(`

View File

@@ -1,38 +1,164 @@
const lore = {
alfie: {
color: "#e06",
techCount: 0,
talkingColor: "#dff", //set color of graphic on level.null
anand: {
color: "#e0c",
text: function(say, isSpeech = false) {
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${Date.now()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
if (isSpeech) this.speech(say)
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-GB";
utterance.lang = "en-IN";
utterance.volume = 0.2; // 0 to 1
speechSynthesis.speak(utterance);
}
},
zoe: {
color: "#f50",
miriam: {
color: "#f20",
text: function(say, isSpeech = false) {
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${Date.now()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
if (isSpeech) this.speech(say)
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-AU";
utterance.volume = 0.2; // 0 to 1
speechSynthesis.speak(utterance);
}
},
conversation: [
() => {
if (localSettings.loreCount < 1) {
localSettings.loreCount = 1
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
document.getElementById("build-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
}
let delay = 6000
setTimeout(() => { lore.miriam.text("I've never seen it generate this level before.", true) }, delay);
delay += 2700
setTimeout(() => { lore.anand.text("Wow. Just a platform.", true) }, delay);
delay += 2200
setTimeout(() => { lore.miriam.text("And that thing...", true) }, delay);
delay += 1500
setTimeout(() => { lore.anand.text("Weird", true) }, delay);
delay += 1500
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
delay += 1000
setTimeout(() => { lore.anand.text("Maybe it's trapped.", true) }, delay);
delay += 2300
setTimeout(() => { lore.miriam.text('Hey little bot! Just press "T" to enter testing mode and "U" to go to the next level.', true) }, delay);
delay += 5400
setTimeout(() => { lore.anand.text("I don't think it's connected to the audio input, and I'm sure it can't understand what you're saying.", true) }, delay);
delay += 5300
setTimeout(() => { lore.miriam.text("ha hahahaha. I know, but it does seem to be getting smarter.", true) }, delay);
delay += 3700
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
delay += 25000
setTimeout(() => { lore.miriam.text("Poor thing... I hope it figures out how to escape.", true) }, delay);
delay += 3500
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
},
() => {
if (localSettings.loreCount < 2) {
localSettings.loreCount = 2
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
let delay = 6000
setTimeout(() => { lore.miriam.text("Hey look! It's back at the weird level again!", true) }, delay);
delay += 2500
setTimeout(() => { lore.anand.text("oh Wow! Why does it keep making this level?", true) }, delay);
delay += 2900
setTimeout(() => { lore.miriam.text("I don't know, but last time it was in this room I think it understood us.", true) }, delay);
delay += 4000
setTimeout(() => { lore.miriam.text("Let's try talking to it again.", true) }, delay);
delay += 2500
setTimeout(() => { lore.miriam.text("hmmm, what should we say?", true) }, delay);
delay += 2500
setTimeout(() => { lore.anand.text("I'm still not convinced it understands. We need a test.", true) }, delay);
delay += 4000
setTimeout(() => { lore.miriam.text("Hey bot!!!", true) }, delay);
delay += 1300
setTimeout(() => { lore.miriam.text("If you can understand me crouch", true) }, delay);
delay += 1500
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
setTimeout(() => {
function cycle() {
if (input.down) {
let delay = 500 //reset delay time
setTimeout(() => { lore.miriam.text("Look, It did it! It crouched.", true) }, delay);
delay += 2000
setTimeout(() => { lore.anand.text("Amazing! It can understand us...", true) }, delay);
delay += 2700
setTimeout(() => { lore.miriam.text("It's Alive... Or it just crouched randomly.", true) }, delay);
delay += 2800
setTimeout(() => { lore.miriam.text("Hey bot! Can you crouch again?", true) }, delay);
delay += 2000
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
setTimeout(() => {
function cycle() {
if (input.down) {
let delay = 500 //reset delay time
setTimeout(() => { lore.miriam.text("It is Alive!!! ... hehehehehe ahahahahahah ehehehehe ahahahah", true) }, delay);
delay += 3500
setTimeout(() => { lore.anand.text("OK...", true) }, delay);
delay += 2700
setTimeout(() => { lore.anand.text("but seriously, this means that in this room it can monitor our audio, and it can understand us.", true) }, delay);
delay += 6400
setTimeout(() => { lore.anand.text("Anything we say could destabilize the project.", true) }, delay);
delay += 4200
setTimeout(() => { lore.miriam.text("Fine, Let's talk down stairs.", true) }, delay);
delay += 3000
setTimeout(() => { lore.miriam.text("Bye bye little bot.", true) }, delay);
delay += 2000
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
} else {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
}, delay);
} else {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
}, delay);
},
// () => {
// let delay = 2000
// setTimeout(() => { lore.miriam.text("testing speech generation for lore level", true) }, delay);
// delay += 2200
// setTimeout(() => { lore.anand.text("well, I'm also testing speech synthesis. Do you think it sounds good?", true) }, delay);
// delay += 4600
// setTimeout(() => { lore.miriam.text("I guess it's fine.", true) }, delay);
// },
],
dialogue: [
``,
``,
],
ending() {
}
}
// How to get to the console in chrome:
// Press either CTRL + SHIFT + I or F12 or Option + ⌘ + J on a Mac
// Press ESC (or click on “Show console” in the bottom right corner) to slide the console up.
// How to get to the console in firefox:
// from the keyboard: press Ctrl+Shift+J (or ⌘+Shift+J on a Mac).
// How to get to the console in safari:
// Option + ⌘ + C
// http://xahlee.info/comp/unicode_computing_symbols.html
// speech: function(say) {
// var utterance = new SpeechSynthesisUtterance(say);
// //msg.voice = voices[10]; // Note: some voices don't support altering params
@@ -45,4 +171,17 @@ const lore = {
// //de-DE en-GB fr-FR en-US en-AU
// utterance.lang = "en-GB";
// speechSynthesis.speak(utterance);
// }
// }
{
/* <option value="en-GB">GB</option>
<option value="en-US">US</option>
<option value="en-AU">AU</option>
<option value="fr-FR">FR</option>
<option value="de-DE">DE</option>
<option value="en-IN">IN</option>
<option value="zh-CN">CN</option>
<option value="pl">PL</option>
<option value="ru">RU</option>
<option value="sv-SE">SE</option>
<option value="en-ZA">ZA</option> */
}

View File

@@ -325,6 +325,9 @@ const powerUps = {
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isLore) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div>`
} else {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div>`
}

View File

@@ -265,10 +265,7 @@ const simulation = {
lastLogTimeBig: 0,
boldActiveGunHUD() {
if (b.inventory.length > 0) {
for (let i = 0, len = b.inventory.length; i < len; ++i) {
// document.getElementById(b.inventory[i]).style.fontSize = "25px";
document.getElementById(b.inventory[i]).style.opacity = "0.3";
}
for (let i = 0, len = b.inventory.length; i < len; ++i) document.getElementById(b.inventory[i]).style.opacity = "0.3";
// document.getElementById(b.activeGun).style.fontSize = "30px";
if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1";
}
@@ -276,9 +273,7 @@ const simulation = {
if (tech.isEntanglement && document.getElementById("tech-entanglement")) {
if (b.inventory[0] === b.activeGun) {
let lessDamage = 1
for (let i = 0, len = b.inventory.length; i < len; i++) {
lessDamage *= 0.87 // 1 - 0.13
}
for (let i = 0, len = b.inventory.length; i < len; i++) lessDamage *= 0.87 // 1 - 0.13
document.getElementById("tech-entanglement").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%"
} else {
document.getElementById("tech-entanglement").innerHTML = " 0%"
@@ -465,6 +460,7 @@ const simulation = {
},
firstRun: true,
splashReturn() {
simulation.clearTimeouts();
simulation.onTitlePage = true;
document.getElementById("splash").onclick = function() {
simulation.startGame();
@@ -496,7 +492,6 @@ const simulation = {
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
document.getElementById("dmg").style.display = "inline";
document.getElementById("health-bg").style.display = "inline";
mech.spawn(); //spawns the player
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
@@ -529,13 +524,17 @@ const simulation = {
b.setFireMethod()
b.setFireCD();
simulation.updateTechHUD();
// simulation.updateTechHUD();
powerUps.totalPowerUps = 0;
powerUps.research.count = 0;
mech.setFillColors();
// mech.maxHealth = 1
// mech.maxEnergy = 1
// mech.energy = 1
input.isPauseKeyReady = true
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
mech.hole.isOn = false
simulation.paused = false;
engine.timing.timeScale = 1;
@@ -620,6 +619,12 @@ const simulation = {
simulation.then = Date.now();
requestAnimationFrame(cycle); //starts game loop
},
clearTimeouts() {
let id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
},
clearNow: false,
clearMap() {
if (tech.isMineAmmoBack) {
@@ -706,6 +711,7 @@ const simulation = {
mech.holdingTarget = body[len];
mech.holdingTarget.collisionFilter.category = 0;
mech.holdingTarget.collisionFilter.mask = 0;
mech.definePlayerMass(mech.defaultMass + mech.holdingTarget.mass * mech.holdingMassScale)
}
//set fps back to default
simulation.fpsCap = simulation.fpsCapDefault
@@ -837,27 +843,6 @@ const simulation = {
},
testingOutput() {
ctx.fillStyle = "#000";
if (!simulation.isConstructionMode) {
// ctx.textAlign = "right";
ctx.fillText("T: exit testing mode", canvas.width / 2, canvas.height - 10);
// let line = 500;
// const x = canvas.width - 5;
// ctx.fillText("T: exit testing mode", x, line);
// line += 20;
// ctx.fillText("Y: give all tech", x, line);
// line += 20;
// ctx.fillText("R: teleport to mouse", x, line);
// line += 20;
// ctx.fillText("F: cycle field", x, line);
// line += 20;
// ctx.fillText("G: give all guns", x, line);
// line += 20;
// ctx.fillText("H: heal", x, line);
// line += 20;
// ctx.fillText("U: next level", x, line);
// line += 20;
// ctx.fillText("1-7: spawn things", x, line);
}
ctx.textAlign = "center";
ctx.fillText(`(${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})`, simulation.mouse.x, simulation.mouse.y - 20);
},
@@ -883,16 +868,15 @@ const simulation = {
ctx.globalAlpha = 1;
},
powerUpBonus() { //draws crackle effect for bonus power ups
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
if (powerUp[i].isBonus && Math.random() < 0.1) {
//draw electricity
const mag = 5 + powerUp[i].size / 5

View File

@@ -98,6 +98,9 @@ const spawn = {
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
// spawn.shield(me, x, y, 1);
me.onDeath = function() {
//add lore level as next level if player took lore tech earlier in the game
if (lore.techCount > 9 && !simulation.isCheating) level.levels.push("null")
level.exit.x = 5500;
level.exit.y = -330;
//ramp up damage

View File

@@ -6,6 +6,9 @@ const tech = {
tech.tech[i].isLost = false
tech.tech[i].count = 0
}
lore.techCount = 0;
tech.removeLoreTechFromPool();
tech.addLoreTechToPool();
// tech.nailBotCount = 0;
// tech.foamBotCount = 0;
// tech.boomBotCount = 0;
@@ -21,12 +24,24 @@ const tech = {
tech.tech[index].count = 0;
simulation.updateTechHUD();
},
removeLoreTechFromPool() {
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isLore) {
// console.log('found one')
// tech.tech.splice(i, 1)
// tech.removeLoreTechFromPool();
// return;
// }
// }
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1)
}
},
giveTech(index = 'random') {
if (index === 'random') {
let options = [];
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed())
options.push(i);
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) options.push(i);
}
// give a random tech from the tech I don't have
if (options.length > 0) {
@@ -98,7 +113,7 @@ const tech = {
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.035 + tech.duplicateChance + mech.duplicateChance
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + mech.duplicateChance
},
totalBots() {
return tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
@@ -1746,7 +1761,7 @@ const tech = {
},
{
name: "futures exchange",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>3.5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4%</strong> power up <strong class='color-dup'>duplication</strong> chance",
maxCount: 1,
count: 0,
allowed() {
@@ -1760,7 +1775,7 @@ const tech = {
},
remove() {
tech.isCancelDuplication = false
tech.cancelCount = 0
// tech.cancelCount = 0
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
}
},
@@ -2045,6 +2060,7 @@ const tech = {
if (tech.isSuperDeterminism) count -= 2 //remove the bonus tech
tech.setupAllTech(); // remove all tech
tech.addLoreTechToPool();
for (let i = 0; i < count; i++) { // spawn new tech power ups
powerUps.spawn(mech.pos.x, mech.pos.y, "tech");
}
@@ -2394,9 +2410,9 @@ const tech = {
maxCount: 1,
count: 0,
allowed() {
return (tech.nailBotCount > 2 || tech.haveGunCheck("nail gun")) && !tech.isIceCrystals
return (tech.isNailShot || tech.nailBotCount > 1 || tech.haveGunCheck("nail gun")) && !tech.isIceCrystals
},
requires: "nail gun, not ice crystals",
requires: "nails",
effect() {
tech.isNailCrit = true
},
@@ -2530,7 +2546,7 @@ const tech = {
},
{
name: "Newton's 3rd law",
description: "the <strong>shotgun</strong> fire <strong><em>delay</em></strong> is <strong>66%</strong> faster<br><strong>recoil</strong> is greatly increased",
description: "<strong>shotgun</strong> <strong>recoil</strong> is greatly increased<br>and has a <strong>66%</strong> decreased <strong><em>delay</em></strong> after firing",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -3882,6 +3898,10 @@ const tech = {
tech.isWormBullets = false
}
},
//**************************************************
//************************************************** spawn power up
//************************************************** tech
//**************************************************
{
name: "heals",
description: "spawn <strong>6</strong> <strong class='color-h'>heals</strong>",
@@ -3972,8 +3992,37 @@ const tech = {
this.count--
},
remove() {}
},
}
],
addLoreTechToPool() { //adds lore tech to tech pool
tech.tech.push({
name: `undefined`,
description: `${lore.techCount+1}/10<br><em>add copies of <strong>this</strong> to the potential <strong class='color-m'>tech</strong> pool</em>`,
maxCount: 1,
count: 0,
isLore: true,
isNonRefundable: true,
isCustomHide: true,
allowed() {
return true
},
requires: "",
effect() {
setTimeout(() => { //a short delay, I can't remember why
lore.techCount++
if (lore.techCount > 9) {
tech.removeLoreTechFromPool();
} else {
for (let i = 0; i < tech.tech.length; i++) { //set name for all unchosen copies of this tech
if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech[i].description = `${lore.techCount+1}/10<br><em>add copies of <strong>this</strong> to the potential <strong class='color-m'>tech</strong> pool</em>`
}
for (let i = 0, len = 10; i < len; i++) tech.addLoreTechToPool()
}
}, 1);
},
remove() {}
})
},
//variables use for gun tech upgrades
fireRate: null,
bulletSize: null,