demineralization
tech: demineralization - after mobs die gain 0.85x damage taken, effect stacks, but fades 10% every second
tech: remineralization - after mobs die gain 1.08x damage, effect stacks, but fades 10% every second
tech: equivalence principle - negative mass field doesn't cost energy
new JUNK tech: aerodynamics
interferometer
slower elevator and lasers
wider side ledges
large laser blocking blocks
flocculation
fewer mobs
it's easier to get out of the slime
pavilion
move vanish elements
easier traversal
secret tunnel
removed debris, but added power ups and blocks
corridor
limited to bosses that don't interact with the movers poorly
gravitron, substructure, corridor, interferometer
added more heal and ammo power ups to match other levels
because some newer levels are zoomed out more
laser max range is 3000->5000
nails last 1/3 of a second longer
bosses spawn an extra ammo power up
and 2 extra ammo on the hardest 2 difficulties
slasher mob's laserSwords will now damage a cloaked player
constraint announcement text looks more like computer code style to match game theme
foam recoil is back: 1->0.7x horizontal force and 2->4.3x vertical up force
this makes it less annoying to horizontally and easier to kinda fly/float
negative mass field damage reduction 0.4->0.5x
holographic principle no longer slows player movement
added 2 research cost
fermion gives 6->5 seconds of invulnerability after mobs die
stability 0.2->0.1x damage taken at max health
non-Newtonian armor 0.3->0.4x damage taken after collisions
Zeno's paradox 0.15->0.2x damage taken
annihilation energy cost 10->8 to destroy mobs after collisions
radiative equilibrium damage is 3->4x for 8->4 seconds
aerostat can be taken 1->3 times
dynamic equilibrium damage increased by 6->8x damage per last damage taken
aerostat no longer has 0.9x damage for being on the ground
launch system 1.2->1.3x ammo for missiles
research says that repeatedly entering alternate realities builds up some positive effects
Hilbert space 4x->3x damage
Ψ(t) collapse 6->4 research on boss death
transdimensional worms: 50% chance for a second worm per block in wormhole
wormhole 7->8 energy regen per second
hidden-variable theory 1.15->1.2 damage after choosing a field tech
ghoster mobs are less likely to get knocked far away from the player for long periods of time
bug fixes
dynamic equilibrium was set to 100 times higher frequency then normal
when constraints hide health bar's it's now hidden in the pause menu
mobs aiming at cloaked player
snakeBoss more intelligently chases player for a few seconds
pulsarBoss aims at player's history 3 seconds in past
pulsar will not stop firing
but it will still not fire at cloaked player
This commit is contained in:
BIN
img/demineralization.webp
Normal file
BIN
img/demineralization.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
img/equivalence principle.webp
Normal file
BIN
img/equivalence principle.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
img/remineralization.webp
Normal file
BIN
img/remineralization.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
22
js/bullet.js
22
js/bullet.js
@@ -2180,7 +2180,7 @@ const b = {
|
||||
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
|
||||
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
|
||||
const r = Vector.normalise(Vector.sub(d, nn));
|
||||
path[path.length] = Vector.add(Vector.mult(r, 3000), path[path.length - 1]);
|
||||
path[path.length] = Vector.add(Vector.mult(r, 5000), path[path.length - 1]);
|
||||
};
|
||||
|
||||
checkForCollisions();
|
||||
@@ -3929,7 +3929,7 @@ const b = {
|
||||
bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * tech.bulletSize, 2 * tech.bulletSize, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
|
||||
Matter.Body.setVelocity(bullet[me], velocity);
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
bullet[me].endCycle = simulation.cycle + 60 + 18 * Math.random();
|
||||
bullet[me].endCycle = simulation.cycle + 80 + 18 * Math.random();
|
||||
bullet[me].dmg = tech.isNailRadiation ? 0 : dmg
|
||||
bullet[me].beforeDmg = function (who) { //beforeDmg is rewritten with ice crystal tech
|
||||
if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
|
||||
@@ -6744,8 +6744,12 @@ const b = {
|
||||
isDischarge: false,
|
||||
knockBack: 0.0005, //set in tech: cavitation
|
||||
applyKnock(velocity) {
|
||||
player.force.x -= this.knockBack * velocity.x
|
||||
player.force.y -= 2 * this.knockBack * velocity.y
|
||||
player.force.x -= 0.7 * this.knockBack * velocity.x
|
||||
if (velocity.y > 0) {
|
||||
player.force.y -= 4.3 * this.knockBack * velocity.y
|
||||
} else {
|
||||
player.force.y -= this.knockBack * velocity.y
|
||||
}
|
||||
},
|
||||
chooseFireMethod() {
|
||||
if (tech.isFoamPressure) {
|
||||
@@ -6771,7 +6775,7 @@ const b = {
|
||||
}
|
||||
const position = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||
b.foam(position, Vector.rotate(velocity, spread), radius)
|
||||
// this.applyKnock(velocity)
|
||||
this.applyKnock(velocity)
|
||||
m.fireCDcycle = m.cycle + Math.floor(1.5 * b.fireCDscale);
|
||||
},
|
||||
doCharges() {
|
||||
@@ -6798,7 +6802,7 @@ const b = {
|
||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
||||
}
|
||||
b.foam(position, Vector.rotate(velocity, spread), radius)
|
||||
// this.applyKnock(velocity)
|
||||
this.applyKnock(velocity)
|
||||
this.charge -= 0.75
|
||||
m.fireCDcycle = m.cycle + 2; //disable firing and adding more charge until empty
|
||||
} else if (!input.fire) {
|
||||
@@ -6826,7 +6830,7 @@ const b = {
|
||||
const position = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||
|
||||
b.foam(position, Vector.rotate(velocity, spread), radius)
|
||||
// this.applyKnock(velocity)
|
||||
this.applyKnock(velocity)
|
||||
m.fireCDcycle = m.cycle + Math.floor(1.5 * b.fireCDscale);
|
||||
this.charge += 1 + tech.isCapacitor
|
||||
},
|
||||
@@ -7386,8 +7390,8 @@ const b = {
|
||||
m.energy -= drain
|
||||
const where = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) }
|
||||
b.laser(where, {
|
||||
x: where.x + 3000 * Math.cos(m.angle),
|
||||
y: where.y + 3000 * Math.sin(m.angle)
|
||||
x: where.x + 5000 * Math.cos(m.angle),
|
||||
y: where.y + 5000 * Math.sin(m.angle)
|
||||
}, tech.laserDamage / b.fireCDscale * this.lensDamage);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -177,8 +177,8 @@ function collisionChecks(event) {
|
||||
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
||||
Matter.Body.setVelocity(player, { x: player.velocity.x + 8 * Math.cos(angle), y: player.velocity.y + 8 * Math.sin(angle) });
|
||||
Matter.Body.setVelocity(mob[k], { x: mob[k].velocity.x - 8 * Math.cos(angle), y: mob[k].velocity.y - 8 * Math.sin(angle) });
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.1 && mob[k].damageReduction > 0) {
|
||||
m.energy -= 0.1 //* Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.08 && mob[k].damageReduction > 0) {
|
||||
m.energy -= 0.08 //* Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
|
||||
if (m.immuneCycle === m.cycle + m.collisionImmuneCycles) m.immuneCycle = 0; //player doesn't go immune to collision damage
|
||||
mob[k].death();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
|
||||
@@ -497,7 +497,7 @@ const build = {
|
||||
<span style="float: right;"><strong class='color-d'>level</strong> ${((m.dmgScale)).toPrecision(4)}x</span>
|
||||
<br><strong class='color-defense'>damage taken</strong> ${(m.defense()).toPrecision(4)}x
|
||||
<span style="float: right;"><strong class='color-defense'>level</strong> ${(simulation.dmgScale).toPrecision(4)}x</span>
|
||||
<br><strong class='color-h'>health</strong> (${(m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
|
||||
<br><strong class='color-h'>health</strong> (${level.isHideHealth ? "null" : (m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
|
||||
<span style="float: right;">${powerUps.research.count} ${powerUps.orb.research()}</span>
|
||||
<br><strong class='color-f'>energy</strong> (${(m.energy * 100).toFixed(0)} / ${(m.maxEnergy * 100).toFixed(0)}) + (${(m.fieldRegen * 6000 * level.isReducedRegen).toFixed(0)}/s)
|
||||
<span style="float: right;">${tech.totalCount} ${powerUps.orb.tech()}</span>
|
||||
|
||||
332
js/level.js
332
js/level.js
@@ -17,6 +17,8 @@ const level = {
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||
// simulation.difficultyMode = 1
|
||||
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
|
||||
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
|
||||
@@ -31,7 +33,7 @@ const level = {
|
||||
// tech.tech[297].frequency = 100
|
||||
// tech.addJunkTechToPool(0.5)
|
||||
// m.couplingChange(10)
|
||||
// m.setField("time dilation") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.setField("negative mass") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.energy = 0
|
||||
// powerUps.research.count = 3
|
||||
// tech.isHookWire = true
|
||||
@@ -48,28 +50,26 @@ const level = {
|
||||
// requestAnimationFrame(() => { tech.giveTech("non-renewables") });
|
||||
// tech.giveTech("dark matter")
|
||||
// tech.addJunkTechToPool(0.5)
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("pigeonhole principle")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("generalist")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("demineralization")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("remineralization")
|
||||
// m.skin.egg();
|
||||
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("many-worlds")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("quasiparticles") });
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("interest") });
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("interest")
|
||||
// m.lastKillCycle = m.cycle
|
||||
// for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "warp");
|
||||
// for (let i = 0; i < 7; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
// for (let i = 0; i < 7; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 250, "research", false);
|
||||
// spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
|
||||
// level.corridor();
|
||||
// level.testing();
|
||||
|
||||
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
||||
|
||||
|
||||
// for (let i = 0; i < 1; ++i) spawn.powerUpBossBaby(1900, -500)
|
||||
// for (let i = 0; i < 10; ++i) spawn.starter(1900, -500)
|
||||
// for (let i = 0; i < 1; i++) spawn.mantisBoss(1900, -500)
|
||||
|
||||
// for (let i = 0; i < 1; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "entanglement");
|
||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "boost");
|
||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "gun");
|
||||
// for (let i = 0; i < 100; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
|
||||
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
|
||||
//lore testing
|
||||
@@ -145,22 +145,6 @@ const level = {
|
||||
}
|
||||
|
||||
level.setConstraints()
|
||||
if (!localSettings.isHideHUD) {
|
||||
requestAnimationFrame(() => {
|
||||
//grow and get bright
|
||||
document.getElementById("right-HUD-constraint").style.opacity = 1
|
||||
document.getElementById("right-HUD-constraint").style.fontSize = "23px"
|
||||
document.getElementById("right-HUD-constraint").style.top = simulation.difficultyMode > 6 ? "6px" : "9px"
|
||||
setTimeout(() => {
|
||||
if (m.alive) {
|
||||
//fade to background
|
||||
document.getElementById("right-HUD-constraint").style.opacity = 0.35
|
||||
document.getElementById("right-HUD-constraint").style.fontSize = "20px"
|
||||
document.getElementById("right-HUD-constraint").style.top = "12px"
|
||||
}
|
||||
}, 5000);
|
||||
});
|
||||
}
|
||||
},
|
||||
newLevelOrPhase() { //runs on each new level but also on final boss phases
|
||||
//used for generalist and pigeonhole principle
|
||||
@@ -285,6 +269,46 @@ const level = {
|
||||
}
|
||||
},
|
||||
constraintIndex: 0,
|
||||
constraintPopUp() {
|
||||
//pause
|
||||
if (!simulation.paused) {
|
||||
simulation.paused = true;
|
||||
simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
|
||||
document.body.style.cursor = "auto";
|
||||
document.getElementById("choose-grid").style.pointerEvents = "auto";
|
||||
document.getElementById("choose-grid").style.transitionDuration = "0s";
|
||||
}
|
||||
//build level info
|
||||
document.getElementById("choose-grid").classList.add('choose-grid-no-images')
|
||||
document.getElementById("choose-grid").classList.remove('choose-grid')
|
||||
document.getElementById("choose-grid").style.gridTemplateColumns = "auto"//"450px"
|
||||
let text = `<div class="constraint-module metallic-sparkle">${level.constraintDescription1}</div>`
|
||||
if (level.constraintDescription2) text += `<div class="constraint-module metallic-sparkle"><span>${level.constraintDescription2}</div>`
|
||||
text += `<div class="choose-grid-module" id = "choose-unPause" style="font-size: 1em;text-align: center;padding: 13px;border-radius:5px;">continue</div>`
|
||||
|
||||
document.getElementById("choose-grid").innerHTML = text
|
||||
//show level info
|
||||
document.getElementById("choose-grid").style.opacity = "1"
|
||||
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
|
||||
document.getElementById("choose-grid").style.visibility = "visible"
|
||||
document.getElementById("choose-unPause").addEventListener("click", () => {
|
||||
level.unPause()
|
||||
document.body.style.cursor = "none";
|
||||
//reset hide image style
|
||||
if (localSettings.isHideImages) {
|
||||
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
|
||||
document.getElementById("choose-grid").classList.remove('choose-grid');
|
||||
} else {
|
||||
document.getElementById("choose-grid").classList.add('choose-grid');
|
||||
document.getElementById("choose-grid").classList.remove('choose-grid-no-images');
|
||||
}
|
||||
});
|
||||
requestAnimationFrame(() => {
|
||||
ctx.fillStyle = `rgba(150,150,150,0.9)`; //`rgba(221,221,221,0.6)`;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
});
|
||||
},
|
||||
setConstraints() {
|
||||
//populate array with possible constraints and reset constraints
|
||||
level.constraintDescription1 = level.constraintDescription2 = ""
|
||||
@@ -303,7 +327,6 @@ const level = {
|
||||
level.constraintDescription1 = level.constraint[level.constraintIndex].description
|
||||
level.constraintIndex++
|
||||
if (level.constraintIndex > level.constraint.length - 1) level.constraintIndex = 0
|
||||
|
||||
if (simulation.difficultyMode > 6 && possible.length) {
|
||||
level.constraint[level.constraintIndex].effect()
|
||||
possible.splice(level.constraintIndex, 1)
|
||||
@@ -312,6 +335,24 @@ const level = {
|
||||
if (level.constraintIndex > level.constraint.length - 1) level.constraintIndex = 0
|
||||
}
|
||||
document.getElementById("right-HUD-constraint").style.display = "block";
|
||||
// level.constraintPopUp()
|
||||
//animate making constraint HUD bigger then smaller
|
||||
if (!localSettings.isHideHUD) {
|
||||
requestAnimationFrame(() => {
|
||||
//grow and get bright
|
||||
document.getElementById("right-HUD-constraint").style.opacity = 1
|
||||
document.getElementById("right-HUD-constraint").style.fontSize = "23px"
|
||||
document.getElementById("right-HUD-constraint").style.top = simulation.difficultyMode > 6 ? "6px" : "9px"
|
||||
setTimeout(() => {
|
||||
if (m.alive) {
|
||||
//fade to background
|
||||
document.getElementById("right-HUD-constraint").style.opacity = 0.35
|
||||
document.getElementById("right-HUD-constraint").style.fontSize = "20px"
|
||||
document.getElementById("right-HUD-constraint").style.top = "12px"
|
||||
}
|
||||
}, 5000);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
document.getElementById("right-HUD-constraint").style.display = "none";
|
||||
}
|
||||
@@ -320,10 +361,10 @@ const level = {
|
||||
}
|
||||
//update HUD with constraints
|
||||
let text = `${level.constraintDescription1}`
|
||||
if (level.constraintDescription1) simulation.inGameConsole(`<span style="color:#624;background-color: rgba(255, 215, 241, 0.4);">constraint</span>: ${level.constraintDescription1}`)
|
||||
if (level.constraintDescription1) simulation.inGameConsole(`level<span class='color-symbol'>.</span>constraint<span class='color-symbol'>.</span>description<span class='color-symbol'>:</span> "<span style="color:#624;background-color: rgba(255, 215, 241, 0.4);border-radius:6px;padding:3px;">${level.constraintDescription1}</span>"`)
|
||||
if (simulation.difficultyMode > 6 && level.constraintDescription2) {
|
||||
text += `<br>${level.constraintDescription2}`
|
||||
if (level.constraintDescription2) simulation.inGameConsole(`<span style="color:#624;background-color: rgba(255, 215, 241, 0.4);">constraint</span>: ${level.constraintDescription2}`)
|
||||
if (level.constraintDescription2) simulation.inGameConsole(`level<span class='color-symbol'>.</span>constraint<span class='color-symbol'>.</span>description<span class='color-symbol'>:</span> "<span style="color:#624;background-color: rgba(255, 215, 241, 0.4);border-radius:6px;padding:3px;">${level.constraintDescription2}</span>"`)
|
||||
}
|
||||
document.getElementById("right-HUD-constraint").innerHTML = text
|
||||
|
||||
@@ -427,7 +468,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
{
|
||||
description: "0.3x damage after getting power ups",
|
||||
description: "0.3x damage after using power ups",
|
||||
effect() {
|
||||
level.isNoDamage = true
|
||||
level.noDamageCycle = 0
|
||||
@@ -1719,7 +1760,7 @@ const level = {
|
||||
},
|
||||
vanish(x, y, width, height, isVertical = false, hide = {
|
||||
x: 0,
|
||||
y: 150
|
||||
y: 400
|
||||
}) {
|
||||
x = x + width / 2
|
||||
y = y + height / 2
|
||||
@@ -6761,26 +6802,34 @@ const level = {
|
||||
level.defaultZoom = 1500
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#dcdcde";
|
||||
spawn.debris(-150, -775, 1425, 3); //16 debris per level
|
||||
spawn.debris(1525, -25, 950, 3); //16 debris per level
|
||||
spawn.debris(-650, -2100, 575, 2); //16 debris per level
|
||||
|
||||
// spawn.debris(-150, -775, 1425, 3); //16 debris per level
|
||||
// spawn.debris(1525, -25, 950, 3); //16 debris per level
|
||||
// spawn.debris(-650, -2100, 575, 2); //16 debris per level
|
||||
powerUps.chooseRandomPowerUp(2075, -1525);
|
||||
powerUps.chooseRandomPowerUp(2550, -1825);
|
||||
powerUps.chooseRandomPowerUp(1975, 250);
|
||||
//bottom floor
|
||||
//entrance
|
||||
spawn.mapRect(-200, -750, 1500, 100);
|
||||
spawn.mapRect(-575, 0, 2150, 500);
|
||||
// spawn.mapRect(-575, 0, 2150, 500);
|
||||
spawn.mapRect(-575, 0, 2150, 165);
|
||||
const mover = level.mover(-525, 270, 2050, 75, 15 * (simulation.isHorizontalFlipped ? -1 : 1))
|
||||
spawn.bodyRect(-1050, -75, 75, 75);
|
||||
spawn.bodyRect(-573, 170, 30, 105);
|
||||
|
||||
// spawn.mapRect(-1275, 275, 875, 225);
|
||||
spawn.mapRect(-1275, 275, 3975, 225);
|
||||
spawn.mapRect(-1300, 275, 4025, 3300);
|
||||
// spawn.mapRect(-1275, 275, 3975, 225);
|
||||
spawn.mapRect(-1050, 0, 325, 50);
|
||||
spawn.mapRect(-775, 0, 50, 140);
|
||||
vanish.push(level.vanish(-725, 13, 150, 25))
|
||||
spawn.mapRect(-200, -750, 100, 600);
|
||||
// spawn.mapRect(1200, -750, 100, 600);
|
||||
vanish.push(level.vanish(-350, -225, 150, 225))
|
||||
vanish.push(level.vanish(-350, -450, 150, 223))
|
||||
vanish.push(level.vanish(-525, -150, 425, 150))
|
||||
vanish.push(level.vanish(-475, -300, 275, 150))
|
||||
vanish.push(level.vanish(-425, -450, 225, 150))
|
||||
vanish.push(level.vanish(-375, -600, 175, 150))
|
||||
vanish.push(level.vanish(-325, -750, 125, 150))
|
||||
spawn.mapRect(2475, -1800, 250, 2300);
|
||||
|
||||
|
||||
spawn.mapRect(1200, -750, 100, 450);
|
||||
spawn.mapRect(1200, -375, 250, 75);
|
||||
powerUps.spawnStartingPowerUps(550, -100);
|
||||
@@ -6789,10 +6838,18 @@ const level = {
|
||||
spawn.bodyRect(1350, -175, 150, 175, 0.5);
|
||||
spawn.bodyRect(1350, -600, 125, 225, 0.2);
|
||||
|
||||
spawn.bodyRect(1575, 50, 50, 225);
|
||||
vanish.push(level.vanish(1900, -25, 325, 25))
|
||||
vanish.push(level.vanish(1925, -375, 275, 25))
|
||||
vanish.push(level.vanish(1950, -725, 225, 25))
|
||||
vanish.push(level.vanish(1950, -1075, 225, 25))
|
||||
spawn.mapRect(1950, -1500, 225, 25);
|
||||
vanish.push(level.vanish(1350, -1075, 225, 25))
|
||||
vanish.push(level.vanish(1637, -1300, 225, 25))
|
||||
|
||||
//middle floor
|
||||
spawn.bodyRect(215, -1175, 100, 100, 0.3);
|
||||
spawn.mapRect(-1300, -1800, 250, 2300);
|
||||
// spawn.mapRect(-1300, -2075, 250, 2575);
|
||||
if (Math.random() < 0.5) {
|
||||
spawn.mapRect(500, -1350, 525, 425);
|
||||
spawn.mapRect(25, -1050, 300, 198);
|
||||
@@ -6800,34 +6857,17 @@ const level = {
|
||||
spawn.mapRect(500, -1350, 525, 497);
|
||||
spawn.mapRect(25, -1050, 300, 150);
|
||||
}
|
||||
if (Math.random() < 0.5) {
|
||||
vanish.push(level.vanish(400, -1600, 175, 25))
|
||||
vanish.push(level.vanish(950, -1600, 175, 25))
|
||||
} else {
|
||||
vanish.push(level.vanish(550, -1575, 50, 225))
|
||||
vanish.push(level.vanish(925, -1575, 50, 225))
|
||||
}
|
||||
|
||||
// vanish.push(level.vanish(575, -1575, 375, 225))
|
||||
spawn.bodyRect(225, -850, 50, 100, 0.4);
|
||||
spawn.mapRect(600, -1800, 325, 225);
|
||||
spawn.mapRect(1900, -1500, 325, 25);
|
||||
// spawn.mapRect(600, -1800, 325, 225);
|
||||
spawn.mapRect(650, -1800, 225, 225);
|
||||
vanish.push(level.vanish(600, -1575, 100, 225))
|
||||
vanish.push(level.vanish(825, -1575, 100, 225))
|
||||
|
||||
spawn.bodyRect(1050, -1825, 250, 20, 0.2);
|
||||
if (Math.random() < 0.5) {
|
||||
vanish.push(level.vanish(1400, -1000, 200, 25))
|
||||
vanish.push(level.vanish(1625, -1250, 200, 25))
|
||||
} else {
|
||||
vanish.push(level.vanish(1400, -1075, 175, 175))
|
||||
vanish.push(level.vanish(1575, -1250, 175, 175))
|
||||
}
|
||||
|
||||
vanish.push(level.vanish(1125, -1800, 625, 25))
|
||||
|
||||
// vanish.push(level.vanish(1500, -1800, 225, 25))
|
||||
vanish.push(level.vanish(-50, -1800, 450, 25))
|
||||
|
||||
//exit
|
||||
// spawn.mapRect(-1050, -1450, 700, 25);
|
||||
// spawn.mapRect(-1050, -1800, 525, 25);
|
||||
spawn.mapRect(-575, -1800, 50, 200);
|
||||
spawn.mapRect(-1050, -1800, 525, 75);
|
||||
spawn.mapRect(-1050, -1450, 700, 75);
|
||||
@@ -6864,8 +6904,10 @@ const level = {
|
||||
|
||||
level.exit.drawAndCheck();
|
||||
level.enter.draw();
|
||||
mover.push();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
mover.draw();
|
||||
//shadow
|
||||
ctx.fillStyle = "rgba(0,10,30,0.1)"
|
||||
ctx.fillRect(-1450, -300, 150, 325);
|
||||
@@ -6873,7 +6915,9 @@ const level = {
|
||||
ctx.fillRect(725, 50, 325, 225)
|
||||
ctx.fillRect(-325, -950, 300, 225)
|
||||
ctx.fillRect(-1025, -1000, 525, 275);
|
||||
ctx.fillRect(-925, -1600, 325, 275);
|
||||
ctx.fillRect(-875, -1600, 225, 275);
|
||||
ctx.fillStyle = "rgba(68,68,68,0.93)"
|
||||
ctx.fillRect(-1575, 150, 2150, 150);
|
||||
for (let i = 0, len = vanish.length; i < len; i++) vanish[i].query()
|
||||
};
|
||||
|
||||
@@ -6888,16 +6932,20 @@ const level = {
|
||||
|
||||
level.exit.drawAndCheck();
|
||||
level.enter.draw();
|
||||
mover.push();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
mover.draw();
|
||||
//shadow
|
||||
ctx.fillStyle = "rgba(0,10,30,0.1)"
|
||||
ctx.fillRect(1300, -300, 150, 325);
|
||||
ctx.fillRect(-200, -675, 1500, 700)
|
||||
ctx.fillRect(500, -950, 525, 225);
|
||||
ctx.fillRect(600, -1600, 325, 275);
|
||||
ctx.fillRect(650, -1600, 225, 275);
|
||||
ctx.fillRect(-1050, 50, 325, 225)
|
||||
ctx.fillRect(25, -950, 300, 225)
|
||||
ctx.fillStyle = "rgba(68,68,68,0.93)"
|
||||
ctx.fillRect(-575, 150, 2150, 150);
|
||||
for (let i = 0, len = vanish.length; i < len; i++) vanish[i].query()
|
||||
};
|
||||
}
|
||||
@@ -7178,6 +7226,12 @@ const level = {
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#d0d5d5";
|
||||
color.map = "#444"
|
||||
powerUps.chooseRandomPowerUp(-1550, 300);
|
||||
powerUps.chooseRandomPowerUp(200, 50);
|
||||
powerUps.chooseRandomPowerUp(-975, -1475);
|
||||
powerUps.chooseRandomPowerUp(2150, -750);
|
||||
powerUps.chooseRandomPowerUp(1850, 1925);
|
||||
|
||||
|
||||
let buttons = []
|
||||
let lasers = []
|
||||
@@ -7202,8 +7256,8 @@ const level = {
|
||||
classType: "body",
|
||||
holdX: 1762,
|
||||
maxHeight: -1580,
|
||||
minHeight: 130,
|
||||
verticalForce: 0.03,
|
||||
minHeight: 90,
|
||||
verticalForce: 0.02,
|
||||
isUp: false,
|
||||
drag: 0.01,
|
||||
move() {
|
||||
@@ -7269,7 +7323,7 @@ const level = {
|
||||
|
||||
let buildMapOutline = function () {
|
||||
//boxes center on zero,zero with deep walls to hide background
|
||||
spawn.mapRect(2025, -2000, 1975, 4000); //right map wall
|
||||
spawn.mapRect(2225, -2000, 1775, 4000); //right map wall
|
||||
spawn.mapRect(-4000, -2000, 2000, 4000); //left map wall
|
||||
spawn.mapRect(-4000, -5000, 8000, 3000); //map ceiling
|
||||
spawn.mapRect(-4000, 2000, 8000, 3000); //floor
|
||||
@@ -7325,13 +7379,13 @@ const level = {
|
||||
|
||||
//lower right side
|
||||
//far right wall ledges
|
||||
spawn.mapRect(1925, -1700, 200, 200);
|
||||
spawn.mapRect(1925, -1200, 200, 200);
|
||||
spawn.mapRect(1925, -700, 200, 200);
|
||||
spawn.mapRect(1925, -200, 200, 200);
|
||||
spawn.mapRect(1925, 300, 200, 200);
|
||||
spawn.mapRect(1925, 800, 200, 200);
|
||||
spawn.mapRect(1925, 1300, 200, 200);
|
||||
spawn.mapRect(1925, -1700, 400, 200);
|
||||
spawn.mapRect(1925, -1200, 400, 200);
|
||||
spawn.mapRect(1925, -700, 400, 200);
|
||||
spawn.mapRect(1925, -200, 400, 200);
|
||||
spawn.mapRect(1925, 300, 400, 200);
|
||||
spawn.mapRect(1925, 800, 400, 200);
|
||||
spawn.mapRect(1925, 1300, 400, 200);
|
||||
|
||||
spawn.mapRect(1250, 1650, 500, 25);
|
||||
spawn.mapRect(1300, 1125, 400, 25);
|
||||
@@ -7402,13 +7456,13 @@ const level = {
|
||||
spawn.mapVertex(-350, -835, "-225 -475 225 -475 225 475 0 500 -225 475");
|
||||
|
||||
//far right wall ledges
|
||||
spawn.mapRect(1925, 1700 - 200, 200, 200);
|
||||
spawn.mapRect(1925, 1200 - 200, 200, 200);
|
||||
spawn.mapRect(1925, 700 - 200, 200, 200);
|
||||
spawn.mapRect(1925, 200 - 200, 200, 200);
|
||||
spawn.mapRect(1925, -300 - 200, 200, 200);
|
||||
spawn.mapRect(1925, -800 - 200, 200, 200);
|
||||
spawn.mapRect(1925, -1300 - 200, 200, 200);
|
||||
spawn.mapRect(1925, 1700 - 200, 400, 200);
|
||||
spawn.mapRect(1925, 1200 - 200, 400, 200);
|
||||
spawn.mapRect(1925, 700 - 200, 400, 200);
|
||||
spawn.mapRect(1925, 200 - 200, 400, 200);
|
||||
spawn.mapRect(1925, -300 - 200, 400, 200);
|
||||
spawn.mapRect(1925, -800 - 200, 400, 200);
|
||||
spawn.mapRect(1925, -1300 - 200, 400, 200);
|
||||
|
||||
spawn.mapRect(1250, -1650 - 25, 500, 25);
|
||||
spawn.mapRect(1300, -1125 - 25, 400, 25);
|
||||
@@ -7559,7 +7613,7 @@ const level = {
|
||||
//background structure
|
||||
ctx.fillStyle = "#c3c7c7"
|
||||
ctx.fillRect(1487, -75 - 1925, 25, 1925);
|
||||
ctx.fillRect(1925, -2050, 125, 4100);
|
||||
ctx.fillRect(1925, -2050, 300, 4100);
|
||||
|
||||
//exit room
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
@@ -7580,7 +7634,7 @@ const level = {
|
||||
//background structure
|
||||
ctx.fillStyle = "#c5c9c9"
|
||||
ctx.fillRect(1487, 75, 25, 1925);
|
||||
ctx.fillRect(1925, -2050, 125, 4100);
|
||||
ctx.fillRect(1925, -2050, 300, 4100);
|
||||
|
||||
//draw flipped exit
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
@@ -7604,7 +7658,7 @@ const level = {
|
||||
ctx.moveTo(balance[i].center.x, balance[i].center.y)
|
||||
ctx.arc(balance[i].center.x, balance[i].center.y, 9, 0, 2 * Math.PI);
|
||||
//rotor spins and stops at vertical and horizontal angles
|
||||
if ((simulation.cycle % 90) < 15) {
|
||||
if ((simulation.cycle % 140) < 15) {
|
||||
balance[i].torque = 0.0002 * balance[i].inertia
|
||||
} else if (Math.floor(10 * (balance[i].angle % (Math.PI / 2))) === 0) {
|
||||
Matter.Body.setAngularVelocity(balance[i], balance[i].angularVelocity * 0.1)
|
||||
@@ -7653,6 +7707,8 @@ const level = {
|
||||
spawn.bodyRect(1325, -1775, 175, 175);
|
||||
spawn.bodyRect(-375, -1725, 100, 75, 0.5);
|
||||
spawn.bodyRect(-900, -1625, 125, 200, 0.5);
|
||||
spawn.bodyRect(875, -25, 200, 175);
|
||||
|
||||
|
||||
spawn.bodyRect(-1662, 1325, 25, 175);
|
||||
spawn.bodyRect(-1662, 1825, 25, 175);
|
||||
@@ -7708,6 +7764,9 @@ const level = {
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#c3d6e1";
|
||||
color.map = "#444"
|
||||
powerUps.chooseRandomPowerUp(-1825, 975);
|
||||
powerUps.chooseRandomPowerUp(-3975, 975);
|
||||
powerUps.chooseRandomPowerUp(3900, 925);
|
||||
|
||||
let buttons = []
|
||||
level.isFlipped = false;
|
||||
@@ -8220,12 +8279,14 @@ const level = {
|
||||
spawn.randomMob(2825, 75, 0.9);
|
||||
spawn.randomLevelBoss(2400, 600);
|
||||
spawn.secondaryBossChance(800, -300)
|
||||
powerUps.spawnStartingPowerUps(600, 375);
|
||||
powerUps.chooseRandomPowerUp(600, 375);
|
||||
powerUps.chooseRandomPowerUp(600, 925);
|
||||
powerUps.spawnStartingPowerUps(1750, -325);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
powerUps.directSpawn(2825, 175, "heal");
|
||||
powerUps.directSpawn(2475, -650, "heal");
|
||||
powerUps.directSpawn(2100, 925, "heal");
|
||||
powerUps.directSpawn(625, -100, "heal");
|
||||
powerUps.chooseRandomPowerUp(2825, 175);
|
||||
powerUps.chooseRandomPowerUp(2475, -650);
|
||||
powerUps.chooseRandomPowerUp(2100, 925);
|
||||
powerUps.chooseRandomPowerUp(625, -100);
|
||||
},
|
||||
corridor() {
|
||||
// simulation.fallHeight = 4000
|
||||
@@ -8235,6 +8296,10 @@ const level = {
|
||||
document.body.style.backgroundColor = "#d0d5d5";
|
||||
color.map = "#444"
|
||||
|
||||
powerUps.chooseRandomPowerUp(5925, -2125);
|
||||
powerUps.chooseRandomPowerUp(75, -4225);
|
||||
powerUps.chooseRandomPowerUp(2950, -1450);
|
||||
|
||||
// level.isHorizontalFlipped = true
|
||||
if (level.isHorizontalFlipped) {
|
||||
level.setPosToSpawn(14075, -625);
|
||||
@@ -8473,8 +8538,8 @@ const level = {
|
||||
spawn.randomMob(3575, 375, 0.6);
|
||||
spawn.randomGroup(5300, -1400, 1.3);
|
||||
|
||||
spawn.randomLevelBoss(2025, -1825);
|
||||
spawn.secondaryBossChance(-1900, -1800);
|
||||
spawn.randomLevelBoss(2025, -1825, ["pulsarBoss", "shieldingBoss", "laserLayerBoss", "shooterBoss"]);
|
||||
spawn.secondaryBossChance(-1900, -1800, ["historyBoss", "spawnerBossCulture", "blockBoss"]);
|
||||
powerUps.spawnStartingPowerUps(11750, -1000);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
@@ -8948,18 +9013,17 @@ const level = {
|
||||
button0.query();
|
||||
if (!button0.isUp) { //summon second set of mobs
|
||||
//1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
|
||||
spawn.randomMob(918, 2695, 0.1);
|
||||
spawn.randomMob(1818, 2719, 0.2);
|
||||
spawn.randomMob(2530, 2460, 0.2);
|
||||
spawn.randomMob(3109, 2665, 0.3);
|
||||
spawn.randomMob(3909, 2191, 0.3);
|
||||
spawn.randomMob(4705, 2711, 0.4);
|
||||
spawn.randomMob(5800, 2796, 0.5);
|
||||
spawn.randomMob(7287, 2757, 0.6);
|
||||
spawn.randomMob(5759, 2691, 0.9);
|
||||
spawn.randomMob(5675, 2225, 0.8);
|
||||
spawn.randomMob(7450, 2775, 0.8);
|
||||
|
||||
spawn.randomMob(918, 2695, 0);
|
||||
spawn.randomMob(1818, 2719, 0.1);
|
||||
spawn.randomMob(2530, 2460, 0.1);
|
||||
spawn.randomMob(3109, 2665, 0.2);
|
||||
spawn.randomMob(3909, 2191, 0.2);
|
||||
spawn.randomMob(4705, 2711, 0.3);
|
||||
spawn.randomMob(5800, 2796, 0.3);
|
||||
spawn.randomMob(7287, 2757, 0.4);
|
||||
spawn.randomMob(5759, 2691, 0.4);
|
||||
spawn.randomMob(5675, 2225, 0.5);
|
||||
spawn.randomMob(7450, 2775, 0.5);
|
||||
spawn.randomGroup(6600, 2400, 0.1);
|
||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(6076, 2341);
|
||||
}
|
||||
@@ -9050,7 +9114,9 @@ const level = {
|
||||
spawn.bodyRect(3825, 2240, 150, 75, 0.5);
|
||||
|
||||
spawn.mapVertex(3500, 2452, "-500 -135 500 -135 500 35 400 135 -400 135 -500 35");
|
||||
spawn.mapVertex(1200, 2875, "-400 0 -300 -100 300 -100 400 0");
|
||||
spawn.mapVertex(1200, 2850, "-500 -100 -550 -50 500 -100 550 -50 550 300 -550 300");
|
||||
// spawn.mapVertex(1200, 2875, "-400 0 -300 -100 300 -100 400 0");
|
||||
|
||||
spawn.mapVertex(1317, 275, "-500 0 -300 -200 300 -200 550 50 550 500 -500 500");
|
||||
spawn.mapVertex(1300, -357, "-300 0 -400 -100 400 -100 300 0");
|
||||
spawn.bodyRect(1550, -308, 50, 208, 0.5);
|
||||
@@ -9081,17 +9147,17 @@ const level = {
|
||||
spawn.mapRect(7625, 2890, 400, 25);
|
||||
spawn.mapRect(7800, 2880, 100, 25);
|
||||
|
||||
spawn.randomMob(2450, 250, 0.2);
|
||||
spawn.randomMob(3250, 325, 0.2);
|
||||
spawn.randomMob(3625, 350, 0.3);
|
||||
spawn.randomMob(1750, -25, 0.4);
|
||||
spawn.randomMob(1300, 1750, 0.5);
|
||||
spawn.randomMob(2350, 1725, 0.6);
|
||||
spawn.randomMob(3350, 1775, 0.7);
|
||||
spawn.randomMob(1025, 750, 0.8);
|
||||
spawn.randomMob(2400, 1775, 0.8);
|
||||
spawn.randomMob(1250, 1725, 0.8);
|
||||
spawn.randomMob(775, 1775, 0.9);
|
||||
spawn.randomMob(2450, 250, 0);
|
||||
spawn.randomMob(3250, 325, 0);
|
||||
spawn.randomMob(3625, 350, 0.1);
|
||||
spawn.randomMob(1750, -25, 0.1);
|
||||
spawn.randomMob(1300, 1750, 0.2);
|
||||
spawn.randomMob(2350, 1725, 0.2);
|
||||
spawn.randomMob(3350, 1775, 0.2);
|
||||
spawn.randomMob(1025, 750, 0.3);
|
||||
spawn.randomMob(2400, 1775, 0.3);
|
||||
spawn.randomMob(1250, 1725, 0.3);
|
||||
spawn.randomMob(775, 1775, 0.4);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
spawn.secondaryBossChance(1822, 1336)
|
||||
|
||||
@@ -9102,7 +9168,7 @@ const level = {
|
||||
|
||||
balance1 = level.rotor(-800 - 25, -395, 25, 390, 0.001) //entrance
|
||||
balance2 = level.rotor(-2605 - 390, 500, 390, 25, 0.001) //falling
|
||||
balance3 = level.rotor(-2608 - 584, 1950, 584, 25, 0.001) //falling
|
||||
balance3 = level.rotor(-2608 - 400, 1950, 400, 25, 0.001) //falling
|
||||
balance5 = level.rotor(-2605 - 390, 1020, 390, 25, 0.001) //falling
|
||||
|
||||
button1.min.x = -button1.min.x - 126
|
||||
@@ -9129,17 +9195,17 @@ const level = {
|
||||
button0.query();
|
||||
if (!button0.isUp) { //summon second set of mobs
|
||||
//1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
|
||||
spawn.randomMob(-7475, 2800, 0.1);
|
||||
spawn.randomMob(-6475, 2500, 0.2);
|
||||
spawn.randomMob(-4575, 2775, 0.3);
|
||||
spawn.randomMob(-7575, 2850, 0.3);
|
||||
spawn.randomMob(-6425, 2575, 0.3);
|
||||
spawn.randomMob(-5750, 2775, 0.4);
|
||||
spawn.randomMob(-4675, 2800, 0.5);
|
||||
spawn.randomMob(-3425, 2800, 0.6);
|
||||
spawn.randomMob(-2475, 2475, 0.7);
|
||||
spawn.randomMob(-3350, 2250, 0.8);
|
||||
spawn.randomMob(-1275, 2725, 0.9);
|
||||
spawn.randomMob(-7475, 2800, 0);
|
||||
spawn.randomMob(-6475, 2500, 0.1);
|
||||
spawn.randomMob(-4575, 2775, 0.2);
|
||||
spawn.randomMob(-7575, 2850, 0.2);
|
||||
spawn.randomMob(-6425, 2575, 0.2);
|
||||
spawn.randomMob(-5750, 2775, 0.3);
|
||||
spawn.randomMob(-4675, 2800, 0.3);
|
||||
spawn.randomMob(-3425, 2800, 0.4);
|
||||
spawn.randomMob(-2475, 2475, 0.4);
|
||||
spawn.randomMob(-3350, 2250, 0.5);
|
||||
spawn.randomMob(-1275, 2725, 0.5);
|
||||
spawn.randomGroup(-6225, 2400, 0.1);
|
||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(-6250, 2350);
|
||||
}
|
||||
@@ -9168,7 +9234,7 @@ const level = {
|
||||
rotor2 = level.rotor(1525, 1900, 650, 50, 0.001, 0, 0.01, 0, -0.0007)
|
||||
balance1 = level.rotor(800, -395, 25, 390, 0.001) //entrance
|
||||
balance2 = level.rotor(2605, 500, 390, 25, 0.001) //falling
|
||||
balance3 = level.rotor(2608, 1950, 584, 25, 0.001) //falling
|
||||
balance3 = level.rotor(2608, 1950, 400, 25, 0.001) //falling
|
||||
balance5 = level.rotor(2605, 1020, 390, 25, 0.001) //falling
|
||||
}
|
||||
|
||||
@@ -34957,8 +35023,8 @@ const level = {
|
||||
y: mob[k].velocity.y - 8 * Math.sin(angle)
|
||||
});
|
||||
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && g.energy > 0.1 && mob[k].damageReduction > 0) {
|
||||
g.energy -= 0.1 //* Math.max(g.maxEnergy, g.energy) //0.33 * g.energy
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && g.energy > 0.08 && mob[k].damageReduction > 0) {
|
||||
g.energy -= 0.08 //* Math.max(g.maxEnergy, g.energy) //0.33 * g.energy
|
||||
if (g.immuneCycle === g.cycle + g.collisionImmuneCycles) g.immuneCycle = 0; //genisis doesn't go immune to collision damage
|
||||
mob[k].death();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
|
||||
32
js/mob.js
32
js/mob.js
@@ -1234,6 +1234,30 @@ const mobs = {
|
||||
m.energy -= 0.05;
|
||||
if (m.energy < 0) m.energy = 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (tech.isRemineralize) {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
//apply mineral damage reduction
|
||||
tech.mineralDamageReduction *= 0.85
|
||||
}
|
||||
if (tech.isDemineralize) {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
//apply mineral damage
|
||||
tech.mineralDamage *= 1.08
|
||||
}
|
||||
|
||||
|
||||
|
||||
powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
|
||||
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
|
||||
mobs.mobDeaths++
|
||||
@@ -1253,9 +1277,11 @@ const mobs = {
|
||||
} else {
|
||||
for (let i = 0; i < amount; i++) b.spore(this.position)
|
||||
}
|
||||
} else if (tech.isExplodeMob) {
|
||||
}
|
||||
if (tech.isExplodeMob) {
|
||||
b.explosion(this.position, Math.min(700, Math.sqrt(this.mass + 6) * (30 + 60 * Math.random())))
|
||||
} else if (tech.nailsDeathMob) {
|
||||
}
|
||||
if (tech.nailsDeathMob) {
|
||||
b.targetedNail(this.position, tech.nailsDeathMob, 39 + 6 * Math.random())
|
||||
}
|
||||
if (tech.isBotSpawnerReset) {
|
||||
@@ -1269,7 +1295,7 @@ const mobs = {
|
||||
this.leaveBody = false; // no body since it turned into the bot
|
||||
}
|
||||
if (tech.isMobDeathImmunity) {
|
||||
const immuneTime = 360
|
||||
const immuneTime = 300
|
||||
if (m.immuneCycle < m.cycle + immuneTime) m.immuneCycle = m.cycle + immuneTime; //player is immune to damage
|
||||
}
|
||||
if (tech.isAddRemoveMaxHealth) {
|
||||
|
||||
64
js/player.js
64
js/player.js
@@ -782,9 +782,9 @@ const m = {
|
||||
defense() {
|
||||
let dmg = 1
|
||||
if (powerUps.boost.isDefense && powerUps.boost.endCycle > simulation.cycle) dmg *= 0.3
|
||||
if (tech.isMaxHealthDefense && m.health === m.maxHealth) dmg *= 0.2
|
||||
if (tech.isMaxHealthDefense && m.health === m.maxHealth) dmg *= 0.1
|
||||
if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075);
|
||||
if (tech.isZeno) dmg *= 0.15
|
||||
if (tech.isZeno) dmg *= 0.2
|
||||
if (tech.isFieldHarmReduction) dmg *= 0.6
|
||||
if (tech.isHarmDarkMatter) dmg *= (tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 0.25 : 0.4
|
||||
if (tech.isImmortal) dmg *= 0.7
|
||||
@@ -795,12 +795,20 @@ const m = {
|
||||
if (tech.isHarmReduce && input.field) dmg *= 0.1
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
||||
if (tech.isBotArmor) dmg *= 0.96 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3;
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.4;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
|
||||
if (tech.isTurret && m.crouch) dmg *= 0.3;
|
||||
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
|
||||
// if (tech.isLowHealthDefense) dmg *= Math.pow(0.3, Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health)))
|
||||
if (tech.isLowHealthDefense) dmg *= Math.pow(0.2, Math.max(0, 1 - (tech.isEnergyHealth ? m.energy / m.maxEnergy : m.health / m.maxHealth)))
|
||||
if (tech.isRemineralize) {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
dmg *= tech.mineralDamageReduction
|
||||
}
|
||||
// return tech.isEnergyHealth ? Math.pow(dmg, 0.7) : dmg //defense has less effect
|
||||
// dmg *= m.fieldHarmReduction
|
||||
return dmg * m.fieldHarmReduction
|
||||
@@ -2736,10 +2744,10 @@ const m = {
|
||||
m.fieldThreshold = Math.cos((m.fieldArc) * Math.PI)
|
||||
},
|
||||
setHoldDefaults() {
|
||||
if (tech.isFreeWormHole && m.fieldMode !== 9) { //not wormhole
|
||||
const removed = tech.removeTech("charmed baryon") //neutronum can get player stuck so it has to be removed if player has wrong field
|
||||
if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
|
||||
}
|
||||
// if (tech.isFreeWormHole && m.fieldMode !== 9) { //not wormhole
|
||||
// const removed = tech.removeTech("charmed baryon") //neutronum can get player stuck so it has to be removed if player has wrong field
|
||||
// if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
|
||||
// }
|
||||
if (tech.isNeutronium && m.fieldMode !== 3) { //not negative mass field
|
||||
const removed = tech.removeTech("neutronium") //neutronum can get player stuck so it has to be removed if player has wrong field
|
||||
if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
|
||||
@@ -2835,7 +2843,7 @@ const m = {
|
||||
} else if (m.fieldMode === 8) {
|
||||
m.fieldRegen = 0.001667 //10 energy per second pilot wave
|
||||
} else if (m.fieldMode === 9) {
|
||||
m.fieldRegen = 0.00117 //7 energy per second wormhole
|
||||
m.fieldRegen = 0.001334 //8 energy per second wormhole
|
||||
} else if (m.fieldMode === 10) {
|
||||
m.fieldRegen = 0.0015 //9 energy per second grappling hook
|
||||
} else {
|
||||
@@ -4011,14 +4019,14 @@ const m = {
|
||||
{
|
||||
name: "negative mass",
|
||||
//<br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>
|
||||
description: `use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br><strong>0.4x</strong> <strong class='color-defense'>damage taken</strong><br><strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br><strong>0.5x</strong> <strong class='color-defense'>damage taken</strong><br><strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
fieldDrawRadius: 0,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.fieldHarmReduction = 0.4;
|
||||
m.fieldHarmReduction = 0.5;
|
||||
m.fieldDrawRadius = 0;
|
||||
|
||||
m.hold = function () {
|
||||
@@ -4032,8 +4040,7 @@ const m = {
|
||||
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
|
||||
m.grabPowerUp();
|
||||
m.lookForPickUp();
|
||||
const DRAIN = 0.00035
|
||||
if (m.energy > DRAIN && m.fieldCDcycle < m.cycle) {
|
||||
if (m.energy > tech.negativeMassCost && m.fieldCDcycle < m.cycle) {
|
||||
if (tech.isFlyFaster) {
|
||||
//look for nearby objects to make zero-g
|
||||
function moveThis(who, range, mag = 1.06) {
|
||||
@@ -4065,13 +4072,13 @@ const m = {
|
||||
moveThis(powerUp, this.fieldDrawRadius, 0);
|
||||
moveThis(body, this.fieldDrawRadius, 0);
|
||||
} else if (input.up) { //up
|
||||
m.energy -= 5 * DRAIN;
|
||||
m.energy -= 5 * tech.negativeMassCost;
|
||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 1100 * 0.03;
|
||||
player.force.y -= 2.25 * player.mass * simulation.g;
|
||||
moveThis(powerUp, this.fieldDrawRadius, 1.8);
|
||||
moveThis(body, this.fieldDrawRadius, 1.8);
|
||||
} else {
|
||||
m.energy -= DRAIN;
|
||||
m.energy -= tech.negativeMassCost;
|
||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 800 * 0.03;
|
||||
player.force.y -= 1.07 * player.mass * simulation.g; // slow upward drift
|
||||
moveThis(powerUp, this.fieldDrawRadius);
|
||||
@@ -4109,13 +4116,13 @@ const m = {
|
||||
verticalForce(powerUp, this.fieldDrawRadius, 0.7);
|
||||
verticalForce(body, this.fieldDrawRadius, 0.7);
|
||||
} else if (input.up) { //up
|
||||
m.energy -= 5 * DRAIN;
|
||||
m.energy -= 5 * tech.negativeMassCost;
|
||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 850 * 0.03;
|
||||
player.force.y -= 1.45 * player.mass * simulation.g;
|
||||
verticalForce(powerUp, this.fieldDrawRadius, 1.38);
|
||||
verticalForce(body, this.fieldDrawRadius, 1.38);
|
||||
} else {
|
||||
m.energy -= DRAIN;
|
||||
m.energy -= tech.negativeMassCost;
|
||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 650 * 0.03;
|
||||
player.force.y -= 1.07 * player.mass * simulation.g; // slow upward drift
|
||||
verticalForce(powerUp, this.fieldDrawRadius);
|
||||
@@ -5051,7 +5058,7 @@ const m = {
|
||||
}
|
||||
}
|
||||
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
|
||||
let isMobsAround = false
|
||||
// let isMobsAround = false
|
||||
const stunRange = m.fieldDrawRadius * 1.25
|
||||
// const drain = 0.01
|
||||
// if (m.energy > drain) {
|
||||
@@ -5358,7 +5365,7 @@ const m = {
|
||||
{
|
||||
name: "wormhole",
|
||||
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>7</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>8</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
drain: 0,
|
||||
effect: function () {
|
||||
m.fieldMeterColor = "#bbf" //"#0c5"
|
||||
@@ -5454,8 +5461,10 @@ const m = {
|
||||
if (tech.isWormholeWorms) { //pandimensional spermia
|
||||
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), -10));
|
||||
// for (let i = 0, len = Math.ceil(1.25 * Math.random()); i < len; i++) {
|
||||
// }
|
||||
if (Math.random() < 0.5) { //chance for a second worm
|
||||
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), -10));
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -5475,13 +5484,12 @@ const m = {
|
||||
if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling * level.isReducedRegen
|
||||
if (m.fieldMode === 0 || m.fieldMode === 9) m.energy += 0.02 * m.coupling * level.isReducedRegen
|
||||
if (tech.isWormholeWorms) { //pandimensional spermia
|
||||
b.worm(Vector.add(m.hole.pos1, Vector.rotate({
|
||||
x: m.fieldRange * 0.4,
|
||||
y: 0
|
||||
}, 2 * Math.PI * Math.random())))
|
||||
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));
|
||||
// for (let i = 0, len = Math.ceil(1.25 * Math.random()); i < len; i++) {
|
||||
// }
|
||||
if (Math.random() < 0.5) { //chance for a second worm
|
||||
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));
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -6239,8 +6247,8 @@ const m = {
|
||||
y: mob[k].velocity.y - 8 * Math.sin(angle)
|
||||
});
|
||||
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.34 * m.maxEnergy) {
|
||||
m.energy -= 0.33 * Math.max(m.maxEnergy, m.energy)
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.08) {
|
||||
m.energy -= 0.08 //* Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
|
||||
m.immuneCycle = 0; //player doesn't go immune to collision damage
|
||||
mob[k].death();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
|
||||
@@ -256,6 +256,8 @@ const powerUps = {
|
||||
powerUps.endDraft(type);
|
||||
},
|
||||
showDraft() {
|
||||
simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
|
||||
//disable clicking for 1/2 a second to prevent mistake clicks
|
||||
document.getElementById("choose-grid").style.pointerEvents = "none";
|
||||
document.body.style.cursor = "none";
|
||||
@@ -264,7 +266,6 @@ const powerUps = {
|
||||
document.getElementById("choose-grid").style.pointerEvents = "auto";
|
||||
document.getElementById("choose-grid").style.transitionDuration = "0s";
|
||||
}, 400);
|
||||
simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
|
||||
if (!simulation.paused) {
|
||||
if (tech.isNoDraftPause || level.isNoPause) {
|
||||
@@ -909,7 +910,7 @@ const powerUps = {
|
||||
}
|
||||
},
|
||||
cancelText(type) {
|
||||
if (tech.isSuperDeterminism) {
|
||||
if (tech.isSuperDeterminism || type === "constraint") {
|
||||
return `<div></div>`
|
||||
} else if (tech.isCancelTech && tech.cancelTechCount === 0) {
|
||||
return `<div class='cancel-card sticky' onclick='powerUps.endDraft("${type}",true)' style="width: 115px;"><span class="color-randomize">randomize</span></div>`
|
||||
@@ -940,7 +941,9 @@ const powerUps = {
|
||||
},
|
||||
researchAndCancelText(type) {
|
||||
let text = `<div class='research-cancel'>`
|
||||
if (type === "entanglement") {
|
||||
if (type === "constraint") {
|
||||
return
|
||||
} else if (type === "entanglement") {
|
||||
text += `<span class='research-card entanglement flipX' style="width: 275px;" onclick='powerUps.endDraft("${type}",true)'><span style="letter-spacing: 6px;">entanglement</span></span>`
|
||||
} else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
|
||||
text += `<span onclick="powerUps.research.use('${type}')" class='research-card' style="width: 275px;float: left;">` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
@@ -1008,6 +1011,12 @@ const powerUps = {
|
||||
return text
|
||||
},
|
||||
hideStyle: `style="height:auto; border: none; background-color: transparent;"`,
|
||||
constraintText(choose, click) {
|
||||
return `<div class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${powerUps.hideStyle}>
|
||||
<div class="card-text">
|
||||
<div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choose].name}</div>
|
||||
${m.fieldUpgrades[choose].description}</div></div>`
|
||||
},
|
||||
gunText(choose, click) {
|
||||
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"`
|
||||
return `<div class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}" ${style}>
|
||||
@@ -1607,6 +1616,8 @@ const powerUps = {
|
||||
}
|
||||
}
|
||||
}
|
||||
powerUps.spawn(x + 25, y - 25, "ammo", false);
|
||||
if (simulation.difficultyMode > 5) powerUps.spawn(x - 25, y - 50, "ammo", false);
|
||||
if (tech.isAddRemoveMaxHealth) {
|
||||
powerUps.spawn(x + 20, y, "tech", false)
|
||||
powerUps.spawn(x - 20, y, "research", false)
|
||||
|
||||
48
js/spawn.js
48
js/spawn.js
@@ -1,6 +1,6 @@
|
||||
//main object for spawning things in a level
|
||||
const spawn = {
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture", "snakeBoss"],
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss, mineBoss, hopMotherBoss //these need a particular level to work so they are not included in the random pool
|
||||
randomBossList: [
|
||||
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||
@@ -114,9 +114,9 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
secondaryBossChance(x, y) {
|
||||
secondaryBossChance(x, y, options = []) {
|
||||
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
|
||||
spawn.randomLevelBoss(x, y);
|
||||
spawn.randomLevelBoss(x, y, options);
|
||||
powerUps.spawn(x - 30, y, "ammo");
|
||||
powerUps.spawn(x + 30, y, "ammo");
|
||||
} else {
|
||||
@@ -3921,8 +3921,8 @@ const spawn = {
|
||||
}
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.memory = 240
|
||||
me.seePlayerFreq = 55
|
||||
me.memory = 900;
|
||||
me.seePlayerFreq = 41
|
||||
me.delay = 5 + 2 * simulation.CDScale;//8 + 3 * simulation.CDScale;
|
||||
me.nextBlinkCycle = me.delay;
|
||||
me.JumpDistance = 0//set in redMode()
|
||||
@@ -4082,21 +4082,18 @@ const spawn = {
|
||||
move()
|
||||
} else if (this.seePlayer.recall) { //chase player's history
|
||||
this.lostPlayer();
|
||||
if (!m.isCloak) {
|
||||
for (let i = 0; i < 50; i++) { //if lost player lock onto a player location in history
|
||||
if (m.isCloak) {
|
||||
move(this.seePlayer.position) //go after where you last saw the player
|
||||
} else {
|
||||
for (let i = 0; i < 55; i++) { //if lost player lock onto a player location in history
|
||||
let history = m.history[(m.cycle - 10 * i) % 600]
|
||||
if (Matter.Query.ray(map, this.position, history.position).length === 0) {
|
||||
this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //cycles before mob falls a sleep
|
||||
this.seePlayer.position.x = history.position.x;
|
||||
this.seePlayer.position.y = history.position.y;
|
||||
this.seePlayer.yes = true;
|
||||
move()
|
||||
move(history.position) //go after where you last saw the player
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.checkStatus();
|
||||
if (this.isInvulnerable) {
|
||||
@@ -4170,7 +4167,7 @@ const spawn = {
|
||||
me.fire = function () {
|
||||
// this.armor();
|
||||
this.checkStatus();
|
||||
if (!m.isCloak && !this.isStunned) {
|
||||
if (!this.isStunned) {
|
||||
if (this.isFiring) {
|
||||
if (this.fireCycle > this.fireDelay) { //fire
|
||||
this.isFiring = false
|
||||
@@ -4221,7 +4218,9 @@ const spawn = {
|
||||
}
|
||||
} else { //aim at player
|
||||
this.fireCycle++
|
||||
this.fireDir = Vector.normalise(Vector.sub(m.pos, this.position)); //set direction to turn to fire
|
||||
//if cloaked, aim at player's history from 3 seconds ago
|
||||
const whereIsPlayer = m.isCloak ? m.history[(m.cycle - 180) % 600].position : m.pos
|
||||
this.fireDir = Vector.normalise(Vector.sub(whereIsPlayer, this.position)); //set direction to turn to fire
|
||||
//rotate towards fireAngle
|
||||
const angle = this.angle + Math.PI / 2;
|
||||
const c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
@@ -4233,7 +4232,7 @@ const spawn = {
|
||||
} else if (this.fireCycle > 45) { //fire
|
||||
unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100)
|
||||
this.fireTarget = Vector.add(this.vertices[1], unit)
|
||||
if (Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur
|
||||
if (Vector.magnitude(Vector.sub(whereIsPlayer, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
this.fireLockCount = 0
|
||||
this.isFiring = true
|
||||
@@ -4277,7 +4276,7 @@ const spawn = {
|
||||
}, Vector.normalise(Vector.sub(this.fireTarget, this.position)));
|
||||
//distance between the target and the player's location
|
||||
if (
|
||||
m.isCloak ||
|
||||
// m.isCloak ||
|
||||
dot > 0.03 || // not looking at target
|
||||
Matter.Query.ray(map, this.fireTarget, this.position).length || Matter.Query.ray(body, this.fireTarget, this.position).length || //something blocking line of sight
|
||||
Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) > 1000 // distance from player to target is very far, (this is because dot product can't tell if facing 180 degrees away)
|
||||
@@ -5056,7 +5055,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle, length) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + length * Math.cos(angle), y: where.y + length * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map] : [map, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5663,7 +5662,7 @@ const spawn = {
|
||||
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
@@ -5762,7 +5761,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5854,7 +5853,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5964,7 +5963,7 @@ const spawn = {
|
||||
me.laserSpear = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead)) {
|
||||
this.swordRadiusGrowRate = 1 / this.swordRadiusGrowRateInitial //!!!! this retracts the sword if it hits the player
|
||||
@@ -6180,7 +6179,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 7, radius, "transparent");
|
||||
let me = mob[mob.length - 1];
|
||||
me.seeAtDistance2 = 500000;
|
||||
me.accelMag = 0.00007 + 0.0001 * simulation.accelScale;
|
||||
me.accelMag = 0.0002 + 0.0001 * simulation.accelScale;
|
||||
if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
|
||||
Matter.Body.setDensity(me, 0.0002); //normal is 0.001
|
||||
me.damageReduction = 0.1
|
||||
@@ -6222,7 +6221,7 @@ const spawn = {
|
||||
if (this.health < 0.8) me.seeAtDistance2 = 2000000;
|
||||
}
|
||||
me.do = function () {
|
||||
if (this.speed > 7) Matter.Body.setVelocity(this, { x: this.velocity.x * 0.8, y: this.velocity.y * 0.8 }); //cap max speed to avoid getting launched by deflection, explosion
|
||||
if (this.speed > 6) Matter.Body.setVelocity(this, { x: this.velocity.x * 0.8, y: this.velocity.y * 0.8 }); //cap max speed to avoid getting launched by deflection, explosion
|
||||
this.seePlayerCheckByDistance();
|
||||
this.checkStatus();
|
||||
this.attraction();
|
||||
@@ -7215,6 +7214,7 @@ const spawn = {
|
||||
me.do = function () {
|
||||
this.seePlayerByHistory(60);
|
||||
this.attraction();
|
||||
if (this.distanceToPlayer2() > 9000000) this.attraction(); //extra attraction if far away
|
||||
this.checkStatus();
|
||||
this.eventHorizon = 950 + 250 * Math.sin(simulation.cycle * 0.005)
|
||||
if (!simulation.isTimeSkipping) {
|
||||
|
||||
249
js/tech.js
249
js/tech.js
@@ -141,7 +141,7 @@ const tech = {
|
||||
if (tech.tech[index].isLost) tech.tech[index].isLost = false; //give specific tech
|
||||
if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false //stops the bug where you can't gets stacks of tech you take with decoherence, I think
|
||||
if (tech.isDamageFieldTech && tech.tech[index].isFieldTech) {
|
||||
tech.damage *= 1.15
|
||||
tech.damage *= 1.2
|
||||
// simulation.inGameConsole(`<strong class='color-d'>damage</strong> <span class='color-symbol'>*=</span> ${1.05}`)
|
||||
simulation.inGameConsole(`<span class='color-var'>tech</span>.damage *= ${1.1} //hidden-variable theory`);
|
||||
}
|
||||
@@ -273,7 +273,7 @@ const tech = {
|
||||
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4
|
||||
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2
|
||||
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.9
|
||||
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.9 : 2
|
||||
if (tech.offGroundDamage && !m.onGround) dmg *= tech.offGroundDamage
|
||||
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
|
||||
if (tech.isGunChoice) dmg *= 1 + 0.4 * b.inventory.length
|
||||
if (powerUps.boost.endCycle > simulation.cycle) dmg *= 1 + powerUps.boost.damage
|
||||
@@ -294,11 +294,19 @@ const tech = {
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(2, ((tech.speedAdded + player.speed) * 0.033))//1 + Math.min(1, (tech.speedAdded + player.speed) * 0.0193)
|
||||
if (tech.isAxion && tech.isHarmDarkMatter) dmg *= ((tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 3.2 : 2)
|
||||
if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3;
|
||||
if (tech.isHarmDamage && m.lastHarmCycle + 240 > m.cycle) dmg *= 4;
|
||||
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit
|
||||
// if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))
|
||||
if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health))
|
||||
if (tech.isJunkDNA) dmg *= 1 + 2 * (tech.junkChance + level.junkAdded)
|
||||
if (tech.isDemineralize) {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
dmg *= tech.mineralDamage
|
||||
}
|
||||
return dmg
|
||||
},
|
||||
duplicationChance() {
|
||||
@@ -430,7 +438,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "Hilbert space",
|
||||
description: "<strong>4x</strong> <strong class='color-d'>damage</strong><br>after a <strong>collision</strong> enter an <strong class='alt'>alternate reality</strong>",
|
||||
description: "<strong>3x</strong> <strong class='color-d'>damage</strong><br>after a <strong>collision</strong> enter an <strong class='alt'>alternate reality</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -441,7 +449,7 @@ const tech = {
|
||||
return !m.isAltSkin && !tech.isResearchReality && !tech.isSwitchReality
|
||||
},
|
||||
requires: "not skinned, Ψ(t) collapse, many-worlds",
|
||||
damage: 4,
|
||||
damage: 3,
|
||||
effect() {
|
||||
m.skin.anodize();
|
||||
tech.damage *= this.damage
|
||||
@@ -549,8 +557,8 @@ const tech = {
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 5,
|
||||
frequencyDefault: 5,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return tech.isEnergyHealth && !tech.isOverHeal
|
||||
},
|
||||
@@ -781,7 +789,7 @@ const tech = {
|
||||
{
|
||||
name: "pigeonhole principle",
|
||||
descriptionFunction() {
|
||||
return `<strong>1.4x</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.gun()}, but your equipped ${powerUps.orb.gun()}<br>cycles each level and you can't <strong>switch</strong>`
|
||||
return `<strong>1.4x</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.gun()}, but your active ${powerUps.orb.gun()}<br>cycles each level and you can't <strong>switch</strong>`
|
||||
},
|
||||
// descriptionFunction() {
|
||||
// let info = ""
|
||||
@@ -1010,7 +1018,7 @@ const tech = {
|
||||
{
|
||||
name: "Pareto efficiency",
|
||||
descriptionFunction() {
|
||||
return `for each ${powerUps.orb.gun()} in your inventory<br>randomly get <strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
|
||||
return `all you ${powerUps.orb.gun()} randomly get<br><strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -1395,6 +1403,64 @@ const tech = {
|
||||
tech.isCrit = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "remineralization",
|
||||
descriptionFunction() {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
|
||||
return `after <strong>mobs</strong> <strong>die</strong> gain <strong>0.85x</strong> <strong class='color-defense'>damage taken</strong><br>effects stack, but fade <strong>10%</strong> every second<em style ="float: right;">(${tech.mineralDamageReduction.toFixed(2)}x)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isRemineralize = true
|
||||
tech.mineralDamageReduction = 1
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
},
|
||||
remove() {
|
||||
tech.isRemineralize = false
|
||||
tech.mineralDamageReduction = 1
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "demineralization",
|
||||
descriptionFunction() {
|
||||
//reduce mineral percent based on time since last check
|
||||
const seconds = (simulation.cycle - tech.mineralLastCheck) / 60
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
tech.mineralDamage = 1 + (tech.mineralDamage - 1) * Math.pow(0.9, seconds);
|
||||
tech.mineralDamageReduction = 1 - (1 - tech.mineralDamageReduction) * Math.pow(0.9, seconds);
|
||||
|
||||
return `after <strong>mobs</strong> <strong>die</strong> gain <strong>1.08x</strong> <strong class='color-d'>damage</strong><br>effects stack, but fade <strong>10%</strong> every second<em style ="float: right;">(${tech.mineralDamage.toFixed(2)}x)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isDemineralize = true
|
||||
tech.mineralDamage = 1
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
},
|
||||
remove() {
|
||||
tech.isDemineralize = false
|
||||
tech.mineralDamage = 1
|
||||
tech.mineralLastCheck = simulation.cycle
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shear stress",
|
||||
description: "after mobs <strong>die</strong><br>they fire a <strong>nail</strong> at nearby mobs",
|
||||
@@ -1403,9 +1469,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
|
||||
return true
|
||||
},
|
||||
requires: "no other mob death tech",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.nailsDeathMob++
|
||||
},
|
||||
@@ -1421,9 +1487,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
|
||||
return true
|
||||
},
|
||||
requires: "no other mob death tech",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isExplodeMob = true;
|
||||
},
|
||||
@@ -1437,22 +1503,16 @@ const tech = {
|
||||
descriptionFunction() {
|
||||
return `after mobs <strong>die</strong> there is a <strong>13%</strong> chance<br>they grow ${b.guns[6].nameString('s')}`
|
||||
},
|
||||
// description: "after mobs <strong>die</strong><br>they have a <strong>+10%</strong> chance to grow <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
|
||||
return true
|
||||
},
|
||||
requires: "no other mob death tech",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.sporesOnDeath += 0.13;
|
||||
// if (tech.isSporeWorm) {
|
||||
// for (let i = 0; i < 4; i++) b.worm(m.pos)
|
||||
// } else {
|
||||
// for (let i = 0; i < 8; i++) b.spore(m.pos)
|
||||
// }
|
||||
},
|
||||
remove() {
|
||||
tech.sporesOnDeath = 0;
|
||||
@@ -2658,7 +2718,7 @@ const tech = {
|
||||
{
|
||||
name: "non-Newtonian armor",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Non-Newtonian_fluid' class="link">non-Newtonian armor</a>`,
|
||||
description: "after mob <strong>collisions</strong><br><strong>0.3x</strong> <strong class='color-defense'>damage taken</strong> for <strong>10</strong> seconds",
|
||||
description: "after mob <strong>collisions</strong><br><strong>0.4x</strong> <strong class='color-defense'>damage taken</strong> for <strong>10</strong> seconds",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2735,7 +2795,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "fermion",
|
||||
description: `for <strong>6</strong> seconds after mobs <strong>die</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
|
||||
description: `for <strong>5</strong> seconds after mobs <strong>die</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3066,7 +3126,7 @@ const tech = {
|
||||
{
|
||||
name: "stability",
|
||||
descriptionFunction() {
|
||||
return `<strong>0.2x</strong> <strong class='color-defense'>damage taken</strong><br>while your <strong class='color-h'>health</strong> is at maximum`
|
||||
return `<strong>0.1x</strong> <strong class='color-defense'>damage taken</strong><br>while your <strong class='color-h'>health</strong> is at maximum`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -3168,7 +3228,7 @@ const tech = {
|
||||
{
|
||||
name: "Zenos paradox",
|
||||
descriptionFunction() {
|
||||
return `<strong>0.15x</strong> <strong class='color-defense'>damage taken</strong><br><strong>–5%</strong> of current ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} every <strong>5</strong> seconds`
|
||||
return `<strong>0.2x</strong> <strong class='color-defense'>damage taken</strong><br><strong>–5%</strong> of current ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} every <strong>5</strong> seconds`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -3576,7 +3636,7 @@ const tech = {
|
||||
{
|
||||
name: "Ψ(t) collapse",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Wave_function_collapse' class="link">Ψ(t) collapse</a>`,
|
||||
description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(6)}<br>if you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong>`,
|
||||
description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(4)}<br>if you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -5812,7 +5872,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "launch system",
|
||||
description: `<strong>5x</strong> <strong>missile</strong> <em>fire rate</em><br><strong>1.2x</strong> missile <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`,
|
||||
description: `<strong>5x</strong> <strong>missile</strong> <em>fire rate</em><br><strong>1.3x</strong> missile <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`,
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -5822,7 +5882,7 @@ const tech = {
|
||||
return tech.haveGunCheck("missiles") && !tech.isMissileBig
|
||||
},
|
||||
requires: "missiles, not cruise missile",
|
||||
ammoBonus: 1.2,
|
||||
ammoBonus: 1.3,
|
||||
effect() {
|
||||
tech.missileFireCD = 10
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -7898,7 +7958,7 @@ const tech = {
|
||||
{
|
||||
name: "radiative equilibrium",
|
||||
descriptionFunction() {
|
||||
return `after losing ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}<br><strong>3x</strong> <strong class='color-d'>damage</strong> for <strong>8</strong> seconds`
|
||||
return `after losing ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}<br><strong>4x</strong> <strong class='color-d'>damage</strong> for <strong>4</strong> seconds`
|
||||
},
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
@@ -7925,13 +7985,13 @@ const tech = {
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 200,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 8 || m.fieldMode === 3
|
||||
},
|
||||
requires: "negative mass, pilot wave",
|
||||
effect() {
|
||||
tech.lastHitDamage += 6;
|
||||
tech.lastHitDamage += 8;
|
||||
},
|
||||
remove() {
|
||||
tech.lastHitDamage = 0;
|
||||
@@ -7946,9 +8006,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 3
|
||||
return m.fieldMode === 3 && tech.negativeMassCost !== 0
|
||||
},
|
||||
requires: "negative mass",
|
||||
requires: "negative mass, not equivalence principle",
|
||||
effect() {
|
||||
tech.isNeutronium = true
|
||||
tech.baseFx *= 0.86
|
||||
@@ -7966,29 +8026,51 @@ const tech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "aerostat",
|
||||
descriptionFunction() {
|
||||
return `<strong>2x</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>0.9x</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong><em style ="float: right;">(${(m.onGround ? 0.9 : 2).toFixed(1)}x)</em>`
|
||||
},
|
||||
name: "equivalence principle",
|
||||
description: `<strong>negative mass</strong> field doesn't cost <strong class='color-f'>energy</strong><br>`,
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 3 && !tech.isNeutronium
|
||||
},
|
||||
requires: "negative mass, not neutronium",
|
||||
effect() {
|
||||
tech.negativeMassCost = 0
|
||||
},
|
||||
//also removed in m.setHoldDefaults() if player switches into a bad field
|
||||
remove() {
|
||||
tech.negativeMassCost = 0.00035
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "aerostat",
|
||||
descriptionFunction() {
|
||||
const damage = m.onGround ? 1 : (tech.offGroundDamage)
|
||||
const infoText = this.count ? `<br><em style ="float: right;">(${damage.toFixed(0)}x)</em>` : ""
|
||||
return `<strong>2x</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong>${infoText}`
|
||||
},
|
||||
isFieldTech: true,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 3 || m.fieldMode === 10
|
||||
},
|
||||
requires: "negative mass, grappling hook",
|
||||
effect() {
|
||||
tech.isNoGroundDamage = true
|
||||
tech.offGroundDamage++
|
||||
},
|
||||
remove() {
|
||||
tech.isNoGroundDamage = false
|
||||
tech.offGroundDamage = 1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "annihilation",
|
||||
description: "after <strong>colliding</strong> with non-boss mobs<br>they are <strong>annihilated</strong> and <strong>–10</strong> <strong class='color-f'>energy</strong>",
|
||||
description: "<strong>mobs</strong> you <strong>collide</strong> with are <strong>annihilated</strong><br><strong>–8</strong> <strong class='color-f'>energy</strong> each time",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -8723,12 +8805,12 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "hidden-variable theory",
|
||||
description: `<strong>1.15x</strong> <strong class='color-d'>damage</strong> each time you <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> ${powerUps.orb.fieldTech()}`,
|
||||
description: `<strong>1.2x</strong> <strong class='color-d'>damage</strong> after you <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> ${powerUps.orb.fieldTech()}`,
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return m.fieldMode === 8
|
||||
},
|
||||
@@ -8742,7 +8824,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "WIMPs",
|
||||
description: `at each <strong>level's</strong> exit, spawn ${powerUps.orb.research(4)}<br> and a dangerous particle that slowly <strong>chases</strong> you`,
|
||||
description: `at the exit to each <strong>level</strong> spawn ${powerUps.orb.research(4)}<br>and a dangerous particle that slowly <strong>chases</strong> you`,
|
||||
isFieldTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -8770,9 +8852,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 6 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
return (m.fieldMode === 8 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
},
|
||||
requires: "wormhole, time dilation, negative mass, pilot wave",
|
||||
requires: "wormhole, pilot wave",
|
||||
effect() {
|
||||
tech.fieldDuplicate = 0.11
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
@@ -8792,7 +8874,7 @@ const tech = {
|
||||
{
|
||||
name: "transdimensional worms",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Dimension' class="link">transdimensional worms</a>`,
|
||||
description: "after a <strong class='color-block'>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>spawn a <strong class='color-p' style='letter-spacing: 2px;'>worm</strong>",
|
||||
description: "after a <strong class='color-block'>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>spawn <strong>1-2</strong> <strong class='color-p' style='letter-spacing: 2px;'>worms</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -8812,7 +8894,7 @@ const tech = {
|
||||
{
|
||||
name: "anyon",
|
||||
descriptionFunction() {
|
||||
return `<strong>2x</strong> <strong class='color-f'>energy</strong> after <strong class='color-dup'>duplicating</strong> a power up<br><strong>+6%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`
|
||||
return `<strong>2x</strong> stored <strong class='color-f'>energy</strong> after <strong class='color-dup'>duplicating</strong> power ups<br><strong>+6%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`
|
||||
},
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
@@ -8903,35 +8985,44 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "holographic principle",
|
||||
description: `<strong>0.8x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong class='color-worm'>wormholes</strong> cost <strong>zero</strong> <strong class='color-f'>energy</strong>`,
|
||||
cost: 2,
|
||||
descriptionFunction() {
|
||||
return `use ${powerUps.orb.research(this.cost)}<br>making <strong class='color-worm'>wormholes</strong> doesn't cost <strong class='color-f'>energy</strong>`
|
||||
},
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 9 && !tech.isWormholeMapIgnore
|
||||
return m.fieldMode === 9 && !tech.isWormholeMapIgnore && (build.isExperimentSelection || powerUps.research.count > this.cost - 1)
|
||||
},
|
||||
requires: "wormhole, not affine connection",
|
||||
effect() {
|
||||
for (let i = 0; i < this.cost; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
tech.isFreeWormHole = true
|
||||
tech.baseFx *= 0.8
|
||||
tech.baseJumpForce *= 0.8
|
||||
m.setMovement()
|
||||
// tech.baseFx *= 0.8
|
||||
// tech.baseJumpForce *= 0.8
|
||||
// m.setMovement()
|
||||
},
|
||||
//also removed in m.setHoldDefaults() if player switches into a bad field
|
||||
remove() {
|
||||
tech.isFreeWormHole = false
|
||||
if (!tech.isNeutronium) {
|
||||
tech.baseFx = 0.08
|
||||
tech.baseJumpForce = 10.5
|
||||
m.setMovement()
|
||||
if (this.count) {
|
||||
powerUps.research.changeRerolls(this.cost)
|
||||
}
|
||||
// if (!tech.isNeutronium) {
|
||||
// tech.baseFx = 0.08
|
||||
// tech.baseJumpForce = 10.5
|
||||
// m.setMovement()
|
||||
// }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "affine connection",
|
||||
description: "<strong class='color-worm'>wormholes</strong> can tunnel through <strong>anything</strong><br>for <strong>2x</strong> <strong class='color-f'>energy</strong> cost",
|
||||
description: "<strong class='color-worm'>wormholes</strong> can tunnel through <strong>anything</strong><br><strong>2x</strong> <strong class='color-f'>energy</strong> cost going through <strong>solids</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -10459,9 +10550,22 @@ const tech = {
|
||||
requires: "",
|
||||
effect() {
|
||||
setInterval(() => {
|
||||
const unit = {
|
||||
x: 1,
|
||||
y: 0
|
||||
}
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const where = Vector.add(m.pos, Vector.mult(Vector.rotate(unit, Math.random() * 2 * Math.PI), 2000 + 2000 * Math.random()))
|
||||
spawn.sucker(where.x, where.y, 140)
|
||||
const who = mob[mob.length - 1]
|
||||
who.locatePlayer()
|
||||
// who.damageReduction = 0.2
|
||||
}
|
||||
|
||||
m.switchWorlds()
|
||||
simulation.trails()
|
||||
}, 20000); //every 30 seconds
|
||||
|
||||
}, 20000); //every 20 seconds
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
@@ -10485,6 +10589,26 @@ const tech = {
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "aerodynamics",
|
||||
description: "reduce air friction for all power ups",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isInstant: true,
|
||||
isJunk: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
const styleEl = document.createElement('style');
|
||||
document.head.appendChild(styleEl);
|
||||
const myStyle = styleEl.sheet;
|
||||
myStyle.insertRule(".choose-grid-no-images {border-radius: 50%;}", 0);
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "pop-ups",
|
||||
description: "sign up to learn endless easy ways to win n-gon<br>that Landgreen doesn't want you to know!!!1!!",
|
||||
@@ -12204,7 +12328,7 @@ const tech = {
|
||||
collidePowerUps: null,
|
||||
isDilate: null,
|
||||
isDiaphragm: null,
|
||||
isNoGroundDamage: null,
|
||||
offGroundDamage: null,
|
||||
isSuperBounce: null,
|
||||
isDivisor: null,
|
||||
isFoamCavitation: null,
|
||||
@@ -12236,4 +12360,9 @@ const tech = {
|
||||
isWiki: null,
|
||||
isStaticBlock: null,
|
||||
isDamageFieldTech: null,
|
||||
isRemineralize: null,
|
||||
mineralDamageReduction: null,
|
||||
isDemineralize: null,
|
||||
mineralDamage: null,
|
||||
negativeMassCost: null,
|
||||
}
|
||||
51
style.css
51
style.css
@@ -746,6 +746,18 @@ summary {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.constraint-module {
|
||||
line-height: 160%;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
font-size: 1.2em;
|
||||
font-family: monospace;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
color: #624;
|
||||
background-color: rgba(255, 240, 250, 1);
|
||||
}
|
||||
|
||||
#right-HUD-constraint {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
@@ -768,6 +780,39 @@ summary {
|
||||
transition: all 0.5s linear;
|
||||
}
|
||||
|
||||
.constraint {
|
||||
color: rgb(141, 23, 88);
|
||||
}
|
||||
|
||||
.metallic-sparkle {
|
||||
background: linear-gradient(90deg,
|
||||
#c38aa6,
|
||||
#e6c0d9,
|
||||
#dca4c6,
|
||||
#c38aa6,
|
||||
#e6c0d9,
|
||||
#dca4c6,
|
||||
#c38aa6);
|
||||
background-size: 200% 100%;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
animation: shimmer 4s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
#text-log {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
@@ -783,12 +828,6 @@ summary {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.constraint {
|
||||
color: rgb(141, 23, 88);
|
||||
/* font-weight: 100; */
|
||||
/* text-decoration: underline; */
|
||||
}
|
||||
|
||||
.color-text {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
158
todo.txt
158
todo.txt
@@ -1,42 +1,65 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
new level corridor
|
||||
new level element fizzler - it removes blocks
|
||||
interferometer has wider platforms, a few helpful blocks, and fewer mobs
|
||||
level constraints are announced in console
|
||||
tech: demineralization - after mobs die gain 0.85x damage taken, effect stacks, but fades 10% every second
|
||||
tech: remineralization - after mobs die gain 1.08x damage, effect stacks, but fades 10% every second
|
||||
tech: equivalence principle - negative mass field doesn't cost energy
|
||||
new JUNK tech: aerodynamics
|
||||
|
||||
foam gun no longer pushes the player back when firing
|
||||
wave gun buffs
|
||||
1.2x base damage
|
||||
1.1x base ammo
|
||||
0.1->0.13x speed in map
|
||||
0.25->0.30x speed in blocks
|
||||
tech: phase velocity 1.4->1.5x damage
|
||||
pigeonhole principle gives 1.3->1.4 damage per gun
|
||||
you can no longer switch guns, your gun cycles each level
|
||||
quenching 0.4->0.5x overheal converts into max health
|
||||
tungsten carbide no longer has reduced coyote cycles
|
||||
control theory 1.5->2x damage at max health
|
||||
stability 0.3->0.2 damage taken at max health
|
||||
overcharge +88->100 max energy, 4->5% JUNK
|
||||
zoospore vector 10->13% chance for spores on mob death
|
||||
replication 15->10% JUNK
|
||||
interest 6->5% of your power ups spawn each level
|
||||
interferometer
|
||||
slower elevator and lasers
|
||||
wider side ledges
|
||||
large laser blocking blocks
|
||||
flocculation
|
||||
fewer mobs
|
||||
it's easier to get out of the slime
|
||||
pavilion
|
||||
move vanish elements
|
||||
easier traversal
|
||||
secret tunnel
|
||||
removed debris, but added power ups and blocks
|
||||
corridor
|
||||
limited to bosses that don't interact with the movers poorly
|
||||
gravitron, substructure, corridor, interferometer
|
||||
added more heal and ammo power ups to match other levels
|
||||
because some newer levels are zoomed out more
|
||||
laser max range is 3000->5000
|
||||
nails last 1/3 of a second longer
|
||||
bosses spawn an extra ammo power up
|
||||
and 2 extra ammo on the hardest 2 difficulties
|
||||
slasher mob's laserSwords will now damage a cloaked player
|
||||
constraint announcement text looks more like computer code style to match game theme
|
||||
|
||||
updated "about" details menu
|
||||
moved classic n-gon to here from settings
|
||||
added links to community content in "about"
|
||||
Are there more links I should add?
|
||||
added an n-gon SVG head image
|
||||
foam recoil is back: 1->0.7x horizontal force and 2->4.3x vertical up force
|
||||
this makes it less annoying to horizontally and easier to kinda fly/float
|
||||
negative mass field damage reduction 0.4->0.5x
|
||||
holographic principle no longer slows player movement
|
||||
added 2 research cost
|
||||
fermion gives 6->5 seconds of invulnerability after mobs die
|
||||
stability 0.2->0.1x damage taken at max health
|
||||
non-Newtonian armor 0.3->0.4x damage taken after collisions
|
||||
Zeno's paradox 0.15->0.2x damage taken
|
||||
annihilation energy cost 10->8 to destroy mobs after collisions
|
||||
radiative equilibrium damage is 3->4x for 8->4 seconds
|
||||
aerostat can be taken 1->3 times
|
||||
dynamic equilibrium damage increased by 6->8x damage per last damage taken
|
||||
aerostat no longer has 0.9x damage for being on the ground
|
||||
launch system 1.2->1.3x ammo for missiles
|
||||
research says that repeatedly entering alternate realities builds up some positive effects
|
||||
Hilbert space 4x->3x damage
|
||||
Ψ(t) collapse 6->4 research on boss death
|
||||
transdimensional worms: 50% chance for a second worm per block in wormhole
|
||||
wormhole 7->8 energy regen per second
|
||||
hidden-variable theory 1.15->1.2 damage after choosing a field tech
|
||||
ghoster mobs are less likely to get knocked far away from the player for long periods of time
|
||||
|
||||
bugs
|
||||
fixed outline on splash screen doesn't sync right on safari browser
|
||||
fixed possible lock out on training levels: "hold", "throw", "throwAt"
|
||||
from losing block behind a door
|
||||
shortcut sort buttons in experiment mode properly order tech without clicking sort
|
||||
fixed/increased the horizontal velocity contribution for some guns
|
||||
this makes bullets shot on moving platforms more realistic
|
||||
nail gun, super balls, foam, harpoon
|
||||
bug fixes
|
||||
dynamic equilibrium was set to 100 times higher frequency then normal
|
||||
when constraints hide health bar's it's now hidden in the pause menu
|
||||
mobs aiming at cloaked player
|
||||
snakeBoss more intelligently chases player for a few seconds
|
||||
pulsarBoss aims at player's history 3 seconds in past
|
||||
pulsar will not stop firing
|
||||
but it will still not fire at cloaked player
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
@@ -59,14 +82,20 @@ player can become crouched while not touching the ground if they exit the ground
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
tech: demineralization - 0.2x damage taken, but it slowly reduces effect
|
||||
increase to full:
|
||||
at start of level?
|
||||
when you get the tech
|
||||
decrease:
|
||||
over time
|
||||
at start of new level
|
||||
tech synergy ideas
|
||||
a tech that spawns mobs that the player can use to trigger mob death tech
|
||||
|
||||
wormhole field needs a buff
|
||||
it's good on wide open maps, but it needs a defensive effect on more closed maps
|
||||
fix?
|
||||
increase energy regen?
|
||||
new tech?
|
||||
a way to make more blocks
|
||||
the block can feed into worms/coupling energy
|
||||
|
||||
|
||||
tech: - remove the research costs of all tech
|
||||
there's about 15 tech with a research cost
|
||||
!!conformal - similar rules for small and big scales linked to holographic principle
|
||||
!!holonomy - parallel transport of a vector leads to movement (applies to curved space)
|
||||
when far away from your wormhole regenerate 1% of your max energy per second
|
||||
@@ -179,6 +208,31 @@ improve new player experience
|
||||
When foam is in an explosion it also explodes with size proportional to the size of the foam bubble
|
||||
Requires foam, explosion source, not aerogel
|
||||
|
||||
new level similar to ash tray maze
|
||||
!!not sure how this works with theme (most levels are locations that have industrial stuff)
|
||||
this might work as another line of sight level?
|
||||
could be fine without line of sight if rooms don't exist until they open up?
|
||||
where to put in game sequence?
|
||||
watch a run through https://www.youtube.com/watch?v=nudSXUMBEV4
|
||||
close off doors as player gets close
|
||||
open up doors as player gets close
|
||||
holes in the floor
|
||||
slide large walls back to open up levels below
|
||||
show a zone, then close it off, but eventually reveal it later
|
||||
rise up pillars during combat
|
||||
small maze rooms, 1-2 really huge rooms, long corridors, medium combat rooms
|
||||
triggers for changes
|
||||
clearing mobs in a zone
|
||||
or time based if player is too slow
|
||||
player gets close to a zone
|
||||
make map elements shift around as player moves through the game
|
||||
start with map elements filling everywhere and slow open up new zones
|
||||
need a cool way to animate adding and removing map elements
|
||||
maybe for the entire level redraw the map every 15 cycles?
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
slide map around
|
||||
small map squares that each add in sequentially
|
||||
|
||||
Cosmological natural selection: do something with black holes
|
||||
spawn black hole mobs
|
||||
after bosses die?
|
||||
@@ -1210,7 +1264,6 @@ possible names for tech
|
||||
amalgam, amalgamation - the action, process, or result of combining or uniting.
|
||||
thermoplastic - the stuff in 3-D printers, use for molecular assembler tech
|
||||
ergosphere - region of a spinning black hole that might allow FTL or alternate realities.
|
||||
equivalence principle - gravity and acceleration are the same
|
||||
Casimir effect - attractive force between two close conductive plates
|
||||
difference engine - early calculator/computer
|
||||
cyanoacrylate - superglue use for a slowing effect?
|
||||
@@ -1255,24 +1308,3 @@ list of powerful synergies
|
||||
electronegativity and high energy?
|
||||
electronegativity + anyon + duplication + Maxwells demon + interest + pair production
|
||||
chain reaction + invulnerable + Abelian group + parasitism = clear all mobs on level
|
||||
|
||||
|
||||
************************************************* COMMUNITY LINKS *************************************************
|
||||
|
||||
load old commits
|
||||
www.cornbread2100.com/n-gon-loader
|
||||
|
||||
n-gon fork
|
||||
kgurchiek.github.io/n-gon-portal-gun
|
||||
3xiondev.github.io/n-gon-upgraded
|
||||
coaldeficit.github.io/c-gon
|
||||
n-gon-enhanced.vercel.app
|
||||
|
||||
bookmarlet
|
||||
github.com/Whyisthisnotavalable/n-scythe
|
||||
github.com/kgurchiek/n-gon-mobile
|
||||
github.com/kgurchiek/n-gon-controller
|
||||
|
||||
text
|
||||
ngon.fandom.com/wiki/N-gon
|
||||
github.com/3xionDev/n-docs
|
||||
Reference in New Issue
Block a user