beetlemania
mob: beetleBoss mob: flutter balance: all mobs at every level are about 2%-3% harder to kill
This commit is contained in:
22
js/level.js
22
js/level.js
@@ -16,7 +16,7 @@ const level = {
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(6 * 4) //30 is near max on hard //60 is near max on why
|
||||
// level.difficultyIncrease(8 * 4) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.maxHealth = m.health = 100
|
||||
// powerUps.research.changeRerolls(100000)
|
||||
@@ -24,7 +24,7 @@ const level = {
|
||||
// powerUps.research.changeRerolls(100)
|
||||
// tech.tech[297].frequency = 100
|
||||
// b.guns[0].ammo = 10000
|
||||
// m.setField("molecular assembler") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
|
||||
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
|
||||
// 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("infrared diode");
|
||||
// tech.giveTech("active cooling");
|
||||
@@ -37,8 +37,8 @@ const level = {
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
|
||||
// spawn.starter(1900, -500, 200)
|
||||
// spawn.starter(1900, -500, 50)
|
||||
// spawn.revolutionBoss(1900, -500)
|
||||
// for (let i = 0; i < 10; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
|
||||
// spawn.beetleBoss(1900, -400)
|
||||
// for (let i = 0; i < 10; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
|
||||
// level.testing(); //not in rotation, used for testing
|
||||
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
|
||||
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
|
||||
@@ -148,7 +148,7 @@ const level = {
|
||||
difficultyIncrease(num = 1) {
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty++
|
||||
m.dmgScale *= 0.925; //damage done by player decreases each level
|
||||
m.dmgScale *= 0.922; //damage done by player decreases each level
|
||||
if (simulation.accelScale < 6) simulation.accelScale *= 1.025 //mob acceleration increases each level
|
||||
if (simulation.CDScale > 0.15) simulation.CDScale *= 0.965 //mob CD time decreases each level
|
||||
}
|
||||
@@ -159,7 +159,7 @@ const level = {
|
||||
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty--
|
||||
m.dmgScale /= 0.925; //damage done by player decreases each level
|
||||
m.dmgScale /= 0.922; //damage done by player decreases each level
|
||||
if (simulation.accelScale > 1) simulation.accelScale /= 1.025 //mob acceleration increases each level
|
||||
if (simulation.CDScale < 1) simulation.CDScale /= 0.965 //mob CD time decreases each level
|
||||
}
|
||||
@@ -254,8 +254,10 @@ const level = {
|
||||
level.levels = shuffle(level.levels); //shuffles order of maps
|
||||
}
|
||||
// level.levels.splice(Math.floor(level.levels.length * (0.4 + 0.6 * Math.random())), 0, "reservoir"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.6, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
// level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.2, level.levels.length * 0.5)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
// level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.7, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(0, 2); //remove 2 levels from the start of the array
|
||||
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
|
||||
level.levels.unshift("intro"); //add level to the start of the randomized levels list
|
||||
@@ -2733,7 +2735,7 @@ const level = {
|
||||
spawn.mapRect(475, -25, 25, 50); //edge shelf
|
||||
},
|
||||
testing() {
|
||||
const hazard = level.hazard(6000, -1000, 5, 1000, 0.4) //laser
|
||||
// const hazard = level.hazard(6000, -1000, 5, 1000, 0.4) //laser
|
||||
const button = level.button(1000, 0)
|
||||
spawn.bodyRect(1000, -50, 50, 50);
|
||||
|
||||
@@ -2747,7 +2749,7 @@ const level = {
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
hazard.opticalQuery();
|
||||
// hazard.opticalQuery();
|
||||
button.query();
|
||||
button.draw();
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||
|
||||
16
js/mob.js
16
js/mob.js
@@ -589,6 +589,22 @@ const mobs = {
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
},
|
||||
wing(a, radius = 250, ellipticity = 0.4) {
|
||||
const minorRadius = radius * ellipticity
|
||||
const perp = { x: Math.cos(a), y: Math.sin(a) } //
|
||||
const where = Vector.add(this.position, Vector.mult(perp, radius + 0.8 * this.radius))
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(where.x, where.y, radius, minorRadius, a, 0, 2 * Math.PI)
|
||||
ctx.fill();
|
||||
|
||||
//check for wing -> player damage
|
||||
const hitPlayer = Matter.Query.ray([player], this.position, Vector.add(this.position, Vector.mult(perp, radius * 2.05)), minorRadius)
|
||||
if (hitPlayer.length && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
|
||||
m.damage(0.00008 * radius * simulation.dmgScale);
|
||||
}
|
||||
},
|
||||
searchSpring() {
|
||||
//draw the two dots on the end of the springs
|
||||
ctx.beginPath();
|
||||
|
||||
@@ -2884,7 +2884,7 @@ const m = {
|
||||
//show sneak attack status
|
||||
// if (m.cycle > m.lastKillCycle + 240) {
|
||||
// if (m.sneakAttackCharge > 0) {
|
||||
if (m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) {
|
||||
if (m.sneakAttackCycle + Math.min(120, 0.7 * (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);
|
||||
|
||||
215
js/spawn.js
215
js/spawn.js
@@ -5,7 +5,8 @@ const spawn = {
|
||||
randomBossList: [
|
||||
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
||||
"snakeBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss"
|
||||
"snakeBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss",
|
||||
"beetleBoss"
|
||||
],
|
||||
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
|
||||
bossTypeSpawnIndex: 0, //increases as the boss type cycles
|
||||
@@ -24,6 +25,7 @@ const spawn = {
|
||||
"slasher", "slasher", "slasher",
|
||||
"stabber", "stabber", "stabber",
|
||||
"springer", "springer", "springer",
|
||||
"flutter", "flutter",
|
||||
"shooter", "shooter",
|
||||
"grenadier", "grenadier",
|
||||
"striker", "striker",
|
||||
@@ -33,7 +35,7 @@ const spawn = {
|
||||
],
|
||||
mobTypeSpawnOrder: [], //preset list of mob names calculated at the start of a run by the randomSeed
|
||||
mobTypeSpawnIndex: 0, //increases as the mob type cycles
|
||||
allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "launcherOne", "stabber", "sniper", "pulsar", "grenadier", "slasher"],
|
||||
allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "launcherOne", "stabber", "sniper", "pulsar", "grenadier", "slasher", "flutter"],
|
||||
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||
spawn.pickList.splice(0, 1);
|
||||
const push = spawn.mobTypeSpawnOrder[spawn.mobTypeSpawnIndex++ % spawn.mobTypeSpawnOrder.length]
|
||||
@@ -2068,8 +2070,9 @@ const spawn = {
|
||||
let targets = [] //track who is in the node boss, for shields
|
||||
mobs.spawn(x, y, 6, radius, "#b386e8");
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.setDensity(me, 0.0032); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
|
||||
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.13 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
|
||||
|
||||
targets.push(me.id) //add to shield protection
|
||||
me.friction = 0;
|
||||
@@ -2110,7 +2113,6 @@ const spawn = {
|
||||
Composite.add(engine.world, cons[cons.length - 1]);
|
||||
cons[len2].length = 100 + 1.5 * radius;
|
||||
me.cons2 = cons[len2];
|
||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
this.gravity();
|
||||
@@ -2134,7 +2136,7 @@ const spawn = {
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
spawn.stabber(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius, 12);
|
||||
Matter.Body.setDensity(mob[mob.length - 1], 0.003); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
mob[mob.length - 1].damageReduction = 0.5
|
||||
mob[mob.length - 1].damageReduction = 0.12
|
||||
targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields
|
||||
}
|
||||
|
||||
@@ -2690,6 +2692,190 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
flutter(x, y, radius = 20 + 6 * Math.random()) {
|
||||
mobs.spawn(x, y, 7, radius, '#16576b');
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||
me.accelMag = 0.0006 + 0.0006 * Math.sqrt(simulation.accelScale);
|
||||
me.frictionAir = 0.05;
|
||||
// me.seePlayerFreq = 40 + Math.floor(13 * Math.random())
|
||||
me.memory = 240;
|
||||
me.restitution = 1;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.lookTorque = 0.000001 * (Math.random() > 0.5 ? -1 : 1);
|
||||
me.fireDir = { x: 0, y: 0 }
|
||||
spawn.shield(me, x, y);
|
||||
|
||||
// me.onDeath = function() {};
|
||||
me.flapRate = 0.3 + Math.floor(3 * Math.random()) / 10 + 100 * me.accelMag
|
||||
me.flapRadius = 100 + 75 * Math.random() + radius * 2
|
||||
me.do = function() {
|
||||
this.seePlayerByHistory()
|
||||
this.checkStatus();
|
||||
if (this.seePlayer.recall) {
|
||||
this.force.x += Math.cos(this.angle) * this.accelMag * this.mass
|
||||
this.force.y += Math.sin(this.angle) * this.accelMag * this.mass
|
||||
|
||||
//set direction to turn to fire
|
||||
if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||
|
||||
//dot product can't tell if mob is facing directly away or directly towards, so check if pointed directly away from player every few cycles
|
||||
const mod = (a, n) => {
|
||||
return a - Math.floor(a / n) * n
|
||||
}
|
||||
const sub = Vector.sub(m.pos, this.position) //check by comparing different between angles. Give this a nudge if angles are 180 degree different
|
||||
const diff = mod(Math.atan2(sub.y, sub.x) - this.angle + Math.PI, 2 * Math.PI) - Math.PI
|
||||
if (Math.abs(diff) > 2.8) this.torque += 0.0002 * this.inertia * Math.random();
|
||||
}
|
||||
|
||||
//rotate towards fireDir
|
||||
const angle = this.angle + Math.PI / 2;
|
||||
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
const threshold = 0.4;
|
||||
const turn = 0.00003 * this.inertia
|
||||
if (c > threshold) {
|
||||
this.torque += turn;
|
||||
} else if (c < -threshold) {
|
||||
this.torque -= turn;
|
||||
}
|
||||
const flapArc = 0.7 //don't go past 1.57 for normal flaps
|
||||
|
||||
ctx.fillStyle = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.2)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
|
||||
this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
}
|
||||
};
|
||||
},
|
||||
beetleBoss(x, y, radius = 60) {
|
||||
mobs.spawn(x, y, 7, radius, '#16576b');
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.nextHealthThreshold = 0.75
|
||||
me.invulnerableCount = 0
|
||||
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||
me.accelMag = 0.0006 + 0.0006 * Math.sqrt(simulation.accelScale);
|
||||
me.frictionAir = 0.05;
|
||||
me.seePlayerFreq = 30
|
||||
me.memory = 420;
|
||||
me.restitution = 1;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.lookTorque = 0.000001 * (Math.random() > 0.5 ? -1 : 1);
|
||||
me.fireDir = { x: 0, y: 0 }
|
||||
spawn.shield(me, x, y);
|
||||
|
||||
// for (let i = 0, len = 4 + 0.2 * simulation.difficulty; i < len; ++i) {
|
||||
// const phase = i / len * 2 * Math.PI
|
||||
// const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
|
||||
// spawn.flutter(where.x, where.y)
|
||||
// }
|
||||
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
|
||||
len = 0.2 * simulation.difficulty
|
||||
if (len > 3) {
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const phase = i / len * 2 * Math.PI
|
||||
const where = Vector.add(this.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
|
||||
spawn.flutter(where.x, where.y)
|
||||
}
|
||||
}
|
||||
};
|
||||
me.onDamage = function() {
|
||||
if (this.health < this.nextHealthThreshold) {
|
||||
this.health = this.nextHealthThreshold - 0.01
|
||||
this.nextHealthThreshold = Math.floor(this.health * 4) / 4
|
||||
this.invulnerableCount = 180 + Math.floor(60 * Math.random())
|
||||
this.isInvulnerable = true
|
||||
this.damageReduction = 0
|
||||
this.frictionAir = 0
|
||||
}
|
||||
};
|
||||
me.do = function() {
|
||||
this.seePlayerByHistory()
|
||||
this.checkStatus();
|
||||
if (this.isInvulnerable) {
|
||||
this.invulnerableCount--
|
||||
if (this.invulnerableCount < 0) {
|
||||
this.isInvulnerable = false
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
this.frictionAir = 0.05
|
||||
}
|
||||
// //draw wings as if they are protecting
|
||||
// const wingShield = (a, size) => {
|
||||
// ctx.beginPath();
|
||||
// const perp = { x: Math.cos(a), y: Math.sin(a) } //
|
||||
// const where = Vector.add(this.position, Vector.mult(perp, 0.2 * this.radius))
|
||||
// ctx.ellipse(where.x, where.y, size, size * 0.8, a, 0, 2 * Math.PI)
|
||||
// ctx.fillStyle = this.fill = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
|
||||
// ctx.fill();
|
||||
// }
|
||||
// wingShield(this.angle + Math.PI / 2, radius * 1.3)
|
||||
// wingShield(this.angle - Math.PI / 2, radius * 1.3)
|
||||
|
||||
//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 = 13 + 5 * Math.random();
|
||||
ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`;
|
||||
ctx.stroke();
|
||||
} else if (this.seePlayer.recall) {
|
||||
// const force = Vector.mult(Vector.normalise(Vector.sub(this.seePlayer.position, this.position)), this.accelMag * this.mass)
|
||||
// const force = Vector.mult({ x: Math.cos(this.angle), y: Math.sin(this.angle) }, this.accelMag * this.mass)
|
||||
// this.force.x += force.x;
|
||||
// this.force.y += force.y;
|
||||
this.force.x += Math.cos(this.angle) * this.accelMag * this.mass
|
||||
this.force.y += Math.sin(this.angle) * this.accelMag * this.mass
|
||||
|
||||
//set direction to turn to fire
|
||||
if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||
|
||||
//dot product can't tell if mob is facing directly away or directly towards, so check if pointed directly away from player every few cycles
|
||||
//check by comparing different between angles. Give this a nudge if angles are 180 degree different
|
||||
const mod = (a, n) => {
|
||||
return a - Math.floor(a / n) * n
|
||||
}
|
||||
const sub = Vector.sub(m.pos, this.position)
|
||||
const diff = mod(Math.atan2(sub.y, sub.x) - this.angle + Math.PI, 2 * Math.PI) - Math.PI
|
||||
if (Math.abs(diff) > 2.8) this.torque += 0.0002 * this.inertia * Math.random();
|
||||
}
|
||||
|
||||
//rotate towards fireDir
|
||||
const angle = this.angle + Math.PI / 2;
|
||||
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
const threshold = 0.4;
|
||||
const turn = 0.00003 * this.inertia
|
||||
if (c > threshold) {
|
||||
this.torque += turn;
|
||||
} else if (c < -threshold) {
|
||||
this.torque -= turn;
|
||||
}
|
||||
const flapRate = 0.5
|
||||
const flapArc = 0.7 //don't go past 1.57 for normal flaps
|
||||
ctx.fillStyle = this.fill = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
|
||||
this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * flapRate), 250, 0.5)
|
||||
this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * flapRate), 250, 0.5)
|
||||
}
|
||||
};
|
||||
},
|
||||
laserTargetingBoss(x, y, radius = 80) {
|
||||
const color = "#07f"
|
||||
mobs.spawn(x, y, 3, radius, color);
|
||||
@@ -3846,6 +4032,10 @@ const spawn = {
|
||||
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.nextHealthThreshold = 0.75
|
||||
me.invulnerableCount = 0
|
||||
|
||||
me.cycle = 0
|
||||
me.inertia = Infinity;
|
||||
me.frictionAir = 0.01
|
||||
me.restitution = 1
|
||||
@@ -3889,9 +4079,6 @@ const spawn = {
|
||||
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
|
||||
@@ -4718,14 +4905,14 @@ const spawn = {
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.00004,
|
||||
damping: 0.1
|
||||
damping: 0.2
|
||||
});
|
||||
Composite.add(engine.world, me.constraint);
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
|
||||
me.isBoss = true;
|
||||
Matter.Body.setDensity(me, 0.008 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
Matter.Body.setDensity(me, 0.01 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
me.isVerticesChange = true
|
||||
@@ -4738,9 +4925,7 @@ const spawn = {
|
||||
me.lookTorque = 0.000006 * (Math.random() > 0.5 ? -1 : 1);
|
||||
me.fireDir = { x: 0, y: 0 };
|
||||
setTimeout(() => {
|
||||
// spawn.spawnOrbitals(me, radius + 200 + 50 * Math.random(), 1);
|
||||
for (let i = 0, len = 3 + 0.5 * Math.sqrt(simulation.difficulty); i < len; i++) spawn.spawnOrbitals(me, radius + 40 + 10 * i, 1);
|
||||
|
||||
}, 100); //have to wait a sec so the tether constraint doesn't attach to an orbital
|
||||
me.onDeath = function() {
|
||||
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
@@ -5051,6 +5236,8 @@ const spawn = {
|
||||
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
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.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
|
||||
me.accelMag = 0.0001 * simulation.accelScale;
|
||||
me.fireFreq = Math.floor(330 * simulation.CDScale)
|
||||
@@ -5062,13 +5249,11 @@ const spawn = {
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
|
||||
|
||||
Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.onDeath = function() {
|
||||
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
|
||||
};
|
||||
me.onDamage = function() {};
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
this.seePlayerCheck();
|
||||
|
||||
12
js/tech.js
12
js/tech.js
@@ -317,9 +317,9 @@ const tech = {
|
||||
// isExperimentHide: true,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
return true
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
requires: "",
|
||||
effect() {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "gun");
|
||||
// this.count--
|
||||
@@ -3043,9 +3043,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isResearchReality //tech.isResearchBoss || tech.isMetaAnalysis || tech.isRerollBots || tech.isDeathAvoid || tech.isRerollDamage || build.isExperimentSelection
|
||||
return !tech.isResearchReality && !tech.isSuperDeterminism //tech.isResearchBoss || tech.isMetaAnalysis || tech.isRerollBots || tech.isDeathAvoid || tech.isRerollDamage || build.isExperimentSelection
|
||||
},
|
||||
requires: "not Ψ(t) collapse", //"abiogenesis, meta-analysis, bot fabrication, anthropic principle, or Bayesian statistics, not Ψ(t) collapse",
|
||||
requires: "not Ψ(t) collapse, superdeterminism", //"abiogenesis, meta-analysis, bot fabrication, anthropic principle, or Bayesian statistics, not Ψ(t) collapse",
|
||||
effect() {
|
||||
tech.isJunkResearch = true;
|
||||
},
|
||||
@@ -3061,9 +3061,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "",
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
tech.isBrainstorm = true
|
||||
tech.isBrainstormActive = false
|
||||
|
||||
24
todo.txt
24
todo.txt
@@ -1,23 +1,19 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
tech: ricochet - nails bounce off mobs and hit other mobs with extra damage per ricochet
|
||||
mob: beetleBoss
|
||||
mob: flutter
|
||||
|
||||
tech: dye laser - 20% efficiency and 20% damage
|
||||
laser diode renamed infrared diode
|
||||
40 -> 50% efficiency but you can't see the laser beam
|
||||
laser-bots acquire new targets much faster
|
||||
iridescence 88 -> 100% damage, a tiny bit harder to hit center of mobs
|
||||
stacks up to 3 -> 9
|
||||
|
||||
dynamic equilibrium scales damage with defense
|
||||
goes up to 9x stacks
|
||||
neutronium 25 -> 20% slower movement
|
||||
|
||||
revolutionBoss laser swords are much slower and shorter
|
||||
but they do more damage
|
||||
balance: all mobs at every level are about 2%-3% harder to kill
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
wings
|
||||
put in mob as a method?
|
||||
add parameter for ellipticity
|
||||
give snakeBoss wings?
|
||||
|
||||
|
||||
|
||||
mob mechanics
|
||||
bullets hit player and stay attached for 4-5 seconds, slowing player
|
||||
hopperBullets?
|
||||
|
||||
Reference in New Issue
Block a user