diff --git a/js/bullet.js b/js/bullet.js index 1dedfff..8417c98 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -96,10 +96,21 @@ const b = { outOfAmmo() { //triggers after firing when you have NO ammo simulation.makeTextLog(`${b.guns[b.activeGun].name}.ammo: 0`); m.fireCDcycle = m.cycle + 30; //fire cooldown - if (tech.isAmmoFromHealth && m.health > 0.01) { - tech.extraMaxHealth -= 0.01 //decrease max health - m.setMaxHealth(); - for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); + if (tech.isAmmoFromHealth) { + const amount = 0.01 + if (tech.isEnergyHealth) { + if (m.maxEnergy > amount) { + tech.healMaxEnergyBonus -= amount + m.setMaxEnergy(); + for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); + } + } else { + if (m.health > amount) { + tech.extraMaxHealth -= amount //decrease max health + m.setMaxHealth(); + for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); + } + } } }, refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to @@ -2888,7 +2899,7 @@ const b = { friction: 0, frictionAir: 0.023, restitution: 0.9, - dmg: 1.2, //damage done in addition to the damage from momentum + dmg: 1.3, //damage done in addition to the damage from momentum lookFrequency: 14 + Math.floor(8 * Math.random()), endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), classType: "bullet", @@ -4376,7 +4387,7 @@ const b = { minDmgSpeed: 2, // lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20, lastLookCycle: simulation.cycle + 60 * Math.random(), - delay: Math.floor((tech.isNailBotUpgrade ? 20 : 105) * b.fireCDscale), + delay: Math.floor((tech.isNailBotUpgrade ? 20 : 110) * b.fireCDscale), acceleration: 0.005 * (1 + 0.5 * Math.random()), range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), endCycle: Infinity, @@ -4407,7 +4418,7 @@ const b = { ) { const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position)) if (this.isUpgraded) { - const SPEED = 50 + const SPEED = 55 b.nail(this.position, Vector.mult(unit, SPEED)) this.force = Vector.mult(unit, -0.018 * this.mass) } else { @@ -4513,9 +4524,9 @@ const b = { restitution: 0.6 * (1 + 0.5 * Math.random()), dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, - lookFrequency: 60 + Math.floor(17 * Math.random()) - 40 * tech.isFoamBotUpgrade, + lookFrequency: 60 + Math.floor(17 * Math.random()) - 45 * tech.isFoamBotUpgrade, cd: 0, - delay: Math.floor(105 * b.fireCDscale), + delay: 20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade, acceleration: 0.005 * (1 + 0.5 * Math.random()), range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), endCycle: Infinity, @@ -4543,7 +4554,7 @@ const b = { const radius = 6 + 7 * Math.random() const SPEED = 29 - radius * 0.4; //(input.down ? 32 : 20) - radius * 0.7; const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED) - b.foam(this.position, velocity, radius + 7 * this.isUpgraded) + b.foam(this.position, velocity, radius + 7.5 * this.isUpgraded) break; } } @@ -4559,7 +4570,7 @@ const b = { const dir = m.angle; const RADIUS = (14 + 6 * Math.random()) bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, { - isUpgraded: tech.isLaserBotUpgrade, + // isUpgraded: tech.isLaserBotUpgrade, botType: "laser", angle: dir, friction: 0, @@ -4571,11 +4582,11 @@ const b = { offPlayer: { x: 0, y: 0, }, dmg: 0, //damage done in addition to the damage from momentum minDmgSpeed: 2, - lookFrequency: 40 + Math.floor(7 * Math.random()) - 10 * tech.isLaserBotUpgrade, - range: (700 + 450 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()), + lookFrequency: 40 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade, + range: (700 + 500 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()), drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4, - drain: (0.5 - 0.43 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode, - laserDamage: 0.85 + 0.7 * tech.isLaserBotUpgrade, + drain: (0.5 - 0.44 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode, + laserDamage: 0.85 + 0.8 * tech.isLaserBotUpgrade, endCycle: Infinity, classType: "bullet", collisionFilter: { @@ -4684,10 +4695,10 @@ const b = { restitution: 1, dmg: 0, minDmgSpeed: 0, - lookFrequency: 43 + Math.floor(7 * Math.random()) - 10 * tech.isBoomBotUpgrade, + lookFrequency: 43 + Math.floor(7 * Math.random()) - 13 * tech.isBoomBotUpgrade, acceleration: 0.005 * (1 + 0.5 * Math.random()), - attackAcceleration: 0.012 + 0.005 * tech.isBoomBotUpgrade, - range: 500 * (1 + 0.1 * Math.random()) + 320 * tech.isBoomBotUpgrade, + attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade, + range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade, endCycle: Infinity, classType: "bullet", collisionFilter: { @@ -4698,7 +4709,7 @@ const b = { explode: 0, beforeDmg() { if (this.lockedOn) { - const explosionRadius = Math.min(136 + 200 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30) + const explosionRadius = Math.min(136 + 230 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30) if (explosionRadius > 60) { this.explode = explosionRadius // @@ -4984,7 +4995,7 @@ const b = { } } }, - range: 190 + 120 * tech.isOrbitBotUpgrade, //range is set in bot upgrade too! + range: 190 + 130 * tech.isOrbitBotUpgrade, //range is set in bot upgrade too! orbitalSpeed: 0, phase: 2 * Math.PI * Math.random(), do() { @@ -4996,8 +5007,8 @@ const b = { }) for (let i = 0; i < q.length; i++) { if (!q[i].isShielded) { - mobs.statusStun(q[i], 210) - const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4 : 1) * (tech.isCrit ? 4 : 1) + mobs.statusStun(q[i], 210 + 90 * this.isUpgraded) + const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4.5 : 1) * (tech.isCrit ? 4 : 1) q[i].damage(dmg); if (q[i].alive) q[i].foundPlayer(); if (q[i].damageReduction) { @@ -6908,7 +6919,6 @@ const b = { charge: 0, isStuckOn: false, angle: 0, - arcRange: 0.78, //1.57, isInsideArc(angle) { const mod = (a, n) => { return a - Math.floor(a / n) * n @@ -6916,21 +6926,22 @@ const b = { let diff = mod(angle - this.angle + Math.PI, 2 * Math.PI) - Math.PI return Math.abs(diff) < this.arcRange }, + arcRange: 0.78, //1.57, lensDamage: 1, + lensDamageOn: 0, //set in tech lens() { this.stuckOn(); this.angle += 0.02 if (this.isInsideArc(m.angle)) { - this.lensDamage = 2.5 //150% damage increase + this.lensDamage = this.lensDamageOn + ctx.lineWidth = 6 + this.lensDamageOn } else { this.lensDamage = 1 + ctx.lineWidth = 2 } - - const radius = 60 ctx.beginPath(); - ctx.arc(m.pos.x, m.pos.y, radius, this.angle - this.arcRange, this.angle + this.arcRange); + ctx.arc(m.pos.x, m.pos.y, 60, this.angle - this.arcRange, this.angle + this.arcRange); ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)' //tech.laserColor - ctx.lineWidth = (this.lensDamage > 1) ? 10 : 2 //3 ctx.stroke(); // const a = { x: radius * Math.cos(this.angle + this.arcRange), y: radius * Math.sin(this.angle + this.arcRange) } // const b = Vector.add(m.pos, a) diff --git a/js/level.js b/js/level.js index 0eb8075..4a48aa7 100644 --- a/js/level.js +++ b/js/level.js @@ -24,15 +24,15 @@ const level = { // powerUps.research.changeRerolls(100) // tech.tech[297].frequency = 100 // b.guns[0].ammo = 10000 - // m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism - // b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser - // tech.giveTech("siphonaptera") - // tech.giveTech("fleas") - // tech.giveTech("colony") - // tech.giveTech("mycelium manufacturing") + // m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole + // b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // tech.giveTech("robotics") + // tech.giveTech("CPT symmetry"); + // tech.giveTech("lens"); + // tech.giveTech("robotics") // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot") - // for (let i = 0; i < 1; ++i) tech.giveTech("necrophage") - // for (let i = 0; i < 1; i++) tech.giveTech("cryodesiccation") + // for (let i = 0; i < 1; ++i) tech.giveTech("electric generator") + // for (let i = 0; i < 9; i++) tech.giveTech("compound lens") // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); // spawn.starter(1900, -500) diff --git a/js/player.js b/js/player.js index 489c1bd..262fe1a 100644 --- a/js/player.js +++ b/js/player.js @@ -133,25 +133,26 @@ const m = { legLength2: 45, transX: 0, transY: 0, - history: [], //tracks the last second of player position + history: new Array(600), //[], //tracks the last second of player position rewindCount: 0, //used with CPT resetHistory() { + const set = { + position: { + x: player.position.x, + y: player.position.y, + }, + velocity: { + x: player.velocity.x, + y: player.velocity.y + }, + yOff: m.yOff, + angle: m.angle, + health: m.health, + energy: m.energy, + activeGun: b.activeGun + } for (let i = 0; i < 600; i++) { //reset history - m.history[i] = { - position: { - x: player.position.x, - y: player.position.y, - }, - velocity: { - x: player.velocity.x, - y: player.velocity.y - }, - yOff: m.yOff, - angle: m.angle, - health: m.health, - energy: m.energy, - activeGun: b.activeGun - } + m.history[i] = set } }, move() { @@ -513,6 +514,7 @@ const m = { let dmg = 1 dmg *= m.fieldHarmReduction // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5 + if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8 if (tech.isZeno) dmg *= 0.15 if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.4 @@ -1413,7 +1415,11 @@ const m = { ) { mob[i].locatePlayer(); m.pushMass(mob[i]); - if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 60 + if (mob[i].isShielded) { + m.fieldCDcycle = m.cycle + 60 + } else if (tech.deflectEnergy && !mob[i].isInvulnerable) { + m.energy += tech.deflectEnergy + } } } }, @@ -2739,7 +2745,7 @@ const m = { }, { name: "metamaterial cloaking", - description: "when not firing activate cloaking
+333% damage for 2 seconds after decloaking
generate 6 energy per second", + description: "when not firing activate cloaking
after decloaking +333% damage for up to 2 s
generate 6 energy per second", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -2750,8 +2756,9 @@ const m = { // m.fieldDamage = 2.46 // 1 + 146/100 m.fieldDrawRadius = 0 m.isSneakAttack = true; + // m.sneakAttackCharge = 0; m.sneakAttackCycle = 0; - m.enterCloakCycle = 0 + m.enterCloakCycle = 0; const drawRadius = 800 m.drawCloak = function() { m.fieldPhase += 0.007 @@ -2770,6 +2777,12 @@ const m = { ctx.clip(); } m.hold = function() { + // if (m.isCloak) { + // if (m.sneakAttackCharge < 120) m.sneakAttackCharge += 0.5 + // } else { + // if (m.sneakAttackCharge > 0) m.sneakAttackCharge-- + // } + if (m.isHolding) { m.drawHold(m.holdingTarget); m.holding(); @@ -2806,13 +2819,12 @@ const m = { if (tech.isCloakStun) { //stun nearby mobs after exiting cloak let isMobsAround = false const stunRange = m.fieldDrawRadius * 1.5 - const drain = 0.1 - const stunTime = 240 + const drain = 0.2 if (m.energy > drain) { for (let i = 0, len = mob.length; i < len; ++i) { if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) < stunRange && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 && !mob[i].isBadTarget) { isMobsAround = true - mobs.statusStun(mob[i], stunTime) + mobs.statusStun(mob[i], 180) } } if (isMobsAround) { @@ -2856,7 +2868,8 @@ const m = { this.drawFieldMeterCloaking() //show sneak attack status // if (m.cycle > m.lastKillCycle + 240) { - if (m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) { + // if (m.sneakAttackCharge > 0) { + if (m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) { ctx.strokeStyle = "rgba(0,0,0,0.5)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})` ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI); diff --git a/js/powerup.js b/js/powerup.js index 374177b..9ed1b0f 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -551,15 +551,12 @@ const powerUps = { let text = "" if (!tech.isSuperDeterminism) text += `
${tech.isCancelTech ? "?":"✕"}
` text += `

