diff --git a/.DS_Store b/.DS_Store index 2a571ef..2c71cdf 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 950a4a3..fb46c60 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -9,12 +9,14 @@ const b = { setFireMethod() { if (tech.isFireMoveLock) { b.fire = b.fireFloat - } else if (tech.isFireNotMove) { - if (tech.isAlwaysFire) { - b.fire = b.fireNotMoveAlwaysFire - } else { - b.fire = b.fireNotMove - } + // } else if (tech.isFireNotMove) { + // if (tech.isAlwaysFire) { + // b.fire = b.fireAlwaysFire + // } else { + // b.fire = b.fireNotMove + // } + } else if (tech.isAlwaysFire) { + b.fire = b.fireAlwaysFire } else { b.fire = b.fireNormal } @@ -46,7 +48,7 @@ const b = { b.guns[b.activeGun].do(); } }, - fireNotMoveAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) + fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) if (b.inventory.length) { if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (b.guns[b.activeGun].ammo > 0) { @@ -222,7 +224,7 @@ const b = { setFireCD() { b.fireCD = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime if (tech.isFireRateForGuns) b.fireCD *= Math.pow(0.86, b.inventory.length) - if (tech.isFireNotMove) b.fireCD *= 0.33 + if (tech.isFireMoveLock) b.fireCD *= 0.5 }, fireAttributes(dir, rotate = true) { if (rotate) { @@ -1579,7 +1581,7 @@ const b = { dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, lookFrequency: 67 + Math.floor(7 * Math.random()), - drain: 0.7 * tech.isLaserDiode * tech.laserFieldDrain, + drain: 0.6 * tech.isLaserDiode * tech.laserFieldDrain, isArmed: false, torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), range: 1500, @@ -1728,7 +1730,7 @@ const b = { sentry() { this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets this.lookFrequency = simulation.cycle + 60 - this.endCycle = simulation.cycle + 1260 + this.endCycle = simulation.cycle + 1620 this.do = function() { //overwrite the do method for this bullet this.force.y += this.mass * 0.002; //extra gravity if (simulation.cycle > this.lookFrequency) { @@ -1759,7 +1761,7 @@ const b = { this.force.y += this.mass * 0.002; //extra gravity if (simulation.cycle > this.lookFrequency) { this.isArmed = true - this.lookFrequency = 50 + Math.floor(27 * Math.random()) + this.lookFrequency = 55 + Math.floor(22 * Math.random()) simulation.drawList.push({ x: this.position.x, y: this.position.y, @@ -1786,7 +1788,7 @@ const b = { }, onEnd() { if (this.isArmed) { - b.targetedNail(this.position, 18) + b.targetedNail(this.position, 22) } if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -1823,7 +1825,7 @@ const b = { angle: Math.random() * 2 * Math.PI, friction: 0, frictionAir: 0.025, - thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), + thrust: (tech.isFastSpores ? 0.0009 : 0.00045) * (1 + 0.3 * (Math.random() - 0.5)), dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism lookFrequency: 100 + Math.floor(117 * Math.random()), classType: "bullet", @@ -2436,6 +2438,7 @@ const b = { b.zeroBotCount() b.clearPermanentBots() for (let i = 0; i < totalTechToConvert; i++) tech.giveTech(type) //spawn tech for the correct bot type + //find index of new bot type tech effect let index = null for (let i = 0; i < tech.tech.length; i++) { @@ -2445,6 +2448,13 @@ const b = { } } for (let i = 0, len = totalPermanentBots - totalTechToConvert; i < len; i++) tech.tech[index].effect(); //also convert any permanent bots that didn't come from a tech + //in experiment mode set the unselect color for bot tech that was converted + if (build.isExperimentSelection) { + + + + + } }, clearPermanentBots() { for (let i = 0; i < bullet.length; i++) { @@ -2679,7 +2689,7 @@ const b = { minDmgSpeed: 2, lookFrequency: 70, cd: 0, - delay: 90, + delay: 80, range: 70 + 3 * b.totalBots(), endCycle: Infinity, classType: "bullet", @@ -3298,7 +3308,7 @@ const b = { if (tech.isNailRadiation) { mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles } else { - let dmg = b.dmgScale * 3.75 + let dmg = b.dmgScale * 4.5 if (tech.isCrit && who.isStunned) dmg *= 4 who.damage(dmg, tech.isNeedleShieldPierce); simulation.drawList.push({ //add dmg to draw queue @@ -3326,7 +3336,7 @@ const b = { this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming } }; - const SPEED = 100 + const SPEED = 90 Matter.Body.setVelocity(bullet[me], { x: m.Vx / 2 + SPEED * Math.cos(angle), y: m.Vy / 2 + SPEED * Math.sin(angle) @@ -3356,10 +3366,10 @@ const b = { // makeNeedle(m.angle - spread) }, fireRivets() { - m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 30 : 25) * b.fireCD); // cool down + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 17) * b.fireCD); // cool down const me = bullet.length; - const size = tech.rivetSize * 6 + const size = tech.rivetSize * 7 bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle)); bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 Matter.Body.setDensity(bullet[me], 0.002); @@ -3470,7 +3480,7 @@ const b = { if (tech.isSlugShot) { const me = bullet.length; const dir = m.angle + 0.02 * (Math.random() - 0.5) - bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 45, 20, b.fireAttributes(dir)); + bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60, 27, b.fireAttributes(dir)); Matter.Body.setDensity(bullet[me], 0.004); World.add(engine.world, bullet[me]); //add bullet to world @@ -3490,7 +3500,7 @@ const b = { } else { bullet[me].endCycle = simulation.cycle + 180 } - bullet[me].minDmgSpeed = 15 + bullet[me].minDmgSpeed = 7 // bullet[me].restitution = 0.4 bullet[me].frictionAir = 0.006; bullet[me].do = function() { @@ -3502,7 +3512,7 @@ const b = { x: Math.cos(this.angle), y: Math.sin(this.angle) } - const mag = 0.0033 + const mag = 0.017 if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { this.torque += mag } else { @@ -3613,7 +3623,7 @@ const b = { if (tech.oneSuperBall) { let dir = m.angle const me = bullet.length; - bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 20 * tech.bulletSize, b.fireAttributes(dir, false)); + bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false)); World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { x: SPEED * Math.cos(dir), @@ -3640,7 +3650,7 @@ const b = { let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; for (let i = 0; i < tech.superBallNumber; i++) { const me = bullet.length; - bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 7.5 * tech.bulletSize, b.fireAttributes(dir, false)); + bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 9 * tech.bulletSize, b.fireAttributes(dir, false)); World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { x: SPEED * Math.cos(dir), @@ -4252,7 +4262,7 @@ const b = { // Matter.Body.setDensity(this, 0.001); } if (tech.fragments && this.speed > 10) { - b.targetedNail(this.position, tech.fragments * 10) + b.targetedNail(this.position, tech.fragments * 15) this.endCycle = 0 //triggers despawn } }, @@ -4340,7 +4350,7 @@ const b = { // Matter.Body.setDensity(this, 0.001); } if (tech.fragments && this.speed > 10) { - b.targetedNail(this.position, tech.fragments * 16) + b.targetedNail(this.position, tech.fragments * 20) this.endCycle = 0 //triggers despawn } }, @@ -4584,7 +4594,7 @@ const b = { if (this.charge > 5) { m.fireCDcycle = m.cycle + 35; // cool down if (tech.beamSplitter) { - const divergence = m.crouch ? 0.2 : 0.5 + const divergence = m.crouch ? 0.15 : 0.35 const angle = m.angle - tech.beamSplitter * divergence / 2 for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence) } else { @@ -4639,7 +4649,7 @@ const b = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) } - const divergence = m.crouch ? 0.2 : 0.5 + const divergence = m.crouch ? 0.15 : 0.35 const angle = m.angle - tech.beamSplitter * divergence / 2 for (let i = 0; i < 1 + tech.beamSplitter; i++) { b.laser(where, { diff --git a/js/index.js b/js/index.js index bbb08e6..b37ed73 100644 --- a/js/index.js +++ b/js/index.js @@ -299,13 +299,15 @@ const build = { } } else if (type === "tech") { if (tech.tech[index].count < tech.tech[index].maxCount) { - if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); + // if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); + if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); tech.giveTech(index) } else if (!tech.tech[index].isNonRefundable) { tech.totalCount -= tech.tech[index].count tech.removeTech(index); who.classList.remove("build-tech-selected"); } else { + // for non refundable tech this makes it flash off for a second, but return to on to show that it can't be set off who.classList.remove("build-tech-selected") setTimeout(() => { who.classList.add("build-tech-selected") @@ -313,7 +315,6 @@ const build = { } } - // } else if (type === "tech") { //remove tech if you have too many // if (tech.tech[index].count < tech.tech[index].maxCount) { // if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); @@ -327,12 +328,9 @@ const build = { // setTimeout(() => { //return energy // who.classList.add("build-tech-selected") // }, 50); - // } // } - - //update tech text //disable not allowed tech for (let i = 0, len = tech.tech.length; i < len; i++) { const techID = document.getElementById("tech-" + i) @@ -367,12 +365,14 @@ const build = { } else { techID.innerHTML = `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}` } + //deselect selected tech options if you don't have the tech any more // for example: when bot techs are converted after a bot upgrade tech is taken + if (tech.tech[i].count === 0 && techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected"); if (techID.classList.contains("experiment-grid-disabled")) { techID.classList.remove("experiment-grid-disabled"); techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`); } - } else { + } else { //disabled color // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].description}` diff --git a/js/level.js b/js/level.js index 166ccf7..c651f69 100644 --- a/js/level.js +++ b/js/level.js @@ -37,7 +37,7 @@ const level = { // level.final() //final boss level // level.gauntlet(); //before final boss level // level.testChamber() - // level.sewers(); + // level.sewers(); // level.satellite(); // level.skyscrapers(); // level.aerie(); @@ -95,13 +95,13 @@ const level = { powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); } if (tech.isHealLowHealth) { - const len = Math.floor((m.maxHealth - m.health) / 0.5) - for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 60 * (Math.random() - 0.5), player.position.y + 60 * (Math.random() - 0.5), "heal", false); + const len = Math.floor((m.maxHealth - m.health) / 0.33) + for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false); } if (tech.isMACHO) spawn.MACHO() for (let i = 0; i < tech.wimpCount; i++) { spawn.WIMP() - for (let j = 0, len = 1 + 2 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) + for (let j = 0, len = 1 + 5 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) } for (let i = 0; i < tech.wimpExperiment; i++) spawn.WIMP() if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) { @@ -115,24 +115,24 @@ const level = { difficultyIncrease(num = 1) { for (let i = 0; i < num; i++) { simulation.difficulty++ - b.dmgScale *= 0.94; //damage done by player decreases each level + b.dmgScale *= 0.92; //damage done by player decreases each level if (simulation.accelScale < 5) simulation.accelScale *= 1.02 //mob acceleration increases each level if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks decreases each level if (simulation.CDScale > 0.2) simulation.CDScale *= 0.97 //mob CD time decreases each level } - simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level + simulation.dmgScale = 0.385 * simulation.difficulty //damage done by mobs increases each level simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale; }, difficultyDecrease(num = 1) { //used in easy mode for simulation.reset() for (let i = 0; i < num; i++) { simulation.difficulty-- - b.dmgScale /= 0.94; //damage done by player decreases each level + b.dmgScale /= 0.92; //damage done by player decreases each level if (simulation.accelScale > 0.2) simulation.accelScale /= 1.02 //mob acceleration increases each level if (simulation.lookFreqScale < 5) simulation.lookFreqScale /= 0.98 //mob cycles between looks decreases each level if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level } if (simulation.difficulty < 1) simulation.difficulty = 0; - simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level + simulation.dmgScale = 0.385 * simulation.difficulty //damage done by mobs increases each level if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1; simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) }, @@ -1569,8 +1569,8 @@ const level = { spawn.mapRect(1225, -1955, 175, 30); const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals let portal, portal2, portal3 - const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser - const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser + const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser + const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser const button = level.button(2100, -2600) const buttonDoor = level.button(600, -550) const door = level.door(312, -750, 25, 190, 185) @@ -1758,11 +1758,13 @@ const level = { button.max.x = -button.max.x + 126 // flip the button horizontally buttonDoor.min.x = -buttonDoor.min.x - 126 // flip the button horizontally buttonDoor.max.x = -buttonDoor.max.x + 126 // flip the button horizontally - hazard.min.x = -hazard.min.x - 700 //-x-width - hazard.max.x = -hazard.max.x - 700 //-x-width - hazard2.min.x = -hazard2.min.x - 150 //-x-width - hazard2.max.x = -hazard2.max.x - 150 //-x-width + //this makes the hazard draw, but not collide for reasons I don't understand + //so don't use it, instead just call the hazard differently based on this flip flag + // hazard.min.x = -hazard.min.x - hazard.width //-x-width + // hazard.max.x = -hazard.max.x - hazard.width //-x-width + // hazard2.min.x = -hazard2.min.x - hazard2.width //-x-width + // hazard2.max.x = -hazard2.max.x - hazard2.width //-x-width portal = level.portal({ x: -2475, y: -140 @@ -1789,6 +1791,7 @@ const level = { // level.custom = () => { }; // level.customTopLayer = () => {}; + } else { portal = level.portal({ x: 2475, @@ -1816,7 +1819,8 @@ const level = { }, sewers() { const button1 = level.button(6600, 2675) - const hazard = level.hazard(4550, 2750, 4550, 150) + // const hazard = level.hazard(4550, 2750, 4550, 150) + const hazard = level.hazard(simulation.isHorizontalFlipped ? -4550 - 4550 : 4550, 2750, 4550, 150) let balance1, balance2, balance3, balance4, rotor const drip1 = level.drip(6100, 1900, 2900, 100) // drip(x, yMin, yMax, period = 100, color = "hsla(160, 100%, 35%, 0.5)") { @@ -1969,8 +1973,6 @@ const level = { drip1.x *= -1 drip2.x *= -1 drip3.x *= -1 - hazard.min.x = -hazard.min.x - 4550 //-x-width - hazard.max.x = -hazard.max.x - 4550 //-x-width level.custom = () => { drip1.draw(); drip2.draw(); @@ -6120,7 +6122,7 @@ const level = { addConstraint(x + 3100 * s, y - height, 0, -10 * s, stiffness, composite[composite.length - 1], pin); } }, - tunnel() { + tunnel() { // by Scarlettt level.custom = () => { level.playerExitCheck(); @@ -6229,21 +6231,7 @@ const level = { secretHazard.draw(); button.draw(); - function drawFlame(x, y, color = "#f81", angle = Math.PI / 2) { - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.strokeStyle = color; - ctx.lineWidth = 3; - for (let i = 0; i < 3; i++) { - let randAng = (Math.random() - 0.5) * 2 + angle; - randLen = 30 + Math.random() * 10; - x = x + Math.cos(randAng) * randLen; - y = y - Math.sin(randAng) * randLen; - ctx.lineTo(x, y); - } - ctx.stroke(); - } // Fire damage let isInRange = flames.reduce((a, i) => a || Math.sqrt((m.pos.x - i[0]) * (m.pos.x - i[0]) + (m.pos.y + 90 - i[1]) * (m.pos.y + 90 - i[1])) < 50, false); @@ -6314,54 +6302,6 @@ const level = { ctx.fillRect(1480, -5000, 1070, 1710); } - function drawProject(startPos, endPos1, endPos2, tValue, tValueM) { - ctx.strokeStyle = "#003"; - ctx.fillStyle = "#0055aa" + ('0' + (tValue * 60 / tValueM).toString(16)).slice(-2); - - let inter = (tValueM - tValue) / tValueM; - let endpos1i = endPos1.map((i, j) => (startPos[j] - i) * inter), - endpos2i = endPos2.map((i, j) => (startPos[j] - i) * inter); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); - ctx.fill(); - ctx.stroke(); - - if (tValue >= tValueM * 2 / 3) { - ctx.fillStyle = "#0055aa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 6.25 * 60 / tValueM).toString(16)).slice(-2); - ctx.strokeStyle = "#000033" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); - ctx.fillRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); - ctx.shadowColor = "#00aaaa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); - ctx.shadowBlur = 10; - ctx.strokeRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); - ctx.shadowBlur = 0; - ctx.shadowColor = "#0000"; - } - } - if (secretAnimTrans > 0) { drawProject([3614, -3530], [2900, -3900], [3400, -3600], secretAnimTrans, 60); if (secretAnimTrans >= 42) { @@ -6399,7 +6339,7 @@ const level = { ctx.fillText("Entity name: m", 1560, -3830); ctx.fillStyle = (tech.totalCount < 25 ? (tech.totalCount < 10 ? "#ffff44" : "#22ff22") : "#ff6644") + Math.floor((secretAnimTrans2 - 40) * 12.75).toString(16); ctx.fillText("Threat level: " + (tech.totalCount < 25 ? (tech.totalCount < 10 ? "Low" : "Medium") : "HIGH"), 1560, -3790); - if (tech.totalCount >= 10) ctx.fillText("PROCEDURE ACTIVATED", 1560, -3750); + if (tech.totalCount >= 15) ctx.fillText("PROCEDURE ACTIVATED", 1560, -3750); ctx.strokeStyle = "#00ff00" + Math.floor((secretAnimTrans2 - 40) * 6).toString(16); ctx.beginPath(); ctx.arc(1950, -3730, 60, 0, 2 * Math.PI); @@ -6416,9 +6356,8 @@ const level = { if (secretAnimTrans2 >= 60) { if (!emergencyActivated && tech.totalCount >= 10) { for (let i = 0; i < 5; i++) { - let randomNum = Math.random() * Math.PI; - spawn.exploder(m.pos.x + Math.cos(randomNum) * 200, m.pos.y + Math.sin(randomNum) * 200); - if (tech.totalCount >= 25) spawn.randomMob(m.pos.x + Math.cos(randomNum) * 200, m.pos.y + Math.sin(randomNum) * 200, Infinity); + spawn.exploder(1614, -3900); + if (tech.totalCount >= 25) spawn.randomMob(1614, -3900, Infinity); } emergencyActivated = true; } @@ -6592,5 +6531,70 @@ const level = { if (simulation.difficulty > 5) spawn[["shooterBoss", "launcherBoss"][randomBoss]](7500, -150); else spawn[["shooter", "launcher"][randomBoss]](7500, -150, 150); spawn[["shooter", "launcher"][randomBoss]](8500, -150, 150); + + // canvas stuff + function drawFlame(x, y, color = "#f81", angle = Math.PI / 2) { + ctx.beginPath(); + ctx.moveTo(x, y); + ctx.strokeStyle = color; + ctx.lineWidth = 3; + for (let i = 0; i < 3; i++) { + let randAng = (Math.random() - 0.5) * 2 + angle; + randLen = 30 + Math.random() * 10; + + x = x + Math.cos(randAng) * randLen; + y = y - Math.sin(randAng) * randLen; + ctx.lineTo(x, y); + } + ctx.stroke(); + } + + function drawProject(startPos, endPos1, endPos2, tValue, tValueM) { + ctx.strokeStyle = "#003"; + ctx.fillStyle = "#0055aa" + ('0' + (tValue * 60 / tValueM).toString(16)).slice(-2); + + let inter = (tValueM - tValue) / tValueM; + let endpos1i = endPos1.map((i, j) => (startPos[j] - i) * inter), + endpos2i = endPos2.map((i, j) => (startPos[j] - i) * inter); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); + ctx.fill(); + ctx.stroke(); + + if (tValue >= tValueM * 2 / 3) { + ctx.fillStyle = "#0055aa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 6.25 * 60 / tValueM).toString(16)).slice(-2); + ctx.strokeStyle = "#000033" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); + ctx.fillRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); + ctx.shadowColor = "#00aaaa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); + ctx.shadowBlur = 10; + ctx.strokeRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); + ctx.shadowBlur = 0; + ctx.shadowColor = "#0000"; + } + } } }; \ No newline at end of file diff --git a/js/player.js b/js/player.js index 555d38d..daf7242 100644 --- a/js/player.js +++ b/js/player.js @@ -499,8 +499,8 @@ const m = { let dmg = 1 dmg *= m.fieldHarmReduction if (tech.isHarmMACHO) dmg *= 0.33 - if (tech.isImmortal) dmg *= 0.79 - if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.50 : 1.1 + if (tech.isImmortal) dmg *= 0.66 + if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 @@ -513,7 +513,6 @@ const m = { if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34 if (tech.energyRegen === 0) dmg *= 0.34 if (tech.isTurret && m.crouch) dmg *= 0.55; - if (tech.isFireMoveLock && input.fire) dmg *= 0.4; if (tech.isEntanglement && b.inventory[0] === b.activeGun) { for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15 } @@ -1601,33 +1600,31 @@ const m = { } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed m.grabPowerUp(); m.lookForPickUp(); - if (m.energy > 0.05) { - //draw field - if (m.holdingTarget) { - ctx.fillStyle = "rgba(110,170,200," + (0.06 + 0.03 * Math.random()) + ")"; - ctx.strokeStyle = "rgba(110, 200, 235, " + (0.35 + 0.05 * Math.random()) + ")" - } else { - ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; - ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" - } - ctx.beginPath(); - ctx.arc(m.pos.x, m.pos.y, m.fieldRange, m.angle - Math.PI * m.fieldArc, m.angle + Math.PI * m.fieldArc, false); - ctx.lineWidth = 2.5 - 1.5 * wave; - ctx.lineCap = "butt" - ctx.stroke(); - const curve = 0.57 + 0.04 * wave - const aMag = (1 - curve * 1.2) * Math.PI * m.fieldArc - let a = m.angle + aMag - let cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) - let cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) - ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle)) - a = m.angle - aMag - cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) - cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) - ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc)) - ctx.fill(); - m.pushMobsFacing(); + //draw field + if (m.holdingTarget) { + ctx.fillStyle = "rgba(110,170,200," + (0.06 + 0.03 * Math.random()) + ")"; + ctx.strokeStyle = "rgba(110, 200, 235, " + (0.35 + 0.05 * Math.random()) + ")" + } else { + ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; + ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" } + ctx.beginPath(); + ctx.arc(m.pos.x, m.pos.y, m.fieldRange, m.angle - Math.PI * m.fieldArc, m.angle + Math.PI * m.fieldArc, false); + ctx.lineWidth = 2.5 - 1.5 * wave; + ctx.lineCap = "butt" + ctx.stroke(); + const curve = 0.57 + 0.04 * wave + const aMag = (1 - curve * 1.2) * Math.PI * m.fieldArc + let a = m.angle + aMag + let cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) + let cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) + ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle)) + a = m.angle - aMag + cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) + cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) + ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc)) + ctx.fill(); + m.pushMobsFacing(); } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released m.pickUp(); } else { @@ -1664,7 +1661,7 @@ const m = { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) { if (tech.isSporeField) { for (let i = 0, len = Math.random() * 20; i < len; i++) { - m.energy -= 0.085 + m.energy -= 0.08 if (m.energy > 0) { b.spore(m.pos) } else { @@ -1673,10 +1670,10 @@ const m = { } } } else if (tech.isMissileField) { - m.energy -= 0.32; + m.energy -= 0.3; b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) } else if (tech.isIceField) { - m.energy -= 0.046; + m.energy -= 0.04; b.iceIX(1) } else { m.energy -= 0.45 * tech.droneEnergyReduction; diff --git a/js/powerup.js b/js/powerup.js index 3fa9a3d..7cb9513 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -164,7 +164,7 @@ const powerUps = { tech.maxDuplicationEvent() } if (tech.isCancelRerolls) { - for (let i = 0; i < 8; i++) { + for (let i = 0; i < 10; i++) { let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo" if (Math.random() < 0.33) { spawnType = "heal" @@ -286,7 +286,7 @@ const powerUps = { } } if (tech.healGiveMaxEnergy) { - tech.healMaxEnergyBonus += 0.05 + tech.healMaxEnergyBonus += 0.06 m.setMaxEnergy(); } }, @@ -308,7 +308,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(0.7 * Math.random() * target.ammoPack) * (tech.isAlwaysFire ? 3 : 1) + const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(0.7 * Math.random() * target.ammoPack) target.ammo += ammoAdded simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } @@ -316,7 +316,7 @@ const powerUps = { for (let i = 0, len = b.inventory.length; i < len; i++) { const target = b.guns[b.inventory[i]] if (target.ammo !== Infinity) { - const ammoAdded = Math.ceil(Math.random() * target.ammoPack) * (tech.isAlwaysFire ? 3 : 1) + const ammoAdded = Math.ceil(Math.random() * target.ammoPack) target.ammo += ammoAdded simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } diff --git a/js/simulation.js b/js/simulation.js index 103c5e8..8e6a2b6 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -506,10 +506,10 @@ const simulation = { if (!m.isShipMode) { m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech m.spawn(); //spawns the player + m.look = m.lookDefault } else { World.add(engine.world, [player]) } - m.look = m.lookDefault simulation.isHorizontalFlipped = (Math.random() < 0.5) ? true : false //if true, some maps are flipped horizontally level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment @@ -790,7 +790,7 @@ const simulation = { } if (tech.relayIce && tech.isFlipFlopOn) { for (let j = 0; j < tech.relayIce; j++) { - for (let i = 0, len = Math.ceil(5 * Math.random()); i < len; i++) b.iceIX(2) + for (let i = 0, len = Math.ceil(8 * Math.random()); i < len; i++) b.iceIX(2) } } diff --git a/js/spawn.js b/js/spawn.js index 6551bb6..a4fd140 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1474,7 +1474,7 @@ const spawn = { } mobs.spawn(x, y, 0, radius, "transparent"); let me = mob[mob.length - 1]; - Matter.Body.setDensity(me, 0.3); //extra dense //normal is 0.001 + Matter.Body.setDensity(me, 0.25); //extra dense //normal is 0.001 me.laserRange = 350; me.seeAtDistance2 = 2000000; me.isBoss = true; diff --git a/js/tech.js b/js/tech.js index 1bcea61..af7fa03 100644 --- a/js/tech.js +++ b/js/tech.js @@ -158,17 +158,17 @@ let dmg = 1 //m.fieldDamage if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 - if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.85 + if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66 if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= 4 if (tech.isTechDamage) dmg *= 1.9 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5 - if (tech.isMaxEnergyTech) dmg *= 1.4 - if (tech.isEnergyNoAmmo) dmg *= 1.5 - if (tech.isDamageForGuns) dmg *= 1 + 0.14 * b.inventory.length + if (tech.isMaxEnergyTech) dmg *= 1.5 + if (tech.isEnergyNoAmmo) dmg *= 1.6 + if (tech.isDamageForGuns) dmg *= 1 + 0.1 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - m.health) if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; - if (tech.isEnergyLoss) dmg *= 1.45; + if (tech.isEnergyLoss) dmg *= 1.55; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9; @@ -181,7 +181,7 @@ return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance + return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.047 + tech.duplicateChance + m.duplicateChance }, maxDuplicationEvent() { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { @@ -250,7 +250,7 @@ }, { name: "arsenal", - description: "increase damage by 14%
for each gun in your inventory", + description: "increase damage by 10%
for each gun in your inventory", maxCount: 1, count: 0, frequency: 2, @@ -286,7 +286,7 @@ }, { name: "generalist", - description: "spawn 6 guns, but you can't switch guns
guns cycle automatically with each new level", + description: "spawn 8 guns, but you can't switch guns
guns cycle automatically with each new level", maxCount: 1, count: 0, frequency: 2, @@ -296,11 +296,11 @@ requires: "arsenal or active cooling", effect() { tech.isGunCycle = true; - for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); + for (let i = 0; i < 8; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); }, remove() { if (tech.isGunCycle) { - for (let i = 0; i < 6; i++) { + for (let i = 0; i < 8; i++) { if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun } tech.isGunCycle = false; @@ -447,63 +447,19 @@ tech.isTurret = false; } }, - { - name: "inertial frame", - description: "66% decreased delay after firing
you can only fire when at rest", - maxCount: 1, - count: 0, - frequency: 2, - allowed() { - return !m.isShipMode - }, - requires: "not ship mode", - effect: () => { - tech.isFireNotMove = true; - b.setFireCD(); - b.setFireMethod(); - }, - remove() { - if (tech.isFireNotMove) { - tech.isFireNotMove = false - b.setFireCD(); - b.setFireMethod(); - } - } - }, - { - name: "automatic", - description: "always fire when at rest
ammo power ups give 250% ammo", - maxCount: 1, - count: 0, - frequency: 4, - allowed() { - return tech.isFireNotMove && !tech.isFireMoveLock - }, - requires: "inertial frame, not Higgs mechanism", - effect: () => { - tech.isAlwaysFire = true; - b.setFireMethod(); - }, - remove() { - if (tech.isAlwaysFire) { - tech.isAlwaysFire = false - b.setFireMethod(); - } - } - }, { name: "dead reckoning", - description: "increase damage by 30% when at rest", + description: "increase damage by 36% when at rest", maxCount: 9, count: 0, - frequency: 4, - frequencyDefault: 4, + frequency: 1, + frequencyDefault: 1, allowed() { - return tech.isFireNotMove + return true }, - requires: "inertial frame", + requires: "", effect: () => { - tech.restDamage += 0.3 + tech.restDamage += 0.36 }, remove() { tech.restDamage = 1; @@ -511,21 +467,23 @@ }, { name: "Higgs mechanism", - description: "while firing your position is locked
and harm is reduced by 60%", + description: "while firing your position is locked
50% decreased delay after firing", maxCount: 1, count: 0, frequency: 2, allowed() { - return !tech.isEnergyHealth && !m.isShipMode && !tech.isAlwaysFire + return !m.isShipMode && !tech.isAlwaysFire }, - requires: "not mass energy, not ship mode, not automatic", + requires: "not ship mode, not automatic", effect: () => { tech.isFireMoveLock = true; + b.setFireCD(); b.setFireMethod(); }, remove() { if (tech.isFireMoveLock) { tech.isFireMoveLock = false + b.setFireCD(); b.setFireMethod(); } } @@ -585,23 +543,6 @@ tech.isSpeedDamage = false } }, - // { - // name: "Galilean group", - // description: "reduce harm by 50% when at rest", - // maxCount: 1, - // count: 0, - // frequency: 2, - // allowed() { - // return tech.isFireNotMove || tech.isFireMoveLock - // }, - // requires: "inertial frame or Higgs manism", - // effect() { - // tech.isRestHarm = true - // }, - // remove() { - // tech.isRestHarm = false; - // } - // }, { name: "kinetic bombardment", description: "increase damage by up to 33%
at a distance of 40 steps from the target", @@ -762,7 +703,7 @@ }, { name: "ammonium nitrate", - description: "increase explosive damage by 20%
increase explosive radius by 20%", + description: "increase explosive damage by 25%
increase explosive radius by 25%", maxCount: 9, count: 0, frequency: 2, @@ -771,7 +712,7 @@ }, requires: "an explosive damage source, not iridium-192", effect: () => { - tech.explosiveRadius += 0.2; + tech.explosiveRadius += 0.25; }, remove() { tech.explosiveRadius = 1; @@ -918,7 +859,7 @@ }, { name: "zoospore vector", - description: "mobs produce spores when they die
9% chance", + description: "mobs produce spores when they die
11% chance", maxCount: 9, count: 0, frequency: 2, @@ -927,7 +868,7 @@ }, requires: "no other mob death tech", effect() { - tech.sporesOnDeath += 0.09; + tech.sporesOnDeath += 0.11; for (let i = 0; i < 8; i++) { b.spore(m.pos) } @@ -965,7 +906,7 @@ count: 0, frequency: 2, allowed() { - return (b.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth + return (b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth }, requires: "drones, spores, mines, or bots", effect() { @@ -1708,7 +1649,7 @@ }, { name: "thermocouple", - description: "if relay switch is in the ON state
condense 1-5 ice IX crystals every second", + description: "if relay switch is in the ON state
condense 1-7 ice IX crystals every second", maxCount: 9, count: 0, frequency: 4, @@ -2078,7 +2019,7 @@ }, { name: "1st ionization energy", - description: "each heal power up you collect
increases your maximum energy by 5", + description: "each heal power up you collect
increases your maximum energy by 6", maxCount: 1, count: 0, frequency: 3, @@ -2121,7 +2062,7 @@ }, { name: "exciton-lattice", - description: `increase damage by 50%, but
ammo will no longer spawn`, + description: `increase damage by 60%, but
ammo will no longer spawn`, maxCount: 1, count: 0, frequency: 2, @@ -2138,7 +2079,7 @@ }, { name: "exothermic process", - description: "increase damage by 45%
if a mob dies drain energy by 25%", + description: "increase damage by 50%
if a mob dies drain energy by 25%", maxCount: 1, count: 0, frequency: 2, @@ -2155,7 +2096,7 @@ }, { name: "heat engine", - description: `increase damage by 40%, but
reduce maximum energy by 50`, + description: `increase damage by 50%, but
reduce maximum energy by 50`, maxCount: 1, count: 0, frequency: 4, @@ -2193,7 +2134,7 @@ }, { name: "overcharge", - description: "increase your maximum energy by 50", + description: "increase your maximum energy by 60
add 10 JUNK tech to the potential pool", maxCount: 9, count: 0, frequency: 1, @@ -2204,15 +2145,17 @@ effect() { tech.bonusEnergy += 0.5 m.setMaxEnergy() + tech.addJunkTechToPool(10) }, remove() { tech.bonusEnergy = 0; m.setMaxEnergy() + if (this.count > 0) tech.removeJunkTechFromPool(10) } }, { name: "Maxwell's demon", - description: "energy above your max decays 92% slower
add 17 JUNK tech to the potential pool", + description: "energy above your max decays 92% slower
add 18 JUNK tech to the potential pool", maxCount: 1, count: 0, frequency: 2, @@ -2222,11 +2165,11 @@ requires: "a source of overfilled energy", effect() { tech.overfillDrain = 0.87 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87) - tech.addJunkTechToPool(17) + tech.addJunkTechToPool(18) }, remove() { tech.overfillDrain = 0.75 - if (this.count > 0) tech.removeJunkTechFromPool(17) + if (this.count > 0) tech.removeJunkTechFromPool(18) } }, { @@ -2285,7 +2228,7 @@ }, { name: "dormancy", - description: "if a mob has died in the last 5 seconds
increase damage by 50% else decrease it by 15%", + description: "if a mob has died in the last 5 seconds
increase damage by 100% else decrease it by 33%", maxCount: 1, count: 0, frequency: 2, @@ -2302,7 +2245,7 @@ }, { name: "torpor", - description: "if a mob has died in the last 5 seconds
reduce harm by 50% else increase it by 10%", + description: "if a mob has died in the last 5 seconds
reduce harm by 66% else increase it by 15%", maxCount: 1, count: 0, frequency: 4, @@ -2468,7 +2411,7 @@ }, { name: "negentropy", - description: `at the start of each level
spawn a heal for every 50 missing health`, + description: `at the start of each level
spawn a heal for every 33 missing health`, maxCount: 1, count: 0, frequency: 2, @@ -2571,7 +2514,7 @@ }, { name: "quantum immortality", - description: "after dying, continue in an alternate reality
reduce harm by 23%", //spawn 4 research + description: "after dying, continue in an alternate reality
reduce harm by 33%", //spawn 4 research maxCount: 1, count: 0, frequency: 4, @@ -2629,7 +2572,7 @@ }, { name: "Ψ(t) collapse", - description: "enter an alternate reality after you research
spawn 12 research", + description: "enter an alternate reality after you research
spawn 15 research", maxCount: 1, count: 0, frequency: 1, @@ -2640,7 +2583,7 @@ requires: "not quantum immortality, many-worlds, non-unitary", effect() { tech.isResearchReality = true; - for (let i = 0; i < 12; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false); + for (let i = 0; i < 15; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false); }, remove() { tech.isResearchReality = false; @@ -2772,7 +2715,7 @@ { name: "WIMPs", //harmful - description: "a harmful particle slowly chases you
spawn 2-3 research at the end of each level", + description: "a harmful particle slowly chases you
spawn 2-6 research at the end of each level", maxCount: 9, count: 0, frequency: 1, @@ -2826,7 +2769,7 @@ }, { name: "replication", - description: "8% chance to duplicate spawned power ups
add 18 JUNK tech to the potential pool", + description: "10% chance to duplicate spawned power ups
add 18 JUNK tech to the potential pool", maxCount: 9, count: 0, frequency: 1, @@ -2836,7 +2779,7 @@ }, requires: "below 100% duplication chance", effect() { - tech.duplicateChance += 0.08 + tech.duplicateChance += 0.1 powerUps.setDo(); //needed after adjusting duplication chance tech.addJunkTechToPool(18) }, @@ -2848,7 +2791,7 @@ }, { name: "stimulated emission", - description: "20% chance to duplicate spawned power ups
but, after a collision eject 1 tech", + description: "22% chance to duplicate spawned power ups
but, after a collision eject 1 tech", maxCount: 1, count: 0, frequency: 1, @@ -2908,7 +2851,7 @@ // }, { name: "futures exchange", - description: "clicking × to cancel a field, tech, or gun
adds 4.3% power up duplication chance", + description: "clicking × to cancel a field, tech, or gun
adds 4.7% power up duplication chance", maxCount: 1, count: 0, frequency: 1, @@ -2930,7 +2873,7 @@ }, { name: "commodities exchange", - description: "clicking × to cancel a field, tech, or gun
spawns 8 heals, ammo, and research", + description: "clicking × to cancel a field, tech, or gun
spawns 10 heals, ammo, and research", maxCount: 1, count: 0, frequency: 1, @@ -4107,7 +4050,7 @@ }, { name: "tinsellated flagella", - description: "sporangium release 2 more spores
spores accelerate 50% faster", + description: "sporangium release 2 more spores
spores accelerate 40% faster", isGunTech: true, maxCount: 1, count: 0, @@ -4216,7 +4159,7 @@ }, { name: "reduced tolerances", - description: "reduce drone energy/ammo costs by 66%
reduce the average drone lifetime by 40%", + description: "increase drone ammo/efficiency by 66%
reduce the average drone lifetime by 40%", isGunTech: true, maxCount: 3, count: 0, @@ -4947,7 +4890,7 @@ }, { name: "annihilation", - description: "touching normal mobs annihilates them
drains 33% of your maximum energy", + description: "touching normal mobs annihilates them
but drains 33% of your maximum energy", isFieldTech: true, maxCount: 1, count: 0, @@ -5306,7 +5249,7 @@ }, { name: "traversable geodesics", - description: "your bullets can traverse wormholes
spawn a gun and ammo", + description: "your bullets can traverse wormholes
spawn 2 guns and ammo", isFieldTech: true, maxCount: 1, count: 0, @@ -5317,11 +5260,18 @@ requires: "wormhole", effect() { tech.isWormBullets = true - powerUps.spawn(m.pos.x, m.pos.y, "gun"); - powerUps.spawn(m.pos.x, m.pos.y, "ammo"); + for (let i = 0; i < 2; i++) { + powerUps.spawn(m.pos.x, m.pos.y, "gun"); + powerUps.spawn(m.pos.x, m.pos.y, "ammo"); + } }, remove() { - tech.isWormBullets = false + if (tech.isWormBullets) { + for (let i = 0; i < 2; i++) { + if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun + } + tech.isWormBullets = false; + } } }, //************************************************** @@ -5338,7 +5288,7 @@ isBadRandomOption: true, isExperimentalMode: true, allowed() { - return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" && !tech.isFireNotMove + return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" }, requires: "", effect() { @@ -5499,6 +5449,29 @@ // }, // remove() {} // }, + { + name: "automatic", + description: "you can't fire when moving
always fire when at rest", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isJunk: true, + allowed() { + return !tech.isFireMoveLock + }, + requires: "not Higgs mechanism", + effect: () => { + tech.isAlwaysFire = true; + b.setFireMethod(); + }, + remove() { + if (tech.isAlwaysFire) { + tech.isAlwaysFire = false + b.setFireMethod(); + } + } + }, { name: "hidden variable", description: "spawn 30 heal power ups
but hide your health bar", @@ -5613,7 +5586,7 @@ } }, remove() { - m.look = m.lookDefault + if (this.count) m.look = m.lookDefault } }, { @@ -5709,7 +5682,7 @@ } }, remove() { - m.look = m.lookDefault + if (this.count) m.look = m.lookDefault } }, { @@ -6868,7 +6841,6 @@ isFireRateForGuns: null, cyclicImmunity: null, isTechDamage: null, - isFireNotMove: null, isRestHarm: null, isFireMoveLock: null, isRivets: null, diff --git a/todo.txt b/todo.txt index d4075bf..e68e5ad 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,54 @@ ******************************************************** NEXT PATCH ******************************************************** +over all game difficulty scaling occurs faster + your damage will feel lower, and you will take more harm, + so you should probably play on a lower difficulty + +tech: Higgs manism gives 50% reduced fire delay instead of harm reduction +tech: inertial frame is removed +tech: automatic is now a junk tech + +balance: + dead reckoning gives 36% damage when at rest (was 30%) + overcharge gives 10 more energy, but adds 10 junk tech + 1st ionization energy gives 6 energy per heal (was 5) + dormancy increases damage by 100% but lowers it by 33% if no recent kills (was +50%, -15%) + torpor decreases harm by 66% increases harm by 15% if no recent kills (was -50%, +10%) + Ψ(t) collapse spawns 3 more research, so it's at 15 + fragmentation gives 30% more nails for railgun + ammonium nitrate +25% (was 20%) + generalist gives 8 guns (was 6) + arsenal gives 10% per gun (was 14%) + rivet gun fires 25% faster, rivets are 15% larger + shotgun slug is 33% bigger + missile bot fires 10% more often + tinsellated flagella gives 40% speed increase (was 50%), base spore speed is 10% faster + beamSplitter has a 20% lower divergence + nano manufacturing tech is all buffed 15% + traversable geodesics gives 2 guns and ammo (was 1) + mines have 25% more nails, laser mines use 20% less energy sentry mines last 33% seconds longer + zoospore vector has an 11% chance to spawn (was 9%) + negentropy spawns a heal for every 33 missing health (was 50 health) + exciton-lattice gives 60% damage + thermocouple spawns 1-8 ice-IX (was 1-5) + WIMPs spawn 2-6 research (was 2-3) + quantum immortality reduces harm by 33% (was 23%) + commodities exchange gives 10 power ups (was 8) + super balls are 17% bigger (this means they do about 25% more damage) + exothermic process increases damage by (was 45%) + heat engine increases damage by 50% (was 40%) + replication gives 10% duplication chance (was 8%) + stimulated emission gives 22% duplication chance + futures exchange gives 4.7% duplication chance per cancel (was 4.3%) + needles are 10% slower and do 15% more damage + +bug fixes: + reduced tolerances text rewritten to clarify that it gives more ammo per ammo pack + hazards on horizontal flipped levels now correctly do damage + ship mode aims properly after you die + although it still doesn't reset + experiment mode selections are highlighted better + ******************************************************** BUGS ******************************************************** @@ -28,6 +77,12 @@ is there a way to check if the player is stuck inside the map or block ******************************************************** TODO ******************************************************** +* inductive coupling - sucks without catabolism, too much delayed gratification. should probably be bundled with transceiver chip + +tech: cloaking field - decrease/increase cooldown on sneak attack? + decrease/increase damage bonus? + decrease/increase visual radius? + have throw charge scale with fire delay in testing mode console log the body you click on