towers
newLevel - towers please give feedback boost level elements can now be pointed at any angle paradigm shift costs 1 health, but cost increases after each use ejecting with paradigm shift tech sets their frequency to zero, so they don't show up again polyurethane foam - makes more foam from super balls bubble fusion - now works with any shield, but only once per mob so it triggers from the shieldingBoss collider - has a higher chance to form tech vs. other power ups removed all ON/OFF tech I just don't think they are fun JUNK tech - wall jump fixed some bugs player damage reduction adjustment: 0.9x -> 0.89x per level per difficulty mode (1,2,4,5) on easy that's 0.28 -> 0.245 by level 12 (a 12% player damage nerf) on why a 50% player damage nerf by level 12
This commit is contained in:
@@ -3790,7 +3790,7 @@ const b = {
|
||||
this.force.y += this.mass * 0.001;
|
||||
if (Matter.Query.collides(this, [player]).length) {
|
||||
this.endCycle = 0
|
||||
m.energy -= 0.05
|
||||
m.energy -= 0.04
|
||||
if (m.energy < 0) m.energy = 0
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
@@ -3828,8 +3828,8 @@ const b = {
|
||||
if (!who.isInvulnerable) {
|
||||
if (tech.oneSuperBall) mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
|
||||
if (tech.isFoamBall) {
|
||||
for (let i = 0, len = 5 * this.mass; i < len; i++) {
|
||||
const radius = 5 + 8 * Math.random()
|
||||
for (let i = 0, len = 6 * this.mass; i < len; i++) {
|
||||
const radius = 6 + 9 * Math.random()
|
||||
const velocity = { x: Math.max(0.5, 2 - radius * 0.1), y: 0 }
|
||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
}
|
||||
|
||||
27
js/engine.js
27
js/engine.js
@@ -113,32 +113,7 @@ function collisionChecks(event) {
|
||||
m.damage(dmg);
|
||||
return
|
||||
}
|
||||
if (tech.isFlipFlop) {
|
||||
if (tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = false
|
||||
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = <strong>OFF</strong>`
|
||||
m.eyeFillColor = 'transparent'
|
||||
m.damage(dmg);
|
||||
} else {
|
||||
tech.isFlipFlopOn = true //immune to damage this hit, lose immunity for next hit
|
||||
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
|
||||
m.eyeFillColor = m.fieldMeterColor //'#0cf'
|
||||
if (!tech.isFlipFlopHarm) m.damage(dmg);
|
||||
}
|
||||
if (tech.isFlipFlopHealth) {
|
||||
m.setMaxHealth();
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "heal") {
|
||||
const oldSize = powerUp[i].size
|
||||
powerUp[i].size = powerUps.heal.size() //update current heals
|
||||
const scale = powerUp[i].size / oldSize
|
||||
Matter.Body.scale(powerUp[i], scale, scale); //grow
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m.damage(dmg); //normal damage
|
||||
}
|
||||
m.damage(dmg); //normal damage
|
||||
|
||||
if (tech.isCollisionRealitySwitch && m.alive) {
|
||||
m.switchWorlds()
|
||||
|
||||
@@ -1430,7 +1430,7 @@ window.addEventListener("keydown", function (event) {
|
||||
simulation.loop = simulation.normalLoop
|
||||
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'none'
|
||||
simulation.makeTextLog("", 0);
|
||||
} else { //if (keys[191])
|
||||
} else {
|
||||
simulation.testing = true;
|
||||
simulation.loop = simulation.testingLoop
|
||||
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
|
||||
|
||||
540
js/level.js
540
js/level.js
@@ -4,13 +4,12 @@ let cons = []; //all constraints between a point and a body
|
||||
let consBB = []; //all constraints between two bodies
|
||||
let composite = [] //rotors and other map elements that don't fit
|
||||
const level = {
|
||||
isEndlessFall: false,
|
||||
fallMode: "",
|
||||
defaultZoom: 1400,
|
||||
onLevel: -1,
|
||||
levelsCleared: 0,
|
||||
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
||||
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers"],
|
||||
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", "arena", "soft"],
|
||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
|
||||
levels: [],
|
||||
@@ -42,9 +41,9 @@ const level = {
|
||||
// requestAnimationFrame(() => { tech.giveTech("optical amplifier") });
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("combinatorial optimization")
|
||||
// tech.giveTech("Pareto efficiency")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("Higgs mechanism")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("active cooling")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("heuristics")
|
||||
for (let i = 0; i < 1; ++i) tech.giveTech("collider")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("anthropic principle")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("bubble fusion")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("ersatz bots") });
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
|
||||
@@ -55,13 +54,13 @@ const level = {
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
|
||||
// level.testing();
|
||||
// level.towers();
|
||||
|
||||
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
|
||||
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
|
||||
// for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
|
||||
// for (let i = 0; i < 1; ++i) spawn.stinger(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.dragonFlyBoss(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.powerUpBossBaby(1900, -500)
|
||||
// spawn.beetleBoss(1900, -500, 25)
|
||||
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
|
||||
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
|
||||
@@ -78,7 +77,9 @@ const level = {
|
||||
// simulation.isAutoZoom = false; //look in close
|
||||
// simulation.zoomScale *= 0.5;
|
||||
// simulation.setZoom();
|
||||
// for (let i = 0; i < 3; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
|
||||
// tech.addJunkTechToPool(0.7)
|
||||
|
||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
|
||||
// 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 < 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);
|
||||
@@ -137,15 +138,7 @@ const level = {
|
||||
mob[mob.length - 1].isDecoupling = true //so you can find it to remove
|
||||
for (let j = 0, len = 4; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
|
||||
}
|
||||
// if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) {
|
||||
if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = true
|
||||
if (tech.isFlipFlopHealth) m.setMaxHealth()
|
||||
if (tech.isRelayEnergy) m.setMaxEnergy()
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
simulation.makeTextLog(`tech.isFlipFlopOn <span class='color-symbol'>=</span> true`);
|
||||
}
|
||||
// if (m.plasmaBall) m.plasmaBall.reset()
|
||||
|
||||
if (m.plasmaBall) m.plasmaBall.fire()
|
||||
if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) {
|
||||
const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
|
||||
@@ -180,23 +173,22 @@ const level = {
|
||||
if (b.activeGun !== null && b.activeGun !== undefined && b.guns[b.activeGun].name !== "laser") {
|
||||
const ammoPerOrb = b.guns[b.activeGun].ammoPack
|
||||
const a = Math.ceil(rate * b.guns[b.activeGun].ammo / ammoPerOrb)
|
||||
powerUps.spawnDelay("ammo", a);
|
||||
powerUps.spawnDelay("ammo", a, 4);
|
||||
simulation.makeTextLog(`${(rate * 100).toFixed(0)}<span class='color-symbol'>%</span> <span class='color-m'>interest</span> on <span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${a > 20 ? a + powerUps.orb.ammo(1) : powerUps.orb.ammo(a)}`)
|
||||
}
|
||||
if (powerUps.research.count > 0) {
|
||||
const r = Math.ceil(rate * powerUps.research.count)
|
||||
simulation.makeTextLog(`${(rate * 100).toFixed(0)}<span class='color-symbol'>%</span> <span class='color-m'>interest</span> on <span class='color-r'>research</span> <span class='color-symbol'>=</span> ${r > 20 ? r + powerUps.orb.research(1) : powerUps.orb.research(r)}`)
|
||||
powerUps.spawnDelay("research", r);
|
||||
powerUps.spawnDelay("research", r, 4);
|
||||
}
|
||||
if (m.coupling > 0) {
|
||||
const c = Math.ceil(rate * m.coupling)
|
||||
powerUps.spawnDelay("coupling", c);
|
||||
powerUps.spawnDelay("coupling", c, 4);
|
||||
simulation.makeTextLog(`${(rate * 100).toFixed(0)}<span class='color-symbol'>%</span> <span class='color-m'>interest</span> on <span class='color-coupling'>coupling</span> <span class='color-symbol'>=</span> ${c > 20 ? c + powerUps.orb.coupling(1) : powerUps.orb.coupling(c)}`)
|
||||
}
|
||||
|
||||
const healPerOrb = (powerUps.heal.size() / 40 / (simulation.healScale ** 0.25)) ** 2
|
||||
const h = Math.ceil(rate * m.health / healPerOrb)
|
||||
powerUps.spawnDelay("heal", h);
|
||||
powerUps.spawnDelay("heal", h, 4);
|
||||
simulation.makeTextLog(`${(rate * 100).toFixed(0)}<span class='color-symbol'>%</span> <span class='color-m'>interest</span> on <span class='color-h'>health</span> <span class='color-symbol'>=</span> ${h > 20 ? h + powerUps.orb.heal(1) : powerUps.orb.heal(h)}`)
|
||||
|
||||
// trying to spawn smaller heals
|
||||
@@ -230,7 +222,7 @@ const level = {
|
||||
difficultyIncrease(num = 1) {
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty++
|
||||
m.dmgScale *= 0.9; //damage done by player decreases each level
|
||||
m.dmgScale *= 0.89; //damage done by player decreases each level
|
||||
if (simulation.accelScale < 6) simulation.accelScale *= 1.024 //mob acceleration increases each level
|
||||
if (simulation.CDScale > 0.15) simulation.CDScale *= 0.964 //mob CD time decreases each level
|
||||
}
|
||||
@@ -241,7 +233,7 @@ const level = {
|
||||
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty--
|
||||
m.dmgScale /= 0.9; //damage done by player decreases each level
|
||||
m.dmgScale /= 0.89; //damage done by player decreases each level
|
||||
if (simulation.accelScale > 1) simulation.accelScale /= 1.024 //mob acceleration increases each level
|
||||
if (simulation.CDScale < 1) simulation.CDScale /= 0.964 //mob CD time decreases each level
|
||||
}
|
||||
@@ -801,65 +793,147 @@ const level = {
|
||||
|
||||
return who
|
||||
},
|
||||
boost(x, y, height = 1000) { //height is how high the player will be flung above y
|
||||
who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("120 40 -120 40 -50 -40 50 -40"), {
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
|
||||
},
|
||||
boostBounds: {
|
||||
min: {
|
||||
x: x,
|
||||
y: y - 20
|
||||
boost(x, y, height = 1000, angle = Math.PI / 2) { //height is how high the player will be flung above y
|
||||
if (angle !== Math.PI / 2) { //angle !== 3 * Math.PI / 2
|
||||
angle *= -1
|
||||
who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("80 40 -80 40 -50 -40 50 -40"), {
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
|
||||
},
|
||||
max: {
|
||||
x: x + 100,
|
||||
y: y
|
||||
}
|
||||
},
|
||||
yVelocity: -1.21 * Math.sqrt(Math.abs(height)),
|
||||
query() {
|
||||
// check for collisions
|
||||
query = (who) => {
|
||||
if (Matter.Query.region(who, this.boostBounds).length > 0) {
|
||||
list = Matter.Query.region(who, this.boostBounds)
|
||||
Matter.Body.setVelocity(list[0], {
|
||||
x: list[0].velocity.x + (Math.random() - 0.5) * 2.5, //add a bit of horizontal drift to reduce endless bounces
|
||||
y: this.yVelocity //give a upwards velocity
|
||||
});
|
||||
yVelocity: 1.21 * Math.sqrt(Math.abs(height)),
|
||||
query() {
|
||||
// check for collisions
|
||||
const rayVector = Vector.add(this.position, Vector.rotate({ x: 100, y: 0 }, angle))
|
||||
query = (who) => {
|
||||
const list = Matter.Query.ray(who, this.position, rayVector, 100)
|
||||
if (list.length > 0) {
|
||||
Matter.Body.setVelocity(list[0].bodyA, Vector.rotate({ x: this.yVelocity, y: 0 }, angle));
|
||||
}
|
||||
}
|
||||
}
|
||||
query(body)
|
||||
query(mob)
|
||||
query(bullet)
|
||||
query(powerUp)
|
||||
//player collision
|
||||
if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) {
|
||||
m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
|
||||
m.hardLandCD = 0 // disable hard landing
|
||||
if (player.velocity.y > 26) {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: player.velocity.x,
|
||||
y: -15 //gentle bounce if coming down super fast
|
||||
});
|
||||
} else {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: player.velocity.x + (Math.random() - 0.5) * 2.5,
|
||||
y: this.yVelocity //give a upwards velocity that will put the player that the height desired
|
||||
});
|
||||
query(body)
|
||||
query(mob)
|
||||
query(bullet)
|
||||
query(powerUp)
|
||||
//player collision
|
||||
const list = Matter.Query.ray([player], this.position, rayVector, 100)
|
||||
if (list.length > 0) {
|
||||
Matter.Body.setVelocity(player, Vector.rotate({ x: this.yVelocity, y: 0 }, angle));
|
||||
m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
|
||||
m.hardLandCD = 0 // disable hard landing
|
||||
}
|
||||
}
|
||||
|
||||
//draw
|
||||
ctx.fillStyle = "rgba(200,0,255,0.15)";
|
||||
ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 10, 100, 30);
|
||||
ctx.fillStyle = "rgba(200,0,255,0.05)";
|
||||
ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 50, 100, 70);
|
||||
// ctx.fillStyle = "rgba(200,0,255,0.02)";
|
||||
// ctx.fillRect(x, y - 120, 100, 120);
|
||||
},
|
||||
});
|
||||
return who
|
||||
|
||||
// if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) {
|
||||
// m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
|
||||
// m.hardLandCD = 0 // disable hard landing
|
||||
// if (player.velocity.y > 26) {
|
||||
// Matter.Body.setVelocity(player, {
|
||||
// x: player.velocity.x,
|
||||
// y: -15 //gentle bounce if coming down super fast
|
||||
// });
|
||||
// } else {
|
||||
// Matter.Body.setVelocity(player, {
|
||||
// x: player.velocity.x + (Math.random() - 0.5) * 2.5,
|
||||
// y: this.yVelocity //give a upwards velocity that will put the player that the height desired
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
//draw
|
||||
const v1 = this.vertices[0]
|
||||
const v2 = this.vertices[1]
|
||||
let unit = Vector.rotate({ x: 60, y: 0 }, angle)
|
||||
let v3 = Vector.add(v2, unit)
|
||||
let v4 = Vector.add(v1, unit)
|
||||
// ctx.beginPath();
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke()
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.lineTo(v2.x, v2.y)
|
||||
ctx.lineTo(v3.x, v3.y)
|
||||
ctx.lineTo(v4.x, v4.y)
|
||||
ctx.fillStyle = "rgba(200,0,255,0.05)";
|
||||
ctx.fill()
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke()
|
||||
|
||||
unit = Vector.rotate({ x: 20, y: 0 }, angle)
|
||||
v3 = Vector.add(v2, unit)
|
||||
v4 = Vector.add(v1, unit)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.lineTo(v2.x, v2.y)
|
||||
ctx.lineTo(v3.x, v3.y)
|
||||
ctx.lineTo(v4.x, v4.y)
|
||||
ctx.fillStyle = "rgba(200,0,255,0.15)";
|
||||
ctx.fill()
|
||||
},
|
||||
});
|
||||
Matter.Body.rotate(who, angle + Math.PI / 2);
|
||||
|
||||
return who
|
||||
} else {
|
||||
who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("120 40 -120 40 -50 -40 50 -40"), {
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
|
||||
},
|
||||
boostBounds: {
|
||||
min: {
|
||||
x: x,
|
||||
y: y - 20
|
||||
},
|
||||
max: {
|
||||
x: x + 100,
|
||||
y: y
|
||||
}
|
||||
},
|
||||
yVelocity: -1.21 * Math.sqrt(Math.abs(height)),
|
||||
query() {
|
||||
// check for collisions
|
||||
query = (who) => {
|
||||
if (Matter.Query.region(who, this.boostBounds).length > 0) {
|
||||
list = Matter.Query.region(who, this.boostBounds)
|
||||
Matter.Body.setVelocity(list[0], {
|
||||
x: list[0].velocity.x + (Math.random() - 0.5) * 2.5, //add a bit of horizontal drift to reduce endless bounces
|
||||
y: this.yVelocity //give a upwards velocity
|
||||
});
|
||||
}
|
||||
}
|
||||
query(body)
|
||||
query(mob)
|
||||
query(bullet)
|
||||
query(powerUp)
|
||||
//player collision
|
||||
if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) {
|
||||
m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
|
||||
m.hardLandCD = 0 // disable hard landing
|
||||
if (player.velocity.y > 26) {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: player.velocity.x,
|
||||
y: -15 //gentle bounce if coming down super fast
|
||||
});
|
||||
} else {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: player.velocity.x + (Math.random() - 0.5) * 2.5,
|
||||
y: this.yVelocity //give a upwards velocity that will put the player that the height desired
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//draw
|
||||
ctx.fillStyle = "rgba(200,0,255,0.15)";
|
||||
ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 10, 100, 30);
|
||||
ctx.fillStyle = "rgba(200,0,255,0.05)";
|
||||
ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 50, 100, 70);
|
||||
// ctx.fillStyle = "rgba(200,0,255,0.02)";
|
||||
// ctx.fillRect(x, y - 120, 100, 120);
|
||||
},
|
||||
});
|
||||
return who
|
||||
}
|
||||
},
|
||||
elevator(x, y, width, height, maxHeight, force = 0.003, friction = {
|
||||
up: 0.01,
|
||||
@@ -2570,27 +2644,6 @@ const level = {
|
||||
ctx.fillStyle = "#ccc"
|
||||
ctx.fill()
|
||||
|
||||
//power up dispenser
|
||||
// ctx.beginPath()
|
||||
// for (let i = 2; i < 10; i++) {
|
||||
// ctx.moveTo(2000, -100 * i)
|
||||
// ctx.lineTo(2080, -100 * i)
|
||||
// }
|
||||
// ctx.strokeStyle = "#ddd"
|
||||
// ctx.lineWidth = 5;
|
||||
// ctx.stroke();
|
||||
|
||||
// ctx.beginPath()
|
||||
// for (let i = 2; i < 10; i++) {
|
||||
// ctx.arc(2040, -100 * i, 30, 0, 2 * Math.PI);
|
||||
// ctx.moveTo(2040, -100 * i)
|
||||
// }
|
||||
// ctx.fillStyle = "rgba(0,0,0,0.3)"
|
||||
// ctx.fill()
|
||||
|
||||
// ctx.fillStyle = "rgba(240,255,255,0.5)"
|
||||
// ctx.fillRect(2000, -1000, 80, 700)
|
||||
|
||||
//exit room
|
||||
ctx.fillStyle = "#f2f2f2"
|
||||
ctx.fillRect(2600, -600, 400, 300)
|
||||
@@ -4198,6 +4251,250 @@ const level = {
|
||||
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
towers() {
|
||||
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
const isFlipped = (simulation.isHorizontalFlipped && Math.random() < 0.33) ? true : false
|
||||
|
||||
level.announceMobTypes()
|
||||
if (isFlipped) {
|
||||
level.setPosToSpawn(9150 + 50, -2230 - 25);
|
||||
level.exit.x = -100 - 50;
|
||||
level.exit.y = -50 + 25;
|
||||
leftRoomColor = "#cff"
|
||||
rightRoomColor = "rgba(0,0,0,0.13)"
|
||||
} else {
|
||||
level.setPosToSpawn(-100, -50);
|
||||
level.exit.x = 9150;
|
||||
level.exit.y = -2230;
|
||||
}
|
||||
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
|
||||
level.fallMode = "position"; //must set level.fallModeBounds in this mode to prevent player getting stuck left or right
|
||||
level.fallModeBounds = { left: level.enter.x, right: level.exit.x } //used with level.fallMode = "position";
|
||||
simulation.fallHeight = 5000 //level.enter.y - 4000
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
|
||||
level.defaultZoom = 2500
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#cdd9df";
|
||||
powerUps.spawnStartingPowerUps(6300, 1025)
|
||||
|
||||
const boost1 = level.boost(7560, 1480, 1700, 1.75)
|
||||
const boost2 = level.boost(7098, 0, 1250, Math.PI / 3) //x,y,push,angle radians
|
||||
const boost3 = level.boost(9700, -730, 1050, 1.95)
|
||||
const boost4 = level.boost(4300, -720, 1500, 1.25)
|
||||
const boost5 = level.boost(3000, -1215, 3000, 1.25)
|
||||
const train1 = level.transport(3650, 100, 415, 500, 8); //x,y,width.height,VxGoal,force
|
||||
const train2 = level.transport(1250, 100, 415, 500, -8); //x,y,width.height,VxGoal,force
|
||||
const train3 = level.transport(4050, 100, 415, 500, 8); //x,y,width.height,VxGoal,force
|
||||
|
||||
let portal1, portal2
|
||||
portal1 = level.portal({
|
||||
x: 3675,
|
||||
y: -2225 + 1025
|
||||
}, -Math.PI / 2, { //up
|
||||
x: 3675,
|
||||
y: -375
|
||||
}, Math.PI / 2) //down
|
||||
|
||||
portal2 = level.portal({
|
||||
x: 6300,
|
||||
y: -1225
|
||||
}, -Math.PI / 2, { //up
|
||||
x: 6300,
|
||||
y: -375
|
||||
}, Math.PI / 2) //down
|
||||
level.custom = () => {
|
||||
boost1.query();
|
||||
boost2.query();
|
||||
boost3.query();
|
||||
boost4.query();
|
||||
boost5.query();
|
||||
//trains oscillate back and forth and act like they are bouncing off each other
|
||||
if (train1.position.x < 2850) {
|
||||
train1.changeDirection(true) //go right
|
||||
} else if (train1.position.x > 3850) {
|
||||
train1.changeDirection(false) //go left
|
||||
}
|
||||
if (train2.position.x < 1450) {
|
||||
train2.changeDirection(true) //go right
|
||||
} else if (train2.position.x > 2450) {
|
||||
train2.changeDirection(false) //go left
|
||||
}
|
||||
if (train3.position.x < 4250) {
|
||||
train3.changeDirection(true) //go right
|
||||
} else if (train3.position.x > 5250) {
|
||||
train3.changeDirection(false) //go left
|
||||
}
|
||||
train1.move();
|
||||
train2.move();
|
||||
train3.move();
|
||||
ctx.fillStyle = "rgba(0,0,0,0.25)"
|
||||
ctx.fillRect(1250, 121, 4200, 6)
|
||||
ctx.fillStyle = "rgba(50,70,100,0.04)"
|
||||
ctx.fillRect(2500, -10000, 1800, 30000);
|
||||
ctx.fillRect(8300, -10000, 1800, 30000);
|
||||
ctx.fillRect(-500, -10000, 1800, 30000);
|
||||
ctx.fillRect(5400, -10000, 1800, 30000);
|
||||
|
||||
portal1[2].query()
|
||||
portal1[3].query()
|
||||
portal2[2].query()
|
||||
portal2[3].query()
|
||||
|
||||
ctx.fillStyle = "#cff"
|
||||
if (isFlipped) {
|
||||
ctx.fillRect(-350, -300, 525, 325); //entrance typically
|
||||
} else {
|
||||
ctx.fillRect(8925, -2575, 525, 400) //exit typically
|
||||
}
|
||||
|
||||
level.exit.drawAndCheck();
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.13)"
|
||||
ctx.fillRect(8300, -1950, 1550, 1275);
|
||||
ctx.fillRect(5400, 875, 1800, 650);
|
||||
ctx.fillRect(2950, -2200, 875, 1050);
|
||||
if (isFlipped) {
|
||||
ctx.fillRect(8925, -2575, 575, 400) //exit typically
|
||||
} else {
|
||||
ctx.fillRect(-350, -300, 525, 325); //entrance typically
|
||||
}
|
||||
|
||||
ctx.fillStyle = "rgba(0,0,0,0.5)"
|
||||
ctx.fillRect(7175, -1515, 125, 180);
|
||||
portal1[0].draw();
|
||||
portal1[1].draw();
|
||||
portal1[2].draw();
|
||||
portal1[3].draw();
|
||||
portal2[0].draw();
|
||||
portal2[1].draw();
|
||||
portal2[2].draw();
|
||||
portal2[3].draw();
|
||||
};
|
||||
|
||||
// four large rounded squares
|
||||
let a = 900 //side length
|
||||
let c = 100 //corner offset
|
||||
// spawn.mapVertex(3400, -1300, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
|
||||
// spawn.mapVertex(9200, -1300, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
|
||||
// spawn.mapVertex(6300, 900, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
|
||||
spawn.mapVertex(400, 900, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
|
||||
//lower 1st zone entrance /exit
|
||||
spawn.mapRect(-400, -350, 575, 75);
|
||||
spawn.mapRect(-400, -300, 75, 375);
|
||||
spawn.mapRect(100, -325, 75, 175);
|
||||
spawn.mapRect(100, -10, 75, 50);
|
||||
|
||||
|
||||
//2nd zone upper hollow square
|
||||
spawn.mapVertex(5650 - 2900, 900 - 2200, `${-a} ${-a + c} ${-a + c} ${-a} ${-400} ${-a} ${-400} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //1/2 square with edges cut off
|
||||
spawn.mapVertex(6950 - 2900, 900 - 2200, `${400} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${400} ${a}`); //1/2 square with edges cut off
|
||||
// spawn.mapRect(5600 - 2900, 1400 - 2200, 1350, 400);
|
||||
spawn.mapRect(2950, -1175, 650, 775);
|
||||
spawn.mapRect(3750, -1175, 100, 775);
|
||||
spawn.mapRect(3575, -1025, 200, 475);
|
||||
|
||||
|
||||
//4th zone far right hollow square near exit
|
||||
spawn.mapVertex(9200, -2050, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${-600} ${-a} ${-600}`); //square with edges cut off --- hollow top
|
||||
spawn.mapVertex(9200, -550, `${-a} ${600} ${a} ${600} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off --- hollow bottom
|
||||
spawn.mapRect(9800, -2100, 300, 1600); //hollow left wall
|
||||
spawn.mapVertex(8175, -1425, "-1400 -90 350 -90 400 -40 400 40 350 90 -1400 90");
|
||||
spawn.mapVertex(6856, -1425, "300 -90 -350 -90 -400 -40 -400 40 -350 90 300 90");
|
||||
//exit housing
|
||||
spawn.mapRect(8925, -2575, 575, 75);
|
||||
if (isFlipped) {
|
||||
spawn.mapRect(8925, -2550, 75, 400);
|
||||
spawn.mapRect(9425, -2550, 75, 125);
|
||||
spawn.mapRect(9425, -2215, 75, 50);
|
||||
spawn.bodyRect(9425, -2425, 75, 210);
|
||||
} else {
|
||||
spawn.mapRect(9425, -2550, 75, 400);
|
||||
spawn.mapRect(8925, -2550, 75, 125);
|
||||
spawn.mapRect(8925, -2215, 75, 50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//lower 3rd zone
|
||||
spawn.mapVertex(6300, 450, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${0} ${-a} ${0}`); //square with edges cut off --- hollow top
|
||||
spawn.mapVertex(6550, 1650, `${-a} ${600} ${a + 500} ${600} ${a + 500} ${a - c} ${a - c + 500} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off --- hollow bottom
|
||||
spawn.mapVertex(6300, 1200, "-400 -40 -350 -90 350 -90 400 -40 400 40 350 90 -350 90 -400 40");
|
||||
|
||||
//upper 3rd zone
|
||||
a = 400 //side length
|
||||
c = 50 //corner offset
|
||||
spawn.mapVertex(6300, -800, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
|
||||
spawn.mapVertex(5800, -1425, "-300 -40 -250 -90 250 -90 300 -40 300 40 250 90 -250 90 -300 40");
|
||||
spawn.mapVertex(5485, -1850, "-400 -40 -350 -90 350 -90 400 -40 400 40 350 90 -350 90 -400 40");
|
||||
spawn.mapVertex(7365, -1850, "-650 -40 -600 -90 600 -90 650 -40 650 40 600 90 -600 90 -650 40"); //long
|
||||
spawn.mapVertex(6300, -2175, "-300 -40 -250 -90 250 -90 300 -40 300 40 250 90 -250 90 -300 40"); //highest
|
||||
spawn.mapVertex(4450, -1850, "-200 -40 -150 -90 150 -90 200 -40 200 40 150 90 -150 90 -200 40");
|
||||
spawn.mapVertex(5500, -300, "-200 -60 -170 -90 170 -90 200 -60 200 60 170 90 -170 90 -200 60");
|
||||
spawn.mapVertex(4600, -590, "-500 -90 170 -90 200 -60 200 60 170 90 -500 90");
|
||||
|
||||
//no debris on this level, so spawn some heals and ammo
|
||||
powerUps.chooseRandomPowerUp(6275, 1425);
|
||||
powerUps.chooseRandomPowerUp(3350, -1250);
|
||||
powerUps.chooseRandomPowerUp(9550, -750);
|
||||
|
||||
//random blocks
|
||||
spawn.bodyRect(7725, -2200, 150, 250, 0.2);
|
||||
spawn.bodyRect(4625, -825, 75, 125, 0.2);
|
||||
spawn.bodyRect(3250, -1200, 25, 25, 0.2);
|
||||
spawn.bodyRect(3375, -1275, 25, 75, 0.2);
|
||||
spawn.bodyRect(3450, -1200, 50, 25, 0.2);
|
||||
spawn.bodyRect(2825, -2225, 25, 25, 0.2);
|
||||
spawn.bodyRect(4075, -2225, 50, 25, 0.2);
|
||||
spawn.bodyRect(8850, -800, 75, 100, 0.2);
|
||||
spawn.bodyRect(6900, -100, 75, 100, 0.2);
|
||||
spawn.bodyRect(8975, -1575, 50, 50, 0.2);
|
||||
spawn.bodyRect(5725, -1700, 125, 175, 0.2);
|
||||
spawn.bodyRect(6850, -1725, 150, 200, 0.2);
|
||||
|
||||
//mobs
|
||||
spawn.randomMob(5700, -75, 0);
|
||||
spawn.randomMob(6200, -100, 0);
|
||||
spawn.randomMob(6900, -100, 0.1);
|
||||
spawn.randomMob(5550, -500, 0.1);
|
||||
spawn.randomMob(4675, -850, 0.1);
|
||||
spawn.randomMob(4450, -2050, 0.1);
|
||||
spawn.randomMob(4050, -2325, 0.1);
|
||||
spawn.randomMob(2850, -2325, 0.1);
|
||||
spawn.randomMob(3350, -1325, 0.2);
|
||||
spawn.randomMob(5300, -2050, 0.2);
|
||||
spawn.randomMob(5675, -2050, 0.2);
|
||||
spawn.randomMob(5850, -1625, 0.3);
|
||||
spawn.randomMob(6775, -1600, 0.3);
|
||||
spawn.randomMob(7700, -1625, 0.4);
|
||||
spawn.randomMob(7850, -2000, 0.4);
|
||||
spawn.randomMob(7225, -2000, 0.4);
|
||||
spawn.randomMob(6350, -2400, 0.5);
|
||||
spawn.randomMob(8850, -1650, 0.5);
|
||||
spawn.randomMob(9500, -1300, 0.5);
|
||||
spawn.randomMob(9250, -900, 0.5);
|
||||
spawn.randomMob(8600, -875, 0.6);
|
||||
spawn.randomMob(5575, 1350, 0.6);
|
||||
spawn.randomMob(6075, 1025, 0.6);
|
||||
spawn.randomMob(6300, 1025, 0.7);
|
||||
spawn.randomMob(6525, 1425, 0.8);
|
||||
spawn.randomMob(7125, 1450, 0.9);
|
||||
// spawn.randomMob(8600, -2325, 0.7);
|
||||
// spawn.randomMob(8650, -2825, 0.8);
|
||||
// spawn.randomMob(9225, -2850, 0.9);
|
||||
// spawn.randomMob(8525, -2375, 0.9);
|
||||
spawn.randomGroup(4925, -2850, 1);
|
||||
if (simulation.difficulty > 1) {
|
||||
spawn.randomLevelBoss(7275, -2475);
|
||||
spawn.secondaryBossChance(8400, -1025)
|
||||
}
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
|
||||
},
|
||||
factory() {
|
||||
level.announceMobTypes()
|
||||
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
@@ -4211,7 +4508,7 @@ const level = {
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
|
||||
level.defaultZoom = 1500
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#d0d2d4s";
|
||||
document.body.style.backgroundColor = "#d0d2d4";
|
||||
// color.map = "#262a2f"
|
||||
let isPowerLeft = true
|
||||
const movers = []
|
||||
@@ -5596,7 +5893,7 @@ const level = {
|
||||
},
|
||||
pavilion() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
const vanish = []
|
||||
level.exit.x = -850;
|
||||
level.exit.y = -1485;
|
||||
@@ -6449,7 +6746,7 @@ const level = {
|
||||
},
|
||||
satellite() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
const boost1 = level.boost(5825, 235, 1400)
|
||||
const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 }
|
||||
level.custom = () => {
|
||||
@@ -6626,7 +6923,7 @@ const level = {
|
||||
},
|
||||
rooftops() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
// level.fallPosition = { x: 5000, y:-4000}
|
||||
const elevator = level.elevator(1450, -990, 235, 45, -2000)
|
||||
const boost1 = level.boost(4950, 0, 1100)
|
||||
@@ -6635,7 +6932,6 @@ const level = {
|
||||
boost1.query();
|
||||
elevator.move();
|
||||
elevator.drawTrack();
|
||||
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
if (isBackwards) {
|
||||
ctx.fillRect(-650, -2300, 440, 300)
|
||||
@@ -6643,7 +6939,6 @@ const level = {
|
||||
ctx.fillRect(3460, -700, 1090, 800)
|
||||
}
|
||||
level.exit.drawAndCheck();
|
||||
|
||||
level.enter.draw();
|
||||
};
|
||||
|
||||
@@ -6815,7 +7110,7 @@ const level = {
|
||||
},
|
||||
aerie() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
const boost1 = level.boost(-425, 100, 1400)
|
||||
const boost2 = level.boost(5350, 275, 2850);
|
||||
|
||||
@@ -7045,7 +7340,7 @@ const level = {
|
||||
},
|
||||
skyscrapers() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
const boost1 = level.boost(475, 0, 1300)
|
||||
const boost2 = level.boost(4450, 0, 1300);
|
||||
level.custom = () => {
|
||||
@@ -7184,11 +7479,8 @@ const level = {
|
||||
},
|
||||
highrise() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, {
|
||||
up: 0.01,
|
||||
down: 0.2
|
||||
}, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
|
||||
level.fallMode = "start";
|
||||
const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, { up: 0.01, down: 0.2 }, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
|
||||
elevator1.addConstraint();
|
||||
// const button1 = level.button(-500, -200)
|
||||
const toggle1 = level.toggle(-300, -200) //(x,y,isOn,isLockOn = true/false)
|
||||
@@ -7470,7 +7762,7 @@ const level = {
|
||||
},
|
||||
warehouse() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.fallMode = "start";
|
||||
level.custom = () => {
|
||||
ctx.fillStyle = "#444" //light fixtures
|
||||
ctx.fillRect(-920, -505, 40, 10)
|
||||
@@ -27198,7 +27490,7 @@ const level = {
|
||||
}
|
||||
};
|
||||
},
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance(), isExtraShield = false) {
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
|
||||
if (this.allowShields && Math.random() < chance) {
|
||||
mobs.spawn(x, y, 9, target.radius + 30, "rgba(255,255,255,0.9)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -27207,7 +27499,6 @@ const level = {
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isUnblockable = true
|
||||
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
@@ -27229,6 +27520,12 @@ const level = {
|
||||
|
||||
me.shieldTargetID = target.id
|
||||
target.isShielded = true;
|
||||
if (target.shieldCount > 0) {
|
||||
target.shieldCount++
|
||||
} else {
|
||||
target.shieldCount = 1
|
||||
}
|
||||
me.shieldCount = target.shieldCount //used with "bubble fusion"
|
||||
target.shieldID = me.id
|
||||
me.onDeath = function () {
|
||||
//clear isShielded status from target
|
||||
@@ -28466,7 +28763,7 @@ const level = {
|
||||
}
|
||||
};
|
||||
},
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance(), isExtraShield = false) {
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
|
||||
if (this.allowShields && Math.random() < chance) {
|
||||
mobs.spawn(x, y, 9, target.radius + 30, "rgba(255,255,255,0.9)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -28475,7 +28772,6 @@ const level = {
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isUnblockable = true
|
||||
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
@@ -28497,6 +28793,12 @@ const level = {
|
||||
|
||||
me.shieldTargetID = target.id
|
||||
target.isShielded = true;
|
||||
if (target.shieldCount > 0) {
|
||||
target.shieldCount++
|
||||
} else {
|
||||
target.shieldCount = 1
|
||||
}
|
||||
me.shieldCount = target.shieldCount //used with "bubble fusion"
|
||||
target.shieldID = me.id
|
||||
me.onDeath = function () {
|
||||
//clear isShielded status from target
|
||||
|
||||
@@ -1161,6 +1161,7 @@ const mobs = {
|
||||
this.onDeath(this); //custom death effects
|
||||
this.removeConsBB();
|
||||
this.alive = false; //triggers mob removal in mob[i].replace(i)
|
||||
console.log(this.shieldCount)
|
||||
|
||||
if (this.isDropPowerUp) {
|
||||
// if (true) {
|
||||
@@ -1306,7 +1307,7 @@ const mobs = {
|
||||
tech.cloakDuplication -= 0.01
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield && this.isDropPowerUp) {
|
||||
} else if (tech.isShieldAmmo && this.shield && this.shieldCount === 1) {
|
||||
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
|
||||
if (Math.random() < 0.4) {
|
||||
type = "heal"
|
||||
|
||||
@@ -8,7 +8,7 @@ const m = {
|
||||
// let vector = Vertices.fromPath("0 40 50 40 50 115 0 115 30 130 20 130"); //player as a series of vertices
|
||||
let vertices = Vertices.fromPath("0,40, 50,40, 50,115, 30,130, 20,130, 0,115, 0,40"); //player as a series of vertices
|
||||
playerBody = Bodies.fromVertices(0, 0, vertices);
|
||||
jumpSensor = Bodies.rectangle(0, 46, 36, 6, {
|
||||
jumpSensor = Bodies.rectangle(0, 46, 36, 6, { //(0, 46, 50, 6, { //for wall jumping
|
||||
//this sensor check if the player is on the ground to enable jumping
|
||||
sleepThreshold: 99999999999,
|
||||
isSensor: true
|
||||
@@ -545,7 +545,7 @@ const m = {
|
||||
},
|
||||
baseHealth: 1,
|
||||
setMaxHealth(isMessage) {
|
||||
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
|
||||
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage
|
||||
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
|
||||
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
@@ -2178,7 +2178,7 @@ const m = {
|
||||
}
|
||||
},
|
||||
setMaxEnergy(isMessage = true) {
|
||||
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
|
||||
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
|
||||
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
|
||||
},
|
||||
fieldMeterColor: "#0cf",
|
||||
|
||||
155
js/powerup.js
155
js/powerup.js
@@ -247,12 +247,14 @@ const powerUps = {
|
||||
if (powerUp[i].isDuplicated) {
|
||||
if (Math.random() < 0.003 && !m.isBodiesAsleep) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
|
||||
b.explosion(powerUp[i].position, 175 + (11 + 3 * Math.random()) * powerUp[i].size);
|
||||
Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (powerUp[i]) {
|
||||
Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
}
|
||||
break
|
||||
}
|
||||
if (Math.random() < 0.3) { //draw electricity
|
||||
const mag = 4 + powerUp[i].size / 5
|
||||
const mag = Math.max(1, 4 + powerUp[i].size / 5)
|
||||
let unit = Vector.rotate({ x: mag, y: mag }, 2 * Math.PI * Math.random())
|
||||
let path = { x: powerUp[i].position.x + unit.x, y: powerUp[i].position.y + unit.y }
|
||||
ctx.beginPath();
|
||||
@@ -328,7 +330,7 @@ const powerUps = {
|
||||
simulation.circleFlare(value);
|
||||
}
|
||||
if (tech.isCancelRerolls) {
|
||||
for (let i = 0, len = 10 + 4 * Math.random(); i < len; i++) {
|
||||
for (let i = 0, len = 8 + 4 * Math.random(); i < len; i++) {
|
||||
let spawnType
|
||||
if (Math.random() < 0.4 && !tech.isEnergyNoAmmo) {
|
||||
spawnType = "ammo"
|
||||
@@ -340,7 +342,7 @@ const powerUps = {
|
||||
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
|
||||
}
|
||||
}
|
||||
if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 8)
|
||||
if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 7)
|
||||
if (tech.isCancelTech && tech.cancelTechCount === 0 && type !== "entanglement") {
|
||||
tech.cancelTechCount++
|
||||
// powerUps.research.use('tech')
|
||||
@@ -524,7 +526,7 @@ const powerUps = {
|
||||
name: "heal",
|
||||
color: "#0eb",
|
||||
size() {
|
||||
return Math.sqrt(0.1 + 0.25) * 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)) * (tech.isFlipFlopOn && tech.isFlipFlopHealth ? Math.sqrt(2) : 1); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
|
||||
return Math.sqrt(0.1 + 0.25) * 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
|
||||
},
|
||||
effect() {
|
||||
if (!tech.isEnergyHealth && m.alive) {
|
||||
@@ -819,30 +821,92 @@ const powerUps = {
|
||||
${tech.tech[choose].name} ${techCountText}</div>
|
||||
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
|
||||
},
|
||||
// junkTechText(choose, click) { //old code with yahoo images
|
||||
// const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
|
||||
// const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
|
||||
// if (!localSettings.isHideImages) {
|
||||
// setTimeout(() => { //delay so that the html element exists
|
||||
// if (tech.tech[choose].url === undefined) { //if on url has been set yet
|
||||
// const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
|
||||
// fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
|
||||
// .then((response) => response.text())
|
||||
// .then((html) => {
|
||||
// const parser = new DOMParser();
|
||||
// const doc = parser.parseFromString(html, "text/html");
|
||||
// const elements = doc.getElementsByClassName("ld");
|
||||
// // console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
|
||||
// const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
|
||||
// if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
|
||||
// tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
|
||||
// } else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
// tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// } else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
// tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// }
|
||||
// }, 1);
|
||||
// }
|
||||
// return `<div id = "junk-${choose}" class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${style}>
|
||||
// <div class="card-text">
|
||||
// <div class="grid-title"><div class="circle-grid junk"></div> ${tech.tech[choose].name} ${techCountText}</div>
|
||||
// ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
|
||||
// },
|
||||
// junkTechText(choose, click) {
|
||||
// const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
|
||||
// const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
|
||||
// if (!localSettings.isHideImages) {
|
||||
// setTimeout(() => { //delay so that the html element exists
|
||||
// if (tech.tech[choose].url === undefined) { //if on url has been set yet
|
||||
// const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
|
||||
// fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
|
||||
// .then((response) => response.text())
|
||||
// .then((html) => {
|
||||
// const parser = new DOMParser();
|
||||
// const doc = parser.parseFromString(html, "text/html");
|
||||
// const elements = doc.getElementsByClassName("ld");
|
||||
// // console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
|
||||
// const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
|
||||
// if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
|
||||
// tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
|
||||
// } else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
// tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// } else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
// tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
// }
|
||||
// }, 1);
|
||||
// }
|
||||
// return `<div id = "junk-${choose}" class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${style}>
|
||||
// <div class="card-text">
|
||||
// <div class="grid-title"><div class="circle-grid junk"></div> ${tech.tech[choose].name} ${techCountText}</div>
|
||||
// ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
|
||||
// },
|
||||
junkTechText(choose, click) {
|
||||
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
|
||||
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
|
||||
if (!localSettings.isHideImages) {
|
||||
setTimeout(() => { //delay so that the html element exists
|
||||
if (tech.tech[choose].url === undefined) { //if on url has been set yet
|
||||
const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
|
||||
const url = `https://api.openverse.engineering/v1/images/?q=${tech.tech[choose].name}`;
|
||||
fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, "text/html");
|
||||
const elements = doc.getElementsByClassName("ld");
|
||||
// console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
|
||||
const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
|
||||
if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
|
||||
tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
|
||||
.then((response) => response.json())
|
||||
.then((responseJson) => {
|
||||
if (responseJson.results.length > 0) {
|
||||
const index = Math.floor(Math.random() * responseJson.results.length) //randomly choose from the images
|
||||
tech.tech[choose].url = responseJson.results[index].url //store the url
|
||||
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
|
||||
} else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
|
||||
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
} else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
|
||||
tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl
|
||||
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -878,7 +942,6 @@ const powerUps = {
|
||||
// console.log(options.length)
|
||||
if (options.length > 0 || !tech.isSuperDeterminism) {
|
||||
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
|
||||
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
|
||||
function removeOption(index) {
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i] === index) {
|
||||
@@ -940,8 +1003,6 @@ const powerUps = {
|
||||
if (i !== m.fieldMode) options.push(i);
|
||||
}
|
||||
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
|
||||
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
|
||||
|
||||
function removeOption(index) {
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i] === index) {
|
||||
@@ -1016,7 +1077,6 @@ const powerUps = {
|
||||
}
|
||||
//set total choices
|
||||
let totalChoices = (tech.isDeterminism ? 1 : 3 + tech.extraChoices + 2 * (m.fieldMode === 8))
|
||||
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
|
||||
if (optionLengthNoDuplicates < totalChoices + 1) { //if not enough options for all the choices
|
||||
totalChoices = optionLengthNoDuplicates
|
||||
if (tech.isBanish) { //when you run out of options eject banish
|
||||
@@ -1214,7 +1274,7 @@ const powerUps = {
|
||||
} else if (tech.tech[choose].isSkin) {
|
||||
text += powerUps.skinTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||
} else if (tech.tech[choose].isInstant) {
|
||||
text += powerUps.instantTechTextTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||
text += powerUps.instantTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||
} else { //normal tech
|
||||
text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`)
|
||||
}
|
||||
@@ -1229,14 +1289,14 @@ const powerUps = {
|
||||
}
|
||||
},
|
||||
},
|
||||
spawnDelay(type, count) {
|
||||
count *= 2
|
||||
spawnDelay(type, count, delay = 2) {
|
||||
count *= delay
|
||||
let cycle = () => {
|
||||
if (count > 0) {
|
||||
if (m.alive) requestAnimationFrame(cycle);
|
||||
if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2)
|
||||
count--
|
||||
if (!(count % 2)) {
|
||||
if (!(count % delay)) {
|
||||
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
|
||||
powerUps.spawn(where.x, where.y, type);
|
||||
}
|
||||
@@ -1256,18 +1316,6 @@ const powerUps = {
|
||||
b.mine(who.position, { x: 0, y: 0 }, 0)
|
||||
}
|
||||
}
|
||||
if (tech.isRelay) {
|
||||
if (tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = false
|
||||
if (document.getElementById("tech-switch")) document.getElementById("tech-switch").innerHTML = ` = <strong>OFF</strong>`
|
||||
m.eyeFillColor = 'transparent'
|
||||
} else {
|
||||
tech.isFlipFlopOn = true //immune to damage this hit, lose immunity for next hit
|
||||
if (document.getElementById("tech-switch")) document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
|
||||
m.eyeFillColor = m.fieldMeterColor //'#0cf'
|
||||
}
|
||||
if (tech.isRelayEnergy) m.setMaxEnergy();
|
||||
}
|
||||
},
|
||||
spawnRandomPowerUp(x, y) { //mostly used after mob dies, doesn't always return a power up
|
||||
if (!tech.isEnergyHealth && (Math.random() * Math.random() - 0.3 > Math.sqrt(m.health)) || Math.random() < 0.04) { //spawn heal chance is higher at low health
|
||||
@@ -1449,8 +1497,10 @@ const powerUps = {
|
||||
// tech.removeTech(index)
|
||||
// } else {
|
||||
// }
|
||||
tech.tech[index].frequency = 0 //banish tech
|
||||
powerUps.ejectTech(index)
|
||||
m.damage(0.04)
|
||||
m.damage(tech.pauseEjectTech * 0.01)
|
||||
tech.pauseEjectTech *= 1.2
|
||||
document.getElementById(`${index}-pause-tech`).style.textDecoration = "line-through"
|
||||
document.getElementById(`${index}-pause-tech`).style.animation = ""
|
||||
document.getElementById(`${index}-pause-tech`).onclick = null
|
||||
@@ -1478,15 +1528,9 @@ const powerUps = {
|
||||
smallIndexes.push(i)
|
||||
}
|
||||
}
|
||||
if (bigIndexes.length > 0) {
|
||||
// console.log("at least 1 big will always spilt")
|
||||
const index = bigIndexes[Math.floor(Math.random() * bigIndexes.length)]
|
||||
for (let i = 0; i < 3; i++) powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
|
||||
|
||||
Matter.Composite.remove(engine.world, powerUp[index]);
|
||||
powerUp.splice(index, 1);
|
||||
} else if (smallIndexes.length > 2 && Math.random() < 0.33) {
|
||||
// console.log("no big, at least 3 small can combine")
|
||||
|
||||
if (smallIndexes.length > 2 && Math.random() < 0.66) { // console.log("no big, at least 3 small can combine")
|
||||
for (let j = 0; j < 3; j++) {
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "heal" || powerUp[i].name === "research" || powerUp[i].name === "ammo" || powerUp[i].name === "coupling" || powerUp[i].name === "boost") {
|
||||
@@ -1499,8 +1543,13 @@ const powerUps = {
|
||||
|
||||
options = ["tech", "gun", "field"]
|
||||
powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
|
||||
} else if (smallIndexes.length > 0) {
|
||||
// console.log("no big, at least 1 small will swap flavors")
|
||||
} else if (bigIndexes.length > 0 && Math.random() < 0.5) { // console.log("at least 1 big can spilt")
|
||||
const index = bigIndexes[Math.floor(Math.random() * bigIndexes.length)]
|
||||
for (let i = 0; i < 3; i++) powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
|
||||
|
||||
Matter.Composite.remove(engine.world, powerUp[index]);
|
||||
powerUp.splice(index, 1);
|
||||
} else if (smallIndexes.length > 0) { // console.log("no big, at least 1 small will swap flavors")
|
||||
const index = Math.floor(Math.random() * powerUp.length)
|
||||
options = options.filter(e => e !== powerUp[index].name); //don't repeat the current power up type
|
||||
powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
|
||||
|
||||
@@ -184,7 +184,7 @@ const simulation = {
|
||||
fpsCapDefault: 72, //use to change fpsCap back to normal after a hit from a mob
|
||||
isCommunityMaps: false,
|
||||
cyclePaused: 0,
|
||||
fallHeight: 6000, //below this y position the player dies
|
||||
fallHeight: 6000, //below this y position the player will teleport to start, take damage, or teleport to the sky based on the value of level.fallMode
|
||||
lastTimeStamp: 0, //tracks time stamps for measuring delta
|
||||
delta: 1000 / 60, //speed of game engine //looks like it has to be 16.6666 to match player input
|
||||
buttonCD: 0,
|
||||
@@ -435,10 +435,10 @@ const simulation = {
|
||||
} else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
|
||||
if (text) text += "<br>" //add a new line, but not on the first line
|
||||
text += tech.tech[i].name
|
||||
if (tech.tech[i].nameInfo) {
|
||||
text += tech.tech[i].nameInfo
|
||||
tech.tech[i].addNameInfo();
|
||||
}
|
||||
// if (tech.tech[i].nameInfo) {
|
||||
// text += tech.tech[i].nameInfo
|
||||
// tech.tech[i].addNameInfo();
|
||||
// }
|
||||
if (tech.tech[i].count > 1) text += ` (${tech.tech[i].count}x)`
|
||||
}
|
||||
}
|
||||
@@ -933,22 +933,8 @@ const simulation = {
|
||||
m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
|
||||
if (m.energy > 1000000) m.energy = 1000000
|
||||
}
|
||||
if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) {
|
||||
if (tech.isFlipFlopOn) {
|
||||
if (m.immuneCycle < m.cycle) m.energy += 0.2;
|
||||
} else {
|
||||
m.energy -= 0.01;
|
||||
if (m.energy < 0) m.energy = 0
|
||||
}
|
||||
}
|
||||
if (tech.relayIce && tech.isFlipFlopOn) {
|
||||
for (let j = 0; j < tech.relayIce; j++) {
|
||||
for (let i = 0, len = 3 + Math.ceil(9 * Math.random()); i < len; i++) b.iceIX(2)
|
||||
}
|
||||
}
|
||||
|
||||
if (m.pos.y > simulation.fallHeight) { // if 4000px deep
|
||||
if (level.isEndlessFall) {
|
||||
if (level.fallMode === "start") {
|
||||
//infinite falling. teleport to sky after falling
|
||||
|
||||
simulation.ephemera.push({
|
||||
@@ -957,7 +943,6 @@ const simulation = {
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0 || m.onGround) simulation.removeEphemera(this.name)
|
||||
// console.log(player.velocity.y)
|
||||
if (player.velocity.y > 70) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
|
||||
if (player.velocity.y > 90) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
|
||||
},
|
||||
@@ -976,13 +961,36 @@ const simulation = {
|
||||
m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
|
||||
// move bots
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
|
||||
// Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) }));
|
||||
// Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
|
||||
}
|
||||
if (bullet[i].botType) Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
|
||||
}
|
||||
} else {
|
||||
} else if (level.fallMode === "position") { //fall and stay in the same horizontal position
|
||||
simulation.ephemera.push({
|
||||
name: "slow player",
|
||||
count: 180, //cycles before it self removes
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0 || m.onGround) simulation.removeEphemera(this.name)
|
||||
if (player.velocity.y > 70) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
|
||||
if (player.velocity.y > 90) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
|
||||
},
|
||||
})
|
||||
const before = { x: player.position.x, y: player.position.y, }
|
||||
let posXClamped = Math.min(Math.max(level.fallModeBounds.left, player.position.x), level.fallModeBounds.right)
|
||||
Matter.Body.setPosition(player, { x: posXClamped, y: level.enter.y - 4000 });
|
||||
|
||||
// translate camera smoothly to preserve illusion to endless fall
|
||||
const change = { x: before.x - posXClamped, y: before.y - player.position.y }
|
||||
m.transX += change.x
|
||||
m.transY += change.y
|
||||
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
|
||||
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
|
||||
m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
|
||||
|
||||
// move bots
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
|
||||
}
|
||||
} else { //get hurt and go to start
|
||||
Matter.Body.setVelocity(player, { x: 0, y: 0 });
|
||||
Matter.Body.setPosition(player, { x: level.enter.x + 50, y: level.enter.y - 20 });
|
||||
// m.damage(0.02 * simulation.difficultyMode);
|
||||
@@ -1049,7 +1057,7 @@ const simulation = {
|
||||
do() {
|
||||
if (Matter.Query.point(map, m.pos).length > 0 || Matter.Query.point(map, player.position).length > 0) {
|
||||
this.count--
|
||||
// console.log('halp, stuck in map!', Matter.Query.point(map, m.pos))
|
||||
|
||||
if (this.count < 0) {
|
||||
simulation.removeEphemera(this.name)
|
||||
Matter.Body.setVelocity(player, { x: 0, y: 0 });
|
||||
@@ -1116,7 +1124,7 @@ const simulation = {
|
||||
clearNow: false,
|
||||
clearMap() {
|
||||
level.isProcedural = false;
|
||||
level.isEndlessFall = false;
|
||||
level.fallMode = "";
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
if (m.alive) {
|
||||
if (tech.isLongitudinal) b.guns[3].waves = []; //empty array of wave bullets
|
||||
@@ -1370,7 +1378,6 @@ const simulation = {
|
||||
// window.getSelection().addRange(range);
|
||||
// document.execCommand("copy");
|
||||
// window.getSelection().removeAllRanges();
|
||||
// console.log(`spawn.mapRect(${simulation.getCoords.pos1.x}, ${simulation.getCoords.pos1.y}, ${simulation.getCoords.pos2.x - simulation.getCoords.pos1.x}, ${simulation.getCoords.pos2.y - simulation.getCoords.pos1.y}); //`);
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
@@ -1544,15 +1551,9 @@ const simulation = {
|
||||
const circleCollisions = [];
|
||||
for (const line of outerCollisions) {
|
||||
for (const vertex of line) {
|
||||
// console.log('hi')
|
||||
const distance = Math.sqrt((vertex.x - pos.x) ** 2 + (vertex.y - pos.y) ** 2)
|
||||
const angle = Math.atan2(vertex.y - pos.y, vertex.x - pos.x);
|
||||
// const queryPoint = {
|
||||
// x: Math.cos(angle) * (distance - 1) + pos.x,
|
||||
// y: Math.sin(angle) * (distance - 1) + pos.y
|
||||
// }
|
||||
const queryPoint = { x: Math.cos(angle + Math.PI) + vertex.x, y: Math.sin(angle + Math.PI) + vertex.y }
|
||||
|
||||
if (Math.abs(distance - radius) < 1 && Matter.Query.ray(map, pos, queryPoint).length == 0) circleCollisions.push(vertex)
|
||||
}
|
||||
}
|
||||
@@ -1917,7 +1918,6 @@ const simulation = {
|
||||
const y = round(simulation.constructMouseDownPosition.y)
|
||||
const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
|
||||
const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
|
||||
// console.log(e.button)
|
||||
if (e.button === 1) {
|
||||
if (level.isProcedural) {
|
||||
simulation.outputMapString(`spawn.randomMob(x+${x}, ${y}, 0);\n`);
|
||||
@@ -1965,8 +1965,8 @@ const simulation = {
|
||||
});
|
||||
|
||||
//undo last element added after you press z
|
||||
document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
|
||||
if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) {
|
||||
document.body.addEventListener("keydown", (event) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
|
||||
if (simulation.testing && event.code === "KeyZ" && simulation.constructMapString.length) {
|
||||
if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level
|
||||
const index = map.length - 1
|
||||
Matter.Composite.remove(engine.world, map[index]);
|
||||
|
||||
76
js/spawn.js
76
js/spawn.js
@@ -1691,6 +1691,7 @@ const spawn = {
|
||||
powerUps.spawnBossPowerUp(me.position.x, me.position.y)
|
||||
powerUps.spawn(me.position.x, me.position.y, "heal");
|
||||
powerUps.spawn(me.position.x, me.position.y, "ammo");
|
||||
powerUps.spawn(me.position.x, me.position.y, "ammo");
|
||||
} else if (!m.isCloak) {
|
||||
me.foundPlayer();
|
||||
}
|
||||
@@ -1698,7 +1699,7 @@ const spawn = {
|
||||
me.isInvulnerable = true
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.damageReduction = 0
|
||||
me.invulnerabilityCountDown = 25 + simulation.difficulty
|
||||
me.invulnerabilityCountDown = 30 + simulation.difficulty
|
||||
me.onHit = function () { //run this function on hitting player
|
||||
if (powerUps.ejectTech()) {
|
||||
powerUps.ejectGraphic("150, 138, 255");
|
||||
@@ -1713,10 +1714,7 @@ const spawn = {
|
||||
if (vertices > 3) {
|
||||
this.isDropPowerUp = false;
|
||||
spawn.powerUpBossBaby(this.position.x, this.position.y, vertices - 1)
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||
x: this.velocity.x,
|
||||
y: this.velocity.y
|
||||
})
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x, y: this.velocity.y })
|
||||
}
|
||||
for (let i = 0; i < powerUp.length; i++) powerUp[i].collisionFilter.mask = cat.map | cat.powerUp
|
||||
};
|
||||
@@ -1770,15 +1768,16 @@ const spawn = {
|
||||
powerUps.spawnBossPowerUp(me.position.x, me.position.y)
|
||||
powerUps.spawn(me.position.x, me.position.y, "heal");
|
||||
powerUps.spawn(me.position.x, me.position.y, "ammo");
|
||||
powerUps.spawn(me.position.x, me.position.y, "ammo");
|
||||
} else if (!m.isCloak) {
|
||||
me.foundPlayer();
|
||||
}
|
||||
|
||||
me.damageReduction = 0.15 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
// me.isInvulnerable = true
|
||||
// me.startingDamageReduction = me.damageReduction
|
||||
// me.damageReduction = 0
|
||||
// me.invulnerabilityCountDown = 60 + simulation.difficulty * 2
|
||||
me.damageReduction = 0.22 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isInvulnerable = true
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.damageReduction = 0
|
||||
me.invulnerabilityCountDown = 30 + simulation.difficulty
|
||||
|
||||
me.onHit = function () { //run this function on hitting player
|
||||
if (powerUps.ejectTech()) {
|
||||
@@ -1794,10 +1793,7 @@ const spawn = {
|
||||
if (vertices > 3) {
|
||||
this.isDropPowerUp = false;
|
||||
spawn.powerUpBoss(this.position.x, this.position.y, vertices - 1)
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||
x: this.velocity.x,
|
||||
y: this.velocity.y
|
||||
})
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x, y: this.velocity.y })
|
||||
}
|
||||
for (let i = 0; i < powerUp.length; i++) powerUp[i].collisionFilter.mask = cat.map | cat.powerUp
|
||||
};
|
||||
@@ -1843,22 +1839,22 @@ const spawn = {
|
||||
// me.constrainPowerUps()
|
||||
me.do = function () {
|
||||
this.stroke = `hsl(0,0%,${80 + 25 * Math.sin(simulation.cycle * 0.01)}%)`
|
||||
// if (this.isInvulnerable) {
|
||||
// if (this.invulnerabilityCountDown > 0) {
|
||||
// this.invulnerabilityCountDown--
|
||||
// ctx.beginPath();
|
||||
// let vertices = this.vertices;
|
||||
// ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
// for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
// ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
// ctx.lineWidth = 20;
|
||||
// ctx.strokeStyle = "rgba(255,255,255,0.7)";
|
||||
// ctx.stroke();
|
||||
// } else {
|
||||
// this.isInvulnerable = false
|
||||
// this.damageReduction = this.startingDamageReduction
|
||||
// }
|
||||
// }
|
||||
if (this.isInvulnerable) {
|
||||
if (this.invulnerabilityCountDown > 0) {
|
||||
this.invulnerabilityCountDown--
|
||||
ctx.beginPath();
|
||||
let vertices = this.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 13 + 5 * Math.random();
|
||||
ctx.strokeStyle = `rgba(255,255,255,${0.5 + 0.2 * Math.random()})`;
|
||||
ctx.stroke();
|
||||
} else {
|
||||
this.isInvulnerable = false
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
}
|
||||
}
|
||||
//steal all power ups
|
||||
// for (let i = 0; i < Math.min(powerUp.length, this.vertices.length); i++) {
|
||||
// powerUp[i].collisionFilter.mask = 0
|
||||
@@ -6898,9 +6894,7 @@ const spawn = {
|
||||
ctx.moveTo(this.vertices[this.vertices.length - 1].x, this.vertices[this.vertices.length - 1].y)
|
||||
const phase = (this.vertices.length + 1) * this.cycle / this.maxCycles
|
||||
if (phase > 1) ctx.lineTo(this.vertices[0].x, this.vertices[0].y)
|
||||
for (let i = 1; i < phase - 1; i++) {
|
||||
ctx.lineTo(this.vertices[i].x, this.vertices[i].y)
|
||||
}
|
||||
for (let i = 1; i < phase - 1; i++) ctx.lineTo(this.vertices[i].x, this.vertices[i].y)
|
||||
ctx.lineWidth = 5
|
||||
ctx.strokeStyle = "rgb(255,255,255)"
|
||||
ctx.stroke();
|
||||
@@ -7584,7 +7578,7 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
},
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance(), isExtraShield = false) {
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
|
||||
if (this.allowShields && Math.random() < chance) {
|
||||
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -7593,7 +7587,6 @@ const spawn = {
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isUnblockable = true
|
||||
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
@@ -7615,7 +7608,14 @@ const spawn = {
|
||||
|
||||
me.shieldTargetID = target.id
|
||||
target.isShielded = true;
|
||||
if (target.shieldCount > 0) {
|
||||
target.shieldCount++
|
||||
} else {
|
||||
target.shieldCount = 1
|
||||
}
|
||||
me.shieldCount = target.shieldCount //used with "bubble fusion"
|
||||
target.shieldID = me.id
|
||||
|
||||
me.onDeath = function () {
|
||||
//clear isShielded status from target
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
@@ -8210,12 +8210,6 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
// bodyRect(x, y, width, height, chance = 1, properties = { friction: 0.05, frictionAir: 0.001 }) {
|
||||
// if (Math.random() < chance) body[body.length] = Bodies.rectangle(x + width / 2, y + height / 2, width, height, properties);
|
||||
// },
|
||||
// bodyVertex(x, y, vector, properties) { //adds shape to body array
|
||||
// body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(vector), properties);
|
||||
// },
|
||||
bodyRect(x, y, width, height, chance = 1, properties = { friction: 0.05, frictionAir: 0.001 }) { //this is the command that adds blocks to the world in the middle of a level
|
||||
if (Math.random() < chance) {
|
||||
body[body.length] = Bodies.rectangle(x + width / 2, y + height / 2, width, height, properties);
|
||||
|
||||
633
js/tech.js
633
js/tech.js
@@ -19,6 +19,7 @@ const tech = {
|
||||
//remove lore if it's your first time playing since it's confusing
|
||||
//also remove lore if cheating
|
||||
tech.removeCount = 0;
|
||||
tech.pauseEjectTech = 1; //used in paradigm shift
|
||||
lore.techCount = 0;
|
||||
if (simulation.isCheating || localSettings.runCount < 1) { //simulation.isCommunityMaps ||
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
@@ -231,7 +232,6 @@ const tech = {
|
||||
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.5 * (1 + 0.033 * m.coupling)
|
||||
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
|
||||
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount
|
||||
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
||||
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.71828
|
||||
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
|
||||
if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1)
|
||||
@@ -545,7 +545,7 @@ const tech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "hyperpolarization",
|
||||
name: "repolarization",
|
||||
descriptionFunction() {
|
||||
return `the <strong class= 'color-d'> damage</strong> from <strong> depolarization</strong> <br>resets <strong>1.25 seconds</strong> sooner after a mob <strong>dies</strong>`
|
||||
},
|
||||
@@ -826,7 +826,7 @@ const tech = {
|
||||
}
|
||||
if (gunTechPool.length) {
|
||||
const index = Math.floor(Math.random() * gunTechPool.length)
|
||||
console.log(gunTechPool, index, gunTechPool[index], tech.tech[gunTechPool[index]].name)
|
||||
// console.log(gunTechPool, index, gunTechPool[index], tech.tech[gunTechPool[index]].name)
|
||||
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[gunTechPool[index]].name}</span>")`, 360)
|
||||
// tech.tech[gunTechPool[index]].isInstant = true //makes it not remove properly under paradigm shift
|
||||
tech.giveTech(gunTechPool[index]) // choose from the gun pool
|
||||
@@ -1390,7 +1390,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "thermal runaway",
|
||||
description: "after mobs <strong>die</strong><br>they <strong class='color-e'>explode</strong>",
|
||||
description: "after mobs <strong>die</strong> they <strong class='color-e'>explode</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1472,7 +1472,7 @@ const tech = {
|
||||
{
|
||||
name: "bubble fusion",
|
||||
descriptionFunction() {
|
||||
return `after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
|
||||
return `after destroying a mob's <strong>shield</strong><br>spawn <strong>1-2</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)} <em>(once per mob)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -2295,7 +2295,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "decorrelation",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>0.3x</strong> <strong class='color-defense'>damage taken</strong>",
|
||||
description: "if your <strong class='color-g'>gun</strong> and <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>0.3x</strong> <strong class='color-defense'>damage taken</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2313,7 +2313,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "anticorrelation",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>2x</strong> <strong class='color-d'>damage</strong>",
|
||||
description: "if your <strong class='color-g'>gun</strong> and <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>2x</strong> <strong class='color-d'>damage</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2422,285 +2422,285 @@ const tech = {
|
||||
tech.isBlockPowerUps = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "NOR gate",
|
||||
description: "if <strong>flip-flop</strong> is <strong class='color-flop'>OFF</strong><br>become <strong>invulnerable</strong> to your next collision",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isFlipFlop
|
||||
},
|
||||
requires: "flip-flop",
|
||||
effect() {
|
||||
tech.isFlipFlopHarm = true //do you have this tech
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlopHarm = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shape-memory alloy",
|
||||
descriptionFunction() {
|
||||
return `if <strong>flip-flop</strong> is <strong class='color-flop'>ON</strong><br><strong>+400</strong> maximum <strong class='color-h'>health</strong> and <strong>2x</strong> ${powerUps.orb.heal()} effect`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isFlipFlop
|
||||
},
|
||||
requires: "flip-flop",
|
||||
effect() {
|
||||
tech.isFlipFlopHealth = true;
|
||||
m.setMaxHealth();
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "heal") {
|
||||
const oldSize = powerUp[i].size
|
||||
powerUp[i].size = powerUps.heal.size() //update current heals
|
||||
const scale = powerUp[i].size / oldSize
|
||||
Matter.Body.scale(powerUp[i], scale, scale); //grow
|
||||
}
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlopHealth = false;
|
||||
m.setMaxHealth();
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "heal") {
|
||||
const oldSize = powerUp[i].size
|
||||
powerUp[i].size = powerUps.heal.size() //update current heals
|
||||
const scale = powerUp[i].size / oldSize
|
||||
Matter.Body.scale(powerUp[i], scale, scale); //grow
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "flip-flop",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Flip-flop_(electronics)' class="link">flip-flop</a>`,
|
||||
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after a <strong>collision</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
|
||||
nameInfo: "<span id = 'tech-flip-flop'></span>",
|
||||
addNameInfo() {
|
||||
setTimeout(function () {
|
||||
if (document.getElementById("tech-flip-flop")) {
|
||||
if (tech.isFlipFlopOn) {
|
||||
document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
|
||||
m.eyeFillColor = m.fieldMeterColor //'#5af'
|
||||
} else {
|
||||
document.getElementById("tech-flip-flop").innerHTML = ` = <strong>OFF</strong>`
|
||||
m.eyeFillColor = "transparent"
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isRelay
|
||||
},
|
||||
requires: "not relay switch",
|
||||
effect() {
|
||||
tech.isFlipFlop = true //do you have this tech?
|
||||
if (!tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = true //what is the state of flip-Flop?
|
||||
}
|
||||
// if (!m.isShipMode) {
|
||||
// m.skin.flipFlop()
|
||||
// }
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlop = false
|
||||
if (tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = false //what is the state of flip-Flop?
|
||||
}
|
||||
m.eyeFillColor = 'transparent'
|
||||
// m.resetSkin();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "NAND gate",
|
||||
description: "if <strong class='color-flop'>ON</strong><br><strong>1.555x</strong> <strong class='color-d'>damage</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isFlipFlop || tech.isRelay
|
||||
},
|
||||
requires: "ON/OFF tech",
|
||||
effect() {
|
||||
tech.isFlipFlopDamage = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlopDamage = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "integrated circuit",
|
||||
description: "if <strong class='color-flop'>ON</strong> <strong>+7</strong> power up <strong>choices</strong><br>if <strong class='color-flop'>OFF</strong> <strong>-1</strong> power up <strong>choices</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (tech.isFlipFlop || tech.isRelay) && !tech.isDeterminism
|
||||
},
|
||||
requires: "ON/OFF tech, not determinism",
|
||||
effect() {
|
||||
tech.isFlipFlopChoices = true //do you have this tech
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlopChoices = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "transistor",
|
||||
description: "if <strong class='color-flop'>ON</strong> generate <strong>+20</strong> <strong class='color-f'>energy</strong> per second<br>if <strong class='color-flop'>OFF</strong> drain <strong>-1</strong> <strong class='color-f'>energy</strong> per second",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isFlipFlop || tech.isRelay
|
||||
},
|
||||
requires: "ON/OFF tech",
|
||||
effect() {
|
||||
tech.isFlipFlopEnergy = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFlipFlopEnergy = false;
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "decoupling",
|
||||
// link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Decoupling_(cosmology)' class="link">decoupling</a>`,
|
||||
// name: "NOR gate",
|
||||
// description: "if <strong>flip-flop</strong> is <strong class='color-flop'>OFF</strong><br>become <strong>invulnerable</strong> to your next collision",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return tech.isFlipFlop
|
||||
// },
|
||||
// requires: "flip-flop",
|
||||
// effect() {
|
||||
// tech.isFlipFlopHarm = true //do you have this tech
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlopHarm = false
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "shape-memory alloy",
|
||||
// descriptionFunction() {
|
||||
// //<span style = 'font-size:80%;'>(${ m.couplingDescription(this.bonus)})</span>
|
||||
// return `if <strong class='color-flop'>ON</strong> <strong>+5</strong> <strong class='color-coupling'>coupling</strong><br>if <strong class='color-flop'>OFF</strong> a dangerous particle slowly <strong>chases</strong> you`
|
||||
// return `if <strong>flip-flop</strong> is <strong class='color-flop'>ON</strong><br><strong>+400</strong> maximum <strong class='color-h'>health</strong> and <strong>2x</strong> ${powerUps.orb.heal()} effect`
|
||||
// },
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// bonus: 5, //coupling given
|
||||
// allowed() {
|
||||
// return tech.isFlipFlop
|
||||
// },
|
||||
// requires: "flip-flop",
|
||||
// effect() {
|
||||
// tech.isFlipFlopHealth = true;
|
||||
// m.setMaxHealth();
|
||||
// for (let i = 0; i < powerUp.length; i++) {
|
||||
// if (powerUp[i].name === "heal") {
|
||||
// const oldSize = powerUp[i].size
|
||||
// powerUp[i].size = powerUps.heal.size() //update current heals
|
||||
// const scale = powerUp[i].size / oldSize
|
||||
// Matter.Body.scale(powerUp[i], scale, scale); //grow
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlopHealth = false;
|
||||
// m.setMaxHealth();
|
||||
// for (let i = 0; i < powerUp.length; i++) {
|
||||
// if (powerUp[i].name === "heal") {
|
||||
// const oldSize = powerUp[i].size
|
||||
// powerUp[i].size = powerUps.heal.size() //update current heals
|
||||
// const scale = powerUp[i].size / oldSize
|
||||
// Matter.Body.scale(powerUp[i], scale, scale); //grow
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "flip-flop",
|
||||
// link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Flip-flop_(electronics)' class="link">flip-flop</a>`,
|
||||
// description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after a <strong>collision</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
|
||||
// // nameInfo: "<span id = 'tech-flip-flop'></span>",
|
||||
// // addNameInfo() {
|
||||
// // setTimeout(function () {
|
||||
// // if (document.getElementById("tech-flip-flop")) {
|
||||
// // if (tech.isFlipFlopOn) {
|
||||
// // document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
|
||||
// // m.eyeFillColor = m.fieldMeterColor //'#5af'
|
||||
// // } else {
|
||||
// // document.getElementById("tech-flip-flop").innerHTML = ` = <strong>OFF</strong>`
|
||||
// // m.eyeFillColor = "transparent"
|
||||
// // }
|
||||
// // }
|
||||
// // }, 100);
|
||||
// // },
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// frequencyDefault: 1,
|
||||
// allowed() {
|
||||
// return !tech.isRelay
|
||||
// },
|
||||
// requires: "not relay switch",
|
||||
// effect() {
|
||||
// tech.isFlipFlop = true //do you have this tech?
|
||||
// if (!tech.isFlipFlopOn) {
|
||||
// tech.isFlipFlopOn = true //what is the state of flip-Flop?
|
||||
// }
|
||||
// // if (!m.isShipMode) {
|
||||
// // m.skin.flipFlop()
|
||||
// // }
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlop = false
|
||||
// if (tech.isFlipFlopOn) {
|
||||
// tech.isFlipFlopOn = false //what is the state of flip-Flop?
|
||||
// }
|
||||
// m.eyeFillColor = 'transparent'
|
||||
// // m.resetSkin();
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "NAND gate",
|
||||
// description: "if <strong class='color-flop'>ON</strong><br><strong>1.555x</strong> <strong class='color-d'>damage</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return tech.isFlipFlop || tech.isRelay
|
||||
// },
|
||||
// requires: "ON/OFF tech",
|
||||
// effect() {
|
||||
// tech.isFlipFlopCoupling = true;
|
||||
// if (tech.isFlipFlopOn) {
|
||||
// m.couplingChange(this.bonus)
|
||||
// } else {
|
||||
// for (let i = 0; i < mob.length; i++) {
|
||||
// if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
|
||||
// }
|
||||
// spawn.WIMP()
|
||||
// mob[mob.length - 1].isDecoupling = true //so you can find it to remove
|
||||
// }
|
||||
// tech.isFlipFlopDamage = true;
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlopCoupling = false;
|
||||
// if (this.count) {
|
||||
// if (tech.isFlipFlop || tech.isRelay) {
|
||||
// if (tech.isFlipFlopOn) {
|
||||
// m.couplingChange(-this.bonus)
|
||||
// } else {
|
||||
// for (let i = 0; i < mob.length; i++) {
|
||||
// if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// tech.isFlipFlopDamage = false;
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "integrated circuit",
|
||||
// description: "if <strong class='color-flop'>ON</strong> <strong>+7</strong> power up <strong>choices</strong><br>if <strong class='color-flop'>OFF</strong> <strong>-1</strong> power up <strong>choices</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return (tech.isFlipFlop || tech.isRelay) && !tech.isDeterminism
|
||||
// },
|
||||
// requires: "ON/OFF tech, not determinism",
|
||||
// effect() {
|
||||
// tech.isFlipFlopChoices = true //do you have this tech
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlopChoices = false
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "transistor",
|
||||
// description: "if <strong class='color-flop'>ON</strong> generate <strong>+20</strong> <strong class='color-f'>energy</strong> per second<br>if <strong class='color-flop'>OFF</strong> drain <strong>-1</strong> <strong class='color-f'>energy</strong> per second",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return tech.isFlipFlop || tech.isRelay
|
||||
// },
|
||||
// requires: "ON/OFF tech",
|
||||
// effect() {
|
||||
// tech.isFlipFlopEnergy = true;
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isFlipFlopEnergy = false;
|
||||
// }
|
||||
// },
|
||||
// // {
|
||||
// // name: "decoupling",
|
||||
// // link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Decoupling_(cosmology)' class="link">decoupling</a>`,
|
||||
// // descriptionFunction() {
|
||||
// // //<span style = 'font-size:80%;'>(${ m.couplingDescription(this.bonus)})</span>
|
||||
// // return `if <strong class='color-flop'>ON</strong> <strong>+5</strong> <strong class='color-coupling'>coupling</strong><br>if <strong class='color-flop'>OFF</strong> a dangerous particle slowly <strong>chases</strong> you`
|
||||
// // },
|
||||
// // maxCount: 1,
|
||||
// // count: 0,
|
||||
// // frequency: 3,
|
||||
// // frequencyDefault: 3,
|
||||
// // bonus: 5, //coupling given
|
||||
// // allowed() {
|
||||
// // return tech.isFlipFlop || tech.isRelay
|
||||
// // },
|
||||
// // requires: "ON/OFF tech",
|
||||
// // effect() {
|
||||
// // tech.isFlipFlopCoupling = true;
|
||||
// // if (tech.isFlipFlopOn) {
|
||||
// // m.couplingChange(this.bonus)
|
||||
// // } else {
|
||||
// // for (let i = 0; i < mob.length; i++) {
|
||||
// // if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
|
||||
// // }
|
||||
// // spawn.WIMP()
|
||||
// // mob[mob.length - 1].isDecoupling = true //so you can find it to remove
|
||||
// // }
|
||||
// // },
|
||||
// // remove() {
|
||||
// // tech.isFlipFlopCoupling = false;
|
||||
// // if (this.count) {
|
||||
// // if (tech.isFlipFlop || tech.isRelay) {
|
||||
// // if (tech.isFlipFlopOn) {
|
||||
// // m.couplingChange(-this.bonus)
|
||||
// // } else {
|
||||
// // for (let i = 0; i < mob.length; i++) {
|
||||
// // if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // },
|
||||
// {
|
||||
// name: "relay switch",
|
||||
// description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after picking up a <strong>power up</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
|
||||
// // nameInfo: "<span id = 'tech-switch'></span>",
|
||||
// // addNameInfo() {
|
||||
// // setTimeout(function () {
|
||||
// // if (document.getElementById("tech-switch")) {
|
||||
// // if (tech.isFlipFlopOn) {
|
||||
// // document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
|
||||
// // m.eyeFillColor = m.fieldMeterColor //'#5af'
|
||||
// // } else {
|
||||
// // document.getElementById("tech-switch").innerHTML = ` = <strong>OFF</strong>`
|
||||
// // m.eyeFillColor = "transparent"
|
||||
// // }
|
||||
// // }
|
||||
// // }, 100);
|
||||
// // },
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// frequencyDefault: 1,
|
||||
// allowed() {
|
||||
// return !tech.isFlipFlop
|
||||
// },
|
||||
// requires: "not flip-flop",
|
||||
// effect() {
|
||||
// m.isAltSkin = true
|
||||
// tech.isRelay = true //do you have this tech?
|
||||
// if (!tech.isFlipFlopOn) {
|
||||
// tech.isFlipFlopOn = true //what is the state of flip-Flop?
|
||||
// }
|
||||
// // if (!m.isShipMode) {
|
||||
// // m.skin.flipFlop()
|
||||
// // }
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isRelay = false
|
||||
// if (tech.isFlipFlopOn) {
|
||||
// tech.isFlipFlopOn = false //what is the state of flip-Flop?
|
||||
// }
|
||||
// m.eyeFillColor = 'transparent'
|
||||
// // m.resetSkin();
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "lithium-ion",
|
||||
// description: "if <strong>relay switch</strong> is <strong class='color-flop'>ON</strong><br><strong>+300</strong> maximum <strong class='color-f'>energy</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return tech.isRelay
|
||||
// },
|
||||
// requires: "relay switch",
|
||||
// effect() {
|
||||
// tech.isRelayEnergy = true
|
||||
// m.setMaxEnergy()
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isRelayEnergy = false
|
||||
// m.setMaxEnergy()
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "thermocouple",
|
||||
// description: "if <strong>relay switch</strong> is <strong class='color-flop'>ON</strong><br>condense <strong>4-13</strong> <strong class='color-s'>ice IX</strong> crystals per second",
|
||||
// maxCount: 9,
|
||||
// count: 0,
|
||||
// frequency: 3,
|
||||
// frequencyDefault: 3,
|
||||
// allowed() {
|
||||
// return tech.isRelay
|
||||
// },
|
||||
// requires: "relay switch",
|
||||
// effect() {
|
||||
// tech.relayIce++
|
||||
// },
|
||||
// remove() {
|
||||
// tech.relayIce = 0
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "relay switch",
|
||||
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after picking up a <strong>power up</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
|
||||
nameInfo: "<span id = 'tech-switch'></span>",
|
||||
addNameInfo() {
|
||||
setTimeout(function () {
|
||||
if (document.getElementById("tech-switch")) {
|
||||
if (tech.isFlipFlopOn) {
|
||||
document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
|
||||
m.eyeFillColor = m.fieldMeterColor //'#5af'
|
||||
} else {
|
||||
document.getElementById("tech-switch").innerHTML = ` = <strong>OFF</strong>`
|
||||
m.eyeFillColor = "transparent"
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isFlipFlop
|
||||
},
|
||||
requires: "not flip-flop",
|
||||
effect() {
|
||||
m.isAltSkin = true
|
||||
tech.isRelay = true //do you have this tech?
|
||||
if (!tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = true //what is the state of flip-Flop?
|
||||
}
|
||||
// if (!m.isShipMode) {
|
||||
// m.skin.flipFlop()
|
||||
// }
|
||||
},
|
||||
remove() {
|
||||
tech.isRelay = false
|
||||
if (tech.isFlipFlopOn) {
|
||||
tech.isFlipFlopOn = false //what is the state of flip-Flop?
|
||||
}
|
||||
m.eyeFillColor = 'transparent'
|
||||
// m.resetSkin();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "lithium-ion",
|
||||
description: "if <strong>relay switch</strong> is <strong class='color-flop'>ON</strong><br><strong>+300</strong> maximum <strong class='color-f'>energy</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isRelay
|
||||
},
|
||||
requires: "relay switch",
|
||||
effect() {
|
||||
tech.isRelayEnergy = true
|
||||
m.setMaxEnergy()
|
||||
},
|
||||
remove() {
|
||||
tech.isRelayEnergy = false
|
||||
m.setMaxEnergy()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "thermocouple",
|
||||
description: "if <strong>relay switch</strong> is <strong class='color-flop'>ON</strong><br>condense <strong>4-13</strong> <strong class='color-s'>ice IX</strong> crystals per second",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return tech.isRelay
|
||||
},
|
||||
requires: "relay switch",
|
||||
effect() {
|
||||
tech.relayIce++
|
||||
},
|
||||
remove() {
|
||||
tech.relayIce = 0
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "first derivative",
|
||||
descriptionFunction() {
|
||||
@@ -3421,6 +3421,7 @@ const tech = {
|
||||
effect() {
|
||||
tech.isHealAttract = true
|
||||
powerUps.setPowerUpMode();
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.03);
|
||||
},
|
||||
remove() {
|
||||
tech.isHealAttract = false
|
||||
@@ -3515,12 +3516,12 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "anthropic principle",
|
||||
nameInfo: "<span id = 'tech-anthropic'></span>",
|
||||
addNameInfo() {
|
||||
setTimeout(function () {
|
||||
powerUps.research.changeRerolls(0)
|
||||
}, 1000);
|
||||
},
|
||||
// nameInfo: "<span id = 'tech-anthropic'></span>",
|
||||
// addNameInfo() {
|
||||
// setTimeout(function () {
|
||||
// powerUps.research.changeRerolls(0)
|
||||
// }, 1000);
|
||||
// },
|
||||
descriptionFunction() {
|
||||
return `once per level, instead of <strong>dying</strong><br>use ${powerUps.orb.research(1)} and spawn ${powerUps.orb.heal(16)}`
|
||||
},
|
||||
@@ -3871,9 +3872,12 @@ const tech = {
|
||||
requires: "not determinism",
|
||||
effect() {
|
||||
tech.isExtraGunField = true;
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.05);
|
||||
},
|
||||
remove() {
|
||||
tech.isExtraGunField = false;
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -3936,7 +3940,7 @@ const tech = {
|
||||
isBadRandomOption: true,
|
||||
isInstant: true,
|
||||
allowed() {
|
||||
return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices && !tech.isExtraBotOption
|
||||
return !tech.extraChoices && !tech.isExtraGunField && !tech.isExtraBotOption
|
||||
},
|
||||
requires: "not emergence, cross-disciplinary, integrated circuit",
|
||||
effect() {
|
||||
@@ -4106,9 +4110,13 @@ const tech = {
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isMassProduction = true
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.03);
|
||||
},
|
||||
remove() {
|
||||
tech.isMassProduction = false
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4307,7 +4315,7 @@ const tech = {
|
||||
name: "residual dipolar coupling",
|
||||
descriptionFunction() {
|
||||
// return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns ${powerUps.orb.coupling(5)}that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> spawns ${powerUps.orb.coupling(8)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> spawns ${powerUps.orb.coupling(7)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4327,7 +4335,7 @@ const tech = {
|
||||
{
|
||||
name: "commodities exchange",
|
||||
descriptionFunction() {
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>10-14</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>8-12</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4382,7 +4390,7 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.isCancelDuplication = false
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4430,13 +4438,13 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.isPowerUpsVanish = false
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "correlated damage",
|
||||
descriptionFunction() {
|
||||
return `<strong class='color-dup'>duplication</strong> increases <strong class='color-d'>damage</strong> by the same percent<br><em>(${(1 + Math.min(1, tech.duplicationChance())).toFixed(2)}x)</em>`
|
||||
return `<strong class='color-dup'>duplication</strong> increases <strong class='color-d'>damage</strong><br><em>(${(1 + Math.min(1, tech.duplicationChance())).toFixed(2)}x)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4467,9 +4475,11 @@ const tech = {
|
||||
effect() {
|
||||
tech.isDuplicateMobs = true;
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.08);
|
||||
},
|
||||
remove() {
|
||||
tech.isDuplicateMobs = false;
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4506,11 +4516,11 @@ const tech = {
|
||||
effect() {
|
||||
tech.isStimulatedEmission = true
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.15);
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.20);
|
||||
},
|
||||
remove() {
|
||||
tech.isStimulatedEmission = false
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4536,6 +4546,7 @@ const tech = {
|
||||
if (this.count > 0 && m.alive) {
|
||||
tech.duplication += 0.11
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
|
||||
tech.damage /= this.damage
|
||||
this.frequency = 0
|
||||
}
|
||||
@@ -4684,7 +4695,7 @@ const tech = {
|
||||
{
|
||||
name: "paradigm shift",
|
||||
descriptionFunction() {
|
||||
return `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <span class='color-remove'>ejects</span> it<br><strong>–4</strong> ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} each time`
|
||||
return `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <span class='color-remove'>ejects</span> it<br><strong>–${tech.pauseEjectTech.toFixed(1)}</strong> ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} cost <em>(1.2x cost each use)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4699,6 +4710,7 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.isPauseEjectTech = false;
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -5332,7 +5344,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
|
||||
},
|
||||
requires: "a freeze effect",
|
||||
effect() {
|
||||
@@ -5351,7 +5363,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
|
||||
},
|
||||
requires: "a freeze effect",
|
||||
effect() {
|
||||
@@ -5370,7 +5382,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
|
||||
},
|
||||
requires: "a localized freeze effect, no other mob death tech",
|
||||
effect() {
|
||||
@@ -5389,7 +5401,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
|
||||
return (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
|
||||
},
|
||||
requires: "ice IX",
|
||||
effect() {
|
||||
@@ -5408,7 +5420,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
|
||||
},
|
||||
requires: "a localized freeze effect",
|
||||
effect() {
|
||||
@@ -5433,7 +5445,7 @@ const tech = {
|
||||
// },
|
||||
// requires: "perfect diamagnetism",
|
||||
allowed() {
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)))
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)))
|
||||
},
|
||||
requires: "a localized freeze effect",
|
||||
effect() {
|
||||
@@ -5485,7 +5497,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "Zectron",
|
||||
description: `<strong>2x</strong> <strong>super ball</strong> density and <strong class='color-d'>damage</strong>, but<br>after colliding with <strong>super balls</strong> <strong>-5</strong> <strong class='color-f'>energy</strong>`,
|
||||
description: `<strong>2x</strong> <strong>super ball</strong> density and <strong class='color-d'>damage</strong>, but<br>after colliding with <strong>super balls</strong> <strong>-4</strong> <strong class='color-f'>energy</strong>`,
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -5630,7 +5642,7 @@ const tech = {
|
||||
tech.wavePacketDamage *= 1.4
|
||||
},
|
||||
remove() {
|
||||
tech.waveFrequency = 0.2
|
||||
tech.waveFrequency = 0.2 //adjust this to make the waves much larger
|
||||
tech.wavePacketDamage = 1
|
||||
}
|
||||
},
|
||||
@@ -8549,7 +8561,7 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.cloakDuplication = 0
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -8719,7 +8731,7 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.fieldDuplicate = 0
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (this.count > 0) powerUps.research.changeRerolls(3)
|
||||
}
|
||||
},
|
||||
@@ -10964,6 +10976,25 @@ const tech = {
|
||||
if (this.count) m.resetSkin();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "wall jump",
|
||||
description: "jump on walls",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
allowed() {
|
||||
return !m.isShipMode
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
jumpSensor.vertices[0].x += -22
|
||||
jumpSensor.vertices[3].x += -22
|
||||
jumpSensor.vertices[1].x += 22
|
||||
jumpSensor.vertices[2].x += 22
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "posture",
|
||||
description: "stand a bit taller",
|
||||
@@ -11935,6 +11966,7 @@ const tech = {
|
||||
isExplodeRadio: null,
|
||||
isPauseSwitchField: null,
|
||||
isPauseEjectTech: null,
|
||||
pauseEjectTech: null,
|
||||
isShieldPierce: null,
|
||||
isDuplicateMobs: null,
|
||||
is100Duplicate: null,
|
||||
@@ -11945,15 +11977,6 @@ const tech = {
|
||||
isSwitchReality: null,
|
||||
isResearchReality: null,
|
||||
isAnthropicDamage: null,
|
||||
isFlipFlop: null,
|
||||
isFlipFlopHarm: null,
|
||||
isFlipFlopOn: null,
|
||||
// isFlipFlopLevelReset: null,
|
||||
isFlipFlopDamage: null,
|
||||
isFlipFlopEnergy: null,
|
||||
isFlipFlopChoices: null,
|
||||
isRelay: null,
|
||||
relayIce: null,
|
||||
isMetaAnalysis: null,
|
||||
isFoamAttract: null,
|
||||
droneCycleReduction: null,
|
||||
@@ -12046,8 +12069,6 @@ const tech = {
|
||||
isTechDebt: null,
|
||||
isPlasmaBall: null,
|
||||
plasmaDischarge: null,
|
||||
isFlipFlopHealth: null,
|
||||
isRelayEnergy: null,
|
||||
coyoteTime: null,
|
||||
missileFireCD: null,
|
||||
isBotField: null,
|
||||
|
||||
Reference in New Issue
Block a user