gun

` - let options = []; for (let i = 0; i < b.guns.length; i++) { if (!b.guns[i].have) options.push(i); } let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices) if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay - - function removeOption(index) { for (let i = 0; i < options.length; i++) { if (options[i] === index) { @@ -568,14 +565,12 @@ const powerUps = { } } } - //check for guns that were a choice last time and remove them for (let i = 0; i < b.guns.length; i++) { if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display if (b.guns[i].isRecentlyShown) removeOption(i) } for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero - if (options.length > 0) { for (let i = 0; i < totalChoices; i++) { const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options @@ -584,6 +579,17 @@ const powerUps = { removeOption(choose) if (options.length < 1) break } + if (tech.isExtraBotOption) { + const botTech = [] //make an array of bot options + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i) + } + if (botTech.length > 0) { //pick random bot tech + const choose = botTech[Math.floor(Math.random() * botTech.length)]; + const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : ""; + text += `
⭓▸●■   ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` + } + } if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { tech.junkResearchNumber = Math.floor(5 * Math.random()) text += `
` @@ -704,7 +710,7 @@ const powerUps = { } for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero - if (options.length > 0) { + if (options.length > 0 || tech.isExtraBotOption) { for (let i = 0; i < totalChoices; i++) { const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options text += `
  ${m.fieldUpgrades[choose].name}
