sprayBoss

new sprayBoss on reactor level
  shows up 50% of the time
  unbalanced right now, so give me feedback
This commit is contained in:
landgreen
2022-02-13 06:48:23 -08:00
parent 67a6ee29d1
commit 8b3a4c0cb9
10 changed files with 218 additions and 86 deletions

View File

@@ -1371,7 +1371,7 @@ const b = {
requestAnimationFrame(() => { who.isShielded = true });
}
if (tech.fragments) {
b.targetedNail(this.vertices[2], tech.fragments * 4)
b.targetedNail(this.vertices[2], tech.fragments * 3)
if (!isReturn) this.endCycle = 0;
}
if (!who.isBadTarget) {
@@ -5650,7 +5650,7 @@ const b = {
Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y });
} else {
if (tech.fragments && this.speed > 10) {
b.targetedNail(this.position, tech.fragments * 17)
b.targetedNail(this.position, tech.fragments * 13)
this.endCycle = 0 //triggers despawn
}
}

View File

@@ -154,6 +154,11 @@ window.addEventListener('load', () => {
}
if (property === "level") document.getElementById("starting-level").value = Math.max(Number(set[property]) - 1, 0)
if (property === "noPower") document.getElementById("no-power-ups").checked = Number(set[property])
// if (property === "seed") {
// document.getElementById("seed").placeholder = Math.initialSeed = String(set[property])
// Math.seed = Math.abs(Math.hash(Math.initialSeed))
// level.populateLevels()
// }
}
} else if (localSettings.isTrainingNotAttempted && localSettings.runCount < 30) { //make training button more obvious for new players
// document.getElementById("training-button").style.border = "0px #333 solid";
@@ -555,6 +560,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
},
shareURL(isCustom = false) {
let url = "https://landgreen.github.io/sidescroller/index.html?"
url += `&seed=${Math.initialSeed}`
let count = 0;
for (let i = 0; i < b.inventory.length; i++) {
if (b.guns[b.inventory[i]].have) {
@@ -585,16 +591,12 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
navigator.clipboard.writeText(url).then(function() {
/* clipboard successfully set */
if (isCustom) {
setTimeout(function() {
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
}, 300);
setTimeout(function() { alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.') }, 300);
}
}, function() {
/* clipboard write failed */
if (isCustom) {
setTimeout(function() {
alert('copy failed')
}, 300);
setTimeout(function() { alert('copy failed') }, 300);
}
console.log('copy failed')
});

View File

@@ -14,22 +14,23 @@ const level = {
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// m.immuneCycle = Infinity //you can't take damage
// localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.setField("standing wave")
// b.giveGuns("harpoon")
// for (let i = 0; i < 100; i++) tech.giveTech("slow light")
// tech.giveTech("recycling")
// tech.giveTech("tungsten carbide")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
// tech.giveTech("tinsellated flagella")
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
// tech.giveTech("nail-bot")
// tech.giveTech("decoherence")
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
// powerUps.research.changeRerolls(100000)
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.tech[297].frequency = 100
// m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode
// level.reactor();
// level.testing(); //not in rotation, used for testing
@@ -220,7 +221,7 @@ const level = {
simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
}
},
populateLevels() {
populateLevels() { //run a second time if URL is loaded
if (document.getElementById("seed").value) {
Math.initialSeed = String(document.getElementById("seed").value)
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it
@@ -250,7 +251,9 @@ const level = {
}
}
//set seeded random lists of mobs and bosses
spawn.mobTypeSpawnOrder = []
for (let i = 0; i < level.levels.length; i++) spawn.mobTypeSpawnOrder.push(spawn.fullPickList[Math.floor(Math.seededRandom(0, spawn.fullPickList.length))])
spawn.bossTypeSpawnOrder = []
for (let i = 0; i < level.levels.length * 2; i++) spawn.bossTypeSpawnOrder.push(spawn.randomBossList[Math.floor(Math.seededRandom(0, spawn.randomBossList.length))])
},
flipHorizontal() {
@@ -2609,25 +2612,33 @@ const level = {
document.body.style.backgroundColor = "#d0d5df" //"#d8dadf";
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
spawn.mapRect(-1525, -2825, 1250, 3925);
spawn.mapRect(-1525, -2825, 1250, 4925);
spawn.mapRect(-400, -2025, 625, 925);
spawn.mapRect(-400, -750, 625, 1200);
spawn.mapRect(-425, 0, 4200, 1100);
// spawn.mapVertex(200, 0, "-200 0 -100 -100 100 -100 200 0");
spawn.bodyRect(225, -100, 100, 100, 0.5);
spawn.bodyRect(225, -200, 75, 100, 0.5);
spawn.bodyRect(325, -70, 150, 70, 1);
spawn.bodyRect(-275, -850, 75, 100, 0.4);
spawn.bodyRect(1525, -100, 100, 100, 0.3);
spawn.bodyRect(2325, -50, 125, 50, 0.3);
spawn.bodyRect(2375, -100, 50, 50, 0.3);
for (let i = 0; i < 3; ++i) powerUps.spawn(400 + 2000 * Math.random(), -25, "ammo");
spawn.mapRect(-425, 0, 4200, 2100);
spawn.mapRect(175, -1250, 50, 300);
spawn.mapRect(-475, -2825, 4250, 1025);
// spawn.mapRect(1200, -1300, 600, 800);
const a = 400 //side length
const c = 100 //corner offset
spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off
spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off
//exit
spawn.mapRect(3300, -2825, 1125, 3925);
spawn.mapRect(3300, -2825, 1125, 4925);
spawn.mapRect(2750, -2150, 1025, 1775);
spawn.mapRect(2750, -475, 50, 300);
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
// spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8);
@@ -2651,6 +2662,8 @@ const level = {
let isSpawnedBoss = false
level.custom = () => {
// player.force.y -= player.mass * simulation.g * 0.4; //float player
if (isDoorsLocked) {
if (!isFightOver && !(simulation.cycle % 120)) { //once a second
let isFoundBoss = false
@@ -2665,7 +2678,6 @@ const level = {
doorIn.isClosing = false
doorOut.isClosing = false
powerUps.spawnBossPowerUp(2900, -100)
for (let i = 0; i < 3; ++i) powerUps.spawn(2900 + 30 * i, -300, "ammo");
}
}
@@ -2688,12 +2700,19 @@ const level = {
doorOut.isClosing = true
if (!isSpawnedBoss) {
isSpawnedBoss = true
for (let i = 0, len = simulation.difficulty / 20; i < len; ++i) spawn.bounceBoss(1487 + 300 * i, -1525, 80, false);
if (Math.random() > 0.5) {
for (let i = 0, len = Math.min(simulation.difficulty / 20, 5); i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
} else {
for (let i = 0, len = Math.min(simulation.difficulty / 10, 10); i < len; ++i) spawn.sprayBoss(2400 - 150 * i, -225, 30, false)
}
// for (let i = 0, len = 3 + simulation.difficulty / 20; i < len; ++i) spawn.mantisBoss(1487 + 300 * i, -1525, 35, false)
}
}
doorIn.openClose();
doorOut.openClose();
ctx.fillStyle = "#d5ebef"
ctx.fillRect(2750, -375, 550, 375)
level.enter.draw();
level.exit.drawAndCheck();
};
@@ -2704,6 +2723,10 @@ const level = {
// }
doorIn.draw();
doorOut.draw();
ctx.fillStyle = "rgba(0,0,0,0.05)"
ctx.fillRect(-275, -1100, 500, 350);
// ctx.fillStyle = "rgba(0,255,255,0.1)"
// ctx.fillRect(2750, -375, 550, 375)
};
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
powerUps.addResearchToLevel() //needs to run after mobs are spawned

View File

@@ -1180,7 +1180,7 @@ const mobs = {
powerUps.spawn(this.position.x, this.position.y, "tech", false)
// if (0.5 < Math.random()) powerUps.spawn(this.position.x, this.position.y, "tech", false)
} else {
const amount = 0.005
const amount = 0.0045
if (tech.isEnergyHealth) {
if (m.maxEnergy > amount) {
tech.healMaxEnergyBonus -= amount

View File

@@ -304,7 +304,14 @@ const powerUps = {
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
for (let i = 0; i < banishLength; i++) {
const index = powerUps.tech.choiceLog.length - i - 1
if (powerUps.tech.choiceLog[index] !== undefined) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
} else { //if no tech options available eject banish tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
powerUps.endDraft("tech");
}
}
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
}
@@ -397,7 +404,18 @@ const powerUps = {
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
for (let i = 0; i < banishLength; i++) {
const index = powerUps.tech.choiceLog.length - i - 1
if (powerUps.tech.choiceLog[index] !== undefined || powerUps.tech.choiceLog[index] !== null) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
// console.log(index)
// console.log(powerUps.tech.choiceLog.length)
// console.log(powerUps.tech.choiceLog[index])
// console.log(tech.tech[powerUps.tech.choiceLog[index]])
if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
} else { //if no tech options available eject banish tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
powerUps.endDraft("tech");
}
}
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
}
@@ -686,6 +704,7 @@ const powerUps = {
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick()
console.log(choice1)
let choice2 = null
let choice3 = null
if (choice1 !== null) {
@@ -776,12 +795,6 @@ const powerUps = {
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else if (tech.isBanish) { //if no tech options available eject banish tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
// simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`)
powerUps.endDraft("tech");
}
}
}

View File

@@ -944,7 +944,6 @@ const simulation = {
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05
console.log(`lastKill = ${m.lastKillCycle}, cycle = ${m.cycle}, health = ${m.health}, maxHealth = ${m.maxHealth}`)
if (tech.isHealthRecovery) m.addHealth(0.01 * m.maxHealth)
}

View File

@@ -1,10 +1,10 @@
//main object for spawning things in a level
const spawn = {
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"],
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
// other bosses: suckerBoss, laserBoss, tetherBoss, mantisBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
randomBossList: ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "mantisBoss", "slashBoss"
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss"
],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -19,26 +19,15 @@ const spawn = {
pickList: ["starter", "starter"],
fullPickList: [
"hopper", "hopper", "hopper",
"slasher", "slasher",
"slasher", "slasher", "hopper",
"stabber", "stabber", "stabber",
"springer", "springer", "springer",
"shooter", "shooter",
"grenadier", "grenadier",
"striker", "striker",
"laser", "laser",
"stabber", "stabber",
"springer", "springer",
"pulsar", "pulsar",
"launcher",
"launcherOne",
"exploder",
"sneaker",
"sucker",
"sniper",
"spinner",
"grower",
"beamer",
"focuser",
"spawner",
"ghoster",
"launcher", "launcherOne", "exploder", "sneaker", "sucker", "sniper", "spinner", "grower", "beamer", "focuser", "spawner", "ghoster",
],
mobTypeSpawnOrder: [], //preset list of mob names calculated at the start of a run by the randomSeed
mobTypeSpawnIndex: 0, //increases as the mob type cycles
@@ -1950,7 +1939,7 @@ const spawn = {
spawn.groupShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
spawn.allowShields = true;
},
mantisBoss(x, y, radius = 35) {
mantisBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 5, radius, "#6ba");
let me = mob[mob.length - 1];
me.babyList = [] //list of mobs that are apart of this boss
@@ -2140,7 +2129,7 @@ const spawn = {
me.onDeath = function() {
this.removeCons();
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) {
this.babyList[i].collisionFilter.mask = cat.map | cat.bullet | cat.player
@@ -3537,7 +3526,98 @@ const spawn = {
ctx.setLineDash([]);
}
},
bounceBoss(x, y, radius = 80, isSpawnBossPOwerUp = true) {
sprayBoss(x, y, radius = 30, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.inertia = Infinity; //no rotation
// me.accelMag = 0.00008 + 0.00007 * simulation.accelScale;
me.burstFireFreq = 20 + Math.floor(20 * simulation.CDScale)
me.burstTotalPhases = 4 + Math.floor(2 / simulation.CDScale)
me.noFireTotalCycles = 390
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0;
me.restitution = 1
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random(), 1)
Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.12 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.onDeath = function() {
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
me.onDamage = function() {};
//draw radial lines from verticies showing future bullet paths?
me.radialLines = function() {
ctx.beginPath();
for (let i = 0, len = this.vertices.length; i < len; i++) {
ctx.moveTo(this.vertices[i].x, this.vertices[i].y)
const unit = Vector.add(Vector.mult(Vector.normalise(Vector.sub(this.vertices[i], this.position)), 1000), this.vertices[i])
ctx.lineTo(unit.x, unit.y)
// console.log(unit, this.vertices, this.position)
}
ctx.lineWidth = 10
ctx.strokeStyle = "rgb(200,0,200,0.03)"
ctx.stroke();
}
me.phaseCycle = 0
me.normalDoStuff = function() {
// this.seePlayerByHistory();
// this.attraction();
this.checkStatus();
me.seePlayer.recall = 1
//maintain speed //faster in the vertical to help avoid repeating patterns
if (this.speed < 0.01) {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1));
} else {
if (Math.abs(this.velocity.y) < 15) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
if (Math.abs(this.velocity.x) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
}
}
me.noFire = function() {
this.normalDoStuff();
this.phaseCycle++
if (this.phaseCycle > this.noFireTotalCycles) { //start burst fire mode
this.phaseCycle = -2
this.do = this.burstFire
this.frictionAir = 1
if (!this.isShielded) spawn.shield(this, this.position.x, this.position.y, 1);
}
};
me.burstFire = function() {
this.normalDoStuff();
this.radialLines()
if (!(simulation.cycle % this.burstFireFreq)) {
this.phaseCycle++
if (this.phaseCycle > this.burstTotalPhases) { //start spiral fire mode
this.phaseCycle = -7
this.do = this.noFire
this.frictionAir = 0;
Matter.Body.setVelocity(this, Vector.rotate({ x: 20, y: 0 }, 2 * Math.PI * Math.random()));
if (this.isShielded) { //remove shield
for (let i = 0; i < mob.length; i++) {
if (mob[i].shield) mob[i].death()
}
}
}
if (this.phaseCycle > -1) {
Matter.Body.rotate(this, 0.08)
for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex
spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 8, 4);
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -26)
Matter.Body.setVelocity(mob[mob.length - 1], {
x: velocity.x,
y: velocity.y
});
}
}
}
};
me.do = me.noFire
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
},
bounceBoss(x, y, radius = 80, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 0, radius, "rgb(255,255,255)") // "rgb(201,202,225)");
let me = mob[mob.length - 1];
Matter.Body.rotate(me, 2 * Math.PI * Math.random());
@@ -3563,7 +3643,7 @@ const spawn = {
this.damageReduction = 0
}
};
if (isSpawnBossPOwerUp) me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) };
if (isSpawnBossPowerUp) me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) };
me.cycle = 0
me.nextHealthThreshold = 0.75
me.fireCount = 0
@@ -4411,8 +4491,7 @@ const spawn = {
}
};
},
sniperBullet(x, y, radius = 9, sides = 4) {
//bullets
sniperBullet(x, y, radius = 9, sides = 4) { //bullets
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
@@ -4431,10 +4510,23 @@ const spawn = {
me.showHealthBar = false;
me.collisionFilter.category = cat.mobBullet;
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
me.onDeath = function() {
if (simulation.difficulty > 11) { //explode AoE
const radius = 100 + simulation.difficulty + 60 * Math.random()
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0004 * radius * simulation.dmgScale);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: radius,
color: "rgba(255,0,155,0.5)",
time: simulation.drawTime
});
}
};
me.do = function() {
// this.gravity();
this.timeLimit();
if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) {
if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 10) {
this.isDropPowerUp = false;
this.death(); //death with no power up
}

View File

@@ -221,7 +221,7 @@ const tech = {
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
if (tech.isMaxEnergyTech) dmg *= 1.5
if (tech.isEnergyNoAmmo) dmg *= 1.66
if (tech.isEnergyNoAmmo) dmg *= 1.70
if (tech.isDamageForGuns) dmg *= 1 + 0.12 * b.inventory.length
if (tech.isLowHealthDmg) dmg *= 1 + Math.max(0, 1 - m.health) * 0.5
if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3;
@@ -230,7 +230,7 @@ const tech = {
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.125;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007
if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count
if (tech.isRerollDamage) dmg *= 1 + 0.038 * powerUps.research.count
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
@@ -580,7 +580,7 @@ const tech = {
},
{
name: "exciton",
description: `increase <strong class='color-d'>damage</strong> by <strong>66%</strong>, but<br>${powerUps.orb.ammo()} will no longer <strong>spawn</strong>`,
description: `increase <strong class='color-d'>damage</strong> by <strong>70%</strong>, but<br>${powerUps.orb.ammo()} will no longer <strong>spawn</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -2879,7 +2879,7 @@ const tech = {
},
{
name: "Bayesian statistics",
description: `increase <strong class='color-d'>damage</strong> by <strong>3.7%</strong><br>for each ${powerUps.orb.research(1)} in your inventory`,
description: `increase <strong class='color-d'>damage</strong> by <strong>3.8%</strong><br>for each ${powerUps.orb.research(1)} in your inventory`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -3067,7 +3067,7 @@ const tech = {
},
{
name: "particle collider",
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while <strong>paused</strong> <strong>ejects</strong> them<br><em><strong>4%</strong> chance to convert that tech into <strong class='color-f'>energy</strong></em>`,
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><em><strong>4%</strong> chance to convert that tech into <strong class='color-f'>energy</strong></em>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3340,9 +3340,9 @@ const tech = {
frequencyDefault: 10,
isNonRefundable: true,
allowed() {
return tech.duplicationChance() > 0.99
return tech.duplicationChance() > 0.7
},
requires: "duplication chance above 99%",
requires: "duplication chance above 70%",
effect() {
tech.is111Duplicate = true;
tech.maxDuplicationEvent()
@@ -3522,7 +3522,7 @@ const tech = {
},
{
name: "reinforcement learning",
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>recursive <strong class='color-m'>tech</strong> you already have by <strong>1000%</strong>",
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current recursive <strong class='color-m'>tech</strong> by <strong>1000%</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -6723,7 +6723,7 @@ const tech = {
},
{
name: "no-cloning theorem",
description: `<strong>40%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>mob</strong> <strong>dies</strong>, lose <strong>2%</strong> <strong class='color-dup'>duplication</strong> chance`,
description: `<strong>45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>mob</strong> <strong>dies</strong>, lose <strong>2%</strong> <strong class='color-dup'>duplication</strong> chance`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -6734,7 +6734,7 @@ const tech = {
},
requires: "cloaking, time dilation",
effect() {
tech.cloakDuplication = 0.4
tech.cloakDuplication = 0.45
powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
},
@@ -6745,7 +6745,7 @@ const tech = {
},
{
name: "symbiosis",
description: "after a <strong>mob</strong> <strong>dies</strong>, lose <strong>0.5</strong> max <strong class='color-h'>health</strong><br><strong>bosses</strong> spawn <strong>1</strong> extra <strong class='color-m'>tech</strong> after they <strong>die</strong>",
description: "after a <strong>mob</strong> <strong>dies</strong>, lose <strong>0.45</strong> max <strong class='color-h'>health</strong><br><strong>bosses</strong> spawn <strong>1</strong> extra <strong class='color-m'>tech</strong> after they <strong>die</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,