tech: MACHO - an object follows you and gives you harm protection when you are inside it's halo

several nano-scale field tech now require some research, and have been buffed
  nano-scale mycelium, ice-IX, missile tech now consume 20% less energy to produce bullets
  nano-scale bot tech: spawn an extra bots

some bug fixes
This commit is contained in:
landgreen
2021-05-24 05:19:36 -07:00
parent 4405327828
commit 8727fee15e
9 changed files with 276 additions and 135 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -95,10 +95,10 @@ const b = {
simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-gun'>ammo</span><span class='color-symbol'>:</span> 0`); simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-gun'>ammo</span><span class='color-symbol'>:</span> 0`);
m.fireCDcycle = m.cycle + 30; //fire cooldown m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth) { if (tech.isAmmoFromHealth) {
if (m.health > 0.05) { if (m.health > 0.03) {
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty m.damage(0.03 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
} }
} }
} }
@@ -2590,7 +2590,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
beforeDmg() {}, beforeDmg() {},
onEnd() {}, onEnd() {},
@@ -2641,7 +2641,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
beforeDmg() {}, beforeDmg() {},
onEnd() {}, onEnd() {},
@@ -2696,7 +2696,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
beforeDmg() {}, beforeDmg() {},
onEnd() {}, onEnd() {},
@@ -2757,7 +2757,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
lockedOn: null, lockedOn: null,
beforeDmg() { beforeDmg() {
@@ -2838,7 +2838,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
lockedOn: null, lockedOn: null,
explode: 0, explode: 0,
@@ -2922,7 +2922,7 @@ const b = {
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
}, },
lockedOn: null, lockedOn: null,
beforeDmg() { beforeDmg() {

View File

@@ -197,7 +197,7 @@ function collisionChecks(event) {
} else if (Math.random() < 0.4 && !tech.isSuperDeterminism) { } else if (Math.random() < 0.4 && !tech.isSuperDeterminism) {
type = "research" type = "research"
} }
for (let i = 0; i < 2; i++) powerUps.spawn(mob[k].position.x, mob[k].position.y, type); powerUps.spawn(mob[k].position.x, mob[k].position.y, type);
} }
const stunTime = dmg / Math.sqrt(obj.mass) const stunTime = dmg / Math.sqrt(obj.mass)

View File

@@ -18,13 +18,14 @@ const level = {
// m.setField("pilot wave") // m.setField("pilot wave")
// b.giveGuns("laser") // b.giveGuns("laser")
// tech.isExplodeRadio = true // tech.isExplodeRadio = true
// tech.giveTech("fermions") // tech.giveTech("WIMPs")
// tech.giveTech("MACHO")
// tech.giveTech("potential well") // tech.giveTech("potential well")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length") // for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 3; i++) tech.giveTech("propagation") // for (let i = 0; i < 3; i++) tech.giveTech("propagation")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state") // for (let i = 0; i < 3; i++) tech.giveTech("bound state")
// for (let i = 0; i < 9; i++) tech.giveTech("WIMPs") // for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
// tech.giveTech("metastability") // tech.giveTech("attract")
level.intro(); //starting level level.intro(); //starting level
@@ -109,7 +110,7 @@ const level = {
const len = Math.floor((m.maxHealth - m.health) / 0.5) const len = Math.floor((m.maxHealth - m.health) / 0.5)
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 60 * (Math.random() - 0.5), player.position.y + 60 * (Math.random() - 0.5), "heal", false); for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 60 * (Math.random() - 0.5), player.position.y + 60 * (Math.random() - 0.5), "heal", false);
} }
if (tech.isMACHO) spawn.MACHO()
for (let i = 0; i < tech.wimpCount; i++) { for (let i = 0; i < tech.wimpCount; i++) {
spawn.WIMP() spawn.WIMP()
for (let j = 0, len = 1 + 2 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) for (let j = 0, len = 1 + 2 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
@@ -1099,21 +1100,18 @@ const level = {
// spawn.starter(1900, -500, 200) //big boy // spawn.starter(1900, -500, 200) //big boy
// spawn.grower(1900, -500) // spawn.grower(1900, -500)
// spawn.pulsarBoss(1900, -500) // spawn.pulsarBoss(1900, -500)
// spawn.shooterBoss(1900, -500) spawn.shooterBoss(1900, -500)
// spawn.launcherBoss(1200, -500) // spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500) // spawn.striker(1600, -500)
// spawn.laserTargetingBoss(1700, -120) // spawn.laserTargetingBoss(1700, -120)
// spawn.bomberBoss(1400, -500) // spawn.bomberBoss(1400, -500)
spawn.ghoster(1800, -120) // spawn.ghoster(1800, -120)
spawn.ghoster(1800, -120)
spawn.ghoster(1800, -120)
spawn.ghoster(1800, -120)
// spawn.streamBoss(1600, -500) // spawn.streamBoss(1600, -500)
// spawn.orbitalBoss(1600, -500) // spawn.orbitalBoss(1600, -500)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
// spawn.shieldingBoss(1600, -500) // spawn.shieldingBoss(1600, -500)
// spawn.beamer(1200, -500) spawn.laser(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "pulsar") // spawn.nodeGroup(1200, -500, "pulsar")
@@ -4721,9 +4719,9 @@ const level = {
} }
//Boss Spawning //Boss Spawning
if (simulation.difficulty > 20) { if (simulation.difficulty > 10) {
spawn.pulsarBoss(-400, -200); spawn.pulsarBoss(-400, -200);
if (simulation.difficulty > 40) { if (simulation.difficulty > 30) {
spawn.pulsarBoss(3600, -400); spawn.pulsarBoss(3600, -400);
if (simulation.difficulty > 60) { if (simulation.difficulty > 60) {
spawn.pulsarBoss(4200, 1000); spawn.pulsarBoss(4200, 1000);

View File

@@ -513,6 +513,7 @@ const m = {
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
if (tech.isHarmMACHO) dmg *= 0.33
if (tech.isImmortal) dmg *= 0.79 if (tech.isImmortal) dmg *= 0.79
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.50 : 1.1 if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.50 : 1.1
if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
@@ -1355,6 +1356,7 @@ const m = {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if ( if (
Vector.magnitude(Vector.sub(mob[i].position, player.position)) - mob[i].radius < m.fieldRange && Vector.magnitude(Vector.sub(mob[i].position, player.position)) - mob[i].radius < m.fieldRange &&
!mob[i].isShielded &&
m.lookingAt(mob[i]) && m.lookingAt(mob[i]) &&
Matter.Query.ray(map, mob[i].position, m.pos).length === 0 Matter.Query.ray(map, mob[i].position, m.pos).length === 0
) { ) {
@@ -1365,7 +1367,11 @@ const m = {
}, },
pushMobs360(range) { // find mobs in range in any direction pushMobs360(range) { // find mobs in range in any direction
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range && Matter.Query.ray(map, mob[i].position, m.pos).length === 0) { if (
Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range &&
!mob[i].isShielded &&
Matter.Query.ray(map, mob[i].position, m.pos).length === 0
) {
mob[i].locatePlayer(); mob[i].locatePlayer();
m.pushMass(mob[i]); m.pushMass(mob[i]);
} }
@@ -1629,7 +1635,7 @@ const m = {
if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) {
if (tech.isSporeField) { if (tech.isSporeField) {
for (let i = 0; i < 30; i++) { for (let i = 0; i < 30; i++) {
m.energy -= 0.11 m.energy -= 0.088
if (m.energy > 0) { if (m.energy > 0) {
b.spore(m.pos) b.spore(m.pos)
} else { } else {
@@ -1638,10 +1644,10 @@ const m = {
} }
} }
} else if (tech.isMissileField) { } else if (tech.isMissileField) {
m.energy -= 0.4; m.energy -= 0.32;
b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
} else if (tech.isIceField) { } else if (tech.isIceField) {
m.energy -= 0.057; m.energy -= 0.046;
b.iceIX(1) b.iceIX(1)
} else { } else {
m.energy -= 0.45 * tech.droneEnergyReduction; m.energy -= 0.45 * tech.droneEnergyReduction;

View File

@@ -8,15 +8,20 @@ const powerUps = {
if (tech.duplicationChance() > 0) { if (tech.duplicationChance() > 0) {
if (tech.isPowerUpsVanish) { if (tech.isPowerUpsVanish) {
powerUps.do = powerUps.doDuplicatesVanish powerUps.do = powerUps.doDuplicatesVanish
} else if (tech.isPowerUpsAttract) {
powerUps.do = powerUps.doAttractDuplicates
} else { } else {
powerUps.do = powerUps.doDuplicates powerUps.do = powerUps.doDuplicates
} }
tech.maxDuplicationEvent() //check to see if hitting 100% duplication tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else if (tech.isPowerUpsAttract) {
powerUps.do = powerUps.doAttract
} else { } else {
powerUps.do = powerUps.doDefault powerUps.do = powerUps.doDefault
} }
}, },
doDefault() { //draw power ups doDefault() {
//draw power ups
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6; ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath(); ctx.beginPath();
@@ -26,6 +31,19 @@ const powerUps = {
} }
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
}, },
doAttract() {
powerUps.doDefault();
//pull in
for (let i = 0, len = powerUp.length; i < len; ++i) {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.0015 * powerUp[i].mass)
powerUp[i].force.x += force.x
powerUp[i].force.y = force.y - simulation.g
}
},
doAttractDuplicates() {
powerUps.doDuplicates();
//pull in
},
doDuplicates() { //draw power ups but give duplicates some electricity doDuplicates() { //draw power ups but give duplicates some electricity
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6; ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
@@ -593,7 +611,7 @@ const powerUps = {
}, },
onPickUp(who) { onPickUp(who) {
if (tech.isTechDamage && who.name === "tech") m.damage(0.11) if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
if (tech.isMassEnergy) m.energy += 2.5; if (tech.isMassEnergy) m.energy += 2;
if (tech.isMineDrop) { if (tech.isMineDrop) {
if (tech.isLaserMine) { if (tech.isLaserMine) {
b.laserMine(who.position) b.laserMine(who.position)

View File

@@ -89,9 +89,8 @@ const spawn = {
}, },
//mob templates ********************************************************************************************* //mob templates *********************************************************************************************
//*********************************************************************************************************** //***********************************************************************************************************
WIMP(x = level.exit.x + 300 * (Math.random() - 0.5), y = level.exit.y + 300 * (Math.random() - 0.5), radius = 75 + 25 * Math.random()) { //immortal mob that follows player MACHO(x = m.pos.x, y = m.pos.y) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the player
//if you have the tech it spawns at start of every level at the exit mobs.spawn(x, y, 3, 0.1, "transparent");
mobs.spawn(x, y, 3, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.stroke = "transparent" me.stroke = "transparent"
me.isShielded = true; //makes it immune to damage me.isShielded = true; //makes it immune to damage
@@ -99,6 +98,63 @@ const spawn = {
me.isBadTarget = true; me.isBadTarget = true;
me.isDropPowerUp = false; me.isDropPowerUp = false;
me.showHealthBar = false; me.showHealthBar = false;
me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 3.3
me.isMACHO = true;
me.frictionAir = 0.006
me.do = function() {
const sine = Math.sin(simulation.cycle * 0.015)
this.radius = 370 * (1 + 0.1 * sine)
//chase player
const sub = Vector.sub(player.position, this.position)
const mag = Vector.magnitude(sub)
// follow physics
// Matter.Body.setVelocity(this, { x: 0, y: 0 });
// const where = Vector.add(this.position, Vector.mult(Vector.normalise(sub), this.chaseSpeed))
// if (mag > 10) Matter.Body.setPosition(this, { x: where.x, y: where.y });
//realistic physics
const force = Vector.mult(Vector.normalise(sub), 0.000000003)
this.force.x += force.x
this.force.y += force.y
if (mag < this.radius) { //buff to player when inside radius
tech.isHarmMACHO = true;
//draw halo
ctx.strokeStyle = "rgba(80,120,200,0.2)" //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 36, 0, 2 * Math.PI);
ctx.lineWidth = 10;
ctx.stroke();
// ctx.strokeStyle = "rgba(255,255,0,0.17)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
// ctx.beginPath();
// ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
// ctx.lineWidth = 30;
// ctx.stroke();
} else {
tech.isHarmMACHO = false;
}
//draw outline
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius + 15, 0, 2 * Math.PI);
ctx.strokeStyle = "#000"
ctx.lineWidth = 1;
ctx.stroke();
}
},
WIMP(x = level.exit.x + 300 * (Math.random() - 0.5), y = level.exit.y + 300 * (Math.random() - 0.5)) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the exit
mobs.spawn(x, y, 3, 0.1, "transparent");
let me = mob[mob.length - 1];
me.stroke = "transparent"
me.isShielded = true; //makes it immune to damage
me.leaveBody = false;
me.isBadTarget = true;
me.isDropPowerUp = false;
me.showHealthBar = false;
me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 1 + 1.5 * Math.random() me.chaseSpeed = 1 + 1.5 * Math.random()
@@ -120,7 +176,7 @@ const spawn = {
m.energy -= DRAIN m.energy -= DRAIN
} else { } else {
m.energy = 0; m.energy = 0;
m.damage(0.007) m.damage(0.007 * simulation.dmgScale)
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, y: this.position.y,
@@ -147,7 +203,7 @@ const spawn = {
// } // }
// } // }
//draw some flashy graphics //draw
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
// ctx.fillStyle = "hsla(160, 100%, 35%,0.75)" //"rgba(255,0,255,0.2)"; // ctx.fillStyle = "hsla(160, 100%, 35%,0.75)" //"rgba(255,0,255,0.2)";

View File

@@ -329,9 +329,9 @@
isNonRefundable: true, isNonRefundable: true,
// isExperimentHide: true, // isExperimentHide: true,
allowed() { allowed() {
return b.inventory.length > 2 return b.inventory.length > 3
}, },
requires: "at least 3 guns", requires: "at least 4 guns",
effect() { effect() {
for (let i = 0; i < b.inventory.length; i++) { for (let i = 0; i < b.inventory.length; i++) {
if (Math.random() < 0.2) { if (Math.random() < 0.2) {
@@ -388,7 +388,7 @@
}, },
{ {
name: "catabolism", name: "catabolism",
description: "when you <strong>fire</strong> while <strong>out</strong> of <strong class='color-g'>ammo</strong><br>gain <strong>4</strong> <strong class='color-g'>ammo</strong>, but lose <strong>5</strong> <strong class='color-h'>health</strong>", description: "when you <strong>fire</strong> while <strong>out</strong> of <strong class='color-g'>ammo</strong><br>gain <strong>4</strong> <strong class='color-g'>ammo</strong>, but lose <strong>3</strong> <strong class='color-h'>health</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -1237,7 +1237,7 @@
effect() { effect() {
tech.isOrbitBotUpgrade = true tech.isOrbitBotUpgrade = true
b.convertBotsTo("orbital-bot") b.convertBotsTo("orbital-bot")
const range = 190 + 60 * tech.isOrbitBotUpgrade const range = 190 + 100 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') { if (bullet[i].botType === 'orbit') {
bullet[i].isUpgraded = true bullet[i].isUpgraded = true
@@ -1249,7 +1249,7 @@
}, },
remove() { remove() {
tech.isOrbitBotUpgrade = false tech.isOrbitBotUpgrade = false
const range = 190 + 60 * tech.isOrbitBotUpgrade const range = 190 + 100 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') { if (bullet[i].botType === 'orbit') {
bullet[i].range = range bullet[i].range = range
@@ -1337,7 +1337,7 @@
allowed() { allowed() {
return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection
}, },
requires: "at least 2 bots, 1 research", requires: "at least 2 bots",
effect: () => { effect: () => {
if (powerUps.research.count > 0) { if (powerUps.research.count > 0) {
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
@@ -1489,9 +1489,9 @@
count: 0, count: 0,
frequency: 2, frequency: 2,
allowed() { allowed() {
return tech.throwChargeRate > 1 return tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
}, },
requires: "mass driver", requires: "mass driver or pilot wave",
effect() { effect() {
tech.isBlockBullets = true tech.isBlockBullets = true
}, },
@@ -1519,15 +1519,15 @@
}, },
{ {
name: "restitution", name: "restitution",
description: "if a <strong class='color-block'>block</strong> you threw kills a mob<br>spawn <strong>2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>", description: "if a <strong class='color-block'>block</strong> you threw kills a mob<br>spawn <strong>1</strong> <strong class='color-h'>heal</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && !tech.isNoHeals && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave"
}, },
requires: "mass driver, not ergodicity, pilot wave", requires: "mass driver, not pilot wave",
effect() { effect() {
tech.isBlockPowerUps = true tech.isBlockPowerUps = true
}, },
@@ -2719,7 +2719,7 @@
{ {
name: "WIMPs", name: "WIMPs",
//<strong class='color-harm'>harmful</strong> //<strong class='color-harm'>harmful</strong>
description: "a weak massive particle slowly <strong>chases</strong> you<br>spawn <strong>2-3</strong> <strong class='color-r'>research</strong> at the end of each <strong>level</strong>", description: "a <strong class='color-harm'>harmful</strong> particle slowly <strong>chases</strong> you<br>spawn <strong>2-3</strong> <strong class='color-r'>research</strong> at the end of each <strong>level</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2735,6 +2735,28 @@
tech.wimpCount = 0 tech.wimpCount = 0
} }
}, },
{
name: "MACHO",
description: "a massive but compact object slowly <strong>follows</strong> you<br>take <strong>66%</strong> less <strong class='color-harm'>harm</strong> inside it's <strong>halo</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
},
requires: "",
effect: () => {
tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO
spawn.MACHO()
},
remove() {
tech.isMACHO = false;
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isMACHO) mob[i].alive = false;
}
}
},
{ {
name: "bubble fusion", name: "bubble fusion",
description: "after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>", description: "after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
@@ -2833,6 +2855,26 @@
powerUps.setDo(); //needed after adjusting duplication chance powerUps.setDo(); //needed after adjusting duplication chance
} }
}, },
// {
// name: "attract",
// description: "",
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// allowed() {
// return true
// },
// requires: "",
// effect: () => {
// tech.isPowerUpsAttract = true
// powerUps.setDo(); //needed after adjusting duplication chance
// },
// remove() {
// tech.isPowerUpsAttract = false
// powerUps.setDo(); //needed after adjusting duplication chance
// }
// },
{ {
name: "futures exchange", name: "futures exchange",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.3%</strong> power up <strong class='color-dup'>duplication</strong> chance", description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.3%</strong> power up <strong class='color-dup'>duplication</strong> chance",
@@ -4606,7 +4648,7 @@
}, },
{ {
name: "flux pinning", name: "flux pinning",
description: "<strong>deflecting</strong> with your <strong>field</strong><br><strong>stuns</strong> mobs for <strong>+2</strong> second", description: "<strong>deflecting</strong> mobs with your <strong>field</strong><br><strong>stuns</strong> them for <strong>2</strong> seconds",
isFieldTech: true, isFieldTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -4642,7 +4684,7 @@
}, },
{ {
name: "bot manufacturing", name: "bot manufacturing",
description: "use <strong>nano-scale manufacturing</strong><br>to build <strong>2</strong> random <strong class='color-bot'>bots</strong>", description: "use <strong>nano-scale manufacturing</strong> and <strong>2</strong> <strong class='color-r'>research</strong><br>to build <strong>3</strong> random <strong class='color-bot'>bots</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4652,10 +4694,13 @@
isNonRefundable: true, isNonRefundable: true,
// isExperimentHide: true, // isExperimentHide: true,
allowed() { allowed() {
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" return powerUps.research.count > 1 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing"
}, },
requires: "nano-scale manufacturing", requires: "nano-scale manufacturing",
effect: () => { effect: () => {
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
m.energy = 0.01; m.energy = 0.01;
b.randomBot() b.randomBot()
b.randomBot() b.randomBot()
@@ -4664,8 +4709,8 @@
remove() {} remove() {}
}, },
{ {
name: "bot prototype", name: "bot prototypes",
description: "use <strong>nano-scale manufacturing</strong> to build<br>a random <strong class='color-bot'>bot</strong> and <strong>upgrade</strong> all <strong class='color-bot'>bots</strong> to that type", description: "use <strong>nano-scale</strong> and <strong>3</strong> <strong class='color-r'>research</strong> to build<br><strong>2</strong> random <strong class='color-bot'>bots</strong> and <strong>upgrade</strong> all <strong class='color-bot'>bots</strong> to that type",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4675,14 +4720,17 @@
isNonRefundable: true, isNonRefundable: true,
// isExperimentHide: true, // isExperimentHide: true,
allowed() { allowed() {
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" return powerUps.research.count > 2 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing"
}, },
requires: "nano-scale manufacturing", requires: "nano-scale manufacturing",
effect: () => { effect: () => {
m.energy = 0.01; for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
//fill array of available bots //fill array of available bots
const notUpgradedBots = [] const notUpgradedBots = []
const num = 1 const num = 2
notUpgradedBots.push(() => { notUpgradedBots.push(() => {
tech.giveTech("nail-bot upgrade") tech.giveTech("nail-bot upgrade")
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
@@ -4733,14 +4781,82 @@
simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`) simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`)
}) })
} }
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it
}, },
remove() {} remove() {}
}, },
{
name: "mycelium manufacturing",
description: "use <strong>3</strong> <strong class='color-r'>research</strong> to repurpose <strong>nano-scale</strong><br>excess <strong class='color-f'>energy</strong> used to grow <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
if (!build.isExperimentSelection) {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}
tech.isSporeField = true;
},
remove() {
tech.isSporeField = false;
}
},
{
name: "missile manufacturing",
description: "use <strong>3</strong> <strong class='color-r'>research</strong> to repurpose <strong>nano-scale</strong><br>excess <strong class='color-f'>energy</strong> used to construct <strong>missiles</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return (build.isExperimentSelection || powerUps.research.count > 2) && m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
if (!build.isExperimentSelection) {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}
tech.isMissileField = true;
},
remove() {
tech.isMissileField = false;
}
},
{
name: "ice IX manufacturing",
description: "use <strong>3</strong> <strong class='color-r'>research</strong> to repurpose <strong>nano-scale</strong><br>excess <strong class='color-f'>energy</strong> used to condense <strong class='color-s'>ice IX</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return (build.isExperimentSelection || powerUps.research.count > 2) && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
if (!build.isExperimentSelection) {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}
tech.isIceField = true;
},
remove() {
tech.isIceField = false;
}
},
{ {
name: "pair production", name: "pair production",
description: "picking up a <strong>power up</strong> gives you <strong>250</strong> <strong class='color-f'>energy</strong>", description: "picking up a <strong>power up</strong> gives you <strong>200</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4751,66 +4867,12 @@
requires: "nano-scale manufacturing", requires: "nano-scale manufacturing",
effect: () => { effect: () => {
tech.isMassEnergy = true // used in m.grabPowerUp tech.isMassEnergy = true // used in m.grabPowerUp
m.energy += 3 m.energy += 2
}, },
remove() { remove() {
tech.isMassEnergy = false; tech.isMassEnergy = false;
} }
}, },
{
name: "mycelium manufacturing",
description: "<strong>nano-scale manufacturing</strong> is repurposed<br>excess <strong class='color-f'>energy</strong> used to grow <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
tech.isSporeField = true;
},
remove() {
tech.isSporeField = false;
}
},
{
name: "missile manufacturing",
description: "<strong>nano-scale manufacturing</strong> is repurposed<br>excess <strong class='color-f'>energy</strong> used to construct <strong>missiles</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return m.maxEnergy > 0.5 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
tech.isMissileField = true;
},
remove() {
tech.isMissileField = false;
}
},
{
name: "ice IX manufacturing",
description: "<strong>nano-scale manufacturing</strong> is repurposed<br>excess <strong class='color-f'>energy</strong> used to condense <strong class='color-s'>ice IX</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab)
},
requires: "nano-scale manufacturing, no other manufacturing",
effect() {
tech.isIceField = true;
},
remove() {
tech.isIceField = false;
}
},
{ {
name: "degenerate matter", name: "degenerate matter",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> is active", description: "reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> is active",
@@ -6717,5 +6779,7 @@
iceIXOnDeath: null, iceIXOnDeath: null,
wimpCount: null, wimpCount: null,
isBlockBullets: null, isBlockBullets: null,
isAddBlockMass: null isAddBlockMass: null,
isMACHO: null,
isHarmMACHO: null
} }

View File

@@ -1,16 +1,16 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
"block" is now styled text tech: MACHO - an object follows you and gives you harm protection when you are inside it's halo
blocking with a shield is now called deflecting
added 100% block damage buffs to flywheel and inelastic collision several nano-scale field tech now require some research, and have been buffed
restitution now spawns 2 power ups (up from 1) nano-scale mycelium, ice-IX, missile tech now consume 20% less energy to produce bullets
nano-scale bot tech: spawn an extra bots
about 75 edits to tech requirement text some bug fixes
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
Why does micro-extruder lag so much anyway Why does micro-extruder lag so much
blue triangle boss can move backwards and aim away from you if set up properly blue triangle boss can move backwards and aim away from you if set up properly
@@ -52,35 +52,34 @@ is there a way to check if the player is stuck inside the map or block
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
full block build works for every level except final boss make nano-scale upgrades all cost research, and buff those tech
block custom css style? make most future tech for guns / fields
tech: pilot wave is projected from the player, not the mouse tech: mine - fire the mine into where you were in the past
maybe also make field move slower? (adjust smoothing function) maybe it could check all your past locations and explode there if there is something in range
less energy drain?
does damage to mobs caught in field?
tech: wormhole through walls tech: increase health and harm taken
pause should show the last in game console message remove air control
negative tech, junk , experiment?
Make ice crystal + rivet gun/needle gun launch freezing rivets/needles with increased energy drain use name axion as a 3rd dark matter tech
WIMPS are cool, but the 2-3 research isn't enough incentive?
tech: MACHO - spawn a mob like WIMP that follows you and gives you a bonus
if it touches WIMP they explode
let the player use research more like money
spend it to do things
buff some special tech and add a research cost
tech: use the ability for power ups to have custom code tech: use the ability for power ups to have custom code
(note: this code is half way done, it just needs to be completed)
attracted to player attracted to player
attracted to other power ups attracted to other power ups
explode if they touch? explode if they touch?
tech: wormhole through walls?
pause should show the last in game console message
general idea: let the player use research more like money
spend it to do things
buff some special tech and add a research cost
tech: picking up heal power ups when at full health does harm equal to the heal values tech: picking up heal power ups when at full health does harm equal to the heal values
benefit on pick up: benefit on pick up:
get ammo get ammo