sprayBoss
new sprayBoss on reactor level shows up 50% of the time unbalanced right now, so give me feedback
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
14
js/index.js
14
js/index.js
@@ -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')
|
||||
});
|
||||
|
||||
51
js/level.js
51
js/level.js
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
140
js/spawn.js
140
js/spawn.js
@@ -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
|
||||
}
|
||||
|
||||
22
js/tech.js
22
js/tech.js
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user