new reactor boss - mineBoss
  1/3 chance for 1 of 3 different bosses to spawn on the reactor level

harpoon starts with 10->3 ammo, and still gets 1 ammo per powerUpx
network effect damage per bot 7->6%
perimeter defense harm reduction 8->7%

bug fix decoherence
This commit is contained in:
landgreen
2022-02-15 19:07:01 -08:00
parent 8b3a4c0cb9
commit e913fb3548
9 changed files with 211 additions and 52 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -3122,10 +3122,9 @@ const b = {
this.target.damage(m.dmgScale * this.damage);
}
} else if (this.target !== null) { //look for a new target
this.target = null
this.collisionFilter.category = cat.bullet;
this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
if (tech.isFoamGrowOnDeath && bullet.length < 180) {
if (tech.isFoamGrowOnDeath && bullet.length < 180 && !this.target.isMobBullet) {
let targets = []
for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
@@ -3147,6 +3146,7 @@ const b = {
}
}
}
this.target = null
} else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map or blocks
const slow = 0.85
Matter.Body.setVelocity(this, {
@@ -5581,7 +5581,7 @@ const b = {
name: "harpoon",
description: "fire a <strong>self-steering</strong> harpoon that uses <strong class='color-f'>energy</strong><br>to <strong>retract</strong> and refund its <strong class='color-ammo'>ammo</strong> cost",
ammo: 0,
ammoPack: 1,
ammoPack: 0.3,
have: false,
do() {},
fire() {

View File

@@ -135,7 +135,7 @@ function collisionChecks(event) {
}
if (tech.isPiezo) m.energy += 20.48;
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(k);
if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);

View File

@@ -15,7 +15,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true
// m.setField("standing wave")
// m.setField("time dilation")
// b.giveGuns("harpoon")
// for (let i = 0; i < 100; i++) tech.giveTech("slow light")
// tech.giveTech("tungsten carbide")
@@ -30,7 +30,7 @@ const level = {
// 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
// level.difficultyIncrease(15) //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
@@ -2617,13 +2617,13 @@ const level = {
spawn.mapRect(-400, -750, 625, 1200);
// 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);
// spawn.bodyRect(225, -100, 100, 100, 0.5);
// spawn.bodyRect(225, -200, 75, 100, 0.5);
spawn.bodyRect(250, -70, 100, 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);
@@ -2700,10 +2700,12 @@ const level = {
doorOut.isClosing = true
if (!isSpawnedBoss) {
isSpawnedBoss = true
if (Math.random() > 0.5) {
if (Math.random() < 0.33) {
for (let i = 0, len = Math.min(simulation.difficulty / 20, 5); i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
} else {
} else if (Math.random() < 0.5) {
for (let i = 0, len = Math.min(simulation.difficulty / 10, 10); i < len; ++i) spawn.sprayBoss(2400 - 150 * i, -225, 30, false)
} else {
for (let i = 0, len = Math.min(simulation.difficulty / 8, 10); i < len; ++i) spawn.mineBoss(1950, -250, 50, false);
}
// for (let i = 0, len = 3 + simulation.difficulty / 20; i < len; ++i) spawn.mantisBoss(1487 + 300 * i, -1525, 35, false)
}

View File

@@ -514,7 +514,7 @@ const m = {
if (tech.isSlowFPS) dmg *= 0.8
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
if (tech.isBotArmor) dmg *= 0.92 ** b.totalBots()
if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
if (tech.energyRegen === 0) dmg *= 0.34
@@ -3618,7 +3618,7 @@ const m = {
m.damage(dmg);
if (tech.isPiezo) m.energy += 20.48;
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(k);
if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);

View File

@@ -306,11 +306,6 @@ const powerUps = {
const index = powerUps.tech.choiceLog.length - i - 1
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)}`)
@@ -404,18 +399,7 @@ 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
// 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");
}
if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
}
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
}
@@ -697,6 +681,10 @@ const powerUps = {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name}</div> ${tech.tech[choose].description}</div>`
return choose
} 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)
}
}
}
@@ -704,7 +692,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)
// console.log(choice1)
let choice2 = null
let choice3 = null
if (choice1 !== null) {

View File

@@ -3617,6 +3617,160 @@ const spawn = {
me.do = me.noFire
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
},
mineBoss(x, y, radius = 120, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 0, radius, "rgba(255,255,255,0.5)") // "rgb(201,202,225)");
let me = mob[mob.length - 1];
// Matter.Body.rotate(me, 2 * Math.PI * Math.random());
me.isBoss = true;
Matter.Body.setDensity(me, 0.001); //normal is 0.001
me.inertia = Infinity;
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.01
me.restitution = 1
me.friction = 0
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map | cat.mob
me.explodeRange = 400
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
me.seePlayer.recall = 1;
// spawn.shield(me, x, y, 1);
me.onDamage = function() {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4
this.invulnerableCount = 60 + simulation.difficulty * 1.5
this.isInvulnerable = true
this.damageReduction = 0
//slow time to look cool
// simulation.fpsCap = 10 //new fps
// simulation.fpsInterval = 1000 / simulation.fpsCap;
//how long to wait to return to normal fps
// m.defaultFPSCycle = m.cycle + 20 + 90
for (let i = 0, len = mob.length; i < len; ++i) { //trigger nearby mines
if (mob[i].isMine && Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.explodeRange) mob[i].isExploding = true
}
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: this.explodeRange,
color: "rgba(255,25,0,0.6)",
time: simulation.drawTime * 2
});
}
};
me.onDeath = function() {
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
for (let i = 0, len = mob.length; i < len; ++i) { //trigger nearby mines
if (mob[i].isMine && Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.explodeRange) mob[i].isExploding = true
}
};
me.cycle = 0
me.nextHealthThreshold = 0.75
me.invulnerableCount = 0
// console.log(me.mass) //100
me.do = function() {
me.seePlayer.recall = 1
//maintain speed //faster in the vertical to help avoid repeating patterns
if (this.speed < 0.01) {
const unit = Vector.sub(player.position, this.position)
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(unit), 0.1));
// this.invulnerableCount = 10 + simulation.difficulty * 0.5
// this.isInvulnerable = true
// this.damageReduction = 0
} else {
if (Math.abs(this.velocity.y) < 10) {
Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.03 });
}
if (Math.abs(this.velocity.x) < 7) {
Matter.Body.setVelocity(this, { x: this.velocity.x * 1.03, y: this.velocity.y });
}
}
if (this.isInvulnerable) {
this.invulnerableCount--
if (this.invulnerableCount < 0) {
this.isInvulnerable = false
this.damageReduction = this.startingDamageReduction
}
//draw invulnerable
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.lineWidth = 20;
ctx.strokeStyle = "rgba(255,255,255,0.7)";
ctx.stroke();
}
this.checkStatus();
if (!(simulation.cycle % 15) && mob.length < 360) spawn.mine(this.position.x, this.position.y)
};
},
mine(x, y) {
mobs.spawn(x, y, 8, 10, "rgb(100,170,150)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
Matter.Body.setDensity(me, 0.0001); //normal is 0.001
// Matter.Body.setStatic(me, true); //make static (disables taking damage)
me.frictionAir = 1
me.damageReduction = 2
me.collisionFilter.category = cat.mobBullet;
me.collisionFilter.mask = cat.bullet | cat.body // | cat.player
me.isMine = true
me.leaveBody = false;
me.isDropPowerUp = false;
me.isBadTarget = true;
me.isMobBullet = true;
me.showHealthBar = false;
me.explodeRange = 200 + 150 * Math.random()
me.isExploding = false
me.countDown = Math.ceil(4 * Math.random())
// me.onHit = function() {
// this.isExploding = true
// };
// me.onDamage = function() {
// this.health = 1
// this.isExploding = true
// };
me.do = function() {
this.checkStatus();
if (Matter.Query.collides(this, [player]).length > 0) {
this.isExploding = true
}
if (this.isExploding) {
if (this.countDown-- < 0) { //explode
this.death();
//hit player
if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange) {
m.damage(0.008 * simulation.dmgScale);
const DRAIN = 0.08 * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.energy > DRAIN) m.energy -= DRAIN
}
// mob[i].isInvulnerable = false //make mineBoss not invulnerable ?
const range = this.explodeRange + 50 //mines get a slightly larger range to explode
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && Vector.magnitude(Vector.sub(this.position, mob[i].position)) < range) {
if (mob[i].isMine) mob[i].isExploding = true //explode other mines
}
}
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: this.explodeRange,
color: "rgba(80,220,190,0.45)",
time: 16
});
}
}
};
},
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];
@@ -3659,10 +3813,10 @@ const spawn = {
// this.damageReduction = 0
} else {
if (Math.abs(this.velocity.y) < 15) {
Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.03 });
}
if (Math.abs(this.velocity.x) < 11) {
Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
Matter.Body.setVelocity(this, { x: this.velocity.x * 1.03, y: this.velocity.y });
}
}

