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,19 +3858,49 @@ const b = {
ammoPack: 36,
have: false,
fire() {
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)
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;
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)
}
b.foam(position, velocity, radius)
}
const position = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
b.foam(position, velocity, radius)
}
},
{

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(() => {
simulation.makeTextLog(`World.clear(engine.world)`);
setTimeout(() => { m.death() }, 1000);
if (!simulation.paused && !simulation.testing) {
simulation.makeTextLog(`World.clear(engine.world)`);
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 ********************************************************
@@ -33,38 +34,26 @@ use the floor of portal sensor on the player? to unstuck player
(repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping
******************************************************** 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
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
final boss: hide boss after spawning mobs
reduce health by 1/3?
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
tech: after using anthropic principle do 100% more damage for the rest of the level
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