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

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`);
m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth) {
if (m.health > 0.05) {
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
if (m.health > 0.03) {
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
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",
collisionFilter: {
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() {},
onEnd() {},
@@ -2641,7 +2641,7 @@ const b = {
classType: "bullet",
collisionFilter: {
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() {},
onEnd() {},
@@ -2696,7 +2696,7 @@ const b = {
classType: "bullet",
collisionFilter: {
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() {},
onEnd() {},
@@ -2757,7 +2757,7 @@ const b = {
classType: "bullet",
collisionFilter: {
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,
beforeDmg() {
@@ -2838,7 +2838,7 @@ const b = {
classType: "bullet",
collisionFilter: {
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,
explode: 0,
@@ -2922,7 +2922,7 @@ const b = {
classType: "bullet",
collisionFilter: {
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,
beforeDmg() {

View File

@@ -197,7 +197,7 @@ function collisionChecks(event) {
} else if (Math.random() < 0.4 && !tech.isSuperDeterminism) {
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)

View File

@@ -18,13 +18,14 @@ const level = {
// m.setField("pilot wave")
// b.giveGuns("laser")
// tech.isExplodeRadio = true
// tech.giveTech("fermions")
// tech.giveTech("WIMPs")
// tech.giveTech("MACHO")
// tech.giveTech("potential well")
// 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("bound state")
// for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
// tech.giveTech("metastability")
// tech.giveTech("attract")
level.intro(); //starting level
@@ -109,7 +110,7 @@ const level = {
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);
}
if (tech.isMACHO) spawn.MACHO()
for (let i = 0; i < tech.wimpCount; i++) {
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)
@@ -1099,21 +1100,18 @@ const level = {
// spawn.starter(1900, -500, 200) //big boy
// spawn.grower(1900, -500)
// spawn.pulsarBoss(1900, -500)
// spawn.shooterBoss(1900, -500)
spawn.shooterBoss(1900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500)
// spawn.laserTargetingBoss(1700, -120)
// 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.orbitalBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.shieldingBoss(1600, -500)
// spawn.beamer(1200, -500)
spawn.laser(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "pulsar")
@@ -4721,9 +4719,9 @@ const level = {
}
//Boss Spawning
if (simulation.difficulty > 20) {
if (simulation.difficulty > 10) {
spawn.pulsarBoss(-400, -200);
if (simulation.difficulty > 40) {
if (simulation.difficulty > 30) {
spawn.pulsarBoss(3600, -400);
if (simulation.difficulty > 60) {
spawn.pulsarBoss(4200, 1000);

View File

@@ -513,6 +513,7 @@ const m = {
harmReduction() {
let dmg = 1
dmg *= m.fieldHarmReduction
if (tech.isHarmMACHO) dmg *= 0.33
if (tech.isImmortal) dmg *= 0.79
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
@@ -1355,6 +1356,7 @@ const m = {
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Vector.magnitude(Vector.sub(mob[i].position, player.position)) - mob[i].radius < m.fieldRange &&
!mob[i].isShielded &&
m.lookingAt(mob[i]) &&
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
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();
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 (tech.isSporeField) {
for (let i = 0; i < 30; i++) {
m.energy -= 0.11
m.energy -= 0.088
if (m.energy > 0) {
b.spore(m.pos)
} else {
@@ -1638,10 +1644,10 @@ const m = {
}
}
} 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)
} else if (tech.isIceField) {
m.energy -= 0.057;
m.energy -= 0.046;
b.iceIX(1)
} else {
m.energy -= 0.45 * tech.droneEnergyReduction;

View File

@@ -8,15 +8,20 @@ const powerUps = {
if (tech.duplicationChance() > 0) {
if (tech.isPowerUpsVanish) {
powerUps.do = powerUps.doDuplicatesVanish
} else if (tech.isPowerUpsAttract) {
powerUps.do = powerUps.doAttractDuplicates
} else {
powerUps.do = powerUps.doDuplicates
}
tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else if (tech.isPowerUpsAttract) {
powerUps.do = powerUps.doAttract
} else {
powerUps.do = powerUps.doDefault
}
},
doDefault() { //draw power ups
doDefault() {
//draw power ups
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
@@ -26,6 +31,19 @@ const powerUps = {
}
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
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
@@ -593,7 +611,7 @@ const powerUps = {
},
onPickUp(who) {
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.isLaserMine) {
b.laserMine(who.position)

View File

@@ -89,9 +89,8 @@ const spawn = {
},
//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
//if you have the tech it spawns at start of every level at the exit
mobs.spawn(x, y, 3, radius, "transparent");
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
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
@@ -99,6 +98,63 @@ const spawn = {
me.isBadTarget = true;
me.isDropPowerUp = 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.chaseSpeed = 1 + 1.5 * Math.random()
@@ -120,7 +176,7 @@ const spawn = {
m.energy -= DRAIN
} else {
m.energy = 0;
m.damage(0.007)
m.damage(0.007 * simulation.dmgScale)
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
@@ -147,7 +203,7 @@ const spawn = {
// }
// }
//draw some flashy graphics
//draw
ctx.beginPath();
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)";

View File

@@ -329,9 +329,9 @@
isNonRefundable: true,
// isExperimentHide: true,
allowed() {
return b.inventory.length > 2
return b.inventory.length > 3
},
requires: "at least 3 guns",
requires: "at least 4 guns",
effect() {
for (let i = 0; i < b.inventory.length; i++) {
if (Math.random() < 0.2) {
@@ -388,7 +388,7 @@
},
{
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,
count: 0,
frequency: 2,
@@ -1237,7 +1237,7 @@
effect() {
tech.isOrbitBotUpgrade = true
b.convertBotsTo("orbital-bot")
const range = 190 + 60 * tech.isOrbitBotUpgrade
const range = 190 + 100 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
bullet[i].isUpgraded = true
@@ -1249,7 +1249,7 @@
},
remove() {
tech.isOrbitBotUpgrade = false
const range = 190 + 60 * tech.isOrbitBotUpgrade
const range = 190 + 100 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
bullet[i].range = range
@@ -1329,7 +1329,7 @@
},
{
name: "robotics",
description: "use <strong>1</strong> <strong class='color-r'>research</strong> to spawn a random <strong>bot</strong><br><strong>quadruple</strong> the <strong class='flicker'>frequency</strong> of finding <strong>bot</strong> <strong class='color-m'>tech</strong>",
description: "use <strong>1</strong> <strong class='color-r'>research</strong> to spawn a random <strong>bot</strong><br><strong>quadruple</strong> the <strong class='flicker'>frequency</strong> of finding <strong>bot</strong> <strong class='color-m'>tech</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -1337,7 +1337,7 @@
allowed() {
return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection
},
requires: "at least 2 bots, 1 research",
requires: "at least 2 bots",
effect: () => {
if (powerUps.research.count > 0) {
powerUps.research.changeRerolls(-1)
@@ -1489,9 +1489,9 @@
count: 0,
frequency: 2,
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() {
tech.isBlockBullets = true
},
@@ -1519,15 +1519,15 @@
},
{
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,
count: 0,
frequency: 3,
frequencyDefault: 3,
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() {
tech.isBlockPowerUps = true
},
@@ -2719,7 +2719,7 @@
{
name: "WIMPs",
//<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,
count: 0,
frequency: 1,
@@ -2735,6 +2735,28 @@
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",
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
}
},
// {
// 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",
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",
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,
maxCount: 9,
count: 0,
@@ -4642,7 +4684,7 @@
},
{
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,
maxCount: 1,
count: 0,
@@ -4652,10 +4694,13 @@
isNonRefundable: true,
// isExperimentHide: true,
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",
effect: () => {
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
m.energy = 0.01;
b.randomBot()
b.randomBot()
@@ -4664,8 +4709,8 @@
remove() {}
},
{
name: "bot prototype",
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",
name: "bot prototypes",
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,
maxCount: 1,
count: 0,
@@ -4675,14 +4720,17 @@
isNonRefundable: true,
// isExperimentHide: true,
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",
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
const notUpgradedBots = []
const num = 1
const num = 2
notUpgradedBots.push(() => {
tech.giveTech("nail-bot upgrade")
for (let i = 0; i < num; i++) {
@@ -4733,14 +4781,82 @@
simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`)
})
}
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it
},
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",
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,
maxCount: 1,
count: 0,
@@ -4751,66 +4867,12 @@
requires: "nano-scale manufacturing",
effect: () => {
tech.isMassEnergy = true // used in m.grabPowerUp
m.energy += 3
m.energy += 2
},
remove() {
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",
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,
wimpCount: null,
isBlockBullets: null,
isAddBlockMass: null
isAddBlockMass: null,
isMACHO: null,
isHarmMACHO: null
}