From 0d9cb3bb4cef9a7a534ad7d08315bfd00c7de4c6 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 19 Sep 2021 07:00:47 -0700 Subject: [PATCH] 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 --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 102 ++++++++++++++++++++++++++++++++------ js/index.js | 22 ++++++-- js/level.js | 135 +++++++++++++++++++++++++++----------------------- js/powerup.js | 9 ++-- js/tech.js | 103 +++++++++++++++++++++++++++++--------- style.css | 6 +-- todo.txt | 31 ++++++------ 8 files changed, 285 insertions(+), 123 deletions(-) diff --git a/.DS_Store b/.DS_Store index dc334b080c71eabc5ad96d84b16037a15b5ac812..812769a0c7114f7c9812f3bed98d89a48ccd783f 100644 GIT binary patch delta 21 ccmZoMXffEJ#mw}4(PSNFKgNK~)y$nD08rKk00000 delta 21 ccmZoMXffEJ#mscz?_?cjKSqYl)y$nD08u{% 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 3 balls in a wide arc
balls bounce 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 } }, { diff --git a/js/index.js b/js/index.js index 6fd93dd..39b4819 100644 --- a/js/index.js +++ b/js/index.js @@ -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" diff --git a/js/level.js b/js/level.js index 5514b23..e8876e0 100644 --- a/js/level.js +++ b/js/level.js @@ -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(); @@ -40,7 +38,7 @@ const level = { // level.rooftops(); // level.warehouse(); // level.highrise(); - // level.office(); + // level.office(); // level.gauntlet(); //only fighting, very simple map, before final boss // level.house() //community level // level.detours() //community level @@ -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); diff --git a/js/powerup.js b/js/powerup.js index 5e0aadd..5336da8 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -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
random bot (+1 cost every 5 bots)` + } } 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) { diff --git a/js/tech.js b/js/tech.js index 1495410..e92d166 100644 --- a/js/tech.js +++ b/js/tech.js @@ -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 damage by 23%
your inventory can only hold 1 gun`, + description: `increase damage by 19.95%
your inventory can only hold 1 gun`, maxCount: 1, count: 0, frequency: 2, @@ -413,7 +414,7 @@ }, { name: "logistics", - description: `${powerUps.orb.ammo()} give 80% more ammo
but it's only added to your current gun`, + description: `${powerUps.orb.ammo()} give 80% more ammo, but
it's only added to your current gun`, maxCount: 1, count: 0, frequency: 1, @@ -452,7 +453,7 @@ }, { name: "cache", - description: `${powerUps.orb.ammo()} gives 11x more ammo, but
you can't store any more ammo than that`, + description: `${powerUps.orb.ammo()} give 11x more ammo, but
you can't store any more ammo than that`, maxCount: 1, count: 0, frequency: 1, @@ -471,7 +472,7 @@ }, { name: "catabolism", - description: `firing while out of ammo spawns ${powerUps.orb.ammo(4)}
and reduces your maximum health by 1`, + description: `firing while out of ammo spawns ${powerUps.orb.ammo(4)}
but it reduces your maximum health by 1`, 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)}
use them to build a random bot`, + //-----------description is overwritten in powerUps.research.changeRerolls------------ + description: `if you collect ${powerUps.orb.research(2)}use them to build a
random bot (+1 cost every 5 bots)`, 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 renormalization chance by 10%
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: `66% decreased delay after firing
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 boss
use ${powerUps.orb.research(4)} or add 49 JUNK to the tech pool`, + description: `at the start of a level spawn a 2nd boss
use ${powerUps.orb.research(4)}or add 49 JUNK to the tech 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: "foam bubbles randomly change position
increase foam damage per second by 50%", + description: "foam and wave particle positions are random
increase their damage by 50%", 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 damage of your next harpoon
by 600% after using it to collect a power up", + 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 +1 harpoon
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 = `null is open` + this.description = `null 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}
add copies of this to the potential tech pool` // } // for (let i = 0, len = 10; i < len; i++) tech.addLoreTechToPool() - this.description = `uncaught error:
${lore.techGoal-lore.techCount} more required for access to null` + this.description = `uncaught error:
${Math.max(0,lore.techGoal-lore.techCount)} more required for access to null` } }, 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 } \ No newline at end of file diff --git a/style.css b/style.css index 0ce7060..46b8bd5 100644 --- a/style.css +++ b/style.css @@ -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 { diff --git a/todo.txt b/todo.txt index a37f92f..8090bb1 100644 --- a/todo.txt +++ b/todo.txt @@ -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 @@ -475,7 +476,7 @@ possible names for tech gnarl SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions. nuclear pasta - hard matter in neutron star - + a tutorial / lore intro needs to be optional so it doesn't slow experienced players put something on the intro map