undefined experiment

tech: toggling harpoon - after picking up a power up with the harpoon, your next harpoon is 7x more dense
  this probably needs to be balanced in the next patch
tech: regularization - use 6 research to increase renormalization by 10%
  (renormalization is 40% chance to get research when you use research)
tech: bot fabrication uses 2 research to build a bot (+1 cost every 5 bots)
tech: uncertainty principle now applies to wave beam in addition to foam
tech: integrated armament gives 19.95% damage (was 23%)

level: labs - platforming rooms have been simplified
start with 7/7 undefined tech if you choose an -experiment- and no other tech
This commit is contained in:
landgreen
2021-09-19 07:00:47 -07:00
parent 4eed719d10
commit 0d9cb3bb4c
8 changed files with 285 additions and 123 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1109,9 +1109,9 @@ const b = {
b.grenade = grenadeDefault
}
},
harpoon(where, target, angle = m.angle, scale = 1, isReturn = false, ropeLength = 15) {
harpoon(where, target, angle = m.angle, harpoonLength = 1, isReturn = false, totalCycles = 15) {
const me = bullet.length;
bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * scale, y: 2, index: 0, isInternal: false }, { x: -40 * scale, y: -2, index: 1, isInternal: false }, { x: 50 * scale, y: -3, index: 3, isInternal: false }, { x: 30 * scale, y: 2, index: 4, isInternal: false }], {
bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * harpoonLength, y: 2, index: 0, isInternal: false }, { x: -40 * harpoonLength, y: -2, index: 1, isInternal: false }, { x: 50 * harpoonLength, y: -3, index: 3, isInternal: false }, { x: 30 * harpoonLength, y: 2, index: 4, isInternal: false }], {
cycle: 0,
angle: angle,
friction: 1,
@@ -1122,14 +1122,14 @@ const b = {
drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
endCycle: simulation.cycle + ropeLength * 2.5 + 15,
endCycle: simulation.cycle + totalCycles * 2.5 + 15,
collisionFilter: {
category: cat.bullet,
mask: tech.isNeedleShieldPierce ? cat.map | cat.body | cat.mob | cat.mobBullet : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield,
},
minDmgSpeed: 0,
lookFrequency: Math.floor(7 + Math.random() * 3),
density: 0.005, //0.001 is normal
density: tech.harpoonDensity, //0.001 is normal for blocks, 0.005 is normal for harpoon, 0.035 when buffed
beforeDmg(who) {
if (tech.isNeedleShieldPierce && who.isShielded) { //disable shields
who.isShielded = false
@@ -1168,6 +1168,7 @@ const b = {
this.caughtPowerUp.effect();
Matter.Composite.remove(engine.world, this.caughtPowerUp);
powerUp.splice(index, 1);
if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.035 //0.005 is normal
} else {
this.dropCaughtPowerUp()
}
@@ -1246,7 +1247,7 @@ const b = {
if (!m.isBodiesAsleep) {
this.cycle++
if (isReturn) {
if (this.cycle > ropeLength) {
if (this.cycle > totalCycles) {
if (m.energy < 0.05) { //snap rope if not enough energy
const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
this.force.x -= returnForce.x
@@ -1317,6 +1318,40 @@ const b = {
// }
}
this.drawString()
if (tech.isHarpoonPowerUp && this.density > 0.01) {
this.drawString = () => {
ctx.beginPath();
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
for (let j = 1, len = this.vertices.length; j < len; j += 1) {
ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
}
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
ctx.lineWidth = 10;
ctx.strokeStyle = "#000";
ctx.lineJoin = "miter"
ctx.miterLimit = 100;
ctx.stroke();
ctx.lineJoin = "round"
ctx.miterLimit = 10
if (isReturn) {
const where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
const sub = Vector.sub(where, this.vertices[0])
const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub))))
const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular)
ctx.strokeStyle = "#000" // "#0ce"
ctx.lineWidth = 0.5
ctx.beginPath();
ctx.moveTo(where.x, where.y);
ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
// ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
ctx.stroke();
}
}
}
},
});
if (!isReturn && !target) {
@@ -2759,7 +2794,7 @@ const b = {
inertia: Infinity,
frictionAir: 0.003,
dmg: 0, //damage on impact
damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isFoamTeleport ? 1.5 : 1), //damage done over time
damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isBulletTeleport ? 1.5 : 1), //damage done over time
scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1),
classType: "bullet",
collisionFilter: {
@@ -2898,7 +2933,7 @@ const b = {
}
}
}
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport
this.nextPortCycle = simulation.cycle + this.portFrequency
const range = 15 * Math.sqrt(this.radius) * Math.random()
Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
@@ -2906,7 +2941,7 @@ const b = {
}
}
});
if (tech.isFoamTeleport) bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency
if (tech.isBulletTeleport) bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], velocity);
},
@@ -4236,7 +4271,7 @@ const b = {
name: "super balls",
description: "fire <strong>3</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss",
ammo: 0,
ammoPack: 11,
ammoPack: 10,
have: false,
// num: 5,
do() {},
@@ -4382,7 +4417,7 @@ const b = {
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage //damage is lower for large radius mobs, since they feel the waves longer
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.5 : 1) //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) {
//draw wave
@@ -4390,6 +4425,14 @@ const b = {
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI);
// collisions
if (!m.isBodiesAsleep) {
if (tech.isBulletTeleport && Math.random() < 0.04) {
const scale = 400 * Math.random()
this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
}
for (let j = 0, len = mob.length; j < len; j++) {
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position))
const r = mob[j].radius + 30
@@ -4464,7 +4507,7 @@ const b = {
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage //damage is lower for large radius mobs, since they feel the waves longer
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.5 : 1) //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) {
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
@@ -4475,6 +4518,19 @@ const b = {
// collisions
//using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector
if (!m.isBodiesAsleep) {
if (tech.isBulletTeleport && Math.random() < 0.05) {
if (Math.random() < 0.5) {
// const scale = 500 * Math.random()
// this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
} else {
this.waves[i].arc *= 1 + 1 * (Math.random() - 0.5)
const halfArc = this.waves[i].arc / 2
const angle = m.angle + 0.5 * (Math.random() - 0.5)
this.waves[i].angle = angle - halfArc
this.waves[i].unit1 = { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }
this.waves[i].unit2 = { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }
}
}
let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
for (let j = 0; j < hits.length; j++) {
const who = hits[j].body
@@ -4566,7 +4622,7 @@ const b = {
slow: 0,
amplitude: (input.down ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * 0.088), //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
minDmgSpeed: 0,
dmg: b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage, //also control damage when you divide by mob.mass
dmg: b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage * (tech.isBulletTeleport ? 1.5 : 1), //also control damage when you divide by mob.mass
classType: "bullet",
collisionFilter: {
category: 0,
@@ -4613,7 +4669,24 @@ const b = {
Matter.Body.setPosition(this, Vector.add(this.position, where))
}
});
if (tech.isBulletTeleport) {
bullet[me].wiggle = function() {
this.cycle++
const where = Vector.mult(transverse, this.amplitude * Math.cos(this.cycle * tech.waveFrequency))
if (Math.random() < 0.005) {
if (Math.random() < 0.33) { //randomize position
const scale = 500 * Math.random()
Matter.Body.setPosition(this, Vector.add({ x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) }, Vector.add(this.position, where)))
} else { //randomize position in velocity direction
const velocityScale = Vector.mult(this.velocity, 50 * (Math.random() - 0.5))
Matter.Body.setPosition(this, Vector.add(velocityScale, Vector.add(this.position, where)))
}
} else {
Matter.Body.setPosition(this, Vector.add(this.position, where))
}
}
}
let waveSpeedMap = 0.1
let waveSpeedBody = 0.25
if (tech.isPhaseVelocity) {
@@ -4977,7 +5050,7 @@ const b = {
setTimeout(() => {
if (!simulation.paused) {
b.foam(position, Vector.rotate(velocity, spread), radius)
// (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.60 : 1)
// (tech.isFastFoam ? 0.044 : 0.011) * (tech.isBulletTeleport ? 1.60 : 1)
bullet[bullet.length - 1].damage *= (1 + 0.7 * tech.foamFutureFire)
}
}, 250 * tech.foamFutureFire);
@@ -5028,7 +5101,7 @@ const b = {
}
}
}
b.harpoon(where, closest.target, m.angle, length, false)
b.harpoon(where, closest.target, m.angle, length, false, 15)
m.fireCDcycle = m.cycle + 40 * b.fireCDscale; // cool down
} else if (tech.extraHarpoons) {
const range = 560 * (tech.isFilament ? 1 + this.ammo / 33 : 1)
@@ -5071,6 +5144,7 @@ const b = {
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
player.force.x -= recoil.x
player.force.y -= recoil.y
tech.harpoonDensity = 0.005
}
},
{

View File

@@ -155,7 +155,7 @@ function setupCanvas() {
canvas.height = window.innerHeight;
canvas.width2 = canvas.width / 2; //precalculated because I use this often (in mouse look)
canvas.height2 = canvas.height / 2;
canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
// canvas.diagonal = Math.sqrt(canvas.width2 * canvas.width2 + canvas.height2 * canvas.height2);
// ctx.font = "18px Arial";
// ctx.textAlign = "center";
ctx.font = "25px Arial";
@@ -590,9 +590,25 @@ const build = {
}
removeOne();
}
simulation.isCheating = true;
// simulation.isCheating = true;
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) tech.tech[i].frequency = 0;
// if ((tech.tech[i].isLore && tech.tech[i].count === 0) || (!tech.tech[i].isLore && tech.tech[i].count > 0)) { //don't remove lore frequency if you only have lore tech
// tech.tech[i].frequency = 0; //remove lore power up chance
// }
if (!simulation.isCheating && tech.tech[i].count > 0 && !tech.tech[i].isLore && !tech.tech[i].isExperimentalMode) {
simulation.isCheating = true;
}
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0; //remove lore power up chance
}
}
//if you have no tech (not cheating) remove all power ups that might have spawned from tech
if (!simulation.isCheating) {
function removeAll(array) {
for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
}
removeAll(powerUp);
powerUp = [];
}
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"

