diff --git a/.DS_Store b/.DS_Store index 949d80d..2ff3b21 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index fab7d0d..a5ac1fa 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -741,6 +741,7 @@ const b = { bullet[me].endCycle = simulation.cycle + Math.floor(input.down ? 120 : 80); bullet[me].restitution = 0.4; bullet[me].do = function() { + // console.log(this.mass * 0.0025) this.force.y += this.mass * 0.0025; //extra gravity for harder arcs }; Composite.add(engine.world, bullet[me]); //add bullet to world @@ -794,6 +795,7 @@ const b = { this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion }; speed = input.down ? 46 : 32 + Matter.Body.setVelocity(bullet[me], { x: m.Vx / 2 + speed * Math.cos(angle), y: m.Vy / 2 + speed * Math.sin(angle) @@ -917,6 +919,8 @@ const b = { } }; speed = 35 + // speed = input.down ? 43 : 32 + bullet[me].endCycle = simulation.cycle + 70; if (input.down) { speed += 9 @@ -950,6 +954,8 @@ const b = { Matter.Body.scale(bullet[me], SCALE, SCALE); speed = input.down ? 25 : 15 + // speed = input.down ? 43 : 32 + Matter.Body.setVelocity(bullet[me], { x: m.Vx / 2 + speed * Math.cos(angle), y: m.Vy / 2 + speed * Math.sin(angle) @@ -1092,9 +1098,36 @@ const b = { } } } + let gunIndex = null + for (let i = 0, len = b.guns.length; i < len; i++) { + if (b.guns[i].name === "grenades") { + gunIndex = i + } + } + + if (tech.isNeutronBomb) { b.grenade = grenadeNeutron + if (tech.isRPG) { + b.guns[gunIndex].do = function() {} + } else { + if (gunIndex) b.guns[gunIndex].do = function() { + const cycles = 80 + const speed = input.down ? 35 : 20 //input.down ? 43 : 32 + const g = input.down ? 0.137 : 0.135 + const v = { x: m.Vx / 2 + speed * Math.cos(m.angle), y: m.Vy / 2 + speed * Math.sin(m.angle) } + ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map + ctx.lineWidth = 2 + ctx.beginPath() + for (let i = 1, len = 19; i < len + 1; i++) { + const time = cycles * i / len + ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + g * time * time) + } + ctx.stroke() + } + } } else if (tech.isRPG) { + b.guns[gunIndex].do = function() {} if (tech.isVacuumBomb) { b.grenade = grenadeRPGVacuum } else { @@ -1102,8 +1135,34 @@ const b = { } } else if (tech.isVacuumBomb) { b.grenade = grenadeVacuum + if (gunIndex) b.guns[gunIndex].do = function() { + const cycles = Math.floor(input.down ? 50 : 30) //30 + const speed = input.down ? 44 : 35 + const v = { x: m.Vx / 2 + speed * Math.cos(m.angle), y: m.Vy / 2 + speed * Math.sin(m.angle) } + ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map + ctx.lineWidth = 2 + ctx.beginPath() + for (let i = 1.6, len = 19; i < len + 1; i++) { + const time = cycles * i / len + ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + 0.34 * time * time) + } + ctx.stroke() + } } else { b.grenade = grenadeDefault + if (gunIndex) b.guns[gunIndex].do = function() { + const cycles = Math.floor(input.down ? 120 : 80) //30 + const speed = input.down ? 43 : 32 + const v = { x: m.Vx / 2 + speed * Math.cos(m.angle), y: m.Vy / 2 + speed * Math.sin(m.angle) } + ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map + ctx.lineWidth = 2 + ctx.beginPath() + for (let i = 0.5, len = 19; i < len + 1; i++) { + const time = cycles * i / len + ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + 0.34 * time * time) + } + ctx.stroke() + } } }, harpoon(where, target, angle = m.angle, harpoonLength = 1, isReturn = false, totalCycles = 15) { @@ -2437,7 +2496,14 @@ const b = { if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle) { const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0) b.explosion(this.position, max * 0.1 + this.isImproved * 110 + 60 * Math.random()); //makes bullet do explosive damage at end - this.endCycle -= max + if (tech.isForeverDrones) { + this.endCycle = 0 + b.drone({ x: m.pos.x + 30 * (Math.random() - 0.5), y: m.pos.y + 30 * (Math.random() - 0.5) }, 5) + bullet[bullet.length - 1].endCycle = Infinity + } else { + + this.endCycle -= max + } } else { //move away from target after hitting const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20) diff --git a/js/index.js b/js/index.js index c624667..caafb22 100644 --- a/js/index.js +++ b/js/index.js @@ -223,7 +223,7 @@ const build = { damage increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}%
harm reduction: ${harm.toFixed(harm > 90 ? 2 : 0)}%
fire delay decrease: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% -
duplication chance: ${(Math.min(1,tech.duplicationChance())*100).toFixed(0)}% +
duplication chance: ${(tech.duplicationChance()*100).toFixed(0)}% ${botText}

tech: ${tech.totalCount}   research: ${powerUps.research.count} diff --git a/js/level.js b/js/level.js index e1eefe7..c9247c9 100644 --- a/js/level.js +++ b/js/level.js @@ -16,9 +16,9 @@ const level = { // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // m.setField("time dilation") - // b.giveGuns("harpoon") - // tech.giveTech("retrocausality") - // tech.giveTech("causality bots") + // b.giveGuns("grenades") + // tech.giveTech("neutron bomb") + // tech.giveTech("vacuum bomb") // tech.giveTech("causality bombs") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // tech.giveTech("antiscience") diff --git a/js/mob.js b/js/mob.js index 6a9e31d..1b1c331 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1167,7 +1167,7 @@ const mobs = { } } if (tech.cloakDuplication && !this.isBoss) { - tech.cloakDuplication -= 0.01 + tech.cloakDuplication -= 0.02 powerUps.setDupChance(); //needed after adjusting duplication chance } } else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) { diff --git a/js/spawn.js b/js/spawn.js index 3372f2e..d1c36f6 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -2379,10 +2379,10 @@ const spawn = { this.checkStatus(); }; }, - pulsarBoss(x, y, radius = 90) { + pulsarBoss(x, y, radius = 90, isNonCollide = false) { mobs.spawn(x, y, 3, radius, "#a0f"); let me = mob[mob.length - 1]; - + if (isNonCollide) me.collisionFilter.mask = cat.bullet | cat.player setTimeout(() => { //fix mob in place, but allow rotation me.constraint = Constraint.create({ pointA: { diff --git a/js/tech.js b/js/tech.js index 14ea775..81b36f7 100644 --- a/js/tech.js +++ b/js/tech.js @@ -234,18 +234,21 @@ return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return Math.max(0, (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.17 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)) + return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.45 : 0)) }, isScaleMobsWithDuplication: false, maxDuplicationEvent() { - if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { - tech.is100Duplicate = false - const range = 500 + if (tech.is111Duplicate && tech.duplicationChance() > 1.11) { + tech.is111Duplicate = false + const range = 1300 tech.isScaleMobsWithDuplication = true - for (let i = 0, len = 8; i < len; i++) { + for (let i = 0, len = 9; i < len; i++) { const angle = 2 * Math.PI * i / len spawn.randomLevelBoss(m.pos.x + range * Math.cos(angle), m.pos.y + range * Math.sin(angle), spawn.nonCollideBossList); } + spawn.historyBoss(0, 0) + spawn.pulsarBoss(level.exit.x, level.exit.y, 70, true) + spawn.blockBoss(level.enter.x, level.enter.y) tech.isScaleMobsWithDuplication = false } }, @@ -2850,15 +2853,15 @@ }, { name: "weak anthropic principle", - description: "after anthropic principle prevents your death
add 50% duplication chance for that level", + description: "after anthropic principle prevents your death
add 45% duplication chance for that level", maxCount: 1, count: 0, frequency: 3, frequencyDefault: 3, allowed() { - return tech.isDeathAvoid && tech.duplicationChance() < 0.66 + return tech.isDeathAvoid }, - requires: "anthropic principle, below 66% duplication chance", + requires: "anthropic principle", effect() { tech.isAnthropicTech = true powerUps.setDupChance(); //needed after adjusting duplication chance @@ -3154,7 +3157,7 @@ }, { name: "replication", - description: "10% chance to duplicate spawned power ups
+30% JUNK to the potential tech pool", + description: "10% chance to duplicate spawned power ups
+40% JUNK to the potential tech pool", maxCount: 9, count: 0, frequency: 1, @@ -3167,7 +3170,7 @@ tech.duplicateChance += 0.1 powerUps.setDupChance(); //needed after adjusting duplication chance if (!build.isExperimentSelection) simulation.circleFlare(0.1); - this.refundAmount += tech.addJunkTechToPool(0.3) + this.refundAmount += tech.addJunkTechToPool(0.4) }, refundAmount: 0, remove() { @@ -3181,7 +3184,7 @@ }, { name: "stimulated emission", - description: "17% chance to duplicate spawned power ups
but, after a collision eject 1 tech", + description: "15% chance to duplicate spawned power ups
but, after a collision eject 1 tech", maxCount: 1, count: 0, frequency: 1, @@ -3192,8 +3195,8 @@ requires: "below 100% duplication chance", effect: () => { tech.isStimulatedEmission = true - powerUps.setDupChance(0.17); //needed after adjusting duplication chance - if (!build.isExperimentSelection) simulation.circleFlare(0.17); + powerUps.setDupChance(); //needed after adjusting duplication chance + if (!build.isExperimentSelection) simulation.circleFlare(0.15); }, remove() { tech.isStimulatedEmission = false @@ -3202,7 +3205,7 @@ }, { name: "metastability", - description: "13% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life ", + description: "12% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life ", maxCount: 1, count: 0, frequency: 1, @@ -3214,7 +3217,7 @@ effect: () => { tech.isPowerUpsVanish = true powerUps.setDupChance(); //needed after adjusting duplication chance - if (!build.isExperimentSelection) simulation.circleFlare(0.13); + if (!build.isExperimentSelection) simulation.circleFlare(0.12); }, remove() { tech.isPowerUpsVanish = false @@ -3223,7 +3226,7 @@ }, { name: "futures exchange", - description: "clicking × to cancel a field, tech, or gun
adds 4.5% power up duplication chance", + description: "clicking × to cancel a field, tech, or gun
adds 4% power up duplication chance", maxCount: 1, count: 0, frequency: 1, @@ -3297,21 +3300,21 @@ }, { name: "apomixis", - description: `when you reach 100% duplication
spawn 8 bosses with 100% more health`, + description: `when you reach 111% duplication
spawn 11 bosses with 111% more health`, maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 10, + frequencyDefault: 10, allowed() { - return tech.duplicationChance() > 0.33 + return tech.duplicationChance() > 0.99 }, requires: "duplication chance above 33%", effect() { - tech.is100Duplicate = true; + tech.is111Duplicate = true; tech.maxDuplicationEvent() }, remove() { - tech.is100Duplicate = false; + tech.is111Duplicate = false; } }, { @@ -3381,10 +3384,8 @@ effect: () => { powerUps.research.changeRerolls(-2) simulation.makeTextLog(`m.research -= 2
${powerUps.research.count}`) - const chanceStore = tech.duplicateChance - tech.duplicateChance = (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.045 + m.duplicateChance + tech.duplicateChance * 2 //increase duplication chance to simulate doubling all 3 sources of duplication chance - powerUps.spawn(m.pos.x, m.pos.y, "tech"); - tech.duplicateChance = chanceStore + powerUps.directSpawn(m.pos.x, m.pos.y, "tech"); + if (Math.random() < tech.duplicationChance() * 2) powerUps.directSpawn(m.pos.x + 10, m.pos.y + 5, "tech"); }, remove() {} }, @@ -5778,9 +5779,9 @@ frequency: 3, frequencyDefault: 3, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && (build.isExperimentSelection || powerUps.research.count > 3) + return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && (build.isExperimentSelection || powerUps.research.count > 3) }, - requires: "perfect diamagnetism or negative mass", + requires: "perfect diamagnetism, negative mass, pilot wave", effect() { tech.isFieldHarmReduction = true for (let i = 0; i < 2; i++) { @@ -6266,7 +6267,7 @@ // }, { name: "retrocausality", - description: "time dilation uses energy to rewind your
health, velocity, and position up to 10 s", + description: "time dilation uses energy to rewind your
health, velocity, and position up to 10 s", isFieldTech: true, maxCount: 1, count: 0, @@ -6316,9 +6317,9 @@ frequency: 3, frequencyDefault: 3, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "time dilation" && (build.isExperimentSelection || powerUps.research.count > 2) + return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 2) }, - requires: "time dilation", + requires: "time dilation, pilot wave", effect() { tech.isFastTime = true m.setMovement(); @@ -6357,7 +6358,7 @@ }, { name: "no-cloning theorem", - description: `38% chance to duplicate spawned power ups
after a mob dies, lose 1% duplication chance`, + description: `40% chance to duplicate spawned power ups
after a mob dies, lose 2% duplication chance`, isFieldTech: true, maxCount: 1, count: 0, @@ -6368,9 +6369,9 @@ }, requires: "cloaking, wormhole or time dilation and below 100% duplication chance", effect() { - tech.cloakDuplication = 0.38 + tech.cloakDuplication = 0.4 powerUps.setDupChance(); //needed after adjusting duplication chance - if (!build.isExperimentSelection) simulation.circleFlare(0.38); + if (!build.isExperimentSelection) simulation.circleFlare(0.4); }, remove() { tech.cloakDuplication = 0 @@ -6607,20 +6608,20 @@ }, { name: "virtual particles", - description: `use ${powerUps.orb.research(4)}to exploit your wormhole for a
14% chance to duplicate spawned power ups`, + description: `use ${powerUps.orb.research(4)}to exploit your wormhole for a
13% chance to duplicate spawned power ups`, isFieldTech: true, maxCount: 1, count: 0, frequency: 3, frequencyDefault: 3, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 3) && tech.duplicationChance() < 1 + return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 3) }, - requires: "wormhole, below 100% duplication chance", + requires: "wormhole", effect() { - tech.wormDuplicate = 0.14 + tech.wormDuplicate = 0.13 powerUps.setDupChance(); //needed after adjusting duplication chance - if (!build.isExperimentSelection) simulation.circleFlare(0.14); + if (!build.isExperimentSelection) simulation.circleFlare(0.13); for (let i = 0; i < 4; i++) { if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } @@ -8727,7 +8728,7 @@ isGunSwitchField: null, isNeedleShieldPierce: null, isDuplicateBoss: null, - is100Duplicate: null, + is111Duplicate: null, isDynamoBotUpgrade: null, isBlockPowerUps: null, isBlockHarm: null, diff --git a/todo.txt b/todo.txt index 9f0a443..1177c6b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,17 @@ ******************************************************** NEXT PATCH ************************************************** -number of undefined tech needed to get lore is now lower at higher difficulty modes +grenades display their trajectory, to help you aim + I'm might get rid of it, but for now we'll try it out -bug fixes +several duplication tech give slightly lower duplication chance +strange attractor now properly includes all your tech in duplication chance (it wasn't updated for recent duplication tech) ******************************************************** TODO ******************************************************** +give all duplicated power ups a half life that scales with the duplication chance + metastability reduces the half life + how to communicate the half-life? + tech: after bullets hit a mob, the mob takes 1% more damage this.damageReduction *= 1.01