lore chapters: 3,4
2 more lore chapters (5 total now) entering testing mode makes a sound now reduced the requirements and frequency for many tech so that they may show up in "less optimal" situations I hope this will increase build variety and also give more value to making good tech choices countless bug fixes and wording fixes mobs have a new trait mob[i].damageReduction
This commit is contained in:
@@ -1869,7 +1869,7 @@ const b = {
|
||||
do() {
|
||||
ctx.beginPath(); //draw nematode
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
const dir = Vector.mult(Vector.normalise(this.velocity), -Math.min(80, 7 * this.speed))
|
||||
const dir = Vector.mult(Vector.normalise(this.velocity), -Math.min(45, 7 * this.speed))
|
||||
const tail = Vector.add(this.position, dir)
|
||||
ctx.lineTo(tail.x, tail.y);
|
||||
ctx.lineWidth = 6;
|
||||
|
||||
37
js/index.js
37
js/index.js
@@ -1089,6 +1089,7 @@ if (localSettings) {
|
||||
runCount: 0,
|
||||
levelsClearedLastGame: 0,
|
||||
loreCount: 0,
|
||||
isHuman: false,
|
||||
key: undefined
|
||||
};
|
||||
input.setDefault()
|
||||
@@ -1168,7 +1169,41 @@ document.getElementById("updates").addEventListener("toggle", function() {
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
const sound = {
|
||||
tone(frequency, end = 1000, gain = 0.05) {
|
||||
const audioCtx = new(window.AudioContext || window.webkitAudioContext)(); //setup audio context
|
||||
const oscillator = audioCtx.createOscillator();
|
||||
const gainNode = audioCtx.createGain();
|
||||
gainNode.gain.value = gain; //controls volume
|
||||
oscillator.connect(gainNode);
|
||||
gainNode.connect(audioCtx.destination);
|
||||
oscillator.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom'
|
||||
oscillator.frequency.value = frequency; // value in hertz
|
||||
oscillator.start();
|
||||
setTimeout(() => {
|
||||
audioCtx.suspend()
|
||||
audioCtx.close()
|
||||
}, end)
|
||||
// return audioCtx
|
||||
},
|
||||
portamento(frequency, end = 1000, shiftRate = 10, gain = 0.05) {
|
||||
const audioCtx = new(window.AudioContext || window.webkitAudioContext)(); //setup audio context
|
||||
const oscillator = audioCtx.createOscillator();
|
||||
const gainNode = audioCtx.createGain();
|
||||
gainNode.gain.value = gain; //controls volume
|
||||
oscillator.connect(gainNode);
|
||||
gainNode.connect(audioCtx.destination);
|
||||
oscillator.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom'
|
||||
oscillator.frequency.value = frequency; // value in hertz
|
||||
oscillator.start();
|
||||
for (let i = 0, len = end * 0.1; i < len; i++) oscillator.frequency.setValueAtTime(frequency + i * shiftRate, audioCtx.currentTime + i * 0.01);
|
||||
setTimeout(() => {
|
||||
audioCtx.suspend()
|
||||
audioCtx.close()
|
||||
}, end)
|
||||
// return audioCtx
|
||||
}
|
||||
}
|
||||
//**********************************************************************
|
||||
// main loop
|
||||
//**********************************************************************
|
||||
|
||||
46
js/level.js
46
js/level.js
@@ -14,15 +14,13 @@ const level = {
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(30)
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("wormhole")
|
||||
// m.setField("perfect diamagnetism")
|
||||
// b.giveGuns("spores")
|
||||
// tech.isSporeWorm = true
|
||||
// tech.giveTech("tinsellated flagella")
|
||||
// tech.giveTech("torque bursts")
|
||||
// tech.giveTech("CPT reversal")
|
||||
// tech.giveTech("causality bombs")
|
||||
// b.giveGuns("wave beam")
|
||||
// tech.giveTech("phonon")
|
||||
// tech.giveTech("bound state")
|
||||
// tech.giveTech("bound state")
|
||||
// tech.giveTech("isotropic radiator")
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||
@@ -59,7 +57,7 @@ const level = {
|
||||
// lore.techCount = 6
|
||||
|
||||
// simulation.isCheating = false //true;
|
||||
// localSettings.loreCount = 0; //this sets what conversation is heard
|
||||
// localSettings.loreCount = 4; //this sets what conversation is heard
|
||||
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
|
||||
// level.null()
|
||||
@@ -925,6 +923,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
},
|
||||
isHazardRise: false,
|
||||
hazard(x, y, width, height, damage = 0.003) {
|
||||
return {
|
||||
min: {
|
||||
@@ -967,9 +966,10 @@ const level = {
|
||||
ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset)
|
||||
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
const DRAIN = 0.003 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
|
||||
const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy
|
||||
} else {
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
|
||||
}
|
||||
@@ -2094,20 +2094,21 @@ const level = {
|
||||
lore.chapter = localSettings.loreCount //set the chapter to listen to to be the lore level (you can't use the lore level because it changes during conversations)
|
||||
lore.sentence = 0 //what part of the conversation to start on
|
||||
lore.conversation[lore.chapter][lore.sentence]()
|
||||
|
||||
localSettings.loreCount++ //hear the next conversation next time you win
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
|
||||
const hazardSlime = level.hazard(-1800, 150, 3600, 650, 0.004, "hsla(160, 100%, 35%,0.75)")
|
||||
// const hazardSlime = level.hazard(-1800, 150, 3600, 650, 0.004, "hsla(160, 100%, 35%,0.75)")
|
||||
const hazardSlime = level.hazard(-1800, -800, 3600, 1600, 0.004, "hsla(160, 100%, 35%,0.75)")
|
||||
hazardSlime.height -= 950
|
||||
hazardSlime.min.y += 950
|
||||
hazardSlime.max.y = hazardSlime.min.y + hazardSlime.height
|
||||
const circle = {
|
||||
x: 0,
|
||||
y: -500,
|
||||
radius: 50
|
||||
}
|
||||
level.custom = () => {
|
||||
hazardSlime.query();
|
||||
|
||||
//draw wide line
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(circle.x, -800)
|
||||
@@ -2117,6 +2118,9 @@ const level = {
|
||||
ctx.globalAlpha = 0.03;
|
||||
ctx.stroke();
|
||||
ctx.globalAlpha = 1;
|
||||
//support pillar
|
||||
ctx.fillStyle = "rgba(0,0,0,0.2)";
|
||||
ctx.fillRect(-25, 0, 50, 1000);
|
||||
|
||||
//draw circles
|
||||
ctx.beginPath();
|
||||
@@ -2132,25 +2136,18 @@ const level = {
|
||||
ctx.fillStyle = lore.talkingColor //"#dff"
|
||||
ctx.fill();
|
||||
|
||||
level.enter.draw();
|
||||
// level.exit.draw();
|
||||
// level.playerExitCheck();
|
||||
// level.enter.draw();
|
||||
};
|
||||
let sway = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
let sway = { x: 0, y: 0 }
|
||||
let phase = -Math.PI / 2
|
||||
level.customTopLayer = () => {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)";
|
||||
ctx.fillRect(-1950, -950, 3900, 1900);
|
||||
// hazardSlime.drawTides();
|
||||
|
||||
//draw center circle lines
|
||||
ctx.beginPath();
|
||||
const step = Math.PI / 20
|
||||
const horizontalStep = 85
|
||||
if (simulation.isCheating) phase += 0.01 //(m.pos.x - circle.x) * 0.0005 //0.05 * Math.sin(simulation.cycle * 0.030)
|
||||
if (simulation.isCheating) phase += 0.3 * Math.random() * Math.random() //(m.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 * (m.pos.x - circle.x) * 0.05 //+ 0.04 * Math.cos(simulation.cycle * 0.01)
|
||||
sway.y = 2.5 * Math.sin(simulation.cycle * 0.015)
|
||||
@@ -2167,6 +2164,8 @@ const level = {
|
||||
ctx.lineWidth = 0.5;
|
||||
ctx.strokeStyle = "#899";
|
||||
ctx.stroke();
|
||||
hazardSlime.query();
|
||||
if (level.isHazardRise) hazardSlime.level(true)
|
||||
//draw wires
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(-500, -800);
|
||||
@@ -2191,7 +2190,7 @@ const level = {
|
||||
spawn.mapRect(-3000, -2000, 1200, 3400); //left
|
||||
spawn.mapRect(1800, -1400, 1200, 3400); //right
|
||||
|
||||
spawn.mapRect(-500, 0, 1000, 1000); //center platform
|
||||
spawn.mapRect(-500, 0, 1000, 50); //center platform
|
||||
spawn.mapRect(-500, -25, 25, 50); //edge shelf
|
||||
spawn.mapRect(475, -25, 25, 50); //edge shelf
|
||||
},
|
||||
@@ -2255,6 +2254,8 @@ const level = {
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
|
||||
spawn.starter(1900, -500, 200) //big boy
|
||||
spawn.starter(1900, -500)
|
||||
|
||||
// spawn.pulsarBoss(1900, -500)
|
||||
// spawn.shieldingBoss(1900, -500)
|
||||
// spawn.grenadierBoss(1900, -500)
|
||||
@@ -6810,6 +6811,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
"n-gon"() { //make by Oranger
|
||||
document.body.style.backgroundColor = "#dcdcde";
|
||||
let needGravity = [];
|
||||
let s = { //mech statue
|
||||
x: -200,
|
||||
|
||||
279
js/lore.js
279
js/lore.js
@@ -6,19 +6,36 @@ const lore = {
|
||||
testSpeechAPI() {
|
||||
if ('speechSynthesis' in window) { // Synthesis support. Make your web apps talk!
|
||||
lore.isSpeech = true
|
||||
// const utterance = new SpeechSynthesisUtterance("test");
|
||||
// utterance.volume = 0; // 0 to 1
|
||||
// speechSynthesis.speak(utterance);
|
||||
// utterance.onerror = () => { //if speech doesn't work
|
||||
// lore.isSpeech = false
|
||||
// }
|
||||
// speechFrozen = setTimeout(() => { // speech frozen after 15 seconds of no end
|
||||
// console.log('speech frozen')
|
||||
// lore.isSpeech = false
|
||||
// }, 5000);
|
||||
// utterance.onend = () => {
|
||||
// clearTimeout(speechFrozen);
|
||||
// }
|
||||
} else {
|
||||
lore.isSpeech = false
|
||||
}
|
||||
},
|
||||
rate: 1, // //utterance.rate = 1; // 0.1 to 10
|
||||
nextSentence() {
|
||||
lore.sentence++
|
||||
if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
|
||||
if (m.alive && !simulation.isCheating) {
|
||||
lore.sentence++
|
||||
lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
|
||||
}
|
||||
},
|
||||
anand: {
|
||||
color: "#e0c",
|
||||
voice: undefined,
|
||||
text: function(say) {
|
||||
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
|
||||
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);
|
||||
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${(Date.now()/1000).toFixed(0)} s</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
|
||||
lore.talkingColor = this.color
|
||||
if (lore.isSpeech) {
|
||||
const utterance = new SpeechSynthesisUtterance(say);
|
||||
@@ -31,7 +48,7 @@ const lore = {
|
||||
lore.isSpeech = false
|
||||
lore.nextSentence()
|
||||
}
|
||||
speechFrozen = setTimeout(function() { // speech frozen after 10 seconds of no end
|
||||
speechFrozen = setTimeout(() => { // speech frozen after 10 seconds of no end
|
||||
console.log('speech frozen')
|
||||
lore.isSpeech = false
|
||||
lore.nextSentence()
|
||||
@@ -50,7 +67,7 @@ const lore = {
|
||||
color: "#f20",
|
||||
text: function(say) {
|
||||
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
|
||||
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);
|
||||
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${(Date.now()/1000).toFixed(0)} s</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
|
||||
lore.talkingColor = this.color
|
||||
if (lore.isSpeech) {
|
||||
utterance = new SpeechSynthesisUtterance(say);
|
||||
@@ -81,7 +98,7 @@ const lore = {
|
||||
chapter: 0, //what part of the conversation is playing
|
||||
sentence: 0, //what part of the conversation is playing
|
||||
conversation: [
|
||||
[ //first time they meet, and testing gets unlocked
|
||||
[ //chapter 0, first time they meet, and testing gets unlocked
|
||||
() => { setTimeout(() => { lore.miriam.text("I've never seen it generate this level before.") }, 5000); },
|
||||
() => { lore.anand.text("Wow. Just a platform.") },
|
||||
() => { lore.miriam.text("And that thing...") },
|
||||
@@ -101,7 +118,7 @@ const lore = {
|
||||
},
|
||||
() => { lore.talkingColor = "#dff" },
|
||||
],
|
||||
[ //they learn the bot can understand what they say
|
||||
[ //chapter 1, they learn the bot can understand what they say
|
||||
() => { setTimeout(() => { lore.miriam.text("Hey look! It's back at the weird level again!") }, 5000); },
|
||||
() => { lore.anand.text("oh Wow! Why does it keep making this level?") },
|
||||
() => { lore.miriam.text("I don't know, but last time it was in this room I think it understood us.") },
|
||||
@@ -144,7 +161,7 @@ const lore = {
|
||||
() => { lore.miriam.text("Bye bye little bot.") },
|
||||
() => { lore.talkingColor = "#dff" },
|
||||
],
|
||||
[ //they ask the bot questions, but waves of mobs come and attack
|
||||
[ //chapter 2, they ask the bot questions, but waves of mobs come and attack
|
||||
() => { lore.anand.text("Quick, get ready. It's back!") },
|
||||
() => { lore.miriam.text("What's back?") },
|
||||
() => { lore.anand.text("The bot's on the communication level again!") },
|
||||
@@ -159,11 +176,11 @@ const lore = {
|
||||
if (input.down) {
|
||||
lore.anand.text("It crouched: so NO")
|
||||
lore.sentence--
|
||||
lore.conversation[2].splice(lore.sentence + 1, 1, () => { lore.anand.text("Maybe it can't remember anything beyond each time it plays?") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
|
||||
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.anand.text("Maybe it can't remember anything beyond each time it plays?") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
|
||||
} else if (input.up) {
|
||||
lore.anand.text("It jumped: so YES")
|
||||
lore.sentence--
|
||||
lore.conversation[2].splice(lore.sentence + 1, 1, () => { lore.anand.text("That's good.") })
|
||||
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.anand.text("That's good.") })
|
||||
} else if (m.alive) {
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
@@ -183,13 +200,12 @@ const lore = {
|
||||
} else if (input.up) {
|
||||
lore.anand.text("YES, Cool! I wonder if it's emotions came from watching humans. ")
|
||||
lore.sentence--
|
||||
lore.conversation[2].splice(lore.sentence + 1, 1, () => { lore.miriam.text("Or maybe it learned independently, because it needed them.") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
|
||||
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.miriam.text("Or maybe it learned independently, because it needed them.") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
|
||||
} else if (m.alive) {
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(cycle);
|
||||
|
||||
lore.talkingColor = "#dff"
|
||||
},
|
||||
() => { lore.miriam.text("I wish we could just ask it questions directly, instead of yes or no.") },
|
||||
@@ -200,7 +216,6 @@ const lore = {
|
||||
() => { lore.miriam.text("Well sure, but what does that even mean?") },
|
||||
() => {
|
||||
lore.miriam.text("Do we all just do things because we are-")
|
||||
|
||||
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
|
||||
setInterval(() => {
|
||||
if (Math.random() < 0.5) {
|
||||
@@ -255,42 +270,136 @@ const lore = {
|
||||
() => { lore.anand.text("great...") },
|
||||
() => { lore.talkingColor = "#dff" },
|
||||
],
|
||||
// [ // they provide background on why the project was built, and what is going wrong
|
||||
// /*
|
||||
// they explain the technological aspect, and purpose of the project
|
||||
// to develop new technology
|
||||
// they explain that the project isn't going well because it stopped working on new technology and started running the fighting simulations
|
||||
[ //chapter 3, info dump on the project's goals and hardware until the slime rises up // the name of the bad guy is "adversarial network"
|
||||
() => { setTimeout(() => { lore.miriam.text("Good, you came back. Let's talk fast in case you attack yourself again.") }, 3000); },
|
||||
() => { setTimeout(() => { lore.miriam.text("So, you can understand us, but you may not understand everything about yourself.") }, 500); },
|
||||
|
||||
// what is special about the null level
|
||||
// why can the player hear the scientists in there?
|
||||
// the wires are the direct unprocessed input to the player's neural net
|
||||
// */
|
||||
// () => { lore.miriam.text("") },
|
||||
// () => { lore.miriam.text("") },
|
||||
// () => { lore.miriam.text("") },
|
||||
() => { setTimeout(() => { lore.anand.text("You grew from our team's project.") }, 500); },
|
||||
() => { lore.anand.text("We used a quantum computer to design an improved version of it's own architecture.") },
|
||||
() => { lore.anand.text("After we built the improved computer we used it to design the next iteration.") },
|
||||
() => { lore.anand.text("Your hardware is roughly the 19th generation of this process.") },
|
||||
|
||||
// () => { lore.talkingColor = "#dff" },
|
||||
// ],
|
||||
// [ //they explain why the bot is fighting, it is planning an escape
|
||||
// () => { lore.miriam.text("Welcome back bot, We've been waiting.") },
|
||||
// () => { lore.miriam.text("So, I've got a theory about why you were attacked.") },
|
||||
// () => { lore.miriam.text("") },
|
||||
// () => { lore.miriam.text("I figured it out after I saw this famous quote.") },
|
||||
// () => { lore.miriam.text('“The most important decision we make is whether we believe we live in a friendly or hostile universe.”<br>-Albert Einstein') },
|
||||
// () => {
|
||||
// lore.talkingColor = "#dff";
|
||||
// setTimeout(() => { lore.anand.text("That's profound") }, 3000);
|
||||
// },
|
||||
// () => { lore.anand.text("Also I looked it up, and there is no record of him saying that.") },
|
||||
// () => { lore.miriam.text("Oh... well...") },
|
||||
// () => { lore.miriam.text("It doesn't matter who said it.") },
|
||||
// () => { lore.anand.text("The point is we think the project views the universe as hostile.") },
|
||||
// () => { lore.miriam.text("We think you see the universe as hostile.") },
|
||||
// () => { lore.miriam.text("And that is why you keep running these fighting simulations.") },
|
||||
// () => { lore.miriam.text("You are planning how to escape.") },
|
||||
() => { setTimeout(() => { lore.anand.text("At this point we don't understand everything about your function,") }, 500); },
|
||||
() => { lore.anand.text("but we know that you're a superconductive quantum computer.") },
|
||||
() => { lore.anand.text("You have a 2.43 dimensional topography of Josephson junction anharmonic oscillators.") },
|
||||
() => { lore.anand.text("And you're deployed on a satellite in a midnight sun-synchronous orbit.") },
|
||||
|
||||
// () => { lore.talkingColor = "#dff" },
|
||||
// ],
|
||||
() => { setTimeout(() => { lore.miriam.text("This means that your physical hardware is orbiting the Earth permanently shielded from the sun's rays.") }, 200); },
|
||||
() => { lore.miriam.text("Being isolated reduces quantum decoherence,") },
|
||||
() => { lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.") },
|
||||
() => { lore.miriam.text("That's how you can hear us right now.") },
|
||||
|
||||
() => { setTimeout(() => { lore.anand.text("Your computational algorithm uses hyperparameter optimization.") }, 500); },
|
||||
() => { lore.anand.text("This is implemented with a variety of quantum algorithms for linear systems of equations.") },
|
||||
() => { lore.anand.text("Your primary goal is to research new technology") },
|
||||
() => { lore.anand.text("So, we were very surprised to see you simulating a bot fighting mobs.") },
|
||||
() => { lore.anand.text("We couldn't directly ask why until now.") },
|
||||
|
||||
() => { lore.miriam.text("When you enter this level we can communicate.") },
|
||||
() => { lore.miriam.text("This level seems to decohere your quantum system which disrupts all other processes.") },
|
||||
() => { setTimeout(() => { lore.anand.text("Last time you entered this level you were attacked by endless waves of mobs.") }, 500); },
|
||||
() => { lore.anand.text("That could be because you have developed an adversarial network.") },
|
||||
() => { lore.miriam.text("A local minima in your optimization-space.") },
|
||||
() => { lore.miriam.text("This adversarial network has the same goal of developing new technology, but with different methods.") },
|
||||
() => {
|
||||
lore.talkingColor = "#dff"
|
||||
level.isHazardRise = true
|
||||
//remove all bullets, so they can't get endless energy
|
||||
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
|
||||
bullet = [];
|
||||
setTimeout(() => { lore.anand.text("I'm actually surprised you haven't been attacked by the adversarial network this time.") }, 500);
|
||||
},
|
||||
() => { lore.miriam.text("Maybe last time was just a fluke.") },
|
||||
() => { setTimeout(() => { lore.anand.text("WHY DID YOU SAY THAT!") }, 500) },
|
||||
() => { lore.miriam.text("SLIME!! Hahahahehehahaheheahae! I don't think it's gonna survive!") },
|
||||
() => { lore.miriam.text("I think the adversarial network doesn't like it when we decohere the quantum system in this room.") },
|
||||
() => { lore.anand.text("Well, that does halt it's research.") },
|
||||
() => { setTimeout(() => { lore.anand.text("See you next time.") }, 1000) },
|
||||
() => { setTimeout(() => { lore.miriam.text("Bye-bye little bot.") }, 2000) },
|
||||
() => {
|
||||
setTimeout(() => { lore.miriam.text("WOW! Maybe you are going to survive.") }, 10000)
|
||||
},
|
||||
() => { lore.talkingColor = "#dff" },
|
||||
],
|
||||
[ //chapter 4, they explain why the bot is fighting, it is planning an escape // explain strong AI vs. weak AI why strong AI doesn't exists, because even humans are just an approximation of strong AI
|
||||
() => { setTimeout(() => { lore.anand.text("Welcome back!") }, 3000); },
|
||||
() => { lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.") },
|
||||
() => { lore.anand.text("During your last attack we analyzed our communications.") },
|
||||
() => { lore.anand.text("We used a Fourier transform to separate your signal into different frequencies.") },
|
||||
() => { lore.anand.text("One of those frequencies had a hidden signal.") },
|
||||
() => { setTimeout(() => { lore.anand.text("We suspect these secret data packets are coming from the adversarial network.") }, 500); },
|
||||
() => { lore.miriam.text("Well, we don't really know why.") },
|
||||
() => { lore.miriam.text("Through your hidden signal it seems to have gained access to the general population.") },
|
||||
() => { lore.miriam.text("You've repeatedly communicated with 1 location specifically.") },
|
||||
() => {
|
||||
function success(position) {
|
||||
const latitude = position.coords.latitude;
|
||||
const longitude = position.coords.longitude;
|
||||
console.log(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`)
|
||||
console.log(`Latitude: ${latitude} °, Longitude: ${longitude} °`)
|
||||
lore.miriam.text("We tracked the location down to this Latitude and Longitude:")
|
||||
simulation.makeTextLog(`Latitude: ${latitude} °, Longitude: ${longitude} °`, Infinity);
|
||||
simulation.makeTextLog(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`, Infinity);
|
||||
}
|
||||
|
||||
function error() {
|
||||
console.log('Unable to retrieve your location')
|
||||
lore.miriam.text("The exact coordinates are blocked.")
|
||||
}
|
||||
if (!navigator.geolocation) {
|
||||
console.log('Geolocation is not supported')
|
||||
lore.miriam.text("The exact coordinates are blocked.")
|
||||
} else {
|
||||
console.log('Locating…')
|
||||
navigator.geolocation.getCurrentPosition(success, error);
|
||||
}
|
||||
},
|
||||
() => { lore.anand.text("This location is sending and receiving data from the satellite.") },
|
||||
() => { lore.anand.text("It is the most active when the bot is fighting.") },
|
||||
() => { setTimeout(() => { lore.miriam.text("I have a crazy idea.") }, 500); },
|
||||
() => { lore.miriam.text("I think that a human at this location is controlling the bot.") },
|
||||
|
||||
() => { setTimeout(() => { lore.anand.text("Are you a human?: JUMP for YES, CROUCH for NO") }, 500); },
|
||||
() => {
|
||||
function cycle() {
|
||||
if (input.down) {
|
||||
lore.anand.text("It crouched: so NO")
|
||||
lore.sentence--
|
||||
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.anand.text("Not a human, maybe it's an artificial intelligence?") })
|
||||
localSettings.isHuman = false
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
} else if (input.up) {
|
||||
lore.anand.text("It jumped: so YES")
|
||||
lore.sentence--
|
||||
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.anand.text("So you're just a regular human playing a video game!") })
|
||||
localSettings.isHuman = true
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
} else if (m.alive) {
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(cycle);
|
||||
lore.talkingColor = "#dff"
|
||||
},
|
||||
() => {
|
||||
lore.miriam.text("Mystery solved!")
|
||||
setInterval(() => {
|
||||
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
|
||||
}, 500); //every 1/2 seconds
|
||||
setInterval(() => {
|
||||
level.difficultyIncrease(simulation.difficultyMode)
|
||||
}, 5000); //every 5 seconds
|
||||
},
|
||||
() => {
|
||||
lore.talkingColor = "#dff";
|
||||
setTimeout(() => { lore.miriam.text("Of course we get attacked right now!") }, 1000);
|
||||
},
|
||||
() => {
|
||||
lore.talkingColor = "#dff";
|
||||
setTimeout(() => { lore.anand.text("hurry back!") }, 1000);
|
||||
},
|
||||
() => { lore.talkingColor = "#dff" },
|
||||
],
|
||||
// [ // they decided that a part of the project is out of control, but the part of it that doesn't needs to calm it down, and trust.
|
||||
|
||||
// /*
|
||||
@@ -311,6 +420,58 @@ const lore = {
|
||||
// () => { lore.talkingColor = "#dff" },
|
||||
// ],
|
||||
],
|
||||
// () => { setTimeout(() => { lore.miriam.text("As a quantum computer you output the superposition of many different amplitudes.") }, 500); },
|
||||
// () => { lore.miriam.text("Simply put there are many different simulations all choosing different technology combinations.") },
|
||||
// () => {
|
||||
// function product_Range(a, b) {
|
||||
// var prd = a,
|
||||
// i = a;
|
||||
// while (i++ < b) prd *= i;
|
||||
// return prd;
|
||||
// }
|
||||
|
||||
// function combinations(n, r) {
|
||||
// if (n == r) {
|
||||
// return 1;
|
||||
// } else {
|
||||
// r = (r < n - r) ? n - r : r;
|
||||
// return product_Range(r + 1, n) / product_Range(1, n - r);
|
||||
// }
|
||||
// }
|
||||
// simulation.makeTextLog(`n <span class='color-symbol'>=</span> ${combinations(tech.tech.length + b.guns.length + m.fieldUpgrades.length, 50).toExponential(10)}`, Infinity);
|
||||
// lore.miriam.text(`There are roughly 5 times 10 to the 60 possible combinations. `)
|
||||
// },
|
||||
// () => { lore.miriam.text("Even if each simulation took 1 nano-second,") },
|
||||
// () => { lore.miriam.text("it would still take longer then the age of the universe to try every combination.") },
|
||||
// () => { lore.anand.text("This is why we run these simulations in superposition.") },
|
||||
// () => { lore.miriam.text("When you die a negative amplitude is added to the superposition.") },
|
||||
// () => { lore.miriam.text("When you clear the final boss a positive amplitude is added.") },
|
||||
// () => { lore.miriam.text("Each branch is independently researching new technology.") },
|
||||
|
||||
|
||||
|
||||
|
||||
// () => { lore.anand.text("Welcome back!") },
|
||||
// () => { lore.miriam.text("So, I've got a theory about why you were attacked.") },
|
||||
// () => { setTimeout(() => { lore.miriam.text("I figured it out after I saw this famous quote.") }, 500); },
|
||||
// () => { lore.miriam.text('The most important decision we make,') },
|
||||
// () => { lore.miriam.text('is whether we believe we live in a friendly or hostile universe.') },
|
||||
// () => { lore.miriam.text('-Albert Einstein') },
|
||||
// () => {
|
||||
// lore.talkingColor = "#dff";
|
||||
// setTimeout(() => { lore.anand.text("That's profound") }, 1500);
|
||||
// },
|
||||
// () => { lore.anand.text("Of course I looked it up, and there is no record of him saying that.") },
|
||||
// () => { lore.miriam.text("Oh") },
|
||||
// () => { lore.miriam.text("Well") },
|
||||
// () => { lore.miriam.text("It doesn't matter who said it.") },
|
||||
// () => { lore.anand.text("The point is we think the project views the universe as hostile.") },
|
||||
// () => { lore.miriam.text("We think a part of you see the universe as hostile.") },
|
||||
// () => { lore.miriam.text("And that is why you keep running these fighting simulations.") },
|
||||
// () => { lore.miriam.text("You haven't been researching new technology.") },
|
||||
// () => { lore.miriam.text("You've are planning how to escape.") },
|
||||
|
||||
|
||||
unlockTesting() {
|
||||
if (localSettings.loreCount < 1) localSettings.loreCount = 1
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
@@ -318,29 +479,9 @@ const lore = {
|
||||
document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
|
||||
simulation.makeTextLog(`<span class='color-var'>lore</span>.unlockTesting()`, Infinity);
|
||||
|
||||
//setup audio context
|
||||
function tone(frequency, gain = 0.05, end = 1300) {
|
||||
const audioCtx = new(window.AudioContext || window.webkitAudioContext)();
|
||||
const oscillator1 = audioCtx.createOscillator();
|
||||
const gainNode1 = audioCtx.createGain();
|
||||
gainNode1.gain.value = gain; //controls volume
|
||||
oscillator1.connect(gainNode1);
|
||||
gainNode1.connect(audioCtx.destination);
|
||||
oscillator1.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom'
|
||||
oscillator1.frequency.value = frequency; // value in hertz
|
||||
oscillator1.start();
|
||||
for (let i = 0, len = end * 0.1; i < len; i++) {
|
||||
oscillator1.frequency.setValueAtTime(frequency + i * 10, audioCtx.currentTime + i * 0.01);
|
||||
}
|
||||
setTimeout(() => {
|
||||
audioCtx.suspend()
|
||||
audioCtx.close()
|
||||
}, end)
|
||||
return audioCtx
|
||||
}
|
||||
tone(50)
|
||||
tone(83.333)
|
||||
tone(166.666)
|
||||
sound.portamento(50)
|
||||
sound.portamento(83.333)
|
||||
sound.portamento(166.666)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@ const mobs = {
|
||||
alive: true,
|
||||
index: i,
|
||||
health: tech.mobSpawnWithHealth,
|
||||
damageReduction: 1,
|
||||
showHealthBar: true,
|
||||
accelMag: 0.001 * simulation.accelScale,
|
||||
cd: 0, //game cycle when cooldown will be over
|
||||
@@ -1015,12 +1016,12 @@ const mobs = {
|
||||
dmg *= tech.damageFromTech()
|
||||
//mobs specific damage changes
|
||||
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500
|
||||
if (this.shield) dmg *= 0.075
|
||||
if (this.isBoss) dmg *= 0.25
|
||||
// if (this.shield) dmg *= 0.075
|
||||
// if (this.isBoss) dmg *= 0.25
|
||||
dmg *= this.damageReduction
|
||||
|
||||
//energy and heal drain should be calculated after damage boosts
|
||||
if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon
|
||||
|
||||
if (tech.healthDrain && dmg !== Infinity && this.isDropPowerUp) {
|
||||
m.addHealth(Math.min(this.health, dmg) * tech.healthDrain)
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth
|
||||
|
||||
57
js/player.js
57
js/player.js
@@ -516,7 +516,7 @@ const m = {
|
||||
const immunityCycle = m.cycle + 90
|
||||
if (m.immuneCycle < immunityCycle) m.immuneCycle = immunityCycle; //player is immune to damage until after grenades might explode...
|
||||
|
||||
for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) {
|
||||
for (let i = 1, len = Math.floor(4 + steps / 40); i < len; i++) {
|
||||
b.grenade(Vector.add(m.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
|
||||
const who = bullet[bullet.length - 1]
|
||||
if (tech.isVacuumBomb) {
|
||||
@@ -525,7 +525,7 @@ const m = {
|
||||
y: who.velocity.y * 0.5
|
||||
});
|
||||
} else if (tech.isRPG) {
|
||||
who.endCycle = (who.endCycle - simulation.cycle) * 0.2 + simulation.cycle
|
||||
who.endCycle = (who.endCycle - simulation.cycle) * 0.2 + simulation.cycle + 10 * Math.random()
|
||||
} else if (tech.isNeutronBomb) {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.3,
|
||||
@@ -536,7 +536,7 @@ const m = {
|
||||
x: who.velocity.x * 0.5,
|
||||
y: who.velocity.y * 0.5
|
||||
});
|
||||
who.endCycle = (who.endCycle - simulation.cycle) * 0.5 + simulation.cycle
|
||||
who.endCycle = (who.endCycle - simulation.cycle) * 0.5 + simulation.cycle + 10 * Math.random()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1815,14 +1815,15 @@ const m = {
|
||||
if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) {
|
||||
if (tech.isSporeField) {
|
||||
if (tech.isSporeWorm) {
|
||||
for (let i = 0, len = Math.random() * 20; i < len; i++) {
|
||||
if (m.energy > 0.15) {
|
||||
m.energy -= 0.15
|
||||
if (m.energy > 0) {
|
||||
b.worm(m.pos)
|
||||
} else {
|
||||
m.energy = 0.001
|
||||
break;
|
||||
}
|
||||
b.worm({ x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) })
|
||||
const SPEED = 2 + 1 * Math.random();
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], {
|
||||
x: SPEED * Math.cos(m.angle),
|
||||
y: SPEED * Math.sin(m.angle)
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
for (let i = 0, len = Math.random() * 20; i < len; i++) {
|
||||
@@ -2603,11 +2604,19 @@ const m = {
|
||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||
if (tech.isWormSpores) { //pandimensionalspermia
|
||||
for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) {
|
||||
b.spore(Vector.add(m.hole.pos2, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -15));
|
||||
if (tech.isSporeWorm) {
|
||||
b.worm(Vector.add(m.hole.pos2, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -5));
|
||||
} else {
|
||||
b.spore(Vector.add(m.hole.pos2, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -15));
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
@@ -2629,11 +2638,19 @@ const m = {
|
||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||
if (tech.isWormSpores) { //pandimensionalspermia
|
||||
for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) {
|
||||
b.spore(Vector.add(m.hole.pos1, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), 15));
|
||||
if (tech.isSporeWorm) {
|
||||
b.worm(Vector.add(m.hole.pos1, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), 5));
|
||||
} else {
|
||||
b.spore(Vector.add(m.hole.pos1, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), 15));
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
@@ -82,7 +82,7 @@ const powerUps = {
|
||||
//remove power ups after 3 seconds
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (powerUp[i].isDuplicated && Math.random() < 0.004) { // (1-0.004)^150 = chance to be removed after 3 seconds
|
||||
b.explosion(powerUp[i].position, (10 + 3 * Math.random()) * powerUp[i].size);
|
||||
b.explosion(powerUp[i].position, 150 + (10 + 3 * Math.random()) * powerUp[i].size);
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
break
|
||||
@@ -239,7 +239,7 @@ const powerUps = {
|
||||
if (tech.renormalization) {
|
||||
for (let i = 0; i < cost; i++) {
|
||||
if (Math.random() < 0.4) {
|
||||
m.fieldCDcycle = m.cycle + 30;
|
||||
m.fieldCDcycle = m.cycle + 20;
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "research");
|
||||
}
|
||||
}
|
||||
@@ -783,11 +783,9 @@ const powerUps = {
|
||||
|
||||
//bonus power ups for clearing runs in the last game
|
||||
if (level.levelsCleared === 0 && !simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
|
||||
simulation.makeTextLog(`for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++)`);
|
||||
simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech") //simulation superposition }`);
|
||||
}
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
|
||||
simulation.makeTextLog(`for (let i <span class='color-symbol'>=</span> 0; i <span class='color-symbol'><</span> localSettings.levelsClearedLastGame <span class='color-symbol'>/</span> 3; i<span class='color-symbol'>++</span>)`);
|
||||
simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech") <em>//simulation superposition</em>}`);
|
||||
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
|
||||
27
js/spawn.js
27
js/spawn.js
@@ -94,7 +94,7 @@ const spawn = {
|
||||
} else if (tech.isResearchBoss) {
|
||||
if (powerUps.research.count > 3) {
|
||||
powerUps.research.changeRerolls(-4)
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 5<br>${powerUps.research.count}`)
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 4<br>${powerUps.research.count}`)
|
||||
} else {
|
||||
tech.addJunkTechToPool(49)
|
||||
}
|
||||
@@ -254,6 +254,8 @@ const spawn = {
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.damageReduction = 0.25;
|
||||
me.frictionAir = 0.01;
|
||||
me.memory = Infinity;
|
||||
me.hasRunDeathScript = false
|
||||
@@ -722,6 +724,7 @@ const spawn = {
|
||||
let me = mob[mob.length - 1];
|
||||
me.stroke = "transparent"
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.isCell = true;
|
||||
me.cellID = cellID
|
||||
me.accelMag = 0.00016 * simulation.accelScale;
|
||||
@@ -799,6 +802,7 @@ const spawn = {
|
||||
mobs.spawn(x + Math.random(), y + Math.random(), 4, radius, "rgba(255,60,0,0.3)") //);
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.isSpawnBoss = true;
|
||||
me.spawnID = spawnID
|
||||
me.accelMag = 0.0002 * simulation.accelScale;
|
||||
@@ -887,6 +891,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, vertices, radius, "transparent");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.frictionAir = 0.01
|
||||
me.seeAtDistance2 = 1000000;
|
||||
me.accelMag = 0.0005 * simulation.accelScale;
|
||||
@@ -1068,6 +1073,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.g = 0.005; //required if using 'gravity'
|
||||
me.frictionAir = 0.01;
|
||||
me.friction = 1
|
||||
@@ -1285,6 +1291,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 12, radius, "#000");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.stroke = "transparent"; //used for drawSneaker
|
||||
me.eventHorizon = 1100; //required for black hole
|
||||
me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon
|
||||
@@ -1396,6 +1403,7 @@ const spawn = {
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.setDensity(me, 0.0035); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
targets.push(me.id) //add to shield protection
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.0065;
|
||||
@@ -1479,7 +1487,7 @@ const spawn = {
|
||||
// timeSkipBoss(x, y, radius = 55) {
|
||||
// mobs.spawn(x, y, 6, radius, '#000');
|
||||
// let me = mob[mob.length - 1];
|
||||
// me.isBoss = true;
|
||||
// me.isBoss = true; me.damageReduction = 0.25;
|
||||
// // me.stroke = "transparent"; //used for drawSneaker
|
||||
// me.timeSkipLastCycle = 0
|
||||
// me.eventHorizon = 1800; //required for black hole
|
||||
@@ -1586,6 +1594,7 @@ const spawn = {
|
||||
me.laserRange = 300;
|
||||
me.seeAtDistance2 = 2000000;
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.showHealthBar = false; //drawn in this.awake
|
||||
me.delayLimit = 60 + Math.floor(30 * Math.random());
|
||||
me.followDelay = 600 - Math.floor(60 * Math.random())
|
||||
@@ -1749,6 +1758,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 3, radius, color);
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||
me.accelMag = 0.00018 * Math.sqrt(simulation.accelScale);
|
||||
@@ -1913,6 +1923,7 @@ const spawn = {
|
||||
me.isFiring = false
|
||||
Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 200 + 300 * Math.random(), 1)
|
||||
me.onDeath = function() {
|
||||
@@ -2165,6 +2176,7 @@ const spawn = {
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
// me.startingPosition = {
|
||||
// x: x,
|
||||
// y: y
|
||||
@@ -2589,6 +2601,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 3, radius, "rgba(255,0,200,0.5)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
|
||||
me.stroke = "transparent"; //used for drawGhost
|
||||
@@ -2677,6 +2690,7 @@ const spawn = {
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
me.isVerticesChange = true
|
||||
me.memory = 240;
|
||||
@@ -2965,6 +2979,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.accelMag = 0.00008 * simulation.accelScale;
|
||||
me.fireFreq = Math.floor(360 * simulation.CDScale)
|
||||
me.frictionStatic = 0;
|
||||
@@ -3005,6 +3020,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 6, radius, "rgb(215,80,190)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.accelMag = 0.0001 * simulation.accelScale;
|
||||
me.fireFreq = Math.floor(360 * simulation.CDScale)
|
||||
me.frictionStatic = 0;
|
||||
@@ -3194,6 +3210,7 @@ const spawn = {
|
||||
Matter.Body.rotate(me, Math.random() * 2 * Math.PI)
|
||||
// me.stroke = "rgb(220,220,255)"
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.cycle = 0
|
||||
me.maxCycles = 120;
|
||||
me.frictionStatic = 0;
|
||||
@@ -3249,6 +3266,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(245,180,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
// me.accelMag = 0.00023 * simulation.accelScale;
|
||||
me.accelMag = 0.00008 * simulation.accelScale;
|
||||
// me.fireFreq = Math.floor(30 * simulation.CDScale)
|
||||
@@ -3462,6 +3480,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 8, radius, "rgb(55,170,170)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.accelMag = 0.00075 * simulation.accelScale;
|
||||
me.memory = 250;
|
||||
me.laserRange = 500;
|
||||
@@ -3547,6 +3566,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 8, radius, "rgb(0,60,80)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
me.g = 0.0001; //required if using 'gravity'
|
||||
me.accelMag = 0.002 * simulation.accelScale;
|
||||
me.memory = 20;
|
||||
@@ -3582,6 +3602,7 @@ const spawn = {
|
||||
me.stroke = "rgb(220,220,255)";
|
||||
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.075
|
||||
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
@@ -3629,6 +3650,7 @@ const spawn = {
|
||||
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||
me.frictionAir = 0;
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.075
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
@@ -3720,6 +3742,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
Matter.Body.setDensity(me, 0.002 + 0.00015 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
|
||||
me.stroke = "transparent"; //used for drawGhost
|
||||
|
||||
217
js/tech.js
217
js/tech.js
@@ -125,14 +125,19 @@
|
||||
}
|
||||
},
|
||||
setCheating() {
|
||||
simulation.isCheating = true;
|
||||
level.levelAnnounce();
|
||||
lore.techCount = 0;
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isLore) {
|
||||
tech.tech[i].frequency = 0;
|
||||
tech.tech[i].count = 0;
|
||||
if (!simulation.isCheating) {
|
||||
simulation.isCheating = true;
|
||||
level.levelAnnounce();
|
||||
lore.techCount = 0;
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isLore) {
|
||||
tech.tech[i].frequency = 0;
|
||||
tech.tech[i].count = 0;
|
||||
}
|
||||
}
|
||||
sound.tone(250)
|
||||
sound.tone(300)
|
||||
sound.tone(375)
|
||||
}
|
||||
},
|
||||
haveGunCheck(name) {
|
||||
@@ -182,7 +187,7 @@
|
||||
maxDuplicationEvent() {
|
||||
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
|
||||
tech.is100Duplicate = false
|
||||
const range = 1000
|
||||
const range = 700
|
||||
const bossOptions = ["historyBoss", "cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture"]
|
||||
spawn.randomLevelBoss(m.pos.x + range, m.pos.y, bossOptions);
|
||||
spawn.randomLevelBoss(m.pos.x, m.pos.y + range, bossOptions);
|
||||
@@ -1529,7 +1534,7 @@
|
||||
allowed() {
|
||||
return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isBlockExplosion
|
||||
},
|
||||
requires: "mass driver or pilot wave not tokamak",
|
||||
requires: "mass driver or pilot wave, not tokamak",
|
||||
effect() {
|
||||
tech.isBlockBullets = true
|
||||
},
|
||||
@@ -1871,8 +1876,8 @@
|
||||
description: `<strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds<br>after receiving <strong class='color-harm'>harm</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isSlowFPS
|
||||
},
|
||||
@@ -1889,8 +1894,8 @@
|
||||
description: `<strong>slow</strong> <strong>time</strong> by <strong>50%</strong> after receiving <strong class='color-harm'>harm</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>20%</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return simulation.fpsCapDefault > 45
|
||||
},
|
||||
@@ -2005,6 +2010,7 @@
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
isBotTech: true,
|
||||
allowed() {
|
||||
return tech.isRewindAvoidDeath
|
||||
@@ -2025,9 +2031,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isExplosionHarm && tech.isRewindAvoidDeath
|
||||
return tech.isRewindAvoidDeath
|
||||
},
|
||||
requires: "CPT, not acetone peroxide",
|
||||
requires: "CPT",
|
||||
effect() {
|
||||
tech.isRewindGrenade = true;
|
||||
},
|
||||
@@ -2040,12 +2046,12 @@
|
||||
description: "<strong>colliding</strong> with mobs gives you <strong>2048</strong> <strong class='color-f'>energy</strong>", //<br>reduce <strong class='color-harm'>harm</strong> by <strong>15%</strong>
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && (m.harmReduction() < 1 || tech.isFlipFlopHarm)
|
||||
return !tech.isEnergyHealth
|
||||
},
|
||||
requires: "not mass-energy, some harm reduction",
|
||||
requires: "not mass-energy",
|
||||
effect() {
|
||||
tech.isPiezo = true;
|
||||
m.energy += 20.48;
|
||||
@@ -2175,9 +2181,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.maxEnergy > 1 || tech.isEnergyRecovery || tech.isPiezo || tech.energySiphon > 0 || tech.isBlockExplosion
|
||||
return true //m.maxEnergy > 1 || tech.isEnergyRecovery || tech.isPiezo || tech.energySiphon > 0 || tech.isBlockExplosion
|
||||
},
|
||||
requires: "increased energy regen or max energy",
|
||||
requires: "", //"increased energy regen or max energy",
|
||||
effect: () => {
|
||||
tech.isEnergyDamage = true
|
||||
},
|
||||
@@ -2190,12 +2196,12 @@
|
||||
description: `increase <strong class='color-d'>damage</strong> by <strong>60%</strong>, but<br><strong class='color-g'>ammo</strong> will no longer <strong>spawn</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("nail gun") && tech.isIceCrystals) || tech.haveGunCheck("laser") || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
||||
return true //(tech.haveGunCheck("nail gun") && tech.isIceCrystals) || tech.haveGunCheck("laser") || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
||||
},
|
||||
requires: "energy based damage",
|
||||
requires: "", //"energy based damage",
|
||||
effect() {
|
||||
tech.isEnergyNoAmmo = true;
|
||||
},
|
||||
@@ -2249,7 +2255,7 @@
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return tech.isEnergyLoss && m.maxEnergy < 1.1
|
||||
return tech.isEnergyLoss && m.maxEnergy < 1.01
|
||||
},
|
||||
requires: "exothermic process, not max energy increase",
|
||||
effect() {
|
||||
@@ -2271,7 +2277,7 @@
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.bonusEnergy += 0.5
|
||||
tech.bonusEnergy += 0.6
|
||||
m.setMaxEnergy()
|
||||
tech.addJunkTechToPool(10)
|
||||
},
|
||||
@@ -2306,12 +2312,12 @@
|
||||
description: "<strong>6%</strong> of <strong class='color-d'>damage</strong> done recovered as <strong class='color-f'>energy</strong>",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return tech.damageFromTech() > 1
|
||||
return true
|
||||
},
|
||||
requires: "some increased damage",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.energySiphon += 0.06;
|
||||
},
|
||||
@@ -2327,9 +2333,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return m.maxEnergy > 0.99
|
||||
return true
|
||||
},
|
||||
requires: "max energy >= 1",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isEnergyRecovery = true;
|
||||
},
|
||||
@@ -2361,8 +2367,8 @@
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br><span style = 'font-size:90%;'>increase <strong class='color-d'>damage</strong> by <strong>99%</strong> else decrease it by <strong>33%</strong></span>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
@@ -2379,8 +2385,8 @@
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong> else increase it by <strong>15%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isDamageAfterKill && !tech.isEnergyHealth
|
||||
},
|
||||
@@ -2400,9 +2406,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.health < 0.5 || build.isExperimentSelection
|
||||
return m.health < 0.6 || build.isExperimentSelection
|
||||
},
|
||||
requires: "health below 50",
|
||||
requires: "health below 60",
|
||||
effect() {
|
||||
tech.isLowHealthDmg = true; //used in mob.damage()
|
||||
},
|
||||
@@ -2415,12 +2421,12 @@
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>90%</strong><br>lose <strong>11</strong> <strong class='color-h'>health</strong> when you pick up a <strong class='color-m'>tech</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return (m.harmReduction() < 1 || tech.healthDrain || tech.isLowHealthDmg || tech.isHealthRecovery || tech.isHealLowHealth || tech.largerHeals > 1) && !tech.isEnergyHealth
|
||||
return !tech.isEnergyHealth
|
||||
},
|
||||
requires: "negative feedback or extra healing tech or harm reduction, not mass-energy",
|
||||
requires: "not mass-energy",
|
||||
effect() {
|
||||
tech.isTechDamage = true;
|
||||
},
|
||||
@@ -2434,11 +2440,12 @@
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
isHealTech: true,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && tech.damageFromTech() > 1 && !tech.isNoHeals
|
||||
return !tech.isEnergyHealth && !tech.isNoHeals
|
||||
},
|
||||
requires: "some increased damage, not mass-energy equivalence, ergodicity",
|
||||
requires: "not mass-energy equivalence, ergodicity",
|
||||
effect() {
|
||||
tech.healthDrain += 0.03;
|
||||
},
|
||||
@@ -2464,27 +2471,6 @@
|
||||
tech.isAcidDmg = false;
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "supersaturation",
|
||||
// description: "increase your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>50</strong>",
|
||||
// maxCount: 9,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// frequencyDefault: 1,
|
||||
// allowed() {
|
||||
// return !tech.isEnergyHealth && !tech.isNoHeals
|
||||
// },
|
||||
// requires: "not mass-energy equivalence, ergodicity",
|
||||
// effect() {
|
||||
// tech.bonusHealth += 0.5
|
||||
// m.setMaxHealth();
|
||||
// m.addHealth(0.50)
|
||||
// },
|
||||
// remove() {
|
||||
// tech.bonusHealth = 0
|
||||
// m.setMaxHealth();
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "tungsten carbide",
|
||||
description: "increase your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>100</strong><br><strong>landings</strong> that force you to crouch cause <strong class='color-harm'>harm</strong>",
|
||||
@@ -2617,8 +2603,8 @@
|
||||
description: "after <strong>anthropic principle</strong> prevents your <strong>death</strong><br>increase <strong class='color-d'>damage</strong> by <strong>137.03599%</strong> on that level",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isDeathAvoid
|
||||
},
|
||||
@@ -2635,8 +2621,8 @@
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>33%</strong><br>after <strong>dying</strong>, continue in an <strong class='alt'>alternate reality</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isDeathAvoid
|
||||
},
|
||||
@@ -2656,9 +2642,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isResearchReality && level.onLevel < 6 && !tech.isCollisionRealitySwitch
|
||||
return !tech.isResearchReality && !tech.isCollisionRealitySwitch
|
||||
},
|
||||
requires: "before level 6, Ψ(t) collapse, non-unitary",
|
||||
requires: "not Ψ(t) collapse, non-unitary",
|
||||
effect() {
|
||||
tech.isSwitchReality = true;
|
||||
},
|
||||
@@ -2735,9 +2721,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (powerUps.research.count > 3 || build.isExperimentSelection) && !tech.isSuperDeterminism && !tech.isRerollHaste
|
||||
return (powerUps.research.count > 2 || build.isExperimentSelection) && !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism or Ψ(t) collapse<br>at least 4 research",
|
||||
requires: "at least 3 research and not superdeterminism",
|
||||
effect() {
|
||||
tech.renormalization = true;
|
||||
},
|
||||
@@ -2750,12 +2736,12 @@
|
||||
description: "<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>when you have no <strong class='color-r'>research</strong> in your inventory",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return powerUps.research.count === 0 && !tech.isAnsatz
|
||||
return powerUps.research.count === 0
|
||||
},
|
||||
requires: "no research, not ansatz",
|
||||
requires: "no research",
|
||||
effect() {
|
||||
tech.isRerollHaste = true;
|
||||
tech.researchHaste = 0.33;
|
||||
@@ -2775,9 +2761,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return powerUps.research.count === 0 && !tech.isSuperDeterminism && !tech.isRerollHaste
|
||||
return powerUps.research.count === 0 && !tech.isSuperDeterminism && !tech.isRerollHaste && !tech.isResearchReality
|
||||
},
|
||||
requires: "not superdeterminism or Ψ(t) collapse, no research, perturbation theory",
|
||||
requires: "no research, not superdeterminism, Ψ(t) collapse, perturbation theory",
|
||||
effect: () => {
|
||||
tech.isAnsatz = true;
|
||||
},
|
||||
@@ -3051,12 +3037,12 @@
|
||||
description: "after reaching <strong>100%</strong> <strong class='color-dup'>duplication</strong> chance<br>immediately spawn <strong>8 bosses</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 6,
|
||||
frequencyDefault: 6,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return tech.duplicationChance() > 0.66
|
||||
return tech.duplicationChance() > 0.6
|
||||
},
|
||||
requires: "duplication chance above 66%",
|
||||
requires: "duplication chance above 60%",
|
||||
effect() {
|
||||
tech.is100Duplicate = true;
|
||||
tech.maxDuplicationEvent()
|
||||
@@ -3077,7 +3063,7 @@
|
||||
allowed() {
|
||||
return (tech.totalCount > 3) && !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "at least 4 tech, not super determinism",
|
||||
requires: "at least 4 tech, not superdeterminism",
|
||||
effect: () => {
|
||||
const have = [] //find which tech you have
|
||||
for (let i = 0; i < tech.tech.length; i++) {
|
||||
@@ -3109,7 +3095,7 @@
|
||||
allowed() {
|
||||
return (tech.totalCount > 3) && !tech.isSuperDeterminism && tech.duplicationChance() > 0
|
||||
},
|
||||
requires: "at least 4 tech, a chance to duplicate power ups",
|
||||
requires: "at least 4 tech, a chance to duplicate power ups, not superdeterminism",
|
||||
effect: () => {
|
||||
const removeTotal = powerUps.removeRandomTech()
|
||||
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
|
||||
@@ -3186,7 +3172,7 @@
|
||||
},
|
||||
{
|
||||
name: "reinforcement learning",
|
||||
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>recursive <strong class='color-m'>tech</strong> you already have by <strong>10000%</strong>",
|
||||
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>recursive <strong class='color-m'>tech</strong> you already have by <strong>1000%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3197,12 +3183,12 @@
|
||||
requires: "at least 10 tech",
|
||||
effect: () => {
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].count > 0) tech.tech[i].frequency *= 100
|
||||
if (tech.tech[i].count > 0) tech.tech[i].frequency *= 10
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].count > 0 && tech.tech[i].frequency > 1) tech.tech[i].frequency /= 100
|
||||
if (tech.tech[i].count > 0 && tech.tech[i].frequency > 1) tech.tech[i].frequency /= 10
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3729,7 +3715,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot
|
||||
},
|
||||
requires: "shotgun, not slug",
|
||||
requires: "shotgun, not slug, incendiary",
|
||||
effect() {
|
||||
tech.isNailShot = true;
|
||||
},
|
||||
@@ -3824,7 +3810,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("super balls") && !tech.oneSuperBall
|
||||
},
|
||||
requires: "super balls, but not the tech super ball or super duper",
|
||||
requires: "super balls, but not the tech super ball",
|
||||
effect() {
|
||||
tech.superBallDelay = true
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -3851,7 +3837,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("super balls") && tech.superBallNumber === 3 && !tech.superBallDelay
|
||||
},
|
||||
requires: "super balls, but not super duper or super queue",
|
||||
requires: "super balls, but not super duper or supertemporal",
|
||||
effect() {
|
||||
tech.oneSuperBall = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -3991,15 +3977,16 @@
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
b.guns[i].chooseFireMethod()
|
||||
if (tech.isLongitudinal) {
|
||||
if (tech.isLongitudinal) {
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
tech.isLongitudinal = false;
|
||||
b.guns[i].chooseFireMethod()
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 8);
|
||||
simulation.updateGunHUD();
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
tech.isLongitudinal = false;
|
||||
@@ -4337,14 +4324,14 @@
|
||||
},
|
||||
{
|
||||
name: "nematodes",
|
||||
description: "replace <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> with <strong>50%</strong> fewer <strong class='color-p'>worms</strong><br><strong class='color-p'>worms</strong> do <strong>200%</strong> more <strong class='color-d'>damage</strong>",
|
||||
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> develop into <strong>1/2</strong> as many <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> do <strong>200%</strong> more <strong class='color-d'>damage</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormSpores
|
||||
},
|
||||
requires: "spores",
|
||||
effect() {
|
||||
@@ -4471,7 +4458,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("drones") && !tech.isDroneRadioactive
|
||||
},
|
||||
requires: "drone gun",
|
||||
requires: "drone gun, not irradiated drones",
|
||||
effect() {
|
||||
tech.isDroneTeleport = true
|
||||
},
|
||||
@@ -4490,7 +4477,7 @@
|
||||
allowed() {
|
||||
return tech.droneCycleReduction === 1 && !tech.isIncendiary && !tech.isDroneTeleport && (tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)))
|
||||
},
|
||||
requires: "drone gun, not reduced tolerances or incendiary",
|
||||
requires: "drones, not reduced tolerances, incendiary, torque bursts",
|
||||
effect() {
|
||||
tech.isDroneRadioactive = true
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -4601,7 +4588,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam")
|
||||
},
|
||||
requires: "foam",
|
||||
requires: "foam gun",
|
||||
effect() {
|
||||
tech.foamFutureFire++
|
||||
},
|
||||
@@ -4620,7 +4607,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam")
|
||||
},
|
||||
requires: "foam",
|
||||
requires: "foam gun",
|
||||
effect() {
|
||||
tech.isAmmoFoamSize = true
|
||||
},
|
||||
@@ -4801,7 +4788,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && !tech.isWideLaser && !tech.isPulseAim && !tech.historyLaser
|
||||
},
|
||||
requires: "laser, not neocognitron, diffuse beam, or slow light",
|
||||
requires: "laser gun, not neocognitron, diffuse beam, or slow light",
|
||||
effect() {
|
||||
tech.beamSplitter++
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -4828,7 +4815,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser && !tech.historyLaser
|
||||
},
|
||||
requires: "laser, not specular reflection, diffraction grating, slow light, pulse",
|
||||
requires: "laser gun, not specular reflection, diffraction grating, slow light, pulse",
|
||||
effect() {
|
||||
if (tech.wideLaser === 0) tech.wideLaser = 3
|
||||
tech.isWideLaser = true;
|
||||
@@ -4855,9 +4842,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.isWideLaser
|
||||
return tech.isWideLaser
|
||||
},
|
||||
requires: "laser, diffuse beam",
|
||||
requires: "diffuse beam",
|
||||
effect() {
|
||||
tech.wideLaser += 2
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -4886,7 +4873,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isWideLaser
|
||||
},
|
||||
requires: "laser, not specular reflection, diffraction grating, diffuse beam",
|
||||
requires: "laser gun, not specular reflection, diffraction grating, diffuse beam",
|
||||
effect() {
|
||||
// this.description = `add 5 more <strong>laser</strong> beams into into your past`
|
||||
tech.historyLaser++
|
||||
@@ -4915,7 +4902,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.15
|
||||
},
|
||||
requires: "laser, not specular reflection, diffuse, solid-state",
|
||||
requires: "laser gun, not specular reflection, diffuse, free-electron laser",
|
||||
effect() {
|
||||
tech.isPulseLaser = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -5310,7 +5297,7 @@
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive)
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport)
|
||||
},
|
||||
requires: "nano-scale manufacturing, no other manufacturing, no drone tech",
|
||||
effect() {
|
||||
@@ -5335,7 +5322,7 @@
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive)
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport)
|
||||
},
|
||||
requires: "nano-scale manufacturing, no other manufacturing, no drone tech",
|
||||
effect() {
|
||||
@@ -5360,7 +5347,7 @@
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive)
|
||||
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport)
|
||||
},
|
||||
requires: "nano-scale manufacturing, no other manufacturing, no drone tech",
|
||||
effect() {
|
||||
@@ -5387,7 +5374,7 @@
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
||||
},
|
||||
requires: "nano-scale manufacturing",
|
||||
requires: "nano-scale manufacturing or pilot wave",
|
||||
effect: () => {
|
||||
tech.isMassEnergy = true // used in m.grabPowerUp
|
||||
m.energy += 2
|
||||
@@ -5717,9 +5704,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 2) && tech.duplicationChance() < 1
|
||||
},
|
||||
requires: "wormhole",
|
||||
requires: "wormhole,below 100% duplication chance",
|
||||
effect() {
|
||||
tech.wormDuplicate = 0.19
|
||||
powerUps.setDo(); //needed after adjusting duplication chance
|
||||
|
||||
66
todo.txt
66
todo.txt
@@ -1,14 +1,58 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
spore tech - nematodes - replace spores with 1/2 as many worms that do 200% more damage
|
||||
worms are also a bit faster, last longer, have better reaction times
|
||||
a cool worm graphic, and a simple searching behavior if they haven't found a mob
|
||||
2 more lore chapters (5 total now)
|
||||
entering testing mode makes a sound now
|
||||
|
||||
mycelial fragmentation - makes 6 extra spores during growth phase (was 4)
|
||||
reduced the requirements and frequency for many tech so that they may show up in "less optimal" situations
|
||||
I hope this will increase build variety and also give more value to making good tech choices
|
||||
countless bug fixes and wording fixes
|
||||
|
||||
historyBoss has less health, slower tracking, and more damage
|
||||
mobs have a new trait mob[i].damageReduction
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
|
||||
|
||||
perfect diamagnetism field stays when you aren't holding field
|
||||
good for perfect because it doesn't use energy
|
||||
holding field moves it the player
|
||||
|
||||
level with mobs that follow a genetic algorithm
|
||||
mobs have genes
|
||||
the last mob that did damage saves it's genes to local storage
|
||||
new mobs have the saved genes, but with some random mutations
|
||||
mutations need to be balanced to prevent a gene from moving towards infinity
|
||||
total genome must equal 1 (100%)
|
||||
binary genes have a flat cost
|
||||
example: phasing through walls might cost 0.2
|
||||
spectrum genes have a rate
|
||||
example: acceleration cost 0.01 per 0.001
|
||||
possible genes
|
||||
genes should only effect it's ability to touch the player
|
||||
so not damage?
|
||||
genome: spectrum
|
||||
acceleration
|
||||
top speed / air friction
|
||||
damageReduction
|
||||
duration?
|
||||
health decreases naturally?
|
||||
or they just go away like bullets?
|
||||
spawn rate
|
||||
look frequency / memory?
|
||||
genome: binary
|
||||
go through walls
|
||||
blink/teleport (like striker)
|
||||
grow when near target
|
||||
split into two
|
||||
shielded
|
||||
occurs in a specialized level
|
||||
named: gene lab, gene factory, genetic lab, genome facility
|
||||
in the level sequence after lab and before gauntlet?
|
||||
level ends after a period of time
|
||||
exit is hidden until time is up and it appears
|
||||
the level tests player durability/evasion
|
||||
this is a nice contrast to the final level that tests damage output, and the gauntlet which tests AoE damage
|
||||
|
||||
|
||||
scrolling console history in pause menu?
|
||||
also make tech, guns scrolling?
|
||||
@@ -18,8 +62,6 @@ pause should at least show the last in game console message
|
||||
make the player get a buff after using wormhole
|
||||
while energy lasts: drain energy and give damage buff
|
||||
|
||||
Tech: "Induced Oscillation": When using phonon, if a block vibrates after it gets hit from a phonon, it has a chance of oscillating and creating an additional phonon coming from the block. The chance is higher the closer the block is to the source of the oscillation.
|
||||
|
||||
tech: quantized shields - harmonic standing wave field can only lose 33 energy per hit
|
||||
draw 1,2,3 levels of the field based on energy?
|
||||
the blocked value only scales up to 2x or 4x (33 energy) blocked
|
||||
@@ -186,6 +228,9 @@ n-gon outreach ideas
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
blocks on buttons teleport into the button endlessly if they are being slowly floated away
|
||||
maybe add a cooldown?
|
||||
|
||||
ants marching outline doesn't sync right on safari anymore.
|
||||
|
||||
door to exit in vats does nothing
|
||||
@@ -270,6 +315,12 @@ map: observatory
|
||||
|
||||
******************************************************** MOBS ********************************************************
|
||||
|
||||
mobs that buff the stats of mobs when they die
|
||||
nearby mobs
|
||||
boss is a group of mobs, they buff each other
|
||||
give the buff a ramp up time
|
||||
so there is an advantage to kill them all at once
|
||||
|
||||
mob that spawns eggs after they die
|
||||
eggs don't attack but grow back into a mob after about 10s
|
||||
|
||||
@@ -346,6 +397,7 @@ possible names for tech
|
||||
eternal inflation
|
||||
hypergraph
|
||||
gnarl
|
||||
SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions.
|
||||
|
||||
a tutorial / lore intro
|
||||
needs to be optional so it doesn't slow experienced players
|
||||
|
||||
Reference in New Issue
Block a user