View File

@@ -17,11 +17,9 @@ const level = {
// simulation.isHorizontalFlipped = true
// m.setField("time dilation")
// b.giveGuns("harpoon")
// tech.giveTech("filament")
// tech.giveTech("unaaq")
// tech.giveTech("reticulum")
// tech.giveTech("reticulum")
// tech.giveTech("reticulum")
// tech.giveTech("toggling harpoon")
// tech.giveTech("phonon")
// tech.giveTech("isotropic radiator")
// tech.giveTech("necrophage")
// for (let i = 0; i < 3; i++) tech.giveTech("super sized")
// for (let i = 0; i < 9; i++) tech.giveTech("MIRV")
@@ -31,7 +29,7 @@ const level = {
// level.template(); //not in rotation, blank start new map development
// level.final() //final boss level
// level.gauntlet(); //before final boss level
// level.labs(); //always before gauntlet level
// level.labs();
// level.testChamber()
// level.sewers();
// level.satellite();
@@ -1119,8 +1117,13 @@ const level = {
const Xoffset2 = 1650 + Math.floor(300 * Math.random())
const hazard4 = level.hazard(x + Xoffset2, y - 240, 10, 250, 0.4) //laser
spawn.mapRect(x + Xoffset2 - 5, y - 250, 20, 20); //laser nose
let isSpawnedMobs = false
spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
spawn.randomMob(x + 175, y + -775, mobSpawnChance);
spawn.randomMob(x + 150, y + -350, mobSpawnChance);
spawn.randomMob(x + 150, y + -75, mobSpawnChance);
spawn.randomMob(x + 650, y + -125, mobSpawnChance);
spawn.randomMob(x + 1200, y + -75, mobSpawnChance);
// let isSpawnedMobs = false
doCustomTopLayer.push(
() => {
toggle.query();
@@ -1132,15 +1135,15 @@ const level = {
hazard2.opticalQuery();
hazard3.opticalQuery();
hazard4.opticalQuery();
if (!isSpawnedMobs && !toggle.isOn) {
isSpawnedMobs = true
spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
spawn.randomMob(x + 175, y + -775, mobSpawnChance);
spawn.randomMob(x + 150, y + -350, mobSpawnChance);
spawn.randomMob(x + 150, y + -75, mobSpawnChance);
spawn.randomMob(x + 650, y + -125, mobSpawnChance);
spawn.randomMob(x + 1200, y + -75, mobSpawnChance);
}
// if (!isSpawnedMobs && !toggle.isOn) {
// isSpawnedMobs = true
// spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
// spawn.randomMob(x + 175, y + -775, mobSpawnChance);
// spawn.randomMob(x + 150, y + -350, mobSpawnChance);
// spawn.randomMob(x + 150, y + -75, mobSpawnChance);
// spawn.randomMob(x + 650, y + -125, mobSpawnChance);
// spawn.randomMob(x + 1200, y + -75, mobSpawnChance);
// }
}
)
},
@@ -1164,11 +1167,11 @@ const level = {
const frictionAir = 0.03
const angularVelocity = 0 //0.01
const spinVariance = 0 //0.02
balance1 = level.spinner(x + 200, y - 500, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance2 = level.spinner(x + 200, y - 950, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 650, y - 650, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance4 = level.spinner(x + 750, y - 1050, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance5 = level.spinner(x + 1250, y - 1100, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance1 = level.spinner(x + 200, y - 500, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance2 = level.spinner(x + 200, y - 950, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 650, y - 750, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
// balance4 = level.spinner(x + 750, y - 1050, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance4 = level.spinner(x + 1250, y - 1000, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
let isInRoom = false
doCustom.push(
@@ -1196,8 +1199,6 @@ const level = {
ctx.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance4.pointA.x, balance4.pointA.y)
ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance5.pointA.x, balance5.pointA.y)
ctx.arc(balance5.pointA.x, balance5.pointA.y, 9, 0, 2 * Math.PI);
ctx.fill();
}
)
@@ -1220,11 +1221,26 @@ const level = {
const variance = 0.2 //Math.PI
const frictionAir = 0.015
const height = 35
balance1 = level.spinner(x + 1300, y - 450, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance3 = level.spinner(x + 750, y - 600, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance2 = level.spinner(x + 300, y - 850, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance4 = level.spinner(x + 850, y - 1100, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance5 = level.spinner(x + 1300, y - 1145, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance1 = level.spinner(x + 1300, y - 425, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance3 = level.spinner(x + 750, y - 650, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance2 = level.spinner(x + 300, y - 425, height, 410, density, angle + variance * (Math.random() - 0.5), frictionAir)
balance4 = level.spinner(x + 1250, y - 950, 50, 550, density, angle, 0.1)
const rotatingBlock = body[body.length - 1]
doCustom.push(
() => {
if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once
isInRoom = true
spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
spawn.randomMob(x + 425, y - 100, mobSpawnChance);
spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
}
ctx.fillStyle = "#d4f4f4"
ctx.fillRect(x + 1600, y - 1300, 400, 350)
rotatingBlock.torque += rotatingBlock.inertia * 0.000005
}
)
} else {
const density = 0.001 //+ (simulation.difficultyMode < 5 ? 0.003 : 0)
const angle = Math.PI / 2
@@ -1233,27 +1249,26 @@ const level = {
const width = 200
const height = 200
const spinVariance = 0.05
balance1 = level.spinner(x + 150, y - 300, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance4 = level.spinner(x + 435, y - 525, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 735, y - 700, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance5 = level.spinner(x + 1040, y - 850, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance2 = level.spinner(x + 1380, y - 750, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance1 = level.spinner(x + 175, y - 300, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance2 = level.spinner(x + 500, y - 525, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 850, y - 700, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
balance4 = level.spinner(x + 1250, y - 850, height, width, density, angle + variance * (Math.random() - 0.5), frictionAir, spinVariance * (Math.random() - 0.5))
doCustom.push(
() => {
if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once
isInRoom = true
spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
spawn.randomMob(x + 425, y - 100, mobSpawnChance);
spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
}
ctx.fillStyle = "#d4f4f4"
ctx.fillRect(x + 1600, y - 1300, 400, 350)
}
)
}
let isInRoom = false
doCustom.push(
() => {
if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once
isInRoom = true
spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
spawn.randomMob(x + 425, y - 100, mobSpawnChance);
spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
}
ctx.fillStyle = "#d4f4f4"
ctx.fillRect(x + 1600, y - 1300, 400, 350)
}
)
doCustomTopLayer.push(
() => {
ctx.fillStyle = "#233"
@@ -1265,8 +1280,6 @@ const level = {
ctx.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance4.pointA.x, balance4.pointA.y)
ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI);
ctx.moveTo(balance5.pointA.x, balance5.pointA.y)
ctx.arc(balance5.pointA.x, balance5.pointA.y, 9, 0, 2 * Math.PI);
ctx.fill();
}
)
@@ -1293,7 +1306,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
b.pulse(100, Math.PI, { x: x + 2000 - 560, y: y - 150 })
b.pulse(90, Math.PI, { x: x + 2000 - 560, y: y - 150 })
}
}
)
@@ -1324,7 +1337,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
b.pulse(100, 0, { x: x + 560, y: y - 150 })
b.pulse(90, 0, { x: x + 560, y: y - 150 })
}
}
)
@@ -1995,7 +2008,7 @@ const level = {
// upDown = upDownOptions[1] //controls what level spawns for map designing building //********************************* DO !NOT! RUN THIS LINE IN THE FINAL VERSION ***************************************
//3x2: 4 short rooms (3000x1500), 1 double tall room (3000x3000)
//rooms
let rooms = ["loot", "enter", "empty", "exit"]
let rooms = ["exit", "loot", "enter", "empty"]
rooms = shuffle(rooms); //shuffles array order
//look... you and I both know there is a better way to do this, but it works so I'm gonna focus on other things
while ( //makes sure that the exit and entrance aren't both on the same floor
@@ -2276,7 +2289,7 @@ const level = {
spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// spawn.starter(1900, -500, 200) //big boy
spawn.starter(1900, -500, 200) //big boy
// spawn.blockGroup(1900, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
// spawn.laserBombingBoss(1900, -500)
@@ -2297,9 +2310,9 @@ const level = {
// spawn.laserTargetingBoss(1600, -500)
// spawn.laserBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
spawn.nodeGroup(1200, -500, "grenadier")
spawn.nodeGroup(1800, -500, "grenadier")
spawn.nodeGroup(1200, 0, "grenadier")
// spawn.nodeGroup(1200, -500, "grenadier")
// spawn.nodeGroup(1800, -500, "grenadier")
// spawn.nodeGroup(1200, 0, "grenadier")
// spawn.snakeBoss(1200, -500)
// spawn.suckerBoss(2900, -500)
// spawn.randomMob(1600, -500)
@@ -4583,8 +4596,8 @@ const level = {
spawn.mapRect(600, -1000, 500, 50); //2nd floor
spawn.spawnStairs(-600, -1000, 4, 250, 350); //stairs 2nd
spawn.mapRect(375, -600, 350, 150); //center table
spawn.mapRect(-600 + 300, -2000 * 0.25, 2000 - 300, 50); //1st floor
spawn.spawnStairs(-600 + 2000 - 50, -500, 4, 250, 350, true); //stairs 1st
spawn.mapRect(-300, -2000 * 0.25, 1690, 50); //1st floor
spawn.spawnStairs(-610 + 2000 - 50, -500, 4, 250, 350, true); //stairs
spawn.spawnStairs(-600, 0, 4, 250, 350); //stairs ground
spawn.bodyRect(700, -200, 100, 100); //center block under wall
spawn.bodyRect(700, -300, 100, 100); //center block under wall
@@ -4604,7 +4617,7 @@ const level = {
// spawn.mapVertex(3160, -525, "625 0 300 0 300 -140 500 -140"); //entrance/exit ramp
spawn.mapRect(3000, -2000 * 0.5, 700, 50); //exit roof
spawn.mapRect(3000, -2000 * 0.25, 2000 - 300, 50); //1st floor
spawn.mapRect(3010, -2000 * 0.25, 1690, 50); //1st floor
spawn.spawnStairs(3000 + 2000 - 50, 0, 4, 250, 350, true); //stairs ground
spawn.randomSmallMob(4575, -560, 1);
spawn.randomSmallMob(1315, -880, 1);

View File

@@ -319,22 +319,25 @@ const powerUps = {
}
}
if (tech.isRerollBots) {
for (const cost = 4; powerUps.research.count > cost - 1; powerUps.research.count -= cost) {
for (const cost = 2 + Math.floor(0.2 * b.totalBots()); powerUps.research.count > cost - 1; powerUps.research.count -= cost) {
b.randomBot()
if (tech.renormalization) {
for (let i = 0; i < cost; i++) {
if (Math.random() < 0.4) {
if (Math.random() < tech.regularization) {
m.fieldCDcycle = m.cycle + 20;
powerUps.spawn(m.pos.x, m.pos.y, "research");
}
}
}
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "bot fabrication") tech.tech[i].description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`
}
}
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
}
if (tech.renormalization && Math.random() < 0.4 && amount < 0) {
if (tech.renormalization && Math.random() < tech.regularization && amount < 0) {
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
}
if (tech.isRerollHaste) {

View File

@@ -135,6 +135,7 @@
tech.tech[i].count = 0;
}
}
console.log('cheating')
sound.tone(250)
sound.tone(300)
sound.tone(375)
@@ -186,7 +187,7 @@
if (tech.isEnergyDamage) dmg *= 1 + m.energy / 11;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.005
if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.23
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.1995
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
@@ -248,7 +249,7 @@
},
tech: [{
name: "integrated armament",
description: `increase <strong class='color-d'>damage</strong> by <strong>23%</strong><br>your inventory can only hold 1 <strong class='color-g'>gun</strong>`,
description: `increase <strong class='color-d'>damage</strong> by <strong>19.95%</strong><br>your inventory can only hold 1 <strong class='color-g'>gun</strong>`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -413,7 +414,7 @@
},
{
name: "logistics",
description: `${powerUps.orb.ammo()} give <strong>80%</strong> more <strong class='color-ammo'>ammo</strong><br>but it's only added to your current <strong class='color-g'>gun</strong>`,
description: `${powerUps.orb.ammo()} give <strong>80%</strong> more <strong class='color-ammo'>ammo</strong>, but<br>it's only added to your current <strong class='color-g'>gun</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -452,7 +453,7 @@
},
{
name: "cache",
description: `${powerUps.orb.ammo()} gives <strong>11x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
description: `${powerUps.orb.ammo()} give <strong>11x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -471,7 +472,7 @@
},
{
name: "catabolism",
description: `firing while <strong>out</strong> of <strong class='color-ammo'>ammo</strong> spawns ${powerUps.orb.ammo(4)}<br>and reduces your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>1</strong>`,
description: `firing while <strong>out</strong> of <strong class='color-ammo'>ammo</strong> spawns ${powerUps.orb.ammo(4)}<br>but it reduces your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>1</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -932,7 +933,7 @@
frequency: 1,
frequencyDefault: 1,
allowed() {
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive && !tech.isDroneTeleport) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedles
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive && !tech.isDroneTeleport) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot
},
requires: "super balls, basic or slug shotgun, drones, not irradiated drones or burst drones",
effect() {
@@ -1464,16 +1465,17 @@
},
{
name: "bot fabrication",
description: `anytime you collect ${powerUps.orb.research(4)}<br>use them to build a random <strong class='color-bot'>bot</strong>`,
//-----------description is overwritten in powerUps.research.changeRerolls------------
description: `if you collect ${powerUps.orb.research(2)}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
isBotTech: true,
allowed() {
return powerUps.research.count > 3 || build.isExperimentSelection
return powerUps.research.count > 2 || build.isExperimentSelection
},
requires: "at least 4 research",
requires: "at least 3 research",
effect() {
tech.isRerollBots = true;
powerUps.research.changeRerolls(0)
@@ -2904,12 +2906,34 @@
},
requires: "at least 3 research and not superdeterminism",
effect() {
tech.renormalization = true;
tech.renormalization = true; //40% set in regularization tech
},
remove() {
tech.renormalization = false;
}
},
{
name: "regularization",
description: `increase <strong>renormalization</strong> chance by <strong>10%</strong><br>use ${powerUps.orb.research(6)}`,
maxCount: 3,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.renormalization && (powerUps.research.count > 5 || build.isExperimentSelection)
},
requires: "renormalization",
effect() {
tech.regularization += 0.1
for (let i = 0; i < 6; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 120 * (Math.random() - 0.5), m.pos.y + 120 * (Math.random() - 0.5), "research", false);
},
remove() {
tech.regularization = 0.4
}
},
{
name: "perturbation theory",
description: `<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>when you have no ${powerUps.orb.research(1)} in your inventory`,
@@ -3021,7 +3045,7 @@
},
{
name: "abiogenesis",
description: `at the start of a level spawn a 2nd <strong>boss</strong><br>use ${powerUps.orb.research(4)} or add <strong>49</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool`,
description: `at the start of a level spawn a 2nd <strong>boss</strong><br>use ${powerUps.orb.research(4)}or add <strong>49</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -4256,9 +4280,9 @@
frequency: 4,
frequencyDefault: 4,
allowed() {
return tech.haveGunCheck("wave beam") && !tech.isPhaseVelocity
return tech.haveGunCheck("wave beam") && !tech.isPhaseVelocity && !tech.isBulletTeleport
},
requires: "wave beam, not phase velocity ",
requires: "wave beam, not phase velocity, uncertainty principle",
effect() {
tech.isLongitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -4887,7 +4911,7 @@
frequency: 2,
frequencyDefault: 2,
allowed() {
return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
},
requires: "foam, not uncertainty",
effect() {
@@ -4899,21 +4923,21 @@
},
{
name: "uncertainty principle",
description: "<strong>foam</strong> bubbles randomly change <strong>position</strong><br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>50%</strong>",
description: "<strong>foam</strong> and <strong>wave</strong> particle <strong>positions</strong> are random<br>increase their <strong class='color-d'>damage</strong> by <strong>50%</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)) || (tech.haveGunCheck("wave beam") && !tech.isLongitudinal)
},
requires: "foam, not electrostatic induction",
requires: "foam, not electrostatic induction, wave beam, not phonon",
effect() {
tech.isFoamTeleport = true
tech.isBulletTeleport = true
},
remove() {
tech.isFoamTeleport = false;
tech.isBulletTeleport = false;
}
},
{
@@ -5032,6 +5056,26 @@
tech.isLargeHarpoon = false;
}
},
{
name: "toggling harpoon",
description: "increase the <strong class='color-d'>damage</strong> of your next <strong>harpoon</strong><br>by <strong>600%</strong> after using it to collect a <strong>power up</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("harpoon")
},
requires: "harpoon",
effect() {
tech.isHarpoonPowerUp = true
},
remove() {
tech.isHarpoonPowerUp = false
tech.harpoonDensity = 0.005
}
},
{
name: "reticulum",
description: "fire <strong>+1</strong> harpoon<br>when there are multiple targets in range",
@@ -6302,6 +6346,7 @@
requires: "",
effect() {
m.shipMode()
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
remove() {}
},
@@ -6325,6 +6370,8 @@
simulation.trails()
}
}, 20000); //every 20 seconds
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
remove() {
if (this.count > 0) clearTimeout(this.interval);
@@ -6350,6 +6397,7 @@
}
}
}, 5000); //every 5 seconds
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
interval: undefined,
remove() {
@@ -6377,6 +6425,7 @@
m.transX += (m.transSmoothX - m.transX) * 0.07;
m.transY += (m.transSmoothY - m.transY) * 0.07;
}
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
remove() {
if (this.count > 0) m.look = m.lookDefault()
@@ -6405,6 +6454,7 @@
}
}
}, 1000); //every 1 seconds
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
interval: undefined,
remove() {
@@ -6425,6 +6475,7 @@
requires: "",
effect() {
tech.deathSpawns = 0.2
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
remove() {
tech.deathSpawns = 0
@@ -6443,7 +6494,8 @@
},
requires: "",
effect() {
tech.wimpExperiment = 3
tech.wimpExperiment = 5
for (let i = 0; i < 7; i++) tech.giveTech("undefined")
},
remove() {
tech.wimpExperiment = 0
@@ -7820,14 +7872,14 @@
if (lore.techCount === lore.techGoal) {
// tech.removeLoreTechFromPool();
this.frequency = 0;
this.description = `<strong class="lore-text">null</strong> is open`
this.description = `<strong class="lore-text">null</strong> is open at level.final()`
} else {
this.frequency += lore.techGoal
// for (let i = 0; i < tech.tech.length; i++) { //set name for all unchosen copies of this tech
// if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech[i].description = `${lore.techCount+1}/${lore.techGoal}<br><em>add copies of <strong class="lore-text">this</strong> to the potential <strong class='color-m'>tech</strong> pool</em>`
// }
// for (let i = 0, len = 10; i < len; i++) tech.addLoreTechToPool()
this.description = `<em>uncaught error:</em><br><strong>${lore.techGoal-lore.techCount}</strong> more required for access to <strong class="lore-text">null</strong>`
this.description = `<em>uncaught error:</em><br><strong>${Math.max(0,lore.techGoal-lore.techCount)}</strong> more required for access to <strong class="lore-text">null</strong>`
}
}, 1);
},
@@ -8108,7 +8160,7 @@
droneRadioDamage: null,
isDroneTeleport: null,
isDroneFastLook: null,
isFoamTeleport: null,
isBulletTeleport: null,
isResearchBoss: null,
isJunkResearch: null,
junkResearchNumber: null,
@@ -8140,5 +8192,8 @@
// isSpear: null,
isLargeHarpoon: null,
extraHarpoons: null,
ammoCap: null
ammoCap: null,
regularization: null,
isHarpoonPowerUp: null,
harpoonDensity: null
}

View File

@@ -261,7 +261,7 @@ summary {
}
.experiment-grid-module {
margin: -1px;
margin: -0.5px;
padding: 10px;
line-height: 170%;
/* border-radius: 6px; */
@@ -734,10 +734,10 @@ summary {
height: 13px;
border-radius: 50%;
display: inline-block;
margin-bottom: -2.5px;
background-color: #f7b;
border: 0.5px #fff solid;
opacity: 0.85;
margin-bottom: -2.5px;
}
.ammo-circle {
@@ -756,10 +756,10 @@ summary {
height: 14px;
border-radius: 50%;
display: inline-block;
margin-bottom: -3px;
background-color: #0d9;
border: 0.5px #fff solid;
opacity: 0.85;
margin-bottom: -3px;
}
.circle-grid-shadow {

View File

@@ -1,17 +1,24 @@
******************************************************** NEXT PATCH **************************************************
tech: cache - ammo power ups give 11x ammo, but you can't hold over 11x ammo
tech: toggling harpoon - after picking up a power up with the harpoon, your next harpoon is 7x more dense
this probably needs to be balanced in the next patch
tech: regularization - use 6 research to increase renormalization by 10%
(renormalization is 40% chance to get research when you use research)
tech: bot fabrication uses 2 research to build a bot (+1 cost every 5 bots)
tech: uncertainty principle now applies to wave beam in addition to foam
tech: integrated armament gives 19.95% damage (was 23%)
harpoon
grabs 1 power up on the way out, or in
harpooned power ups are predictable
they attach to the harpoon instead of using physics to move towards player
bugs fixes
lasers were broke, but I fixed them
level: labs - platforming rooms have been simplified
start with 7/7 undefinded tech if you choose an -experiment- and no other tech
******************************************************** TODO ********************************************************
Tech: Make player smol
Tech: For the particle waves gun, Incompatible with phonon
shooting creates small particles that randomly jump around the map, often randomly changing their position completely instead of randomly jumping
combine with foam uncertainty?
"Interstellar Disturbance": Cosmic String applies to mobs who cross the wormhole's path, even after initial wormholing, but at reduced damage and stun time.
disable zoom progress when paused
@@ -23,8 +30,6 @@ harpoon tech
tech that buffs alt fire:
remove the string, all shots are alt fire
alt fire has a 50% chance to not use ammo?
ammo power ups are 10% more likely to spawn from dead mobs
ammo power ups give the harpoon 2x more ammo
holding down fire lets the string extend farther,
this can overwrite crouch mode
can't have 2+ harpoons
@@ -33,13 +38,9 @@ harpoon tech
2+ harpoons, with separate CDs
can't have extended string?
grappling hook?
remove string in all modes, why?
increase ammo
tracking so good harpoon can hit a target, circle around and hit it again
doesn't seem to be good physics
level:lab too much walking around and too much platforming
tech - explode after getting hit, but while you are immune to harm
on mouse down wormhole shows a possible wormhole