laserLayerBoss
laserLayerBoss - sends lasers to player's location snakes bosses - after you kill a tail piece the rest of the tails lose 5% life this makes targeting any part of the tail a viable strategy accretion disk - 5% damage for every power up on this level requires accretion unified field theory has buttons to cycle field forwards or backwards when paused iceIX range and damage increased 15% electric tech in labs level is finally nerfed drains energy, but doesn't do damage pushes player away
This commit is contained in:
BIN
img/accretion disk.webp
Normal file
BIN
img/accretion disk.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -3035,7 +3035,7 @@ const b = {
|
|||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const THRUST = 0.0018
|
const THRUST = 0.0018
|
||||||
const RADIUS = 18
|
const RADIUS = 18
|
||||||
const SCALE = 1 - 0.12 / tech.bulletsLastLonger
|
const SCALE = 1 - 0.11 / tech.bulletsLastLonger
|
||||||
bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, {
|
bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, {
|
||||||
angle: dir - Math.PI,
|
angle: dir - Math.PI,
|
||||||
// inertia: Infinity,
|
// inertia: Infinity,
|
||||||
|
|||||||
53
js/index.js
53
js/index.js
@@ -351,7 +351,6 @@ const build = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fade alpha for all pixels
|
// fade alpha for all pixels
|
||||||
// for (let i = 0; i < data.length; i += 4) {
|
// for (let i = 0; i < data.length; i += 4) {
|
||||||
// if (data[i + 3] > 0) {
|
// if (data[i + 3] > 0) {
|
||||||
@@ -424,11 +423,8 @@ const build = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
pauseGrid() {
|
pauseGrid() {
|
||||||
// build.pixelDraw();
|
|
||||||
|
|
||||||
build.generatePauseLeft() //makes the left side of the pause menu with the tech
|
build.generatePauseLeft() //makes the left side of the pause menu with the tech
|
||||||
build.generatePauseRight() //makes the right side of the pause menu with the tech
|
build.generatePauseRight() //makes the right side of the pause menu with the tech
|
||||||
|
|
||||||
document.getElementById("tech").style.display = "none"
|
document.getElementById("tech").style.display = "none"
|
||||||
document.getElementById("guns").style.display = "none"
|
document.getElementById("guns").style.display = "none"
|
||||||
document.getElementById("field").style.display = "none"
|
document.getElementById("field").style.display = "none"
|
||||||
@@ -436,12 +432,8 @@ const build = {
|
|||||||
document.getElementById("health-bg").style.display = "none"
|
document.getElementById("health-bg").style.display = "none"
|
||||||
document.getElementById("defense-bar").style.display = "none"
|
document.getElementById("defense-bar").style.display = "none"
|
||||||
document.getElementById("damage-bar").style.display = "none"
|
document.getElementById("damage-bar").style.display = "none"
|
||||||
|
|
||||||
|
|
||||||
//show in game console
|
//show in game console
|
||||||
// document.getElementById("text-log").style.display = "inline"
|
|
||||||
simulation.lastLogTime = m.cycle //hide in game console
|
simulation.lastLogTime = m.cycle //hide in game console
|
||||||
|
|
||||||
},
|
},
|
||||||
generatePauseLeft() {
|
generatePauseLeft() {
|
||||||
//used for junk estimation
|
//used for junk estimation
|
||||||
@@ -504,12 +496,29 @@ ${junkCount ? `<br><strong class='color-junk'>JUNK</strong>: ${(junkCount / tota
|
|||||||
${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
||||||
</span></div>`;
|
</span></div>`;
|
||||||
// deaths: ${mobs.mobDeaths}
|
// deaths: ${mobs.mobDeaths}
|
||||||
if (tech.isPauseSwitchField && !simulation.isChoosing) {
|
// if (tech.isPauseSwitchField && !simulation.isChoosing) {
|
||||||
|
// const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
|
||||||
|
// text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
|
||||||
|
// <div class="card-text" style = "animation: fieldColorCycle 1s linear infinite alternate;">
|
||||||
|
// <div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
|
||||||
|
// ${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
|
||||||
|
if ((tech.isPauseSwitchField || simulation.testing)) { //&& !simulation.isChoosing
|
||||||
|
// const fieldNameP = m.fieldUpgrades[m.fieldMode > 1 ? m.fieldMode - 1 : m.fieldUpgrades.length - 1].name
|
||||||
|
// const fieldNameN = m.fieldUpgrades[m.fieldMode === m.fieldUpgrades.length - 2 ? 1 : m.fieldMode + 1].name
|
||||||
|
//button above for previous
|
||||||
|
text += `<div class="pause-grid-module" id ="pause-field-previous" style="animation: fieldColorCycle 3s linear infinite alternate; border-top: 1px solid #000;border-bottom: 1px solid #000;">
|
||||||
|
<div class="grid-title" style="text-align: center;">↑ <div class="circle-grid field"></div> ↑</div></div>`
|
||||||
|
//button for current
|
||||||
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
|
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
|
||||||
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
|
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
|
||||||
<div class="card-text" style = "animation: fieldColorCycle 1s linear infinite alternate;">
|
<div class="card-text">
|
||||||
<div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
|
<div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
|
||||||
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
|
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
|
||||||
|
//button below for next
|
||||||
|
text += `<div class="pause-grid-module" id ="pause-field-next" style="animation: fieldColorCycle 3s linear infinite alternate;border-bottom: 1px solid #000;">
|
||||||
|
<div class="grid-title" style="text-align: center;">↓ <div class="circle-grid field"></div> ↓</div></div>`
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
|
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
|
||||||
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
|
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
|
||||||
@@ -1356,7 +1365,24 @@ window.addEventListener("keydown", function (event) {
|
|||||||
document.body.style.cursor = "auto";
|
document.body.style.cursor = "auto";
|
||||||
|
|
||||||
if (tech.isPauseSwitchField || simulation.testing) {
|
if (tech.isPauseSwitchField || simulation.testing) {
|
||||||
document.getElementById("pause-field").addEventListener("click", () => {
|
document.getElementById("pause-field-previous").addEventListener("click", () => {
|
||||||
|
const energy = m.energy //save current energy
|
||||||
|
if (m.fieldMode === 4 && simulation.molecularMode > 0) {
|
||||||
|
simulation.molecularMode--
|
||||||
|
m.fieldUpgrades[4].description = m.fieldUpgrades[4].setDescription()
|
||||||
|
} else {
|
||||||
|
m.setField((m.fieldMode < 2) ? m.fieldUpgrades.length - 1 : m.fieldMode - 1) //cycle to previous field, skip field emitter
|
||||||
|
if (m.fieldMode === 4) {
|
||||||
|
simulation.molecularMode = 3
|
||||||
|
m.fieldUpgrades[4].description = m.fieldUpgrades[4].setDescription()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.energy = energy //return to current energy
|
||||||
|
document.getElementById("pause-field").style.backgroundImage = `url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? Math.floor(Math.random() * 10) : ""}.webp')`
|
||||||
|
document.getElementById("pause-field").innerHTML = `<div class="card-text"> <div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>${m.fieldUpgrades[m.fieldMode].description}</div>`
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("pause-field-next").addEventListener("click", () => {
|
||||||
const energy = m.energy //save current energy
|
const energy = m.energy //save current energy
|
||||||
if (m.fieldMode === 4 && simulation.molecularMode < 3) {
|
if (m.fieldMode === 4 && simulation.molecularMode < 3) {
|
||||||
simulation.molecularMode++
|
simulation.molecularMode++
|
||||||
@@ -1371,10 +1397,7 @@ window.addEventListener("keydown", function (event) {
|
|||||||
m.energy = energy //return to current energy
|
m.energy = energy //return to current energy
|
||||||
// document.getElementById("pause-field").innerHTML = `<div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}`
|
// document.getElementById("pause-field").innerHTML = `<div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}`
|
||||||
document.getElementById("pause-field").style.backgroundImage = `url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? Math.floor(Math.random() * 10) : ""}.webp')`
|
document.getElementById("pause-field").style.backgroundImage = `url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? Math.floor(Math.random() * 10) : ""}.webp')`
|
||||||
document.getElementById("pause-field").innerHTML = `
|
document.getElementById("pause-field").innerHTML = `<div class="card-text"> <div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>`
|
||||||
<div class="card-text" style = "animation: fieldColorCycle 1s linear infinite alternate;">
|
|
||||||
<div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
|
|
||||||
${m.fieldUpgrades[m.fieldMode].description}</div>`
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
js/level.js
33
js/level.js
@@ -19,8 +19,8 @@ const level = {
|
|||||||
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||||
// simulation.isHorizontalFlipped = true
|
// simulation.isHorizontalFlipped = true
|
||||||
// tech.giveTech("performance")
|
// tech.giveTech("performance")
|
||||||
// level.difficultyIncrease(3 * 2) //30 is near max on hard //60 is near max on why
|
// level.difficultyIncrease(7 * 2) //30 is near max on hard //60 is near max on why
|
||||||
// m.maxHealth = m.health = 100000000
|
// m.maxHealth = m.health = 1//00000000
|
||||||
// m.maxEnergy = m.energy = 10000000
|
// m.maxEnergy = m.energy = 10000000
|
||||||
// tech.isRerollDamage = true
|
// tech.isRerollDamage = true
|
||||||
// powerUps.research.changeRerolls(99999)
|
// powerUps.research.changeRerolls(99999)
|
||||||
@@ -47,7 +47,7 @@ const level = {
|
|||||||
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
|
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
|
||||||
// m.lastKillCycle = m.cycle
|
// m.lastKillCycle = m.cycle
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("swarf")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("swarf")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("CPT symmetry")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("unified field theory")
|
||||||
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
||||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||||
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||||
@@ -57,8 +57,8 @@ const level = {
|
|||||||
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
|
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
|
||||||
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
|
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
|
||||||
// for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
|
// for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
|
||||||
// for (let i = 0; i < 3; ++i) spawn.laser(1900, -500)
|
// for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500)
|
||||||
// for (let i = 0; i < 1; ++i) spawn.laserBombingBoss(1900, -2500)
|
// for (let i = 0; i < 1; ++i) spawn.dragonFlyBoss(1900, -500)
|
||||||
// spawn.beetleBoss(1900, -500, 25)
|
// spawn.beetleBoss(1900, -500, 25)
|
||||||
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
|
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
|
||||||
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
|
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
|
||||||
@@ -4996,10 +4996,7 @@ const level = {
|
|||||||
powerUps.directSpawn(x + 998, y - 333, "tech", false);
|
powerUps.directSpawn(x + 998, y - 333, "tech", false);
|
||||||
}
|
}
|
||||||
const powerUp1 = powerUp[powerUp.length - 1]
|
const powerUp1 = powerUp[powerUp.length - 1]
|
||||||
powerUp1.holdPosition = {
|
powerUp1.holdPosition = { x: powerUp1.position.x, y: powerUp1.position.y }
|
||||||
x: powerUp1.position.x,
|
|
||||||
y: powerUp1.position.y
|
|
||||||
}
|
|
||||||
let isSpawnedMobs = false
|
let isSpawnedMobs = false
|
||||||
doCustom.push(
|
doCustom.push(
|
||||||
() => {
|
() => {
|
||||||
@@ -5014,9 +5011,23 @@ const level = {
|
|||||||
if (Vector.magnitudeSquared(Vector.sub(m.pos, powerUp1.position)) < 90000) { //zone radius is 300
|
if (Vector.magnitudeSquared(Vector.sub(m.pos, powerUp1.position)) < 90000) { //zone radius is 300
|
||||||
//damage player and drain energy
|
//damage player and drain energy
|
||||||
if (m.immuneCycle < m.cycle) {
|
if (m.immuneCycle < m.cycle) {
|
||||||
m.damage(0.01);
|
if (m.energy < 0.02) {
|
||||||
if (m.energy > 0.1) m.energy -= 0.02
|
//push out
|
||||||
|
// const force = Vector.mult(Vector.normalise(Vector.sub(player.position, powerUp1.position)), 0.02 * player.mass)
|
||||||
|
// player.force.x += force.x
|
||||||
|
// player.force.y += force.y
|
||||||
|
player.force.x += (player.position.x > powerUp1.position.x) ? 0.02 * player.mass : - 0.02 * player.mass
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m.energy -= 0.01
|
||||||
|
//friction
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: player.velocity.x * 0.45,
|
||||||
|
y: player.velocity.y * 0.98
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw electricity going towards player
|
//draw electricity going towards player
|
||||||
const unit = Vector.normalise(Vector.sub(m.pos, powerUp1.position))
|
const unit = Vector.normalise(Vector.sub(m.pos, powerUp1.position))
|
||||||
let xElec = powerUp1.position.x + 40 * unit.x;
|
let xElec = powerUp1.position.x + 40 * unit.x;
|
||||||
|
|||||||
48
js/player.js
48
js/player.js
@@ -540,10 +540,10 @@ const m = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
baseHealth: 1,
|
baseHealth: 1,
|
||||||
setMaxHealth() {
|
setMaxHealth(isMessage) {
|
||||||
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
|
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
|
||||||
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
|
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
|
||||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
|
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
|
||||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||||
m.displayHealth();
|
m.displayHealth();
|
||||||
},
|
},
|
||||||
@@ -605,10 +605,7 @@ const m = {
|
|||||||
|
|
||||||
let history = m.history[(m.cycle - steps) % 600]
|
let history = m.history[(m.cycle - steps) % 600]
|
||||||
Matter.Body.setPosition(player, history.position);
|
Matter.Body.setPosition(player, history.position);
|
||||||
Matter.Body.setVelocity(player, {
|
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||||
x: history.velocity.x,
|
|
||||||
y: history.velocity.y
|
|
||||||
});
|
|
||||||
m.yOff = history.yOff
|
m.yOff = history.yOff
|
||||||
if (m.yOff < 48) {
|
if (m.yOff < 48) {
|
||||||
m.doCrouch()
|
m.doCrouch()
|
||||||
@@ -2125,14 +2122,8 @@ const m = {
|
|||||||
hole: {
|
hole: {
|
||||||
isOn: false,
|
isOn: false,
|
||||||
isReady: false,
|
isReady: false,
|
||||||
pos1: {
|
pos1: { x: 0, y: 0 },
|
||||||
x: 0,
|
pos2: { x: 0, y: 0 },
|
||||||
y: 0
|
|
||||||
},
|
|
||||||
pos2: {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
fieldArc: 0,
|
fieldArc: 0,
|
||||||
fieldThreshold: 0,
|
fieldThreshold: 0,
|
||||||
@@ -2175,20 +2166,14 @@ const m = {
|
|||||||
m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
m.isBodiesAsleep = true;
|
m.isBodiesAsleep = true;
|
||||||
m.wakeCheck();
|
m.wakeCheck();
|
||||||
m.setMaxEnergy();
|
m.setMaxEnergy(false);
|
||||||
m.setMaxHealth();
|
m.setMaxHealth(false);
|
||||||
m.couplingChange()
|
m.couplingChange()
|
||||||
m.hole = {
|
m.hole = {
|
||||||
isOn: false,
|
isOn: false,
|
||||||
isReady: false,
|
isReady: false,
|
||||||
pos1: {
|
pos1: { x: 0, y: 0 },
|
||||||
x: 0,
|
pos2: { x: 0, y: 0 },
|
||||||
y: 0
|
|
||||||
},
|
|
||||||
pos2: {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setMaxEnergy(isMessage = true) {
|
setMaxEnergy(isMessage = true) {
|
||||||
@@ -3436,15 +3421,9 @@ const m = {
|
|||||||
}
|
}
|
||||||
} else if (simulation.molecularMode === 1) {
|
} else if (simulation.molecularMode === 1) {
|
||||||
m.energy -= 0.33;
|
m.energy -= 0.33;
|
||||||
const direction = {
|
const direction = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
||||||
x: Math.cos(m.angle),
|
|
||||||
y: Math.sin(m.angle)
|
|
||||||
}
|
|
||||||
const push = Vector.mult(Vector.perp(direction), 0.08)
|
const push = Vector.mult(Vector.perp(direction), 0.08)
|
||||||
b.missile({
|
b.missile({ x: m.pos.x + 30 * direction.x, y: m.pos.y + 30 * direction.y }, m.angle, -15)
|
||||||
x: m.pos.x + 30 * direction.x,
|
|
||||||
y: m.pos.y + 30 * direction.y
|
|
||||||
}, m.angle, -15)
|
|
||||||
bullet[bullet.length - 1].force.x += push.x * (Math.random() - 0.5)
|
bullet[bullet.length - 1].force.x += push.x * (Math.random() - 0.5)
|
||||||
bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5)
|
bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5)
|
||||||
// b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
|
// b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
|
||||||
@@ -3538,10 +3517,7 @@ const m = {
|
|||||||
radiusLimit: 10,
|
radiusLimit: 10,
|
||||||
damage: 0.8,
|
damage: 0.8,
|
||||||
setPositionToNose() {
|
setPositionToNose() {
|
||||||
const nose = {
|
const nose = { x: m.pos.x + 10 * Math.cos(m.angle), y: m.pos.y + 10 * Math.sin(m.angle) }
|
||||||
x: m.pos.x + 10 * Math.cos(m.angle),
|
|
||||||
y: m.pos.y + 10 * Math.sin(m.angle)
|
|
||||||
}
|
|
||||||
Matter.Body.setPosition(this, Vector.add(nose, Vector.mult(Vector.normalise(Vector.sub(nose, m.pos)), circleRadiusScale * this.circleRadius)));
|
Matter.Body.setPosition(this, Vector.add(nose, Vector.mult(Vector.normalise(Vector.sub(nose, m.pos)), circleRadiusScale * this.circleRadius)));
|
||||||
},
|
},
|
||||||
fire() {
|
fire() {
|
||||||
|
|||||||
231
js/spawn.js
231
js/spawn.js
@@ -6,7 +6,8 @@ const spawn = {
|
|||||||
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||||
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
||||||
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
|
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
|
||||||
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss", "mantisBoss"
|
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss", "mantisBoss",
|
||||||
|
"laserLayerBoss"
|
||||||
],
|
],
|
||||||
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
|
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
|
||||||
bossTypeSpawnIndex: 0, //increases as the boss type cycles
|
bossTypeSpawnIndex: 0, //increases as the boss type cycles
|
||||||
@@ -4216,7 +4217,7 @@ const spawn = {
|
|||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.moveTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
||||||
ctx.lineTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
ctx.lineTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
||||||
ctx.lineWidth = 5 + 5 * this.lasers[i].fade;
|
ctx.lineWidth = 2 + 40 - 40 * this.lasers[i].fade;
|
||||||
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.lasers[i].fade})`;
|
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.lasers[i].fade})`;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
@@ -4238,21 +4239,207 @@ const spawn = {
|
|||||||
this.force.x += force.x;
|
this.force.x += force.x;
|
||||||
this.force.y += force.y;
|
this.force.y += force.y;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.cycle++
|
this.cycle++
|
||||||
this.torque = this.lookTorque * this.inertia * 0.6;
|
this.torque = this.lookTorque * this.inertia * 0.6;
|
||||||
this.seePlayerCheck();
|
this.seePlayerCheck();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.drift();
|
this.drift();
|
||||||
//add new laser to lasers array
|
//add new laser to lasers array
|
||||||
this.addLaser()
|
this.addLaser()
|
||||||
this.fireLaser()
|
this.fireLaser()
|
||||||
// if (this.seePlayer.recall) {
|
// if (this.seePlayer.recall) {
|
||||||
// //set direction to turn to fire
|
// //set direction to turn to fire
|
||||||
// if (!(simulation.cycle % this.seePlayerFreq)) this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
// if (!(simulation.cycle % this.seePlayerFreq)) this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
laserLayerBoss(x, y, radius = 65) {
|
||||||
|
const color = "#f09"
|
||||||
|
mobs.spawn(x, y, 4, radius, color);
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||||
|
for (let i = 0; i < 4; i += 2) {
|
||||||
|
let spike = Vector.mult(Vector.normalise(Vector.sub(me.vertices[i], me.position)), radius * 2)
|
||||||
|
me.vertices[i].x = me.position.x + spike.x
|
||||||
|
me.vertices[i].y = me.position.y + spike.y
|
||||||
|
}
|
||||||
|
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||||
|
me.accelMag = 0.0001 * simulation.accelScale;
|
||||||
|
|
||||||
|
|
||||||
|
me.isBoss = true;
|
||||||
|
me.onDeath = function () {
|
||||||
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
|
};
|
||||||
|
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
|
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
|
me.startingDamageReduction = me.damageReduction
|
||||||
|
me.isInvulnerable = false
|
||||||
|
me.nextHealthThreshold = 0.75
|
||||||
|
me.invulnerableCount = 0
|
||||||
|
me.onDamage = function () {
|
||||||
|
if (this.health < this.nextHealthThreshold) {
|
||||||
|
this.health = this.nextHealthThreshold - 0.01
|
||||||
|
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
|
||||||
|
this.invulnerableCount = 120
|
||||||
|
this.isInvulnerable = true
|
||||||
|
this.damageReduction = 0
|
||||||
|
|
||||||
|
// if (this.health > 0.74) this.laserLimit += 2 //increase total lasers once player gets into combat
|
||||||
|
// this.addLaser()
|
||||||
|
this.laserDelay = 130
|
||||||
|
}
|
||||||
|
};
|
||||||
|
me.lasers = [] //keeps track of static laser beams
|
||||||
|
// me.laserLimit = 1 + 2 * (simulation.difficultyMode < 3 ? 1 : 2)
|
||||||
|
me.laserLimit = 2 + (simulation.difficultyMode < 3 ? 1 : 2)
|
||||||
|
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
|
||||||
|
me.cycle = 0
|
||||||
|
me.laserDelay = 210
|
||||||
|
me.addLaser = function () {
|
||||||
|
if (this.cycle > this.laserDelay) {
|
||||||
|
this.cycle = 0
|
||||||
|
const seeRange = 6000;
|
||||||
|
let add = (where, angle) => {
|
||||||
|
const v1 = { x: where.x + seeRange * Math.cos(angle), y: where.y + seeRange * Math.sin(angle) };
|
||||||
|
const v2 = { x: where.x + seeRange * Math.cos(angle + Math.PI), y: where.y + seeRange * Math.sin(angle + Math.PI) };
|
||||||
|
//find where v1,v2 hit walls and make them stop there
|
||||||
|
let best1 = vertexCollision(where, v1, [map]);
|
||||||
|
let best2 = vertexCollision(where, v2, [map]);
|
||||||
|
if (best2.who === null) {
|
||||||
|
best2.x = v2.x
|
||||||
|
best2.y = v2.y
|
||||||
|
}
|
||||||
|
if (best1.who === null) { //if the path never hits the map , just stop at seeRange
|
||||||
|
best1.x = v1.x
|
||||||
|
best1.y = v1.y
|
||||||
|
}
|
||||||
|
if (best1.y > best2.y) { //make laser beams always fire from top to bottom so they are predicable, and not stopped by blocks on the ground
|
||||||
|
const save1X = best1.x
|
||||||
|
const save1Y = best1.y
|
||||||
|
best1.x = best2.x
|
||||||
|
best1.y = best2.y
|
||||||
|
best2.x = save1X
|
||||||
|
best2.y = save1Y
|
||||||
|
}
|
||||||
|
this.lasers.push({ a: { x: best1.x, y: best1.y }, b: { x: best2.x, y: best2.y }, fade: 0 })
|
||||||
|
}
|
||||||
|
// add(m.pos, m.angle)
|
||||||
|
add(m.pos, this.angle + Math.PI / 4 + Math.PI / 2)
|
||||||
|
add(this.position, this.angle + Math.PI / 4)
|
||||||
|
//friction to animate the mob dropping something
|
||||||
|
Matter.Body.setVelocity(this, Vector.mult(this.velocity, 0.05));
|
||||||
|
Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.05)
|
||||||
|
if (!this.seePlayer.recall && (Vector.magnitude(Vector.sub(this.position, this.driftGoal)) < 200 || 0.3 > Math.random())) {
|
||||||
|
//used in drift when can't find player
|
||||||
|
const radius = Math.random() * 1000;
|
||||||
|
const angle = Math.random() * 2 * Math.PI;
|
||||||
|
this.driftGoal = Vector.add(this.driftCenter, { x: radius * Math.cos(angle), y: radius * Math.sin(angle) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me.fireLaser = function () {
|
||||||
|
for (let i = 0; i < this.lasers.length; i++) { //fire all lasers in the array
|
||||||
|
let best = vertexCollision(this.lasers[i].a, this.lasers[i].b, m.isCloak ? [body] : [body, [playerBody, playerHead]]); //not checking map to fix not hitting player bug, this might make some lasers look strange when the map changes
|
||||||
|
if (this.lasers[i].fade > 0.99) {
|
||||||
|
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
|
||||||
|
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
|
||||||
|
const dmg = 0.05 * simulation.dmgScale;
|
||||||
|
m.damage(dmg);
|
||||||
|
simulation.drawList.push({ //add dmg to draw queue
|
||||||
|
x: best.x,
|
||||||
|
y: best.y,
|
||||||
|
radius: dmg * 1500,
|
||||||
|
color: "rgba(255,0,100,0.5)",
|
||||||
|
time: 20
|
||||||
|
});
|
||||||
|
this.lasers.splice(i, 1) //remove this laser node
|
||||||
|
if (this.distanceToPlayer < 1000) { //mob jumps away from player
|
||||||
|
const forceMag = 0.03 * this.mass;
|
||||||
|
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||||
|
this.force.x -= 2 * forceMag * Math.cos(angle);
|
||||||
|
this.force.y -= 2 * forceMag * Math.sin(angle); // - 0.0007 * this.mass; //antigravity
|
||||||
|
}
|
||||||
|
} else if (best.who && best.who.classType === "body") { //hitting block
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(best.x, best.y);
|
||||||
|
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
||||||
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
} else { //hitting nothing
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
||||||
|
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
||||||
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
}
|
||||||
|
} else {//fade in warning
|
||||||
|
this.lasers[i].fade += 0.007
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
||||||
|
ctx.lineTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
||||||
|
ctx.lineWidth = 2 + 40 - 40 * this.lasers[i].fade;
|
||||||
|
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.lasers[i].fade})`;
|
||||||
|
ctx.stroke();
|
||||||
|
if (this.lasers[i].fade > 0.99) {
|
||||||
|
this.lasers[i].fade = 1;
|
||||||
|
if (this.lasers.length > this.laserLimit) this.lasers.shift() //cap total lasers
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me.driftCenter = { ...me.position }; //copy position with out reference so it doesn't change as mob moves
|
||||||
|
const r = Math.random() * 100;
|
||||||
|
const a = Math.random() * 2 * Math.PI;
|
||||||
|
me.driftGoal = Vector.add(me.driftCenter, { x: r * Math.cos(a), y: r * Math.sin(a) }) //updated in addLaser()
|
||||||
|
me.drift = function () {
|
||||||
|
//accelerate towards the player
|
||||||
|
if (this.seePlayer.recall) {
|
||||||
|
const force = Vector.mult(Vector.normalise(Vector.sub(this.seePlayer.position, this.position)), this.accelMag * this.mass)
|
||||||
|
this.force.x += force.x;
|
||||||
|
this.force.y += force.y;
|
||||||
|
} else { //drift
|
||||||
|
const force = Vector.mult(Vector.normalise(Vector.sub(this.driftGoal, this.position)), 0.00001 * this.mass)
|
||||||
|
// const force = Vector.mult(this.driftGoal, 0.0001 * this.mass)
|
||||||
|
this.force.x += force.x;
|
||||||
|
this.force.y += force.y;
|
||||||
|
}
|
||||||
|
this.torque = this.lookTorque * this.inertia * 0.9;
|
||||||
|
}
|
||||||
|
me.do = function () {
|
||||||
|
this.cycle++
|
||||||
|
this.seePlayerCheck();
|
||||||
|
this.checkStatus();
|
||||||
|
this.drift();
|
||||||
|
//add new laser to lasers array
|
||||||
|
this.addLaser()
|
||||||
|
this.fireLaser()
|
||||||
|
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 = 13 + 5 * Math.random();
|
||||||
|
ctx.strokeStyle = `rgba(255,255,255,${0.5 + 0.2 * Math.random()})`;
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
laser(x, y, radius = 30) {
|
laser(x, y, radius = 30) {
|
||||||
const color = "#f00"
|
const color = "#f00"
|
||||||
@@ -4325,7 +4512,6 @@ const spawn = {
|
|||||||
laserBoss(x, y, radius = 30) {
|
laserBoss(x, y, radius = 30) {
|
||||||
mobs.spawn(x, y, 3, radius, "#f00");
|
mobs.spawn(x, y, 3, radius, "#f00");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
|
|
||||||
setTimeout(() => { //fix mob in place, but allow rotation
|
setTimeout(() => { //fix mob in place, but allow rotation
|
||||||
me.constraint = Constraint.create({
|
me.constraint = Constraint.create({
|
||||||
pointA: { x: me.position.x, y: me.position.y },
|
pointA: { x: me.position.x, y: me.position.y },
|
||||||
@@ -5551,7 +5737,7 @@ const spawn = {
|
|||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
|
|
||||||
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
|
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
|
||||||
me.frictionAir = 0.01;
|
me.frictionAir = 0.01;
|
||||||
@@ -5667,7 +5853,7 @@ const spawn = {
|
|||||||
this.isVanished = true
|
this.isVanished = true
|
||||||
this.cloak();
|
this.cloak();
|
||||||
//teleport to near the end of player history
|
//teleport to near the end of player history
|
||||||
Matter.Body.setPosition(this, m.history[Math.floor((m.history.length - 1) * (0.66 + 0.33 * Math.random()))].position)
|
Matter.Body.setPosition(this, m.history[Math.floor((m.history.length - 1) * (0.3 + 0.4 * Math.random()))].position)
|
||||||
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
||||||
this.damageReduction = 0 //immune to harm for the rest of this game cycle
|
this.damageReduction = 0 //immune to harm for the rest of this game cycle
|
||||||
}
|
}
|
||||||
@@ -7176,7 +7362,7 @@ const spawn = {
|
|||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
me.startingDamageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
me.startingDamageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
me.damageReduction = 0
|
me.damageReduction = 0
|
||||||
me.isInvulnerable = true
|
me.isInvulnerable = true
|
||||||
|
|
||||||
@@ -7283,6 +7469,9 @@ const spawn = {
|
|||||||
if (this.snakeHeadID === mob[i].id) {
|
if (this.snakeHeadID === mob[i].id) {
|
||||||
mob[i].isInvulnerable = false
|
mob[i].isInvulnerable = false
|
||||||
mob[i].damageReduction = mob[i].startingDamageReduction
|
mob[i].damageReduction = mob[i].startingDamageReduction
|
||||||
|
} else if (mob[i].isSnakeTail) {
|
||||||
|
//damage all snake tails
|
||||||
|
mob[i].health *= 0.95
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|||||||
25
js/tech.js
25
js/tech.js
@@ -231,6 +231,7 @@ const tech = {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
if (tech.isPowerUpDamage) dmg *= 1 + 0.05 * powerUp.length
|
||||||
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.45 : 4.33
|
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.45 : 4.33
|
||||||
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.93
|
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.93
|
||||||
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
|
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
|
||||||
@@ -3338,6 +3339,27 @@ const tech = {
|
|||||||
powerUps.setPowerUpMode();
|
powerUps.setPowerUpMode();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "accretion disk",
|
||||||
|
descriptionFunction() {
|
||||||
|
return `<strong>+5%</strong> <strong class='color-d'>damage</strong> <em>(${5 * powerUp.length}%)</em><br>for each <strong>power up</strong> that exists on this <strong>level</strong>`
|
||||||
|
},
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 3,
|
||||||
|
frequencyDefault: 3,
|
||||||
|
isHealTech: true,
|
||||||
|
allowed() {
|
||||||
|
return tech.isHealAttract
|
||||||
|
},
|
||||||
|
requires: "accretion",
|
||||||
|
effect() {
|
||||||
|
tech.isPowerUpDamage = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isPowerUpDamage = false
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "self-assembly",
|
name: "self-assembly",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
@@ -4067,7 +4089,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unified field theory",
|
name: "unified field theory",
|
||||||
description: `when <strong>paused</strong> clicking your <strong class='color-f'>field</strong> <strong>cycles</strong> it<br><strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong><strong class='color-m'>tech</strong>`,
|
description: `in the <strong>pause</strong> menu click to <strong>switch</strong> <strong class='color-f'>fields</strong><br><strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong><strong class='color-m'>tech</strong>`,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -12166,4 +12188,5 @@ const tech = {
|
|||||||
isMobLowHealth: null,
|
isMobLowHealth: null,
|
||||||
isDamageCooldown: null,
|
isDamageCooldown: null,
|
||||||
isDamageCooldownTime: null,
|
isDamageCooldownTime: null,
|
||||||
|
isPowerUpDamage: null,
|
||||||
}
|
}
|
||||||
@@ -1264,7 +1264,7 @@ summary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
background-color: rgb(200, 255, 255)
|
background-color: rgb(0, 204, 255)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
47
todo.txt
47
todo.txt
@@ -1,41 +1,24 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
mob: laserLayer - leaves behind lasers that persist for a few seconds
|
laserLayerBoss - sends lasers to player's location
|
||||||
ghoster mobs do 66% less damage, but they eject your ammo
|
snakes bosses - after you kill a tail piece the rest of the tails lose 5% life
|
||||||
|
this makes targeting any part of the tail a viable strategy
|
||||||
grappling hook tech rupture renamed swarf
|
|
||||||
fires several nails at nearby mobs, not explosions
|
|
||||||
grappling hook 6->9 energy per second
|
|
||||||
CIWS 18->10 energy
|
|
||||||
reel +40->75 energy reeling blocks
|
|
||||||
wormhole 5->7% duplication
|
|
||||||
cloaking no longer drains energy, this fixes a can't cloak bug
|
|
||||||
dazzler no longer drains energy
|
|
||||||
dazzler range reduced by 15%
|
|
||||||
dazzler stuns for 3->2 seconds
|
|
||||||
zero point energy 100->166 max energy
|
|
||||||
expansion 40->77 max energy
|
|
||||||
annihilation -33% of max energy -> 10 energy
|
|
||||||
dynamical systems is no longer a field tech 35->30 damage
|
|
||||||
tessellation is no longer a field tech 50->35 defense
|
|
||||||
yield stress removed
|
|
||||||
topological defect 80->111% damage
|
|
||||||
brittle 80->111% damage
|
|
||||||
commodities exchange 6-12 -> 10-14 power ups
|
|
||||||
heat engine 50->40% damage
|
|
||||||
flame test grenades clusters explode 40% faster
|
|
||||||
alternator uses 10->0% energy for harpoon
|
|
||||||
|
|
||||||
finally made a shared vertexCollision function
|
|
||||||
this might cause some bugs with laser-like effects...
|
|
||||||
|
|
||||||
|
accretion disk - 5% damage for every power up on this level
|
||||||
|
requires accretion
|
||||||
|
unified field theory has buttons to cycle field forwards or backwards when paused
|
||||||
|
iceIX range and damage increased 15%
|
||||||
|
electric tech in labs level is finally nerfed
|
||||||
|
drains energy, but doesn't do damage
|
||||||
|
pushes player away
|
||||||
|
|
||||||
*********************************************************** TODO *****************************************************
|
*********************************************************** TODO *****************************************************
|
||||||
|
|
||||||
increase damage for each not picked up power up on the level
|
boss - tracks the position, velocity, angle of power ups, blocks, and bullets it fires
|
||||||
|
reactor only?
|
||||||
make a laserLayerBoss
|
will rewind time
|
||||||
add lasers on player's history
|
after damage threshold?
|
||||||
|
does it track player bullets?
|
||||||
|
|
||||||
button/switch input ideas from Cocoon game
|
button/switch input ideas from Cocoon game
|
||||||
pick up blocks that have a rubber band attached to a sliding switch
|
pick up blocks that have a rubber band attached to a sliding switch
|
||||||
|
|||||||
Reference in New Issue
Block a user