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

BIN
.DS_Store vendored

Binary file not shown.

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,11 +2612,21 @@ 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);
@@ -2622,12 +2635,10 @@ const level = {
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,

View File

@@ -1,20 +1,21 @@
******************************************************** NEXT PATCH **************************************************
harpoon's crouch is now a harpoon sized railgun
tech: halfwave rectifier now gives energy on harpoon/railgun charge and also stops harpoon from draining energy when it retracts
toggling harpoon does 800 -> 600% more damage
perfect diamagnetism default field is a bit larger
bug fix with several periodic checks running off simulation time
they now run on player time and will be active during time dilation
fixed a bug where lore wasn't working
new sprayBoss on reactor level
shows up 50% of the time
unbalanced right now, so give me feedback
******************************************************** TODO ********************************************************
tech doing damage refunds up to 50% of damage take in last 10 seconds
use history to manage this?
tech: frozen mobs dies at 10% life
CPt disables the falling damage tech
make a seed/hash system that controls only the tech/guns/fields shown
URL sharing could include a seed
seed will control:
seed controls:
seeded random at start - random level boss, mob types list, level order, horizontal flip
seeded random during run - tech, gun, field choices
not seeded random - mob spawns, mob size, minor level differences, custom level boss choices, ammo rewards, tech effect randomness
@@ -22,11 +23,6 @@ make a seed/hash system that controls only the tech/guns/fields shown
make option for a daily seed: seed = day+year
give 1 extra tech for doing the daily seeded run
make the option for the daily run, a secret exit in the intro level?
when you die
randomize seed
display new seed
show previous run seed
edit div in settings
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
@@ -35,13 +31,20 @@ JUNK tech: https://bindingofisaacrebirth.fandom.com/wiki/Damocles
cloaking field doesn't show energy over max
junk tech or regular tech with this named
wiki: List of common misconceptions
run more profiles of n-gon to fix performance issues
sprayBoss
reactor or everywhere?
reactor
hopBoss
life-like cellular automata boss
https://scratch.mit.edu/projects/77724260/
night/day?
boss on far right produces more "on" cells
tailBoss
story the last 5 seconds of position, draw damage circles over those positions, like a tail
limit mantis boss to only reactor?
laserBoss?
swoopBoss: hides in top center
take a lap around the map that you have to dodge
spawn mobs