plasma ball

plasma ball is now live, but it's still in beta
  still needs
    new graphics
    damage balancing
    fast decay in mob shields
    player angle rotation speed while firing adds to fire speed
    tech upgrade to get electrical arcs that randomly damage nearby mobs
    current tech synergy
      capacitor bank,plasma jet(range?)

reservoir level is less crowded, so you can dodge mobs easier
  horizontal flipped version is so reenabled
pure science renamed paradigm shift
difficulty scaling for heal and mob damage reduced 2%

some possible bug fixes, I don't know...
This commit is contained in:
landgreen
2022-03-20 15:43:51 -07:00
parent fc64d2daa4
commit dde4432279
11 changed files with 489 additions and 140 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1519,6 +1519,7 @@ const b = {
if (input.fire && Matter.Query.collides(this, map).length) { if (input.fire && Matter.Query.collides(this, map).length) {
Matter.Body.setPosition(this, Vector.add(this.position, { x: 20 * Math.cos(this.angle), y: 20 * Math.sin(this.angle) })) Matter.Body.setPosition(this, Vector.add(this.position, { x: 20 * Math.cos(this.angle), y: 20 * Math.sin(this.angle) }))
if (Matter.Query.collides(this, map).length) { if (Matter.Query.collides(this, map).length) {
Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Sleeping.set(this, true) Matter.Sleeping.set(this, true)
this.endCycle = simulation.cycle + 5 this.endCycle = simulation.cycle + 5
this.dropCaughtPowerUp() this.dropCaughtPowerUp()
@@ -2605,7 +2606,7 @@ const b = {
}, },
worm(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death() worm(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death()
const bIndex = bullet.length; const bIndex = bullet.length;
const wormSize = 6 + tech.wormSize * 7.2 * Math.random() const wormSize = 6 + tech.wormSize * 7 * Math.random()
if (bIndex < 500) { //can't make over 500 spores if (bIndex < 500) { //can't make over 500 spores
bullet[bIndex] = Bodies.polygon(where.x, where.y, 3, 3, { bullet[bIndex] = Bodies.polygon(where.x, where.y, 3, 3, {
inertia: Infinity, inertia: Infinity,
@@ -2616,7 +2617,7 @@ const b = {
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.001 : 0.0005) * (1 + 0.5 * (Math.random() - 0.5)), thrust: (tech.isFastSpores ? 0.001 : 0.0005) * (1 + 0.5 * (Math.random() - 0.5)),
wormSize: wormSize, wormSize: wormSize,
wormTail: 1 + wormSize, wormTail: 1 + Math.max(4, wormSize - 2 * tech.wormSize),
dmg: (tech.isMutualism ? 7 : 2.9) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm dmg: (tech.isMutualism ? 7 : 2.9) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm
lookFrequency: 100 + Math.floor(37 * Math.random()), lookFrequency: 100 + Math.floor(37 * Math.random()),
classType: "bullet", classType: "bullet",
@@ -3329,6 +3330,165 @@ const b = {
y: speed * Math.sin(dir) y: speed * Math.sin(dir)
}); });
}, },
// plasmaBall(position, velocity, radius) {
// // radius *= Math.sqrt(tech.bulletSize)
// const me = bullet.length;
// bullet[me] = Bodies.polygon(position.x, position.y, 20, radius, {
// density: 0.000001, // 0.001 is normal density
// inertia: Infinity,
// frictionAir: 0.003,
// dmg: 0, //damage on impact
// damage: 0, //damage done over time
// scale: 1 - 0.006 / tech.isBulletsLastLonger,
// classType: "bullet",
// collisionFilter: {
// category: cat.bullet,
// mask: 0 //cat.mob | cat.mobBullet // cat.map | cat.body | cat.mob | cat.mobShield
// },
// minDmgSpeed: 0,
// endCycle: Infinity,
// count: 0,
// radius: radius,
// portFrequency: 5 + Math.floor(5 * Math.random()),
// nextPortCycle: Infinity, //disabled unless you have the teleport tech
// beforeDmg(who) {
// if (!this.target && who.alive) {
// this.target = who;
// if (who.radius < 20) {
// this.targetRelativePosition = {
// x: 0,
// y: 0
// } //find relative position vector for zero mob rotation
// } else if (Matter.Query.collides(this, [who]).length > 0) {
// const normal = Matter.Query.collides(this, [who])[0].normal
// this.targetRelativePosition = Vector.rotate(Vector.sub(Vector.sub(this.position, who.position), Vector.mult(normal, -this.radius)), -who.angle) //find relative position vector for zero mob rotation
// } else {
// this.targetRelativePosition = Vector.rotate(Vector.sub(this.position, who.position), -who.angle) //find relative position vector for zero mob rotation
// }
// this.collisionFilter.category = cat.body;
// this.collisionFilter.mask = null;
// let bestVertexDistance = Infinity
// let bestVertex = null
// for (let i = 0; i < this.target.vertices.length; i++) {
// const dist = Vector.magnitude(Vector.sub(this.position, this.target.vertices[i]));
// if (dist < bestVertexDistance) {
// bestVertex = i
// bestVertexDistance = dist
// }
// }
// this.targetVertex = bestVertex
// }
// },
// onEnd() {},
// do() {
// if (this.count < 20) {
// this.count++
// //grow
// const SCALE = 1.06
// Matter.Body.scale(this, SCALE, SCALE);
// this.radius *= SCALE;
// } else {
// //shrink
// Matter.Body.scale(this, this.scale, this.scale);
// this.radius *= this.scale;
// if (this.radius < 8) this.endCycle = 0;
// }
// if (this.target && this.target.alive) { //if stuck to a target
// const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector
// if (this.target.isVerticesChange) {
// Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
// } else {
// Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position))
// }
// if (this.target.isBoss) {
// if (this.target.speed > 8) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.98))
// } else {
// if (this.target.speed > 4) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.95))
// }
// Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9);
// // Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
// if (this.target.isShielded) {
// this.target.damage(m.dmgScale * this.damage, true); //shield damage bypass
// const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded
// Matter.Body.scale(this, SCALE, SCALE);
// this.radius *= SCALE;
// } else {
// this.target.damage(m.dmgScale * this.damage);
// }
// } else if (this.target !== null) { //look for a new target
// this.collisionFilter.category = cat.bullet;
// this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
// if (tech.isSpawnBulletsOnDeath && bullet.length < 180 && !this.target.isMobBullet) {
// let targets = []
// for (let i = 0, len = mob.length; i < len; i++) {
// const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
// if (dist < 1000000) targets.push(mob[i])
// }
// const radius = Math.min(this.radius * 0.5, 9)
// const len = bullet.length < 80 ? 2 : 1
// for (let i = 0; i < len; i++) {
// if (targets.length - i > 0) {
// const index = Math.floor(Math.random() * targets.length)
// const speed = 6 + 6 * Math.random()
// const velocity = Vector.mult(Vector.normalise(Vector.sub(targets[index].position, this.position)), speed)
// b.foam(this.position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius)
// } else {
// b.foam(this.position, Vector.rotate({
// x: 15 + 10 * Math.random(),
// y: 0
// }, 2 * Math.PI * Math.random()), radius)
// }
// }
// }
// this.target = null
// } else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map or blocks
// const slow = 0.85
// Matter.Body.setVelocity(this, {
// x: this.velocity.x * slow,
// y: this.velocity.y * slow
// });
// const SCALE = 0.96
// Matter.Body.scale(this, SCALE, SCALE);
// this.radius *= SCALE;
// // } else if (Matter.Query.collides(this, body).length > 0) {
// } else if (Matter.Query.point(body, this.position).length > 0) {
// const slow = 0.9
// Matter.Body.setVelocity(this, {
// x: this.velocity.x * slow,
// y: this.velocity.y * slow
// });
// const SCALE = 0.96
// Matter.Body.scale(this, SCALE, SCALE);
// this.radius *= SCALE;
// } else {
// this.force.y += this.mass * tech.foamGravity; //gravity
// if (tech.isFoamAttract) {
// for (let i = 0, len = mob.length; i < len; i++) {
// if (!mob[i].isBadTarget && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
// this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * 0.004)
// const slow = 0.9
// Matter.Body.setVelocity(this, {
// x: this.velocity.x * slow,
// y: this.velocity.y * slow
// });
// break
// }
// }
// }
// }
// if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport
// this.nextPortCycle = simulation.cycle + this.portFrequency
// const range = 15 * Math.sqrt(this.radius) * Math.random()
// Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
// }
// }
// });
// if (tech.isBulletTeleport) bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency
// Composite.add(engine.world, bullet[me]); //add bullet to world
// Matter.Body.setVelocity(bullet[me], velocity);
// },
foam(position, velocity, radius) { foam(position, velocity, radius) {
// radius *= Math.sqrt(tech.bulletSize) // radius *= Math.sqrt(tech.bulletSize)
const me = bullet.length; const me = bullet.length;

View File

@@ -188,7 +188,7 @@ function collisionChecks(event) {
time: simulation.drawTime time: simulation.drawTime
}); });
} }
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.01 : 1.06 if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.005 : 1.05
return; return;
} }
//mob + body collisions //mob + body collisions

View File

@@ -326,7 +326,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isLore) { } else if (tech.tech[i].isLore) {
text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore" ${style}></div> &nbsp; ${tech.tech[i].name} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>` text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[i].name} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
} else { } else {
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>` text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
} }
@@ -379,7 +379,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected");
tech.giveTech(index) tech.giveTech(index)
} else if (!tech.tech[index].isNonRefundable) { } else if (!tech.tech[index].isNonRefundable) {
tech.totalCount -= tech.tech[index].count // tech.totalCount -= tech.tech[index].count
tech.removeTech(index); tech.removeTech(index);
who.classList.remove("build-tech-selected"); who.classList.remove("build-tech-selected");
} else { } else {

View File

@@ -15,35 +15,35 @@ const level = {
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("molecular assembler") // m.setField("metamaterial cloaking")
// b.giveGuns("drones") // b.giveGuns("harpoon")
// tech.giveTech("autonomous navigation") // tech.giveTech("grappling hook")
// tech.giveTech("delivery drone") // tech.giveTech("bulk modulus")
// tech.giveTech("dynamo-bot upgrade")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
// for (let i = 0; i < 9; i++) tech.giveTech("dynamo-bot") // for (let i = 0; i < 9; i++) tech.giveTech("dynamo-bot")
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(100000)
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot") // for (let i = 0; i < 2; i++) tech.giveTech("undefined")
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.setField("plasma torch")
// tech.giveTech("plasma ball")
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.reactor(); // level.reactor();
// level.testing(); //not in rotation, used for testing // level.pavilion(); //not in rotation, used for testing
// level.perplex() if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
if (simulation.isTraining) { level.walk(); } else { level.intro(); }
// powerUps.research.changeRerolls(3000) // powerUps.research.changeRerolls(3000)
// for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); // for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
// for (let i = 0; i < 3; i++) tech.giveTech("undefined") // for (let i = 0; i < 3; i++) tech.giveTech("undefined")
// lore.techCount = 3 // lore.techCount = 3
// simulation.isCheating = false //true; // simulation.isCheating = false //true;
// localSettings.loreCount = 2; //this sets what conversation is heard // localSettings.loreCount = 0; //this sets what conversation is heard
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage // if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation // level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
// level.null() // level.null()
// lore.unlockTesting(); // lore.unlockTesting();
// tech.giveTech("tinker"); //show junk tech in experiment mode // tech.giveTech("tinker"); //show junk tech in experiment mode
} else { } else {
@@ -113,6 +113,9 @@ const level = {
for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "tech", false); //start // for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "tech", false); //start
} }
if (m.plasmaBall) {
m.plasmaBall.isOn = false
}
}, },
trainingText(say) { trainingText(say) {
simulation.lastLogTime = 0; //clear previous messages simulation.lastLogTime = 0; //clear previous messages
@@ -130,7 +133,7 @@ const level = {
simulation.accelScale = 1 //mob acceleration increases each level simulation.accelScale = 1 //mob acceleration increases each level
simulation.CDScale = 1 //mob CD time decreases each level simulation.CDScale = 1 //mob CD time decreases each level
simulation.dmgScale = Math.max(0.1, 0.34 * simulation.difficulty) //damage done by mobs scales with total levels simulation.dmgScale = Math.max(0.1, 0.34 * simulation.difficulty) //damage done by mobs scales with total levels
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale; simulation.healScale = 1 / (1 + simulation.difficulty * 0.052) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
}, },
difficultyIncrease(num = 1) { difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
@@ -140,7 +143,7 @@ const level = {
if (simulation.CDScale > 0.15) simulation.CDScale *= 0.965 //mob CD time decreases each level if (simulation.CDScale > 0.15) simulation.CDScale *= 0.965 //mob CD time decreases each level
} }
simulation.dmgScale = Math.max(0.1, 0.34 * simulation.difficulty) //damage done by mobs scales with total levels simulation.dmgScale = Math.max(0.1, 0.34 * simulation.difficulty) //damage done by mobs scales with total levels
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale; simulation.healScale = 1 / (1 + simulation.difficulty * 0.052) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
// console.log(`CD = ${simulation.CDScale}`) // console.log(`CD = ${simulation.CDScale}`)
}, },
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset() difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
@@ -151,8 +154,8 @@ const level = {
if (simulation.CDScale < 1) simulation.CDScale /= 0.965 //mob CD time decreases each level if (simulation.CDScale < 1) simulation.CDScale /= 0.965 //mob CD time decreases each level
} }
if (simulation.difficulty < 1) simulation.difficulty = 0; if (simulation.difficulty < 1) simulation.difficulty = 0;
simulation.dmgScale = Math.max(0.1, 0.35 * simulation.difficulty) //damage done by mobs scales with total levels simulation.dmgScale = Math.max(0.1, 0.34 * simulation.difficulty) //damage done by mobs scales with total levels
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) simulation.healScale = 1 / (1 + simulation.difficulty * 0.052)
}, },
difficultyText() { difficultyText() {
if (simulation.difficultyMode === 1) { if (simulation.difficultyMode === 1) {
@@ -836,7 +839,7 @@ const level = {
// const block = body[body.length] = Bodies.rectangle(x, y, width, height, { // const block = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.map, category: cat.map,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet mask: cat.player | cat.body | cat.bullet | cat.powerUp // | cat.mob | cat.mobBullet
}, },
isNoSetCollision: true, isNoSetCollision: true,
inertia: Infinity, //prevents rotation inertia: Infinity, //prevents rotation
@@ -3173,9 +3176,12 @@ const level = {
//right //right
spawn.mapVertex(425 + 437, -50, "490 0 350 80 -350 80 -490 0 -350 -80 350 -80"); spawn.mapVertex(425 + 437, -50, "490 0 350 80 -350 80 -490 0 -350 -80 350 -80");
spawn.mapRect(325, -100, 1070, 100); spawn.mapRect(325, -100, 1070, 100);
spawn.mapRect(225, 675, 375, 25); // spawn.mapRect(225, 675, 375, 25);
spawn.mapRect(675, 450, 375, 25); // spawn.mapRect(675, 450, 375, 25);
spawn.mapRect(1125, 225, 375, 25); // spawn.mapRect(1125, 225, 375, 25);
spawn.mapRect(175, 675, 425, 25);
spawn.mapRect(1125, 225, 425, 25);
spawn.mapRect(650, 450, 425, 25);
if (Math.random() < 0.33) { if (Math.random() < 0.33) {
spawn.mapVertex(855, -1000, "-100 -300 0 -350 100 -300 100 300 0 350 -100 300"); spawn.mapVertex(855, -1000, "-100 -300 0 -350 100 -300 100 300 0 350 -100 300");
@@ -3190,12 +3196,19 @@ const level = {
spawn.mapVertex(-687, -1936, "-612 50 0 100 612 50 612 -50 -612 -50"); spawn.mapVertex(-687, -1936, "-612 50 0 100 612 50 612 -50 -612 -50");
//2nd floor right building //2nd floor right building
spawn.mapRect(550, -3050, 600, 175); // spawn.mapRect(550, -3050, 600, 175);
spawn.mapRect(550, -3050, 600, 75);
spawn.bodyRect(-125, -2025, 475, 25); spawn.bodyRect(-125, -2025, 475, 25);
//2nd floor left building //2nd floor left building
spawn.mapRect(-925, -2350, 675, 200); // if (Math.random() > 0.5) {
spawn.mapRect(-825, -2825, 425, 275); // spawn.mapRect(-925, -2350, 675, 200);
// } else {
// }
spawn.mapRect(-925, -2350, 675, 50);
spawn.mapRect(-825, -2825, 425, 50);
// spawn.mapRect(-825, -2825, 425, 275);
spawn.mapRect(-450, -3125, 50, 350); spawn.mapRect(-450, -3125, 50, 350);
spawn.mapRect(-750, -3150, 350, 50); spawn.mapRect(-750, -3150, 350, 50);
spawn.mapRect(-650, -3400, 250, 300); spawn.mapRect(-650, -3400, 250, 300);
@@ -3203,8 +3216,11 @@ const level = {
spawn.bodyRect(-375, -2150, 100, 150, 0.2); spawn.bodyRect(-375, -2150, 100, 150, 0.2);
//2nd floor left pillar //2nd floor left pillar
spawn.mapRect(-1400, -2625, 325, 25); spawn.mapRect(-1400, -2625, 325, 25);
spawn.mapRect(-1400, -3225, 325, 25); spawn.mapRect(-1450, -3225, 425, 25);
spawn.mapRect(-1400, -3825, 325, 25); // spawn.mapRect(-1500, -3825, 525, 25);
spawn.mapRect(-1512.5, -3825, 550, 25);
// spawn.mapRect(-1400, -3225, 325, 25);
// spawn.mapRect(-1400, -3825, 325, 25);
spawn.randomMob(1000, -275, 0.2); spawn.randomMob(1000, -275, 0.2);
spawn.randomMob(950, -1725, 0.1); spawn.randomMob(950, -1725, 0.1);
@@ -3231,7 +3247,7 @@ const level = {
slime.min.y += slime.maxHeight slime.min.y += slime.maxHeight
slime.max.y = slime.min.y + slime.height slime.max.y = slime.min.y + slime.height
const elevator1 = level.elevator(-1625, -90, 310, 800, -2000, 0.0025, { up: 0.1, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { const elevator1 = level.elevator(-1625, -90, 310, 800, -2000, 0.0025, { up: 0.1, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
const elevator2 = level.elevator(1175, -3050, 200, 300, -4475, 0.0025, { up: 0.12, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { const elevator2 = level.elevator(1175, -3050, 200, 250, -4475, 0.0025, { up: 0.12, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
let waterFallWidth = 0 let waterFallWidth = 0
let waterFallX = 0 let waterFallX = 0
let waterFallSmoothX = 0 let waterFallSmoothX = 0
@@ -3242,10 +3258,10 @@ const level = {
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
if (simulation.isHorizontalFlipped) { //flip the map horizontally if (simulation.isHorizontalFlipped) { //flip the map horizontally
spawn.mapVertex(584, -2435, "0 0 300 0 150 600 0 600"); spawn.mapVertex(584, -2500, "0 0 300 0 150 600 0 600");
spawn.mapVertex(1116, -2435, "0 0 300 0 300 600 150 600"); spawn.mapVertex(1116, -2500, "0 0 300 0 300 600 150 600");
spawn.bodyRect(-200, -125, 625, 25); spawn.bodyRect(-200, -125, 625, 25);
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
@@ -3255,7 +3271,7 @@ const level = {
spinnerArray.push(level.spinner(-110, -3325, 45, 600, 0.003, 0, 0, 0.01)) // spinner(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0) { spinnerArray.push(level.spinner(-110, -3325, 45, 600, 0.003, 0, 0, 0.01)) // spinner(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0) {
const boost1 = level.boost(-900, -2000, 700) const boost1 = level.boost(-900, -2000, 790)
level.setPosToSpawn(500, 850); //normal spawn level.setPosToSpawn(500, 850); //normal spawn
level.custom = () => { level.custom = () => {
ctx.fillStyle = "#c0c3c9" ///!!!!!!!!!! for flipped x: newX = -oldX - width ctx.fillStyle = "#c0c3c9" ///!!!!!!!!!! for flipped x: newX = -oldX - width
@@ -3287,11 +3303,11 @@ const level = {
ctx.fill(); ctx.fill();
//shadow //shadow
ctx.fillStyle = "rgba(0,10,30,0.1)" ctx.fillStyle = "rgba(0,10,30,0.1)"
ctx.fillRect(-1150, -2900, 600, 925); ctx.fillRect(-1150, -3000, 600, 1025);
ctx.fillRect(450, -3100, 300, 275); ctx.fillRect(450, -3100, 300, 275);
ctx.fillRect(450, -3625, 200, 225); ctx.fillRect(450, -3625, 200, 225);
ctx.fillRect(400, -2575, 425, 325); ctx.fillRect(400, -2775, 425, 450);
ctx.fillRect(250, -2150, 675, 150); ctx.fillRect(250, -2300, 675, 300);
slime.query(); slime.query();
if (isWaterfallFilling) { if (isWaterfallFilling) {
@@ -3319,6 +3335,8 @@ const level = {
} }
}; };
} else { //not flipped } else { //not flipped
spawn.mapVertex(1116, -2500, "0 0 300 0 150 600 0 600");
spawn.mapVertex(584, -2500, "0 0 300 0 300 600 150 600");
if (Math.random() < 0.33) { if (Math.random() < 0.33) {
spinnerArray.push(level.spinner(65, -300, 40, 450, 0.003, Math.PI / 2)) spinnerArray.push(level.spinner(65, -300, 40, 450, 0.003, Math.PI / 2))
@@ -3336,7 +3354,7 @@ const level = {
Matter.Body.setVertices(spinnerArray[spinnerArray.length - 1].bodyB, Vertices.fromPath(hexagon)) Matter.Body.setVertices(spinnerArray[spinnerArray.length - 1].bodyB, Vertices.fromPath(hexagon))
} }
const boost1 = level.boost(800, -2000, 700) const boost1 = level.boost(800, -2000, 790)
level.custom = () => { level.custom = () => {
ctx.fillStyle = "#c0c3c9" ctx.fillStyle = "#c0c3c9"
@@ -3346,7 +3364,6 @@ const level = {
ctx.fillStyle = "#d0d4d6" ctx.fillStyle = "#d0d4d6"
ctx.fillRect(-1100, -1925, 825, 2925) //large pillar background ctx.fillRect(-1100, -1925, 825, 2925) //large pillar background
ctx.fillRect(450, -1925, 825, 2925) //large pillar background ctx.fillRect(450, -1925, 825, 2925) //large pillar background
ctx.fillStyle = "#cff" //exit ctx.fillStyle = "#cff" //exit
ctx.fillRect(1475, -4900, 525, 425) ctx.fillRect(1475, -4900, 525, 425)
level.exit.drawAndCheck(); level.exit.drawAndCheck();
@@ -3369,11 +3386,11 @@ const level = {
ctx.fill(); ctx.fill();
//shadow //shadow
ctx.fillStyle = "rgba(0,10,30,0.1)" ctx.fillStyle = "rgba(0,10,30,0.1)"
ctx.fillRect(550, -2900, 600, 925); ctx.fillRect(550, -3000, 600, 1025);
ctx.fillRect(-750, -3100, 300, 275); ctx.fillRect(-750, -3100, 300, 275);
ctx.fillRect(-650, -3625, 200, 225); ctx.fillRect(-650, -3625, 200, 225);
ctx.fillRect(-825, -2575, 425, 325); ctx.fillRect(-825, -2775, 425, 450);
ctx.fillRect(-925, -2150, 675, 150); ctx.fillRect(-925, -2300, 675, 300);
slime.query(); slime.query();
if (isWaterfallFilling) { if (isWaterfallFilling) {
@@ -6019,10 +6036,10 @@ const level = {
const balance = level.spinner(5500, -412.5, 25, 660) //entrance const balance = level.spinner(5500, -412.5, 25, 660) //entrance
const rotor = level.rotor(7000, 580, -0.001); const rotor = level.rotor(7000, 580, -0.001);
const doorSortieSalle = level.door(8590, -520, 20, 800, 750) const doorSortieSalle = level.door(8590, -520, 20, 800, 750)
let buttonSortieSalle // let buttonSortieSalle
let portalEnBas // let portalEnBas
let portalEnHaut let portalEnHaut
let door3isClosing = false; // let door3isClosing = false;
function drawOnTheMapMapRect(x, y, dx, dy) { function drawOnTheMapMapRect(x, y, dx, dy) {
spawn.mapRect(x, y, dx, dy); spawn.mapRect(x, y, dx, dy);

View File

@@ -34,9 +34,9 @@ const m = {
category: cat.player, category: cat.player,
mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
}, },
death() { // death() {
m.death(); // m.death();
} // }
}); });
Matter.Body.setMass(player, m.mass); Matter.Body.setMass(player, m.mass);
Composite.add(engine.world, [player]); Composite.add(engine.world, [player]);
@@ -2085,7 +2085,126 @@ const m = {
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away", description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away",
set() { set() {
b.isExtruderOn = false b.isExtruderOn = false
if (tech.isExtruder) { if (m.plasmaBall) {
m.plasmaBall.isOn = false
Matter.Composite.remove(engine.world, m.plasmaBall);
}
if (tech.isPlasmaBall) {
// m.plasmaBall = {
// position: { x: m.pos.x + 10 * Math.cos(m.angle), y: m.pos.y + 10 * Math.sin(m.angle) },
// velocity: { x: 0, y: 0 },
// radius: 1,
// }
m.plasmaBall = Bodies.circle(m.pos.x + 10 * Math.cos(m.angle), m.pos.y + 10 * Math.sin(m.angle), 1, {
collisionFilter: {
group: 0,
category: 0,
mask: 0 //cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
},
frictionAir: 0,
// radius: 1,
// friction: 0,
// frictionStatic: 0,
// restitution: 0,
alpha: 0.6,
isAttached: false,
isOn: false,
drain: 0.0012,
radiusLimit: 10,
damage: 0.18,
setPositionToNose() {
const nose = { x: m.pos.x + 10 * Math.cos(m.angle), y: m.pos.y + 10 * Math.sin(m.angle) }
Matter.Body.setPosition(this, Vector.add(nose, Vector.mult(Vector.normalise(Vector.sub(nose, m.pos)), this.circleRadius)));
},
fire() {
this.isAttached = false;
const speed = 4 //scale with mass?
Matter.Body.setVelocity(this, {
x: 0.4 * player.velocity.x + speed * Math.cos(m.angle),
y: 0.2 * player.velocity.y + speed * Math.sin(m.angle)
});
},
do() {
if (this.isOn) {
//collisions with map
if (Matter.Query.collides(this, map).length > 0) {
const scale = Math.max(0.7, 0.99 - 1 / m.plasmaBall.circleRadius)
Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast
if (m.plasmaBall.circleRadius < m.plasmaBall.radiusLimit) this.isOn = false
}
//collisions with mobs
const whom = Matter.Query.collides(this, mob)
const dmg = this.damage * m.dmgScale
for (let i = 0, len = whom.length; i < len; i++) {
if (whom[i].bodyA.alive) whom[i].bodyA.damage(dmg);
if (whom[i].bodyB.alive) whom[i].bodyB.damage(dmg);
}
//graphics
var gradient = ctx.createRadialGradient(this.position.x, this.position.y, 0, this.position.x, this.position.y, this.circleRadius);
gradient.addColorStop(0, `rgba(255,255,255,${this.alpha})`);
gradient.addColorStop(0.2, `rgba(255,200,255,${this.alpha})`);
gradient.addColorStop(1, `rgba(255,0,255,${this.alpha})`);
ctx.fillStyle = gradient
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.circleRadius, 0, 2 * Math.PI);
ctx.fill();
}
},
});
Composite.add(engine.world, m.plasmaBall);
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
m.grabPowerUp();
m.lookForPickUp();
//field is active
if (!m.plasmaBall.isAttached) { //return ball to player
const scale = 0.7
Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast
if (m.plasmaBall.circleRadius < m.plasmaBall.radiusLimit) {
m.plasmaBall.isAttached = true
m.plasmaBall.isOn = true
m.plasmaBall.setPositionToNose()
}
} else if (m.energy > m.plasmaBall.drain) { //charge up when attached
m.energy -= m.plasmaBall.drain;
const scale = 1 + 5 * Math.pow(Math.max(1, m.plasmaBall.circleRadius), -1.5)
Matter.Body.scale(m.plasmaBall, scale, scale); //grow
m.plasmaBall.setPositionToNose()
//add friction for player when holding ball, maybe more friction in vertical
} else {
m.fieldCDcycle = m.cycle + 90;
m.plasmaBall.fire()
}
} else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
m.pickUp();
} else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
if (m.plasmaBall.isAttached) {
m.fieldCDcycle = m.cycle + 30;
m.plasmaBall.fire()
}
}
m.drawFieldMeter("rgba(0, 0, 0, 0.2)")
m.plasmaBall.do()
}
} else if (tech.isExtruder) {
m.hold = function() { m.hold = function() {
b.isExtruderOn = false b.isExtruderOn = false
if (m.isHolding) { if (m.isHolding) {

View File

@@ -821,7 +821,7 @@ const simulation = {
level.zones = []; level.zones = [];
simulation.drawList = []; simulation.drawList = [];
if (tech.isDronesTravel) { if (tech.isDronesTravel && player.alive) {
//count drones //count drones
let count = 0 let count = 0
let deliveryCount = 0 let deliveryCount = 0
@@ -945,7 +945,7 @@ const simulation = {
} }
} }
if (m.pos.y > simulation.fallHeight) { // if 4000px deep if (m.pos.y > simulation.fallHeight || isNaN(player.position.x)) { // if 4000px deep
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
x: 0, x: 0,
y: 0 y: 0

View File

@@ -3747,7 +3747,7 @@ const spawn = {
if (this.countDown-- < 0) { //explode if (this.countDown-- < 0) { //explode
this.death(); this.death();
//hit player //hit player
if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) {
m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1)); m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1));
m.energy -= 0.1 * (tech.isRadioactiveResistance ? 0.25 : 1) m.energy -= 0.1 * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0

View File

@@ -58,6 +58,7 @@ const tech = {
simulation.makeTextLog(`<span class='color-var'>tech</span>.removeTech("<span class='color-text'>${tech.tech[index].name}</span>")`) simulation.makeTextLog(`<span class='color-var'>tech</span>.removeTech("<span class='color-text'>${tech.tech[index].name}</span>")`)
tech.tech[index].remove(); tech.tech[index].remove();
tech.tech[index].count = 0; tech.tech[index].count = 0;
tech.totalCount -= totalRemoved
simulation.updateTechHUD(); simulation.updateTechHUD();
tech.tech[index].isLost = true tech.tech[index].isLost = true
simulation.updateTechHUD(); simulation.updateTechHUD();
@@ -211,7 +212,7 @@ const tech = {
}, },
damageFromTech() { damageFromTech() {
let dmg = 1 //m.fieldDamage let dmg = 1 //m.fieldDamage
if (tech.isTechDebt) dmg *= 4 - 0.1 * tech.totalCount if (tech.isTechDebt) dmg *= 4 - 0.08 * tech.totalCount
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction()) if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
if (tech.OccamDamage) dmg *= tech.OccamDamage if (tech.OccamDamage) dmg *= tech.OccamDamage
if (tech.isCloakingDamage) dmg *= 1.35 if (tech.isCloakingDamage) dmg *= 1.35
@@ -370,7 +371,7 @@ const tech = {
if (gunTechPool.length) { if (gunTechPool.length) {
const index = Math.floor(Math.random() * gunTechPool.length) const index = Math.floor(Math.random() * gunTechPool.length)
tech.giveTech(gunTechPool[index]) // choose from the gun pool tech.giveTech(gunTechPool[index]) // choose from the gun pool
tech.tech[gunTechPool[index]].isFromAppliedScience = true //makes it not remove properly under pure science tech.tech[gunTechPool[index]].isFromAppliedScience = true //makes it not remove properly under paradigm shift
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[gunTechPool[index]].name}</span>")`) simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[gunTechPool[index]].name}</span>")`)
} }
} }
@@ -747,7 +748,7 @@ const tech = {
}, },
{ {
name: "regression", name: "regression",
description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>6%</strong> for mobs <em>(1% for bosses)</em>", description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>5%</strong> for mobs <em>(0.5% for bosses)</em>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1620,7 +1621,7 @@ const tech = {
}, },
{ {
name: "Pauli exclusion", name: "Pauli exclusion",
description: `after receiving <strong class='color-harm'>harm</strong> from a <strong>collision</strong> become<br><strong>immune</strong> to <strong class='color-harm'>harm</strong> for <strong>1.5</strong> extra seconds`, description: `after receiving <strong class='color-harm'>harm</strong> from a <strong>collision</strong> become<br><strong>immune</strong> to <strong class='color-harm'>harm</strong> for <strong>2.5</strong> extra seconds`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1628,7 +1629,7 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.collisionImmuneCycles += 90; tech.collisionImmuneCycles += 150;
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
}, },
remove() { remove() {
@@ -1637,7 +1638,7 @@ const tech = {
}, },
{ {
name: "spinstatistics theorem", name: "spinstatistics theorem",
description: `become <strong>immune</strong> to <strong class='color-harm'>harm</strong> for <strong>1.9</strong> seconds<br>once every <strong>7</strong> seconds`, description: `become <strong>immune</strong> to <strong class='color-harm'>harm</strong> for <strong>1.75</strong> seconds<br>once every <strong>7</strong> seconds`,
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1647,7 +1648,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.cyclicImmunity += 114; tech.cyclicImmunity += 105;
}, },
remove() { remove() {
tech.cyclicImmunity = 0; tech.cyclicImmunity = 0;
@@ -3068,7 +3069,7 @@ const tech = {
} }
}, },
{ {
name: "pure science", name: "paradigm shift",
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>4%</strong> chance to convert that tech into ${powerUps.orb.research(1)}`, description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>4%</strong> chance to convert that tech into ${powerUps.orb.research(1)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3088,7 +3089,7 @@ const tech = {
// description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned(${4 - 0.1 * tech.totalCount})`, // description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned(${4 - 0.1 * tech.totalCount})`,
// description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong>, but reduce <strong class='color-d'>damage</strong><br>by <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned`, // description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong>, but reduce <strong class='color-d'>damage</strong><br>by <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned`,
descriptionFunction() { descriptionFunction() {
return `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong><br>for <strong class='color-m'>tech</strong> you have learned <em>(${Math.floor(100*(4 - 0.1 * tech.totalCount))-100}%)</em>` return `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>8%</strong><br>for <strong class='color-m'>tech</strong> you have learned <em>(${Math.floor(100*(4 - 0.08 * tech.totalCount))-100}%)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3704,7 +3705,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.nailRecoil) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isRivets && !tech.isIncendiary && !tech.isIceCrystals return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.nailRecoil) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isRivets && !tech.isIncendiary && !tech.isIceCrystals && !tech.isIceShot
}, },
requires: "nail gun, shotgun, not ice crystal, rivets, rotary cannon, or pneumatic, incendiary, nail-shot, rivets, foam-shot, worm-shot, ice-shot", requires: "nail gun, shotgun, not ice crystal, rivets, rotary cannon, or pneumatic, incendiary, nail-shot, rivets, foam-shot, worm-shot, ice-shot",
effect() { effect() {
@@ -3743,7 +3744,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isNeedles && !tech.isIceCrystals return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isNeedles && !tech.isIceCrystals && !tech.isIceShot
}, },
requires: "nail gun shot gun, not ice crystal, needles, or pneumatic actuator", requires: "nail gun shot gun, not ice crystal, needles, or pneumatic actuator",
effect() { effect() {
@@ -5004,7 +5005,7 @@ const tech = {
name: "annelids", name: "annelids",
description: "increase <strong class='color-p' style='letter-spacing: -0.8px;'>worm</strong> size and <strong class='color-d'>damage</strong><br>between <strong>10%</strong> and <strong>120%</strong>", description: "increase <strong class='color-p' style='letter-spacing: -0.8px;'>worm</strong> size and <strong class='color-d'>damage</strong><br>between <strong>10%</strong> and <strong>120%</strong>",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 3,
count: 0, count: 0,
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
@@ -6445,7 +6446,7 @@ const tech = {
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport) return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport || tech.isDronesTravel)
}, },
requires: "molecular assembler, no other manufacturing, no drone tech", requires: "molecular assembler, no other manufacturing, no drone tech",
effect() { effect() {
@@ -6472,7 +6473,7 @@ const tech = {
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return (build.isExperimentSelection || powerUps.research.count > 0) && m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport) return (build.isExperimentSelection || powerUps.research.count > 0) && m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport || tech.isDronesTravel)
}, },
requires: "molecular assembler, no other manufacturing, no drone tech", requires: "molecular assembler, no other manufacturing, no drone tech",
effect() { effect() {
@@ -6499,7 +6500,7 @@ const tech = {
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport) return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport || tech.isDronesTravel)
}, },
requires: "molecular assembler, no other manufacturing, no drone tech", requires: "molecular assembler, no other manufacturing, no drone tech",
effect() { effect() {
@@ -6635,6 +6636,27 @@ const tech = {
if (this.count > 0) powerUps.research.changeRerolls(this.count * 2) if (this.count > 0) powerUps.research.changeRerolls(this.count * 2)
} }
}, },
{
name: "plasma ball",
description: "charge up a ball of <strong class='color-plasma'>plasma</strong> and fire it",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && !tech.isExtruder
},
requires: "plasma torch, not extruder",
effect() {
tech.isPlasmaBall = true;
m.fieldUpgrades[m.fieldMode].set()
},
remove() {
tech.isPlasmaBall = false;
if (this.count) m.fieldUpgrades[m.fieldMode].set()
}
},
{ {
name: "extruder", name: "extruder",
description: "<strong class='color-plasma'>plasma</strong> <strong>torch</strong> <strong class='color-plasma'>extrudes</strong> a thin hot wire<br>increases <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain", description: "<strong class='color-plasma'>plasma</strong> <strong>torch</strong> <strong class='color-plasma'>extrudes</strong> a thin hot wire<br>increases <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain",
@@ -6644,9 +6666,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && !tech.isPlasmaBall
}, },
requires: "plasma torch", requires: "plasma torch, not plasma ball",
effect() { effect() {
tech.isExtruder = true; tech.isExtruder = true;
m.fieldUpgrades[m.fieldMode].set() m.fieldUpgrades[m.fieldMode].set()
@@ -7642,54 +7664,6 @@ const tech = {
if (this.count) m.look = m.lookDefault if (this.count) m.look = m.lookDefault
} }
}, },
{
name: "Mech v4.48",
description: `open a portal to a primordial version of reality`,
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
window.open('https://scratch.mit.edu/projects/14005697/fullscreen/', '_blank')
},
remove() {}
},
{
name: "planetesimals",
description: `play <strong>planetesimals</strong> <em style = 'font-size:80%;'>(an asteroids-like game)</em><br>clear <strong>levels</strong> in <strong>planetesimals</strong> to spawn <strong class='color-m'>tech</strong><br>if you <strong style="color:red;">die</strong> in <strong>planetesimals</strong> you <strong style="color:red;">die</strong> in <strong>n-gon</strong>`,
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
window.open('../../planetesimals/index.html', '_blank')
// powerUps.spawn(m.pos.x, m.pos.y, "tech");
// for communicating to other tabs, like planetesimals
// Connection to a broadcast channel
const bc = new BroadcastChannel('planetesimals');
bc.activated = false
bc.onmessage = function(ev) {
if (ev.data === 'tech') powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') {
m.death()
bc.close(); //end session
}
if (ev.data === 'ready' && !bc.activated) {
bc.activated = true //prevents n-gon from activating multiple copies of planetesimals
bc.postMessage("activate");
}
}
},
remove() {}
},
{ {
name: "facsimile", name: "facsimile",
description: `inserts a copy of your current level into the level list`, description: `inserts a copy of your current level into the level list`,
@@ -9165,6 +9139,54 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "Mech v4.48",
description: `open a portal to a primordial version of reality`,
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
window.open('https://scratch.mit.edu/projects/14005697/fullscreen/', '_blank')
},
remove() {}
},
{
name: "planetesimals",
description: `play <strong>planetesimals</strong> <em style = 'font-size:80%;'>(an asteroids-like game)</em><br>clear <strong>levels</strong> in <strong>planetesimals</strong> to spawn <strong class='color-m'>tech</strong><br>if you <strong style="color:red;">die</strong> in <strong>planetesimals</strong> you <strong style="color:red;">die</strong> in <strong>n-gon</strong>`,
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
window.open('../../planetesimals/index.html', '_blank')
// powerUps.spawn(m.pos.x, m.pos.y, "tech");
// for communicating to other tabs, like planetesimals
// Connection to a broadcast channel
const bc = new BroadcastChannel('planetesimals');
bc.activated = false
bc.onmessage = function(ev) {
if (ev.data === 'tech') powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') {
m.death()
bc.close(); //end session
}
if (ev.data === 'ready' && !bc.activated) {
bc.activated = true //prevents n-gon from activating multiple copies of planetesimals
bc.postMessage("activate");
}
}
},
remove() {}
},
//************************************************** //**************************************************
//************************************************** undefined / lore //************************************************** undefined / lore
//************************************************** tech //************************************************** tech
@@ -9537,5 +9559,6 @@ const tech = {
isGrapple: null, isGrapple: null,
isImmuneGrapple: null, isImmuneGrapple: null,
isDronesTravel: null, isDronesTravel: null,
isTechDebt: null isTechDebt: null,
isPlasmaBall: null
} }

View File

@@ -236,7 +236,7 @@ summary {
margin: 0px; margin: 0px;
display: none; display: none;
grid-template-columns: 320px; grid-template-columns: 325px;
/* grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); */ /* grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); */
grid-auto-rows: minmax(auto, auto); grid-auto-rows: minmax(auto, auto);
grid-gap: 0px; grid-gap: 0px;

View File

@@ -1,20 +1,62 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: autonomous navigation - drones travel with you through levels and drones reset durability plasma ball is now live, but it's still in beta
tech: technical debt - increase damage by 300%, but reduce damage by 10% for each tech you have still needs
new graphics
damage balancing
fast decay in mob shields
player angle rotation speed while firing adds to fire speed
tech upgrade to get electrical arcs that randomly damage nearby mobs
current tech synergy
capacitor bank,plasma jet(range?)
molecular assembler now has a higher bullet spawn cap 200->300 reservoir level is less crowded, so you can dodge mobs easier
but it increases energy cost per spawn above around 150 horizontal flipped version is so reenabled
pure science renamed paradigm shift
difficulty scaling for heal and mob damage reduced 2%
fragments are about 15% fewer some possible bug fixes, I don't know...
thermal runaway is about 40% bigger and more damage
plasma torch: extruder uses less energy
pilot wave uses less energy
bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
bug: harpoon attack gave a mob really high levels of health
recent events:
had 3 harpoons at a time
tech: immune with grappling hook, Bulk modulus
cancel true colors with pure science
attack with harpoon at slasher mobs
they didn't die, but they should in one hit instead they got a huge health bar, then I just died for no reason after touching one
bug: maybe I can put in an event listener to reset inputs to false when you tab out to prevent key sticking
enemies stuck with foam receive upward force over time
only form aerogel tech?
bug: often game puts player position at NaN
try:
cloaking/harpoon grapple on normal, continue past beating the final boss
clues:
maybe with vanish or other special blocks and grapple hook
very high level for tech, duplication
maybe not about JUNK though
maybe on tons of bullets
maybe grappling hook, Bulk modulus
solution: just kill the player if they go NaN
Tech: superglue
Requires: foam + another gun or plasma torch or molecular assembler
Foam bubbles decay 50% slower
Enemies stuck with foam cannot move
Foam does 0 damage
Enemies stuck with foam take 25% more damage
should foam bots gets this also or is that too strong
buff pilot wave damage or lower energy drain
lower base harpoon density
const ctx = canvas.getContext('2d', {willReadFrequently': true}); const ctx = canvas.getContext('2d', {willReadFrequently': true});
//deal with game crashes? //deal with game crashes?
@@ -33,22 +75,10 @@ setting to remove UI, except health bar
except active gun? to see ammo except active gun? to see ammo
checkbox in pause and in settings checkbox in pause and in settings
bug: often game puts player position at NaN
clues:
after apoximis?
very high level for tech, duplication
maybe not about JUNK though
tech that does less damage the more tech you have?
tech.totalCount
add coyote jump add coyote jump
log game m.cycle when last on ground log game m.cycle when last on ground
for jump check if game cycle is < last on ground cycle -2 for jump check if game cycle is < last on ground cycle -2
tech - Plasma railgun
like foam, or phonon?
pause time like invariant for other things... pause time like invariant for other things...
throwing blocks throwing blocks
charging railgun charging railgun