${m.fieldUpgrades[choose].description}
` @@ -712,6 +718,17 @@ const powerUps = { removeOption(choose) if (options.length < 1) break } + if (tech.isExtraBotOption) { + const botTech = [] //make an array of bot options + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i) + } + if (botTech.length > 0) { //pick random bot tech + const choose = botTech[Math.floor(Math.random() * botTech.length)]; + const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : ""; + text += `
⭓▸●■   ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` + } + } if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { tech.junkResearchNumber = Math.floor(5 * Math.random()) text += `
` @@ -846,9 +863,6 @@ const powerUps = { tech.tooManyTechChoices = false totalChoices = optionLengthNoDuplicates } - - - //check for tech that were a choice last time and remove them if (optionLengthNoDuplicates > totalChoices) { // console.log('check for tech that were a choice last time and remove them', optionLengthNoDuplicates, options.length) @@ -904,6 +918,18 @@ const powerUps = { } if (options.length < 1) break } + if (tech.isExtraBotOption) { + const botTech = [] //make an array of bot options + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i) + } + if (botTech.length > 0) { //pick random bot tech + const choose = botTech[Math.floor(Math.random() * botTech.length)]; + const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : ""; + text += `
⭓▸●■   ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` + } + } + if (tech.isExtraGunField) { if (Math.random() > 0.5 && b.inventory.length < b.guns.length) { let gunOptions = []; diff --git a/js/simulation.js b/js/simulation.js index e55f06f..d2fc0af 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -180,7 +180,7 @@ const simulation = { cyclePaused: 0, fallHeight: 6000, //below this y position the player dies lastTimeStamp: 0, //tracks time stamps for measuring delta - delta: 1000 / 60, //speed of game engine //looks like it has to be 16 to match player input + delta: 1000 / 60, //speed of game engine //looks like it has to be 16.6666 to match player input buttonCD: 0, isHorizontalFlipped: false, //makes some maps flipped horizontally levelsCleared: 0, diff --git a/js/tech.js b/js/tech.js index 89707c1..14832fc 100644 --- a/js/tech.js +++ b/js/tech.js @@ -252,7 +252,8 @@ const tech = { if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6 // if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg - if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg + if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg + // if (m.isSneakAttack && m.sneakAttackCharge > 0) dmg *= tech.sneakAttackDmg if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction() return dmg * tech.slowFire * tech.aimDamage }, @@ -261,8 +262,8 @@ const tech = { }, isScaleMobsWithDuplication: false, maxDuplicationEvent() { - if (tech.is111Duplicate && tech.duplicationChance() > 1.11) { - tech.is111Duplicate = false + if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { + tech.is100Duplicate = false const range = 1300 tech.isScaleMobsWithDuplication = true for (let i = 0, len = 9; i < len; i++) { @@ -308,7 +309,7 @@ const tech = { }, tech: [{ name: "ordnance", - description: "triple the frequency of finding guntech
spawn a gun", + description: "double the frequency of finding guntech
spawn a gun", maxCount: 1, count: 0, frequency: 1, @@ -324,7 +325,7 @@ const tech = { powerUps.spawn(m.pos.x, m.pos.y, "gun"); // this.count-- for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 3 + if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2 } }, remove() {} @@ -584,15 +585,15 @@ const tech = { }, { name: "catabolism", - description: `if you fire while out of ammo
spawn ${powerUps.orb.ammo(4)} and –1 maximum health`, + descriptionFunction() { return `if you fire while out of ammo
spawn ${powerUps.orb.ammo(4)} and –1 maximum ${tech.isEnergyHealth ? "energy" : "health"}` }, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return !tech.isEnergyNoAmmo && !tech.isEnergyHealth + return !tech.isEnergyNoAmmo }, - requires: "not exciton, mass-energy", + requires: "not exciton", effect: () => { tech.isAmmoFromHealth = true; }, @@ -1372,7 +1373,7 @@ const tech = { { name: "dynamo-bot", link: `dynamo-bot`, - description: "a bot damages mobs while it traces your path
when it's near generate 7 energy per second", + description: "a bot damages mobs while it traces your path
when it's near generate +7 energy per second", maxCount: 9, count: 0, frequency: 1, @@ -1396,7 +1397,7 @@ const tech = { { name: "dynamo-bot upgrade", link: `dynamo-bot upgrade`, - description: "convert your bots to dynamo-bots
when it's near generate 23 energy per second", + description: "convert your bots to dynamo-bots
when it's near generate +23 energy per second", maxCount: 1, count: 0, frequency: 3, @@ -1451,37 +1452,6 @@ const tech = { // this.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)` } }, - { - name: "robotics", - description: `spawn 2 random bots
quadruple the frequency of finding bot tech`, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isBotTech: true, - allowed() { - return b.totalBots() > 1 || build.isExperimentSelection - }, - requires: "at least 2 bots", - effect: () => { - b.randomBot() - b.randomBot() - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 4 - } - }, - remove() { - if (this.count > 0) { - b.removeBot() - b.removeBot() - b.clearPermanentBots(); - b.respawnBots(); - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 4) - } - } - } - }, { name: "perimeter defense", description: "for each permanent bot
+6% defense", @@ -1578,6 +1548,91 @@ const tech = { } } }, + // { + // name: "robotics", + // description: `spawn 2 random bots
quadruple the frequency of finding bot tech`, + // maxCount: 1, + // count: 0, + // frequency: 1, + // frequencyDefault: 1, + // isBotTech: true, + // allowed() { + // return b.totalBots() > 1 || build.isExperimentSelection + // }, + // requires: "at least 2 bots", + // effect: () => { + // b.randomBot() + // b.randomBot() + // for (let i = 0, len = tech.tech.length; i < len; i++) { + // if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 4 + // } + // }, + // remove() { + // if (this.count > 0) { + // b.removeBot() + // b.removeBot() + // b.clearPermanentBots(); + // b.respawnBots(); + // for (let i = 0, len = tech.tech.length; i < len; i++) { + // if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 4) + // } + // } + // } + // }, + { + name: "robotics", + description: `spawn 2 random bots
tech, fields, and guns have +1 bot choice`, //tech have an extra bot tech option + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isBotTech: true, + allowed() { + return b.totalBots() > 1 || build.isExperimentSelection + }, + requires: "at least 2 bots", + effect: () => { + tech.isExtraBotOption = true + for (let i = 0; i < 2; i++) b.randomBot() + }, + remove() { + if (this.count > 0) { + for (let i = 0; i < 2; i++) b.removeBot() + b.clearPermanentBots(); + b.respawnBots(); + } + tech.isExtraBotOption = false + } + }, + { + name: "open-source", //digital fabricator + description: `spawn 3 random bots
triple the frequency of finding bot tech`, + maxCount: 1, + count: 0, + frequency: 0, + frequencyDefault: 0, + isBotTech: true, + allowed() { + return tech.isExtraBotOption + }, + requires: "robotics", + effect: () => { + for (let i = 0; i < 3; i++) b.randomBot() + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3 + } + }, + remove() { + if (this.count > 0) { + for (let i = 0; i < 3; i++) b.removeBot() + b.clearPermanentBots(); + b.respawnBots(); + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 3) + } + } + } + }, { name: "mass driver", description: "+300% block collision damage", @@ -1853,7 +1908,7 @@ const tech = { }, { name: "transistor", - description: "if ON generate 20 energy per second
if OFF drain 1 energy per second", + description: "if ON generate +20 energy per second
if OFF drain -1 energy per second", maxCount: 1, count: 0, frequency: 4, @@ -2138,7 +2193,7 @@ const tech = { }, { name: "piezoelectricity", - description: "if you collide with a mob
generate 2048 energy", //
reduce defense by 15% + description: "if you collide with a mob
generate +2048 energy", //
reduce defense by 15% maxCount: 1, count: 0, frequency: 1, @@ -2528,7 +2583,7 @@ const tech = { }, { name: "negative feedback", - description: "for each 10 health below 100
+5% damage", + description: `for each health below 100
+0.5% damage`, maxCount: 1, count: 0, frequency: 1, @@ -2544,6 +2599,42 @@ const tech = { tech.isLowHealthDmg = false; } }, + { + name: "homeostasis", + description: `for each health below 100
+0.8% defense`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return (m.health < 0.6 || build.isExperimentSelection) && !tech.isEnergyHealth + }, + requires: "health below 60, not mass-energy", + effect() { + tech.isLowHealthDefense = true; + }, + remove() { + tech.isLowHealthDefense = false; + } + }, + // { + // name: "overshoot", //annoying to code because you'd have to update fire rate too often + // descriptionFunction() { return `for each ${tech.isEnergyHealth ? "energy" : "health"} below 100
+2% fire rate` }, + // maxCount: 1, + // count: 0, + // frequency: 1, + // frequencyDefault: 1, + // allowed() { + // return m.health < 0.5 || build.isExperimentSelection + // }, + // requires: "health below 60", + // effect() { + // tech.isLowHealthFireRate = true; + // }, + // remove() { + // tech.isLowHealthFireRate = false; + // } + // }, { name: "antiscience", description: "+90% damage
–11 health after picking up a tech", @@ -3463,22 +3554,22 @@ const tech = { }, { name: "apomixis", - description: `when you reach 111% duplication
spawn 11 bosses with 111% more durability`, + description: `when you reach 100% duplication
spawn 11 bosses with 100% more durability`, maxCount: 1, count: 0, frequency: 6, frequencyDefault: 6, isNonRefundable: true, allowed() { - return tech.duplicationChance() > 0.6 + return tech.duplicationChance() > 0.5 }, - requires: "NOT EXPERIMENT MODE, duplication chance above 60%", + requires: "NOT EXPERIMENT MODE, duplication chance above 50%", effect() { - tech.is111Duplicate = true; + tech.is100Duplicate = true; tech.maxDuplicationEvent() }, remove() { - tech.is111Duplicate = false; + tech.is100Duplicate = false; } }, { @@ -3624,7 +3715,7 @@ const tech = { }, { name: "reinforcement learning", - description: "increase the frequency of finding copies of
your current recursive tech by 1000%", + description: "increase the frequency of finding copies of
your current tech by 1000%", maxCount: 1, count: 0, frequency: 1, @@ -4211,7 +4302,7 @@ const tech = { }, { name: "thermoelectric effect", - description: "killing mobs with ice IX
generates 100 energy", + description: "after killing mobs with ice IX
+100 energy", isGunTech: true, maxCount: 9, count: 0, @@ -5964,7 +6055,7 @@ const tech = { effect() { let techGiven = 0 for (let j = 0; j < 3; j++) { - const names = ["lens", "arc length", "laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light"] + const names = ["lens", "compound lens", "arc length", "laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"] //convert names into indexes const options = [] for (let i = 0; i < names.length; i++) { @@ -6099,9 +6190,9 @@ const tech = { }, { name: "lens", - description: "+150% laser gun damage if it passes
through a revolving +90° arc circular lens", //π / 2 + description: "+150% laser gun damage if it passes
through a revolving 90° arc circular lens", //π / 2 isGunTech: true, - maxCount: 3, + maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, @@ -6111,15 +6202,73 @@ const tech = { requires: "laser", effect() { tech.isLaserLens = true - b.guns[11].arcRange += 0.78 b.guns[11].chooseFireMethod() + // if (this.count > 0) b.guns[11].lensDamageOn += 20 * Math.PI / 180 + // b.guns[11].arcRange = 0.78 }, remove() { tech.isLaserLens = false - b.guns[11].arcRange = 0 b.guns[11].chooseFireMethod() + // b.guns[11].lensDamageOn = 2.5 // 100% + 150% + // b.guns[11].arcRange = 0 } }, + { + name: "compound lens", + description: "+77% laser lens damage
+10° lens arc", + isGunTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.isLaserLens + }, + requires: "lens", + effect() { + b.guns[11].arcRange += 10 * Math.PI / 180 / 2 + b.guns[11].lensDamageOn += 0.77 + }, + remove() { + b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn + b.guns[11].lensDamageOn = 2.5 + } + }, + // { + // name: "lens", + // // description: "+150% laser gun damage if it passes
through a revolving +90° arc circular lens", //π / 2 + // descriptionFunction() { + // if (this.count) { + // return `+70% lens damage
+20° arc circular lens` + // } else { + // return `+150% laser gun damage if it passes
through a revolving 90° arc circular lens` + // } + // }, + // isGunTech: true, + // maxCount: 3, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("laser") + // }, + // requires: "laser", + // effect() { + // tech.isLaserLens = true + // if (this.count) { + // b.guns[11].lensDamageOn += 0.7 + // b.guns[11].arcRange += 20 * Math.PI / 180 + // } else [ + // b.guns[11].lensDamageOn = 2.5 // 100% + 150% + // ] + // b.guns[11].chooseFireMethod() + // }, + // remove() { + // tech.isLaserLens = false + // b.guns[11].arcRange = 90 * Math.PI / 180 + // b.guns[11].chooseFireMethod() + // } + // }, // { // name: "arc length", // description: "increase the circular arc of your laser lens
by +π / 4", @@ -6614,26 +6763,6 @@ const tech = { // tech.isFreezeMobs = false // } // }, - { - name: "pair production", - description: "after picking up a power up
+200 energy", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" - }, - requires: "molecular assembler, pilot wave, standing wave", - effect: () => { - tech.isMassEnergy = true // used in m.grabPowerUp - m.energy += 2 - }, - remove() { - tech.isMassEnergy = false; - } - }, { name: "bot manufacturing", description: `use ${powerUps.orb.research(2)} to build
3 random bots`, @@ -6644,9 +6773,8 @@ const tech = { frequencyDefault: 1, isBotTech: true, isNonRefundable: true, - // isExperimentHide: true, allowed() { - return powerUps.research.count > 1 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" + return powerUps.research.count > 1 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") }, requires: "NOT EXPERIMENT MODE, molecular assembler", effect: () => { @@ -6672,7 +6800,7 @@ const tech = { isNonRefundable: true, // isExperimentHide: true, allowed() { - return powerUps.research.count > 2 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" + return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") }, requires: "NOT EXPERIMENT MODE, molecular assembler", effect: () => { @@ -6817,6 +6945,45 @@ const tech = { // if (this.count > 0) powerUps.research.changeRerolls(1) // } // }, + { + name: "pair production", + description: "after picking up a power up
+200 energy", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" + }, + requires: "molecular assembler, pilot wave, standing wave", + effect: () => { + tech.isMassEnergy = true // used in m.grabPowerUp + m.energy += 2 + }, + remove() { + tech.isMassEnergy = false; + } + }, + { + name: "electric generator", + description: "after deflecting mobs
molecular assembler generates +50 energy", + isFieldTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" + }, + requires: "molecular assembler", + effect() { + tech.deflectEnergy += 0.5; + }, + remove() { + tech.deflectEnergy = 0; + } + }, { name: "tokamak", description: "throwing a block converts it into energy
and a pulsed fusion explosion", @@ -6828,7 +6995,7 @@ const tech = { allowed() { return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler" }, - requires: "plasma torch or molecular assembler", + requires: "plasma torch, molecular assembler", effect() { tech.isTokamak = true; }, @@ -6845,9 +7012,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth + return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth }, - requires: "plasma torch, perfect diamagnetism, pilot wave, not mass-energy", + requires: "molecular assembler, plasma torch, perfect diamagnetism, pilot wave, not mass-energy", effect() { tech.isHarmReduce = true }, @@ -7182,7 +7349,8 @@ const tech = { }, { name: "dazzler", - description: "after decloaking stun nearby mobs
for –10 energy", + link: `dazzler`, + description: "after decloaking stun nearby mobs
for –15 energy", isFieldTech: true, maxCount: 1, count: 0, @@ -7243,7 +7411,7 @@ const tech = { } }, { - name: "discrete optimization", + name: "combinatorial optimization", description: "+35% damage
–35% fire rate", isFieldTech: true, maxCount: 1, @@ -9681,7 +9849,7 @@ const tech = { effect() {}, remove() {}, state: [ - [Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false] + [false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false] ], rule(state, a, b, c) { //30 @@ -9706,27 +9874,29 @@ const tech = { b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around this.state.push(b) if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML - if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); - setTimeout(() => { loop() }, 400); + if (this.count && this.state.length < 150 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); + setTimeout(() => { loop() }, 300); } } - setTimeout(() => { loop() }, 400); + setTimeout(() => { loop() }, 300); this.id++ - return `${this.outputText()}` + return `${this.outputText()}` }, outputText() { - let text = "" + let text = "
"
                 for (let j = 0; j < this.state.length; j++) {
-                    text += "

" + // text += "

" + text += "

" for (let i = 0; i < this.state[j].length; i++) { if (this.state[j][i]) { - text += "⬛" //"█" //"■" + text += "■" //"☻" //"⬛" //"█" //"■" } else { - text += "⬜" //"    " //"□" + text += " " //"□" //"☺" //"⬜" //"    " //"□" } } text += "

" } + text += "
" return text }, }, @@ -9743,7 +9913,7 @@ const tech = { effect() {}, remove() {}, state: [ - [false, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, true, true, false, false, false, false, Math.random() > 0.8, Math.random() > 0.8, false, false, false, false, false, false, Math.random() > 0.8] + [false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false] ], rule(state, a, b, c) { //90 if (state[a] && state[b] && state[c]) return false; // TTT => F @@ -9768,27 +9938,29 @@ const tech = { b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around this.state.push(b) if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML - if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); - setTimeout(() => { loop() }, 400); + if (this.count && this.state.length < 150 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); + setTimeout(() => { loop() }, 300); } } - setTimeout(() => { loop() }, 400); + setTimeout(() => { loop() }, 300); this.id++ - return `${this.outputText()}` + return `${this.outputText()}` }, outputText() { - let text = "" + let text = "
"
                 for (let j = 0; j < this.state.length; j++) {
-                    text += "

" + // text += "

" + text += "

" for (let i = 0; i < this.state[j].length; i++) { if (this.state[j][i]) { - text += "⬛" //"█" //"■" + text += "■" //"☻" //"⬛" //"█" //"■" } else { - text += "⬜" //"    " //"□" + text += " " //"□" //"☺" //"⬜" //"    " //"□" } } text += "

" } + text += "
" return text }, }, @@ -10051,6 +10223,8 @@ const tech = { squirrelFx: null, isCrit: null, isLowHealthDmg: null, + isLowHealthDefense: null, + isLowHealthFireRate: null, isFarAwayDmg: null, isEntanglement: null, isMassEnergy: null, @@ -10216,7 +10390,7 @@ const tech = { isPauseEjectTech: null, isShieldPierce: null, isDuplicateBoss: null, - is111Duplicate: null, + is100Duplicate: null, isDynamoBotUpgrade: null, isBlockPowerUps: null, isDamageAfterKillNoRegen: null, @@ -10257,6 +10431,7 @@ const tech = { harmonics: null, isStandingWaveExpand: null, isTokamak: null, + deflectEnergy: null, superBallDelay: null, isBlockExplode: null, isOverHeal: null, @@ -10353,4 +10528,5 @@ const tech = { isLaserLens: null, laserCrit: null, isSporeColony: null, + isExtraBotOption: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 33f1d3c..e82a0ca 100644 --- a/todo.txt +++ b/todo.txt @@ -1,17 +1,54 @@ ******************************************************** NEXT PATCH ************************************************** -cloaking +damage occurs for 2 seconds after decloaking - need to cloak for 4 seconds to get the full 2 seconds of +damage - ambush 666% -> 555% damage -boson composite drains 25% more energy when you move through mobs +tech: electric generator - deflecting mobs generates energy for molecular assembler +tech: homeostasis - for each health below 100 +0.8% defense +tech: compound lens - +77% laser lens damage, +10° lens arc -nail gun gets 20% more ammo -harpoons now properly do damage on the frame before they retract - smelting removes 10% more ammo to get another harpoon for railgun -grenade fireworks explosive petals are 25% closer together +tech: robotics - 2 random bots, power up choices include a bot tech option +tech: open-source - 3 random bots, 4x bot tech frequency + renamed from previous robotics tech +slightly buffed all bot upgrades + ++9% iceIX damage +catabolism uses energy instead of health if you have mass-energy +optical amplifier laser tech options include laser-bot +rule 90 and rule 30 looks better on more browsers, I hope *********************************************************** TODO ***************************************************** +store value of last hit health lost + names: patch + + tech: after cloaking regen 1/2 of the last hit + spawning a heal power up is annoying because you'd be cloaked, so direct healing? + time limit for effect? + while still under ambush damage? + + tech: killing the mob that caused the last hit spawns a heal power up equal to 1/2 of last hit + time limit for effect? 3-4 seconds? + + tech: doing damage can recover up to 1/2 of the last hit + spawn a heal equal to 1/2 of last hit + time limit for effect? 3-4 seconds? + + tech increase damage by how much health was lost in last hit + +damage = 3x health lost? + if you went from 100 -> 60 health = +40%*3 = 120% damage + negative mass field tech? + too similar to radiative equilibrium + pick between them? + + +path-finding + build a path-finding map on level load + how to convert vertices into block grid? + check points for map collisions and build grid + is there a path-finding algorithm for vertices, instead of block grid + use for: + mobs, + drones? + bots that can go far from player and return + tech ______ effect that last until you get hit field or bots can check your health every cycle and see if it lower if it's high update the health check value