quantum foam

all mobs that move through walls and blocks now have a transparent fill
player and power ups float in hazards

tech: apomixis - after reaching 100% duplication spawn 4 level bosses
tech: quantum foam - +153% foam damage, fire 0.35s into the future
bullets are bigger, and  easier to see
This commit is contained in:
landgreen
2021-02-12 06:02:34 -08:00
parent 045039171e
commit 5aa7233bc8
9 changed files with 254 additions and 103 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -3017,7 +3017,7 @@ const b = {
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
},
fireNeedles() {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 35 : 20) * b.fireCD); // cool down
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 33 : 16) * b.fireCD); // cool down
function makeNeedle(angle = m.angle) {
const me = bullet.length;
@@ -3047,7 +3047,7 @@ const b = {
if (tech.isNailRadiation) {
mobs.statusDoT(who, tech.isFastRadiation ? 8 : 2, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
} else {
let dmg = b.dmgScale * 3
let dmg = b.dmgScale * 3.25
if (tech.isCrit && who.isStunned) dmg *= 4
who.damage(dmg, tech.isNeedleShieldPierce);
simulation.drawList.push({ //add dmg to draw queue
@@ -3173,6 +3173,32 @@ const b = {
defaultAmmoPack: 5.5,
have: false,
fire() {
// if (true) {
// const direction = {
// x: Math.cos(m.angle),
// y: Math.sin(m.angle)
// }
// for (let i = 0; i < 2; i++) {
// const push = Vector.mult(Vector.perp(direction), 0.08)
// const where = {
// x: m.pos.x + 40 * direction.x,
// y: m.pos.y + 40 * direction.y
// }
// b.missile(where, m.angle, 0, 0.5) //where, angle, speed, size = 1)
// // bullet[bullet.length - 1].force.x += push.x;
// // bullet[bullet.length - 1].force.y += push.y;
// }
// }
// setTimeout(() => {
// if (!simulation.paused) {
// b.foam(position, velocity, radius)
// bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
// }
// }, 350 * tech.foamFutureFire);
let knock, spread
if (m.crouch) {
spread = 0.75
@@ -3832,6 +3858,35 @@ const b = {
ammoPack: 36,
have: false,
fire() {
if (tech.foamFutureFire) {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down
const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = 18 - radius * 0.4;
const dir = m.angle + 0.2 * (Math.random() - 0.5)
const velocity = {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
}
const position = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
simulation.drawList.push({ //add dmg to draw queue
x: position.x,
y: position.y,
radius: 5,
color: "rgba(0,0,0,0.1)",
time: 21 * tech.foamFutureFire
});
setTimeout(() => {
if (!simulation.paused) {
b.foam(position, velocity, radius)
bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
}
}, 350 * tech.foamFutureFire);
} else {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down
const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = 18 - radius * 0.4;
@@ -3846,6 +3901,7 @@ const b = {
}
b.foam(position, velocity, radius)
}
}
},
{
name: "rail gun",

View File

@@ -760,7 +760,7 @@ const level = {
mapB.portalPair = mapA
return [portalA, portalB, mapA, mapB]
},
hazard(x, y, width, height, damage = 0.0005, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) {
hazard(x, y, width, height, damage = 0.0008, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) {
return {
min: {
x: x,
@@ -791,6 +791,29 @@ const level = {
}
const drain = 0.005
if (m.energy > drain) m.energy -= drain
//float
if (!isOptical) {
if (player.velocity.y > 3) player.force.y -= 0.96 * player.mass * simulation.g
const slowY = (player.velocity.y > 0) ? Math.max(0.3, 1 - 0.0015 * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - 0.001 * Math.abs(player.velocity.y)) //down : up
Matter.Body.setVelocity(player, {
x: Math.max(0.6, 1 - 0.07 * Math.abs(player.velocity.x)) * player.velocity.x,
y: slowY * player.velocity.y
});
}
}
//float power ups
if (!isOptical) {
powerUpCollide = Matter.Query.region(powerUp, this)
for (let i = 0, len = powerUpCollide.length; i < len; i++) {
const diameter = 2 * powerUpCollide[i].size
const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter
powerUpCollide[i].force.y -= buoyancy * 1.1 * powerUpCollide[i].mass * simulation.g;
Matter.Body.setVelocity(powerUpCollide[i], {
x: powerUpCollide[i].velocity.x,
y: 0.95 * powerUpCollide[i].velocity.y
});
}
}
},
draw() {
@@ -1054,18 +1077,19 @@ const level = {
// spawn.boost(1500, 0, 900);
// spawn.starter(1900, -500, 200) //big boy
spawn.starter(1900, -500)
// spawn.starter(1900, -500)
// spawn.historyBoss(1900, -500)
// spawn.sneaker(2900, -500)
// spawn.ghoster(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500)
// spawn.shooter(1700, -120)
// spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500)
// spawn.cellBossCulture(1600, -500)
spawn.sniper(1800, -120)
// spawn.streamBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.bomberBoss(1600, -500)
// spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
@@ -1139,8 +1163,10 @@ const level = {
powerUps.spawn(1675, -50, "ammo");
powerUps.spawn(3350, -75, "ammo");
powerUps.spawn(3925, -50, "ammo");
powerUps.spawn(4250, -75, "ammo");
powerUps.spawn(4550, -75, "ammo");
powerUps.spawn(5025, -50, "ammo");
powerUps.spawn(4725, -50, "ammo");
powerUps.spawn(4975, -350, "ammo");
powerUps.spawn(5125, -350, "ammo");
powerUps.spawn(5075, -425, "ammo");

View File

@@ -874,7 +874,7 @@ const mobs = {
Matter.Query.ray(map, this.position, this.mPosRange()).length === 0 && //see player
Matter.Query.ray(body, this.position, this.mPosRange()).length === 0
) {
spawn.bomb(this.position.x, this.position.y + this.radius * 0.5, 10 + Math.ceil(this.radius / 15), 5);
spawn.bomb(this.position.x, this.position.y + this.radius * 0.7, 9 + Math.ceil(this.radius / 15), 5);
//add spin and speed
Matter.Body.setAngularVelocity(mob[mob.length - 1], (Math.random() - 0.5) * 0.5);
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -909,7 +909,7 @@ const mobs = {
this.torque -= 0.000004 * this.inertia;
} else if (this.noseLength > 1.5) {
//fire
spawn.bullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5);
spawn.bullet(this.vertices[1].x, this.vertices[1].y, 9 + Math.ceil(this.radius / 15));
const v = 15;
Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + this.fireDir.x * v + 3 * Math.random(),

View File

@@ -497,7 +497,7 @@ const m = {
harmReduction() {
let dmg = 1
dmg *= m.fieldHarmReduction
if (tech.isBlockHarm && m.isHolding) dmg *= 0.4
if (tech.isBlockHarm && m.isHolding) dmg *= 0.25
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (tech.isSlowFPS) dmg *= 0.8
@@ -506,7 +506,7 @@ const m = {
if (tech.isBotArmor) dmg *= 0.96 ** tech.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.6
if (tech.energyRegen === 0) dmg *= 0.4
if (tech.energyRegen === 0) dmg *= 0.34
if (tech.isTurret && m.crouch) dmg *= 0.5;
if (tech.isFireMoveLock && input.fire) dmg *= 0.4;
if (tech.isEntanglement && b.inventory[0] === b.activeGun) {

View File

@@ -36,7 +36,10 @@ const powerUps = {
},
endDraft(type, isCanceled = false) {
if (isCanceled) {
if (tech.isCancelDuplication) tech.cancelCount++
if (tech.isCancelDuplication) {
tech.cancelCount++
tech.maxDuplicationEvent()
}
if (tech.isCancelRerolls) {
for (let i = 0; i < 8; i++) {
let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
@@ -174,7 +177,7 @@ const powerUps = {
if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) {
const target = b.guns[b.activeGun]
if (target.ammo !== Infinity) {
const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack)
const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(0.7 * Math.random() * target.ammoPack)
target.ammo += ammoAdded
simulation.makeTextLog(`${target.name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`)
}

View File

@@ -112,18 +112,23 @@ const spawn = {
} else {
//reset game
setTimeout(() => {
simulation.makeTextLog(`simulation.end()`);
simulation.makeTextLog(`simulation.complete()`);
let delay = 1000
for (let i = 20; i > 0; i--) {
for (let i = 0; i < 1.01; i += 0.01 + 0.1 * Math.random()) {
setTimeout(function() {
simulation.makeTextLog(`delay = ${i*1000}`);
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${(i).toFixed(3)}`);
}, delay);
delay += 1000
}
delay += 1000
setTimeout(function() {
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> 1`);
}, delay);
delay += 2000
setTimeout(() => {
if (!simulation.paused && !simulation.testing) {
simulation.makeTextLog(`World.clear(engine.world)`);
setTimeout(() => { m.death() }, 1000);
setTimeout(() => { m.death() }, 2000);
}
}, delay);
}, 5000);
}
@@ -514,22 +519,21 @@ const spawn = {
}
},
cellBoss(x, y, radius = 20, cellID) {
mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,150,155,0.7)");
mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,100,105,0)");
let me = mob[mob.length - 1];
me.stroke = "#099"
me.isBoss = true;
me.isCell = true;
me.cellID = cellID
me.accelMag = 0.00015 * simulation.accelScale;
me.accelMag = 0.00016 * simulation.accelScale;
me.memory = 40;
me.isVerticesChange = true
me.frictionAir = 0.012
me.seePlayerFreq = Math.floor(11 + 7 * Math.random())
me.seeAtDistance2 = 1400000;
me.cellMassMax = 70
me.collisionFilter.mask = cat.player | cat.bullet
Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
// console.log(me.mass, me.radius)
me.collisionFilter.mask = cat.player | cat.bullet //| cat.map | cat.body
Matter.Body.setDensity(me, 0.001) // normal density is 0.001 // this reduces life by half and decreases knockback
const k = 642 //k=r^2/m
me.split = function() {
Matter.Body.scale(this, 0.4, 0.4);
@@ -556,16 +560,16 @@ const spawn = {
this.radius = Math.sqrt(this.mass * k / Math.PI)
}
if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs
const repelRange = 200
const attractRange = 800
const repelRange = 150
const attractRange = 700
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isCell && mob[i].id !== this.id) {
const sub = Vector.sub(this.position, mob[i].position)
const dist = Vector.magnitude(sub)
if (dist < repelRange) {
this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.006)
this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002)
} else if (dist > attractRange) {
this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.004)
this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.003)
}
}
}
@@ -594,7 +598,7 @@ const spawn = {
me.frictionAir = 0.01
me.seeAtDistance2 = 1000000;
me.accelMag = 0.0005 * simulation.accelScale;
Matter.Body.setDensity(me, 0.0006); //normal is 0.001
Matter.Body.setDensity(me, 0.001); //normal is 0.001
me.collisionFilter.mask = cat.bullet | cat.player
me.memory = Infinity;
me.seePlayerFreq = 30
@@ -908,7 +912,7 @@ const spawn = {
me.collisionFilter.mask = cat.player | cat.bullet
// me.frictionAir = 0.005;
me.memory = 1600;
Matter.Body.setDensity(me, 0.05); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.075); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() {
//applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -1008,7 +1012,7 @@ const spawn = {
let targets = [] //track who is in the node boss, for shields
mobs.spawn(x, y, 6, radius, "#b386e8");
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
targets.push(me.id) //add to shield protection
me.friction = 0;
@@ -1510,7 +1514,7 @@ const spawn = {
me.count = 0;
me.frictionAir = 0.03;
// me.torque -= me.inertia * 0.002
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.05); //extra dense //normal is 0.001 //makes effective life much larger
// spawn.shield(me, x, y, 1); //not working, not sure why
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2023,7 +2027,7 @@ const spawn = {
if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002)
};
},
bullet(x, y, radius = 6, sides = 0) {
bullet(x, y, radius = 9, sides = 0) {
//bullets
mobs.spawn(x, y, sides, radius, "rgb(255,0,0)");
let me = mob[mob.length - 1];
@@ -2038,6 +2042,7 @@ const spawn = {
me.restitution = 0.8;
me.leaveBody = false;
me.dropPowerUp = false;
me.showHealthBar = false;
me.collisionFilter.category = cat.mobBullet;
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
@@ -2046,7 +2051,7 @@ const spawn = {
this.timeLimit();
};
},
bomb(x, y, radius = 6, sides = 5) {
bomb(x, y, radius = 9, sides = 5) {
mobs.spawn(x, y, sides, radius, "rgb(255,0,0)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
@@ -2155,7 +2160,7 @@ const spawn = {
this.torque -= 0.000004 * this.inertia;
} else if (this.noseLength > 1.5) {
//fire
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 4);
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 4);
const v = 20 * simulation.accelScale;
Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + this.fireDir.x * v + Math.random(),
@@ -2208,7 +2213,7 @@ const spawn = {
}
};
},
sniperBullet(x, y, radius = 6, sides = 4) {
sniperBullet(x, y, radius = 9, sides = 4) {
//bullets
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
let me = mob[mob.length - 1];
@@ -2252,7 +2257,7 @@ const spawn = {
Matter.Body.setAngularVelocity(this, 0.14)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6)
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 7)
//give the bullet a rotational velocity as if they were attached to a vertex
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -8)
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -2290,7 +2295,7 @@ const spawn = {
Matter.Body.setAngularVelocity(this, 0.11)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6)
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 8)
//give the bullet a rotational velocity as if they were attached to a vertex
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -10)
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -2342,14 +2347,14 @@ const spawn = {
// this.force.x -= 2 * forceMag * Math.cos(angle);
// this.force.y -= 2 * forceMag * Math.sin(angle); // - 0.0007 * this.mass; //antigravity
}
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 4)
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6)
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -10)
Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + velocity.x,
y: this.velocity.y + velocity.y
});
spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 4)
spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 6)
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
const velocity2 = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex2])), -10)
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -2378,7 +2383,7 @@ const spawn = {
}
};
},
seeker(x, y, radius = 5, sides = 6) {
seeker(x, y, radius = 8, sides = 6) {
//bullets
mobs.spawn(x, y, sides, radius, "rgb(255,0,255)");
let me = mob[mob.length - 1];
@@ -2511,8 +2516,8 @@ const spawn = {
});
World.add(engine.world, consBB[consBB.length - 1]);
},
snakeBody(x, y, radius = 20) {
mobs.spawn(x, y, 4, radius, "rgb(55,170,170)");
snakeBody(x, y, radius = 14) {
mobs.spawn(x, y, 8, radius, "transparent");
let me = mob[mob.length - 1];
// me.onHit = function() {
// //run this function on hitting player
@@ -2523,6 +2528,8 @@ const spawn = {
me.leaveBody = false;
me.frictionAir = 0.02;
me.isSnakeTail = true;
me.stroke = "#099"
me.onDeath = function() {
if (this.isSnakeTail) { //wake up tail mobs
for (let i = 0; i < mob.length; i++) {

View File

@@ -132,6 +132,17 @@ const tech = {
duplicationChance() {
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance
},
maxDuplicationEvent() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
tech.is100Duplicate = false
const range = 1000
const bossOptions = ["historyBoss", "cellBossCulture", "bomberBoss", "powerUpBoss", "suckerBoss"]
spawn.randomLevelBoss(m.pos.x + range, m.pos.y, bossOptions);
spawn.randomLevelBoss(m.pos.x, m.pos.y + range, bossOptions);
spawn.randomLevelBoss(m.pos.x - range, m.pos.y, bossOptions);
spawn.randomLevelBoss(m.pos.x, m.pos.y - range, bossOptions);
}
},
totalBots() {
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
},
@@ -1115,7 +1126,7 @@ const tech = {
},
{
name: "inelastic collision",
description: "while you are <strong>holding</strong> a <strong>block</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong>",
description: "while you are <strong>holding</strong> a <strong>block</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>75%</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1814,6 +1825,7 @@ const tech = {
effect: () => {
tech.isBayesian = true
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
tech.maxDuplicationEvent()
},
remove() {
tech.isBayesian = false
@@ -1822,7 +1834,7 @@ const tech = {
},
{
name: "replication",
description: "<strong>7.5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>16</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
description: "<strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>11</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
maxCount: 9,
count: 0,
allowed() {
@@ -1832,7 +1844,8 @@ const tech = {
effect() {
tech.duplicateChance += 0.075
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
tech.addJunkTechToPool(16)
tech.addJunkTechToPool(11)
tech.maxDuplicationEvent()
},
remove() {
tech.duplicateChance = 0
@@ -1892,12 +1905,12 @@ const tech = {
}
},
{
name: "cloning",
name: "parthenogenesis",
description: "each level has a chance to spawn a <strong>level boss</strong><br>equal to <strong>double</strong> your <strong class='color-dup'>duplication</strong> chance",
maxCount: 1,
count: 0,
allowed() {
return tech.duplicationChance() > 0.2
return tech.duplicationChance() > 0
},
requires: "some duplication chance",
effect() {
@@ -1907,6 +1920,22 @@ const tech = {
tech.isDuplicateBoss = false;
}
},
{
name: "apomixis",
description: "after reaching <strong>100%</strong> <strong class='color-dup'>duplication</strong> chance<br>immediately spawn <strong>4 level bosses</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.isDuplicateBoss
},
requires: "parthenogenesis",
effect() {
tech.is100Duplicate = true;
},
remove() {
tech.is100Duplicate = false;
}
},
{
name: "exchange symmetry",
description: "convert <strong>1</strong> a random <strong class='color-m'>tech</strong> into <strong>3</strong> new <strong class='color-g'>guns</strong><br><em>recursive tech lose all stacks</em>",
@@ -3189,6 +3218,24 @@ const tech = {
tech.isAmmoFoamSize = false;
}
},
{
name: "quantum foam",
description: "<strong>foam</strong> gun fires <strong>0.35</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>153%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
allowed() {
return tech.haveGunCheck("foam")
},
requires: "foam",
effect() {
tech.foamFutureFire++
},
remove() {
tech.foamFutureFire = 0;
}
},
// {
// name: "foam size",
// description: "increase <strong>foam</strong> <strong class='color-d'>damage</strong> by <strong>200%</strong><br><strong>foam</strong> dissipates <strong>50%</strong> faster",
@@ -3869,7 +3916,7 @@ const tech = {
maxCount: 1,
count: 0,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
},
requires: "plasma torch",
effect() {
@@ -3960,7 +4007,7 @@ const tech = {
},
{
name: "phase decoherence",
description: "become <strong>intangible</strong> while <strong class='color-cloaked'>cloaked</strong><br>but, passing through <strong>mobs</strong> drains your <strong class='color-f'>energy</strong>",
description: "<strong>intangible</strong> to blocks and mobs while <strong class='color-cloaked'>cloaked</strong><br>passing through <strong>mobs</strong> drains your <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -4221,10 +4268,31 @@ const tech = {
// },
// remove() {}
// },
{
name: "lubrication",
description: "reduce block density and friction for this level",
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isCustomHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < body.length; i++) {
Matter.Body.setDensity(body[i], 0.0001) // 0.001 is normal
body[i].friction = 0.01
}
},
remove() {}
},
{
name: "pitch",
description: "oscillate the pitch of your world",
maxCount: 9,
maxCount: 1,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4242,7 +4310,7 @@ const tech = {
{
name: "umbra",
description: "produce a blue glow around everything<br>and probably some simulation lag",
maxCount: 9,
maxCount: 1,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4261,7 +4329,7 @@ const tech = {
{
name: "lighter",
description: `ctx.globalCompositeOperation = "lighter"`,
maxCount: 9,
maxCount: 1,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4736,7 +4804,7 @@ const tech = {
{
name: "stun",
description: "<strong>stun</strong> all mobs for up to <strong>8</strong> seconds",
maxCount: 1,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4754,7 +4822,7 @@ const tech = {
{
name: "re-arm",
description: "<strong>eject</strong> all your <strong class='color-g'>guns</strong>",
maxCount: 1,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4782,7 +4850,7 @@ const tech = {
{
name: "re-research",
description: "<strong>eject</strong> all your <strong class='color-r'>research</strong>",
maxCount: 1,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4801,7 +4869,7 @@ const tech = {
{
name: "quantum black hole",
description: "use all your <strong class='color-f'>energy</strong> to <strong>spawn</strong> inside the event horizon of a huge <strong>black hole</strong>",
maxCount: 1,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -4820,7 +4888,7 @@ const tech = {
{
name: "black hole cluster",
description: "spawn <strong>2</strong> <strong class='color-r'>research</strong><br><strong>spawn</strong> 40 nearby <strong>black holes</strong>",
maxCount: 1,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
@@ -5038,7 +5106,9 @@ const tech = {
isGunSwitchField: null,
isNeedleShieldPierce: null,
isDuplicateBoss: null,
is100Duplicate: null,
isDynamoBotUpgrade: null,
isBlockPowerUps: null,
isBlockHarm: null
isBlockHarm: null,
foamFutureFire: null
}

View File

@@ -1,10 +1,11 @@
******************************************************** NEXT PATCH ********************************************************
several new junk tech
unified field theory: now cycles fields after you click the field box when paused
all mobs that move through walls and blocks now have a transparent fill
player and power ups float in hazards
tech: restitution - mobs killed by blocks spawn power ups
tech: inelastic collision - 60% harm reduction when holding a block
tech: apomixis - after reaching 100% duplication spawn 4 level bosses
tech: quantum foam - +153% foam damage, fire 0.35s into the future
bullets are bigger, and easier to see
******************************************************** BUGS ********************************************************
@@ -34,37 +35,25 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
holding a block gives some defense
can still block?
just make the block more transparent so it's clear you can't block
increase bullet size, but don't increase bullet damage
final boss: hide boss after spawning mobs
reduce health by 1/3?
When you beat the boss without lore the output thing should read simulation complete, processing results, terminating simulation
shutdown progress: 0%
And count up by ten to 100% before you die, so that players know they won and don't think theyre stuck or something, and so its not surprising when you die
tech: after using anthropic principle do 100% more damage for the rest of the level
Additionally, a stats screen would be nice. Like when you die, and it fades to white, output reads simulation result: failure (or success if you beat the boss)
Then reads some stats like kills, tech picked up, research picked up, damage dealt/taken, etc
mechanic: immune to next collision
track number of possible collisions, if number is > 0 immune and --
graphical indication? (recolor health bar while immune)
tech: after taking damage go immune to next collision
tech: at the start of each level go immune to 1 collision
copy time-like foam to other guns?
wave gun
shotgun
nail gun
tech fire gun in the future
laser doesn't work because of draw, needs to be a bullet
foam? shotgun?
const where = {
x: m.pos.x + 20 * Math.cos(m.angle),
y: m.pos.y + 20 * Math.sin(m.angle)
}
setTimeout(() => {
}, 1000);
tech: when you switch guns switch a random bot to a different bot. If the bot you had was upgraded the new one will be too.
or switch all bots
tech: buff block throwing
require +100% damage for blocks
works with pilot wave?
tech: when you switch guns switch all bots to a different bot
lore: a tutorial / lore intro
needs to be optional so it doesn't slow experienced players