View File

@@ -234,7 +234,7 @@ const tech = {
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)
if (tech.isBotDamage) dmg *= 1 + 0.07 * b.totalBots()
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.5
return dmg * tech.slowFire * tech.aimDamage
},
@@ -1395,7 +1395,7 @@ const tech = {
},
{
name: "perimeter defense",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>8%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>7%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
maxCount: 1,
count: 0,
frequency: 2,
@@ -1414,7 +1414,7 @@ const tech = {
},
{
name: "network effect",
description: "increase <strong class='color-d'>damage</strong> by <strong>7%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
maxCount: 1,
count: 0,
frequency: 2,
@@ -7768,7 +7768,7 @@ const tech = {
},
{
name: "emergency broadcasting",
description: "emit 2 sound sine waveforms at 853 Hz and 960 Hz<br><em>lower your volume</em>",
description: "emit 2 sine waveforms at 853 Hz and 960 Hz<br><em>lower your volume</em>",
maxCount: 1,
count: 0,
frequency: 0,

View File

@@ -1,17 +1,33 @@
******************************************************** NEXT PATCH **************************************************
new sprayBoss on reactor level
shows up 50% of the time
unbalanced right now, so give me feedback
new reactor boss - mineBoss
1/3 chance for 1 of 3 different bosses to spawn on the reactor level
harpoon starts with 10->3 ammo, and still gets 1 ammo per powerUpx
network effect damage per bot 7->6%
perimeter defense harm reduction 8->7%
bug fix decoherence
******************************************************** TODO ********************************************************
+damage for each different bot type you have
disables bot upgrades?
improve rail gun / use ammo to crouch fire style for harpoon
spend ammo to get some tech
ammo cost on reticulum
spend ammo to make harpoon radioactive
tech disables filament and unaaq? probably don't need to
give rail gun the auto targeting
improve auto-target with a tech?
you already tried this and target probably can't get better
try to get grappling hook working again
tech doing damage refunds up to 50% of damage take in last 10 seconds
use history to manage this?
use history[] to manage this?
tech: frozen mobs dies at 10% life
CPt disables the falling damage tech
tech: frozen mobs die at 10% life
make a seed/hash system that controls only the tech/guns/fields shown
URL sharing could include a seed
@@ -24,7 +40,6 @@ make a seed/hash system that controls only the tech/guns/fields shown
give 1 extra tech for doing the daily seeded run
make the option for the daily run, a secret exit in the intro level?
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
JUNK tech: https://bindingofisaacrebirth.fandom.com/wiki/Damocles
@@ -33,10 +48,10 @@ cloaking field doesn't show energy over max
run more profiles of n-gon to fix performance issues
sprayBoss
reactor or everywhere?
reactor
mineBoss - bounces around and drops mines
mines explode with a large radius that can trigger other mines
mines have a short delay before exploding so they don't all go up in the same cycle
life-like cellular automata boss
https://scratch.mit.edu/projects/77724260/
night/day?