winter vacation update
mob health tech
tech: cascading failure - +222% damage to mobs below 25% health
tech: yield stress - +55% damage to mobs at maximum health
cloaking tech: topological defect - +88% damage to mobs at maximum health
harpoon tech: brittle - +88% harpoon/grapple damage to mobs at maximum health
cloaking buffs
50->66% defense while cloaked
recloak 0.25s faster
simplified cloaking field graphics
boson composite drains much less energy while moving through mobs and shields
fixed bug where mines and egg mobs were colliding with player while intangible
patch no longer drains energy when you heal on cloaking
metamaterial absorber gets 17->22% chance to spawn a power up for each mob alive
no-cloning theorem changes to 45->40% duplication and 2->1% duplication loss on killing a mob
finalBoss phases:
new: slow zone, antigravity pulse
nerfed: laser, black hole, orbitals
buffed: oscillation, mobs
improved graphics: boulder
Hilbert space has a skin. 99->142% damage increase, but randomize tech after taking damage
Higgs mechanism has a skin. +45->77% fire rate, player can't move while firing
induction furnace gives +77% harpoon/grapple damage for 8 seconds after picking up a power up
collider 50->100% chance to combine and randomize power ups
quenching gives more bonus max health at high difficulty level (maybe around 30% more health)
accretion gives 5->7 heal power ups
dynamo bots follow player much closer when you have many of them
scrap-bots don't follow the player as accurately or as quickly
scrap bot duration 13->15 seconds
JUNK tech: planned obsolescence - make 100 scrap bots that last for about 30 seconds
community map dojo by werid_pusheen
fixed by Cornbread 2100
hard mode gets 1 less heal at the start
hard and why difficulty don't begin with starter mobs
hopBullet mobs last 2 seconds less time
adjusted button heights on train station level to be consistently the same height
This commit is contained in:
BIN
img/brittle.webp
Normal file
BIN
img/brittle.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
BIN
img/cascading failure.webp
Normal file
BIN
img/cascading failure.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
BIN
img/field/field emitter25.webp
Normal file
BIN
img/field/field emitter25.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
img/topological defect.webp
Normal file
BIN
img/topological defect.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
BIN
img/yield stress.webp
Normal file
BIN
img/yield stress.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
599
js/bullet.js
599
js/bullet.js
@@ -288,7 +288,7 @@ const b = {
|
|||||||
if (m.fieldMode === 6) b.fireCDscale *= 0.8
|
if (m.fieldMode === 6) b.fireCDscale *= 0.8
|
||||||
if (tech.isFastTime) b.fireCDscale *= 0.5
|
if (tech.isFastTime) b.fireCDscale *= 0.5
|
||||||
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, Math.max(0, b.inventory.length - 1))
|
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, Math.max(0, b.inventory.length - 1))
|
||||||
if (tech.isFireMoveLock) b.fireCDscale *= 0.55
|
if (tech.isFireMoveLock) b.fireCDscale *= 0.23 // 77% fire rate
|
||||||
},
|
},
|
||||||
fireAttributes(dir, rotate = true) {
|
fireAttributes(dir, rotate = true) {
|
||||||
if (rotate) {
|
if (rotate) {
|
||||||
@@ -1508,8 +1508,9 @@ const b = {
|
|||||||
},
|
},
|
||||||
minDmgSpeed: 4,
|
minDmgSpeed: 4,
|
||||||
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||||
density: 0.004, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
density: 0.004, //0.001 is normal for blocks, 0.004 is normal for harpoon
|
||||||
drain: 0.001,
|
drain: 0.001,
|
||||||
|
powerUpDamage: tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle,
|
||||||
draw() {
|
draw() {
|
||||||
// draw rope
|
// draw rope
|
||||||
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||||
@@ -1559,9 +1560,26 @@ const b = {
|
|||||||
// ctx.stroke();
|
// ctx.stroke();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (this.powerUpDamage) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
|
||||||
|
ctx.lineTo(this.vertices[2].x, this.vertices[2].y);
|
||||||
|
ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
|
||||||
|
ctx.lineTo(this.vertices[4].x, this.vertices[4].y);
|
||||||
|
ctx.lineJoin = "miter"
|
||||||
|
ctx.miterLimit = 30;
|
||||||
|
ctx.lineWidth = 25;
|
||||||
|
ctx.strokeStyle = "rgba(0,255,255,0.4)";
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineWidth = 8;
|
||||||
|
ctx.strokeStyle = "rgb(0,255,255)";
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineJoin = "round"
|
||||||
|
ctx.miterLimit = 5
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
//draw hook
|
//draw hook
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
@@ -1581,6 +1599,42 @@ const b = {
|
|||||||
}
|
}
|
||||||
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
||||||
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||||
|
// if (this.powerUpDamage) this.density = 2 * 0.004 //double damage after pick up power up for 8 seconds
|
||||||
|
|
||||||
|
|
||||||
|
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) {
|
||||||
|
Matter.Body.setDensity(this, 1.8 * 0.004); //+90% damage after pick up power up for 8 seconds
|
||||||
|
} else if (tech.isHarpoonFullHealth && who.health === 1) {
|
||||||
|
Matter.Body.setDensity(this, 1.9 * 0.004); //+90% damage if mob has full health do
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "grapple outline",
|
||||||
|
count: 3, //cycles before it self removes
|
||||||
|
vertices: this.vertices,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
for (let j = 1, len = this.vertices.length; j < len; j += 1) ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
|
||||||
|
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
ctx.lineJoin = "miter"
|
||||||
|
ctx.miterLimit = 20;
|
||||||
|
ctx.lineWidth = 40;
|
||||||
|
ctx.strokeStyle = "rgba(255,0,100,0.35)";
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineWidth = 10;
|
||||||
|
ctx.strokeStyle = `#f07`;
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineJoin = "round"
|
||||||
|
ctx.miterLimit = 5
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fill();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.retract()
|
this.retract()
|
||||||
},
|
},
|
||||||
caughtPowerUp: null,
|
caughtPowerUp: null,
|
||||||
@@ -1602,7 +1656,7 @@ const b = {
|
|||||||
this.caughtPowerUp.effect();
|
this.caughtPowerUp.effect();
|
||||||
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
||||||
powerUp.splice(index, 1);
|
powerUp.splice(index, 1);
|
||||||
if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.004 * 6 //0.005 is normal
|
if (tech.isHarpoonPowerUp) tech.harpoonPowerUpCycle = simulation.cycle
|
||||||
} else {
|
} else {
|
||||||
this.dropCaughtPowerUp()
|
this.dropCaughtPowerUp()
|
||||||
}
|
}
|
||||||
@@ -1893,321 +1947,6 @@ const b = {
|
|||||||
});
|
});
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
// grapple(where, angle = m.angle, harpoonSize = 1) {
|
|
||||||
// const me = bullet.length;
|
|
||||||
// const returnRadius = 100 * Math.sqrt(harpoonSize)
|
|
||||||
// bullet[me] = Bodies.fromVertices(where.x, where.y, [{
|
|
||||||
// x: -50 * harpoonSize,
|
|
||||||
// y: 2 * harpoonSize,
|
|
||||||
// index: 0,
|
|
||||||
// isInternal: false
|
|
||||||
// }, {
|
|
||||||
// x: -50 * harpoonSize,
|
|
||||||
// y: -2 * harpoonSize,
|
|
||||||
// index: 1,
|
|
||||||
// isInternal: false
|
|
||||||
// }, {
|
|
||||||
// x: 45 * harpoonSize,
|
|
||||||
// y: -3 * harpoonSize,
|
|
||||||
// index: 2,
|
|
||||||
// isInternal: false
|
|
||||||
// }, {
|
|
||||||
// x: 50 * harpoonSize,
|
|
||||||
// y: 0,
|
|
||||||
// index: 3,
|
|
||||||
// isInternal: false
|
|
||||||
// }, {
|
|
||||||
// x: 45 * harpoonSize,
|
|
||||||
// y: 3 * harpoonSize,
|
|
||||||
// index: 4,
|
|
||||||
// isInternal: false
|
|
||||||
// }], {
|
|
||||||
// angle: angle,
|
|
||||||
// friction: 1,
|
|
||||||
// frictionAir: 0.4,
|
|
||||||
// thrustMag: 0.1,
|
|
||||||
// dmg: 6, //damage done in addition to the damage from momentum
|
|
||||||
// classType: "bullet",
|
|
||||||
// endCycle: simulation.cycle + 70,
|
|
||||||
// collisionFilter: {
|
|
||||||
// category: cat.bullet,
|
|
||||||
// mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
|
|
||||||
// },
|
|
||||||
// minDmgSpeed: 4,
|
|
||||||
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
|
||||||
// density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
|
||||||
// drain: tech.isRailEnergy ? 0.0006 : 0.006,
|
|
||||||
// beforeDmg(who) {
|
|
||||||
// if (tech.isShieldPierce && who.isShielded) { //disable shields
|
|
||||||
// who.isShielded = false
|
|
||||||
// requestAnimationFrame(() => {
|
|
||||||
// who.isShielded = true
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// if (tech.fragments) {
|
|
||||||
// b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
|
|
||||||
// }
|
|
||||||
// if (tech.isFoamBall) {
|
|
||||||
// for (let i = 0, len = 4 * this.mass; i < len; i++) {
|
|
||||||
// const radius = 5 + 8 * Math.random()
|
|
||||||
// const velocity = {
|
|
||||||
// x: Math.max(0.5, 2 - radius * 0.1),
|
|
||||||
// y: 0
|
|
||||||
// }
|
|
||||||
// b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
|
||||||
// }
|
|
||||||
// // this.endCycle = 0;
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// caughtPowerUp: null,
|
|
||||||
// dropCaughtPowerUp() {
|
|
||||||
// if (this.caughtPowerUp) {
|
|
||||||
// this.caughtPowerUp.collisionFilter.category = cat.powerUp
|
|
||||||
// this.caughtPowerUp.collisionFilter.mask = cat.map | cat.powerUp
|
|
||||||
// this.caughtPowerUp = null
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// onEnd() {
|
|
||||||
// if (this.caughtPowerUp && !simulation.isChoosing && (this.caughtPowerUp.name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)) {
|
|
||||||
// let index = null //find index
|
|
||||||
// for (let i = 0, len = powerUp.length; i < len; ++i) {
|
|
||||||
// if (powerUp[i] === this.caughtPowerUp) index = i
|
|
||||||
// }
|
|
||||||
// if (index !== null) {
|
|
||||||
// powerUps.onPickUp(this.caughtPowerUp);
|
|
||||||
// this.caughtPowerUp.effect();
|
|
||||||
// Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
|
||||||
// powerUp.splice(index, 1);
|
|
||||||
// if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.004 * 6 //0.005 is normal
|
|
||||||
// } else {
|
|
||||||
// this.dropCaughtPowerUp()
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// this.dropCaughtPowerUp()
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// draw() {
|
|
||||||
// const where = {
|
|
||||||
// x: m.pos.x + 30 * Math.cos(m.angle),
|
|
||||||
// y: m.pos.y + 30 * Math.sin(m.angle)
|
|
||||||
// }
|
|
||||||
// const sub = Vector.sub(where, this.vertices[0])
|
|
||||||
// const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
|
|
||||||
// ctx.strokeStyle = "#000" // "#0ce"
|
|
||||||
// ctx.lineWidth = 0.5
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(where.x, where.y);
|
|
||||||
// ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
|
|
||||||
// // ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
|
||||||
// ctx.stroke();
|
|
||||||
// //draw harpoon spikes
|
|
||||||
// const spikeLength = 2
|
|
||||||
// ctx.beginPath();
|
|
||||||
// const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength))
|
|
||||||
// ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
|
||||||
// ctx.lineTo(spike1.x, spike1.y);
|
|
||||||
// ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
|
|
||||||
|
|
||||||
// const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength))
|
|
||||||
// ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
|
||||||
// ctx.lineTo(spike2.x, spike2.y);
|
|
||||||
// ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
|
|
||||||
// ctx.fillStyle = '#000'
|
|
||||||
// ctx.fill();
|
|
||||||
// },
|
|
||||||
// returnToPlayer() {
|
|
||||||
// if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
|
|
||||||
// this.endCycle = 0;
|
|
||||||
// // if (m.energy < 0.05) {
|
|
||||||
// // m.fireCDcycle = m.cycle + 120; //fire cooldown
|
|
||||||
// // } else if (m.cycle + 15 * b.fireCDscale < m.fireCDcycle) {
|
|
||||||
// // m.fireCDcycle = m.cycle + 15 * b.fireCDscale //lower cd to 25 if it is above 25
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// if (m.energy < 0.05) this.dropCaughtPowerUp()
|
|
||||||
|
|
||||||
// //recoil on catching
|
|
||||||
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
|
|
||||||
// player.force.x += momentum.x
|
|
||||||
// player.force.y += momentum.y
|
|
||||||
// // refund ammo
|
|
||||||
// b.guns[9].ammo++;
|
|
||||||
// simulation.updateGunHUD();
|
|
||||||
|
|
||||||
// // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
|
||||||
// // if (b.guns[i].name === "harpoon") {
|
|
||||||
// // b.guns[i].ammo++;
|
|
||||||
// // simulation.updateGunHUD();
|
|
||||||
// // break;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// } else {
|
|
||||||
// if (m.energy > this.drain) m.energy -= this.drain
|
|
||||||
// const sub = Vector.sub(this.position, m.pos)
|
|
||||||
// const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
|
|
||||||
// const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
|
|
||||||
// this.force.x -= returnForce.x
|
|
||||||
// this.force.y -= returnForce.y
|
|
||||||
// this.grabPowerUp()
|
|
||||||
// }
|
|
||||||
// this.draw();
|
|
||||||
// },
|
|
||||||
// grabPowerUp() { //grab power ups near the tip of the harpoon
|
|
||||||
// if (this.caughtPowerUp) {
|
|
||||||
// Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
|
||||||
// Matter.Body.setVelocity(this.caughtPowerUp, {
|
|
||||||
// x: 0,
|
|
||||||
// y: 0
|
|
||||||
// })
|
|
||||||
// } else { //&& simulation.cycle % 2
|
|
||||||
// for (let i = 0, len = powerUp.length; i < len; ++i) {
|
|
||||||
// const radius = powerUp[i].circleRadius + 50
|
|
||||||
// if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius) {
|
|
||||||
// if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
|
|
||||||
// this.caughtPowerUp = powerUp[i]
|
|
||||||
// Matter.Body.setVelocity(powerUp[i], {
|
|
||||||
// x: 0,
|
|
||||||
// y: 0
|
|
||||||
// })
|
|
||||||
// Matter.Body.setPosition(powerUp[i], this.vertices[2])
|
|
||||||
// powerUp[i].collisionFilter.category = 0
|
|
||||||
// powerUp[i].collisionFilter.mask = 0
|
|
||||||
// this.thrustMag *= 0.6
|
|
||||||
// this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
|
|
||||||
// break //just pull 1 power up if possible
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// do() {
|
|
||||||
// if (input.fire) { //&& !Matter.Query.collides(this, body).length
|
|
||||||
// this.grabPowerUp()
|
|
||||||
// if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction
|
|
||||||
// this.endCycle = simulation.cycle + 60
|
|
||||||
// // m.fireCDcycle = m.cycle + 120 // cool down
|
|
||||||
// this.do = this.returnToPlayer
|
|
||||||
// Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
|
||||||
// if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
|
|
||||||
// this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// //if not enough energy
|
|
||||||
// if (m.energy < 0.05) this.dropCaughtPowerUp()
|
|
||||||
// // const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
|
|
||||||
// // this.force.x -= returnForce.x
|
|
||||||
// // this.force.y -= returnForce.y
|
|
||||||
// // this.frictionAir = 0.002
|
|
||||||
// // this.do = () => {
|
|
||||||
// // if (this.speed < 20) this.force.y += 0.0005 * this.mass;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // } else {
|
|
||||||
// //return to player
|
|
||||||
// this.do = this.returnToPlayer
|
|
||||||
// this.endCycle = simulation.cycle + 60
|
|
||||||
// Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
|
||||||
// if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
|
|
||||||
// this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
|
|
||||||
// //recoil on catching
|
|
||||||
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
|
|
||||||
// player.force.x += momentum.x
|
|
||||||
// player.force.y += momentum.y
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// //grappling hook
|
|
||||||
// if (input.fire && Matter.Query.collides(this, map).length) {
|
|
||||||
// Matter.Body.setPosition(this, Vector.add(this.position, {
|
|
||||||
// x: 20 * Math.cos(this.angle),
|
|
||||||
// y: 20 * Math.sin(this.angle)
|
|
||||||
// }))
|
|
||||||
// if (Matter.Query.collides(this, map).length) {
|
|
||||||
// Matter.Body.setVelocity(this, {
|
|
||||||
// x: 0,
|
|
||||||
// y: 0
|
|
||||||
// });
|
|
||||||
// Matter.Sleeping.set(this, true)
|
|
||||||
// this.endCycle = simulation.cycle + 5
|
|
||||||
// this.dropCaughtPowerUp()
|
|
||||||
// this.do = () => {
|
|
||||||
// //between player nose and the grapple
|
|
||||||
// const sub = Vector.sub(this.vertices[0], {
|
|
||||||
// x: m.pos.x + 30 * Math.cos(m.angle),
|
|
||||||
// y: m.pos.y + 30 * Math.sin(m.angle)
|
|
||||||
// })
|
|
||||||
// let dist = Vector.magnitude(sub)
|
|
||||||
// if (input.fire) {
|
|
||||||
// // m.fireCDcycle = m.cycle + 30; // cool down if out of energy
|
|
||||||
// m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
|
|
||||||
// this.endCycle = simulation.cycle + 10
|
|
||||||
// if (input.down) { //down
|
|
||||||
// dist = 0
|
|
||||||
// player.force.y += 5 * player.mass * simulation.g;
|
|
||||||
// }
|
|
||||||
// if (m.energy > this.drain) {
|
|
||||||
// Matter.Body.setVelocity(player, {
|
|
||||||
// x: player.velocity.x * 0.8,
|
|
||||||
// y: player.velocity.y * 0.8
|
|
||||||
// });
|
|
||||||
// const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200))
|
|
||||||
// player.force.x += pull.x
|
|
||||||
// player.force.y += pull.y
|
|
||||||
|
|
||||||
// if (dist > 500) {
|
|
||||||
// m.energy -= this.drain
|
|
||||||
// if (m.energy < 0) {
|
|
||||||
// this.endCycle = 0;
|
|
||||||
// if (m.cycle + 50 < m.fireCDcycle) m.fireCDcycle = m.cycle + 50
|
|
||||||
// // refund ammo
|
|
||||||
// b.guns[9].ammo++;
|
|
||||||
// simulation.updateGunHUD();
|
|
||||||
// // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
|
||||||
// // if (b.guns[i].name === "harpoon") {
|
|
||||||
// // break;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (tech.isImmuneGrapple && m.immuneCycle < m.cycle + 10) {
|
|
||||||
// m.immuneCycle = m.cycle + 10;
|
|
||||||
// if (m.energy > 0.001) {
|
|
||||||
// m.energy -= 0.001
|
|
||||||
// } else { //out of energy
|
|
||||||
// Matter.Sleeping.set(this, false)
|
|
||||||
// this.collisionFilter.category = 0
|
|
||||||
// this.collisionFilter.mask = 0
|
|
||||||
// this.do = this.returnToPlayer
|
|
||||||
// this.endCycle = simulation.cycle + 60
|
|
||||||
// m.fireCDcycle = m.cycle + 120; //fire cooldown
|
|
||||||
// //recoil on catching
|
|
||||||
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
|
|
||||||
// player.force.x += momentum.x
|
|
||||||
// player.force.y += momentum.y
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// Matter.Sleeping.set(this, false)
|
|
||||||
// this.collisionFilter.category = 0
|
|
||||||
// this.collisionFilter.mask = 0
|
|
||||||
// this.do = this.returnToPlayer
|
|
||||||
// this.endCycle = simulation.cycle + 60
|
|
||||||
// //recoil on catching
|
|
||||||
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
|
|
||||||
// player.force.x += momentum.x
|
|
||||||
// player.force.y += momentum.y
|
|
||||||
// }
|
|
||||||
// this.draw();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
|
|
||||||
// this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
|
|
||||||
// this.draw()
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// Composite.add(engine.world, bullet[me]); //add bullet to world
|
|
||||||
// },
|
|
||||||
harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const returnRadius = 100 * Math.sqrt(harpoonSize)
|
const returnRadius = 100 * Math.sqrt(harpoonSize)
|
||||||
@@ -2274,12 +2013,43 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tech.isFoamBall) {
|
if (tech.isFoamBall) {
|
||||||
for (let i = 0, len = Math.min(50, 2.5 + 3 * Math.sqrt(this.mass)); i < len; i++) {
|
for (let i = 0, len = Math.min(30, 2 + 2 * Math.sqrt(this.mass)); i < len; i++) {
|
||||||
const radius = 5 + 8 * Math.random()
|
const radius = 5 + 8 * Math.random()
|
||||||
const velocity = { x: Math.max(0.5, 2 - radius * 0.1), y: 0 }
|
const velocity = { x: Math.max(0.5, 2 - radius * 0.1), y: 0 }
|
||||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) {
|
||||||
|
Matter.Body.setDensity(this, 1.8 * tech.harpoonDensity); //+90% damage after pick up power up for 8 seconds
|
||||||
|
} else if (tech.isHarpoonFullHealth && who.health === 1) {
|
||||||
|
Matter.Body.setDensity(this, 1.9 * tech.harpoonDensity); //+90% damage if mob has full health do
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "harpoon outline",
|
||||||
|
count: 2, //cycles before it self removes
|
||||||
|
vertices: this.vertices,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
for (let j = 1, len = this.vertices.length; j < len; j += 1) ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
|
||||||
|
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
ctx.lineJoin = "miter"
|
||||||
|
ctx.miterLimit = 20;
|
||||||
|
ctx.lineWidth = 40;
|
||||||
|
ctx.strokeStyle = "rgba(255,0,100,0.35)";
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineWidth = 10;
|
||||||
|
ctx.strokeStyle = `#f07`;
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.lineJoin = "round"
|
||||||
|
ctx.miterLimit = 5
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fill();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
caughtPowerUp: null,
|
caughtPowerUp: null,
|
||||||
dropCaughtPowerUp() {
|
dropCaughtPowerUp() {
|
||||||
@@ -2300,7 +2070,7 @@ const b = {
|
|||||||
this.caughtPowerUp.effect();
|
this.caughtPowerUp.effect();
|
||||||
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
||||||
powerUp.splice(index, 1);
|
powerUp.splice(index, 1);
|
||||||
if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.004 * 6 //0.006 is normal
|
if (tech.isHarpoonPowerUp) tech.harpoonPowerUpCycle = simulation.cycle
|
||||||
} else {
|
} else {
|
||||||
this.dropCaughtPowerUp()
|
this.dropCaughtPowerUp()
|
||||||
}
|
}
|
||||||
@@ -2308,29 +2078,26 @@ const b = {
|
|||||||
this.dropCaughtPowerUp()
|
this.dropCaughtPowerUp()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
drawToggleHarpoon() {
|
drawDamageAura() {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
|
ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
for (let j = 1, len = this.vertices.length; j < len; j += 1) ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
|
for (let j = 1, len = this.vertices.length; j < len; j += 1) ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
|
||||||
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
ctx.lineJoin = "miter"
|
ctx.lineJoin = "miter"
|
||||||
ctx.miterLimit = 100;
|
ctx.miterLimit = 20;
|
||||||
ctx.lineWidth = 60;
|
ctx.lineWidth = 15;
|
||||||
ctx.strokeStyle = "rgba(0,255,255,0.25)";
|
ctx.strokeStyle = "rgba(255,0,100,0.25)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineWidth = 20;
|
ctx.lineWidth = 4;
|
||||||
ctx.strokeStyle = "rgb(0,255,255)";
|
ctx.strokeStyle = `#f07`;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineJoin = "round"
|
ctx.lineJoin = "round"
|
||||||
ctx.miterLimit = 10
|
ctx.miterLimit = 5
|
||||||
ctx.fillStyle = "#000"
|
ctx.fillStyle = "#000"
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
},
|
},
|
||||||
drawString() {
|
drawString() {
|
||||||
const where = {
|
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
|
||||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
|
||||||
}
|
|
||||||
const sub = Vector.sub(where, this.vertices[0])
|
const sub = Vector.sub(where, this.vertices[0])
|
||||||
const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub))))
|
const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub))))
|
||||||
const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular)
|
const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular)
|
||||||
@@ -2384,10 +2151,7 @@ const b = {
|
|||||||
grabPowerUp() { //grab power ups near the tip of the harpoon
|
grabPowerUp() { //grab power ups near the tip of the harpoon
|
||||||
if (this.caughtPowerUp) {
|
if (this.caughtPowerUp) {
|
||||||
Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
||||||
Matter.Body.setVelocity(this.caughtPowerUp, {
|
Matter.Body.setVelocity(this.caughtPowerUp, { x: 0, y: 0 })
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
})
|
|
||||||
} else { //&& simulation.cycle % 2
|
} else { //&& simulation.cycle % 2
|
||||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||||
const radius = powerUp[i].circleRadius + 50
|
const radius = powerUp[i].circleRadius + 50
|
||||||
@@ -2395,10 +2159,7 @@ const b = {
|
|||||||
if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
|
if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
|
||||||
powerUp[i].isGrabbed = true
|
powerUp[i].isGrabbed = true
|
||||||
this.caughtPowerUp = powerUp[i]
|
this.caughtPowerUp = powerUp[i]
|
||||||
Matter.Body.setVelocity(powerUp[i], {
|
Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 })
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
})
|
|
||||||
Matter.Body.setPosition(powerUp[i], this.vertices[2])
|
Matter.Body.setPosition(powerUp[i], this.vertices[2])
|
||||||
powerUp[i].collisionFilter.category = 0
|
powerUp[i].collisionFilter.category = 0
|
||||||
powerUp[i].collisionFilter.mask = 0
|
powerUp[i].collisionFilter.mask = 0
|
||||||
@@ -2459,15 +2220,15 @@ const b = {
|
|||||||
this.draw();
|
this.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tech.isHarpoonPowerUp && bullet[me].density > 0.01) {
|
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) { //8 seconds
|
||||||
if (isReturn) {
|
if (isReturn) {
|
||||||
bullet[me].draw = function () {
|
bullet[me].draw = function () {
|
||||||
this.drawToggleHarpoon()
|
this.drawDamageAura()
|
||||||
this.drawString()
|
this.drawString()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bullet[me].draw = function () {
|
bullet[me].draw = function () {
|
||||||
this.drawToggleHarpoon()
|
this.drawDamageAura()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isReturn) {
|
} else if (isReturn) {
|
||||||
@@ -2628,15 +2389,9 @@ const b = {
|
|||||||
if (dist < radius * radius) {
|
if (dist < radius * radius) {
|
||||||
if (mob[i].speed > 2) {
|
if (mob[i].speed > 2) {
|
||||||
if (mob[i].isBoss || mob[i].isShielded) {
|
if (mob[i].isBoss || mob[i].isShielded) {
|
||||||
Matter.Body.setVelocity(mob[i], {
|
Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.95, y: mob[i].velocity.y * 0.95 });
|
||||||
x: mob[i].velocity.x * 0.95,
|
|
||||||
y: mob[i].velocity.y * 0.95
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
Matter.Body.setVelocity(mob[i], {
|
Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.25, y: mob[i].velocity.y * 0.25 });
|
||||||
x: mob[i].velocity.x * 0.25,
|
|
||||||
y: mob[i].velocity.y * 0.25
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Matter.Body.setPosition(this, Vector.add(this.position, mob[i].velocity)) //move with the medium
|
// Matter.Body.setPosition(this, Vector.add(this.position, mob[i].velocity)) //move with the medium
|
||||||
@@ -5139,39 +4894,39 @@ const b = {
|
|||||||
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({
|
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({
|
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.nailBotCount; i++) b.nailBot({
|
for (let i = 0; i < tech.nailBotCount; i++) b.nailBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.foamBotCount; i++) b.foamBot({
|
for (let i = 0; i < tech.foamBotCount; i++) b.foamBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.soundBotCount; i++) b.soundBot({
|
for (let i = 0; i < tech.soundBotCount; i++) b.soundBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.boomBotCount; i++) b.boomBot({
|
for (let i = 0; i < tech.boomBotCount; i++) b.boomBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.orbitBotCount; i++) b.orbitBot({
|
for (let i = 0; i < tech.orbitBotCount; i++) b.orbitBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot({
|
for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
for (let i = 0; i < tech.missileBotCount; i++) b.missileBot({
|
for (let i = 0; i < tech.missileBotCount; i++) b.missileBot({
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||||
}, false)
|
})
|
||||||
if (tech.isIntangible && m.isCloak) {
|
if (tech.isIntangible && m.isCloak) {
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType) bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield
|
if (bullet[i].botType) bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield
|
||||||
@@ -5250,7 +5005,6 @@ const b = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
setDynamoBotDelay() {
|
setDynamoBotDelay() {
|
||||||
//reorder orbital bot positions around a circle
|
|
||||||
let total = 0
|
let total = 0
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'dynamo') total++
|
if (bullet[i].botType === 'dynamo') total++
|
||||||
@@ -5259,13 +5013,17 @@ const b = {
|
|||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'dynamo') {
|
if (bullet[i].botType === 'dynamo') {
|
||||||
count++
|
count++
|
||||||
const step = Math.max(60 - 3 * total, 20)
|
const step = Math.max(60 - 3 * total, 10)
|
||||||
bullet[i].followDelay = (step * count) % 600
|
if (bullet[i].isKeep) {
|
||||||
|
bullet[i].followDelay = (step * count) % 600
|
||||||
|
} else {
|
||||||
|
bullet[i].followDelay = Math.floor(step * bullet.length * Math.random()) % 600
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dynamoBot(position = player.position, isConsole = true) {
|
dynamoBot(position = player.position, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.dynamoBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.dynamoBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.polygon(position.x, position.y, 5, 10, {
|
bullet[me] = Bodies.polygon(position.x, position.y, 5, 10, {
|
||||||
isUpgraded: tech.isDynamoBotUpgrade,
|
isUpgraded: tech.isDynamoBotUpgrade,
|
||||||
@@ -5274,7 +5032,8 @@ const b = {
|
|||||||
frictionStatic: 0,
|
frictionStatic: 0,
|
||||||
frictionAir: 0.02,
|
frictionAir: 0.02,
|
||||||
spin: 0.07 * (Math.random() < 0.5 ? -1 : 1),
|
spin: 0.07 * (Math.random() < 0.5 ? -1 : 1),
|
||||||
// isStatic: true,
|
// isStatic: true,
|
||||||
|
isKeep: isKeep,
|
||||||
isSensor: true,
|
isSensor: true,
|
||||||
restitution: 0,
|
restitution: 0,
|
||||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||||
@@ -5359,17 +5118,14 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let history = m.history[(m.cycle - this.followDelay) % 600]
|
let history = m.history[(m.cycle - this.followDelay) % 600]
|
||||||
Matter.Body.setPosition(this, {
|
Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
|
||||||
x: history.position.x,
|
|
||||||
y: history.position.y - history.yOff + 24.2859
|
|
||||||
}) //bullets move with player
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
b.setDynamoBotDelay()
|
b.setDynamoBotDelay()
|
||||||
},
|
},
|
||||||
nailBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
nailBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
const RADIUS = (12 + 4 * Math.random())
|
const RADIUS = (12 + 4 * Math.random())
|
||||||
@@ -5386,8 +5142,8 @@ const b = {
|
|||||||
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
|
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
|
||||||
lastLookCycle: simulation.cycle + 60 * Math.random(),
|
lastLookCycle: simulation.cycle + 60 * Math.random(),
|
||||||
delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85) * b.fireCDscale),
|
delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85) * b.fireCDscale),
|
||||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
|
||||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
|
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100,
|
||||||
endCycle: Infinity,
|
endCycle: Infinity,
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
@@ -5433,8 +5189,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
missileBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
missileBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, {
|
bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, {
|
||||||
botType: "missile",
|
botType: "missile",
|
||||||
@@ -5504,8 +5260,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
foamBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
foamBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.foamBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.foamBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
const RADIUS = (10 + 5 * Math.random())
|
const RADIUS = (10 + 5 * Math.random())
|
||||||
@@ -5524,8 +5280,8 @@ const b = {
|
|||||||
fireCount: 0,
|
fireCount: 0,
|
||||||
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
|
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
|
||||||
delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
||||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
|
||||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), //how far from the player the bot will move
|
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
|
||||||
endCycle: Infinity,
|
endCycle: Infinity,
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
@@ -5625,8 +5381,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
soundBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
soundBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.soundBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.soundBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
bullet[me] = Bodies.rectangle(position.x, position.y, 12, 30, {
|
bullet[me] = Bodies.rectangle(position.x, position.y, 12, 30, {
|
||||||
@@ -5644,8 +5400,8 @@ const b = {
|
|||||||
fireCount: 0,
|
fireCount: 0,
|
||||||
fireLimit: 5 + 2 * tech.isSoundBotUpgrade,
|
fireLimit: 5 + 2 * tech.isSoundBotUpgrade,
|
||||||
delay: Math.floor((120 + (tech.isSoundBotUpgrade ? 0 : 70)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
delay: Math.floor((120 + (tech.isSoundBotUpgrade ? 0 : 70)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
||||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
|
||||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), //how far from the player the bot will move
|
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
|
||||||
endCycle: Infinity,
|
endCycle: Infinity,
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
@@ -5791,11 +5547,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
laserBot(position = {
|
laserBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.laserBot()`);
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
|
||||||
}, isConsole = true) {
|
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.laserBot()`);
|
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
const RADIUS = (14 + 6 * Math.random())
|
const RADIUS = (14 + 6 * Math.random())
|
||||||
@@ -5833,10 +5586,7 @@ const b = {
|
|||||||
const mag = Math.min(farAway, 4) * this.mass * this.acceleration
|
const mag = Math.min(farAway, 4) * this.mass * this.acceleration
|
||||||
this.force = Vector.mult(Vector.normalise(Vector.sub(playerPos, this.position)), mag)
|
this.force = Vector.mult(Vector.normalise(Vector.sub(playerPos, this.position)), mag)
|
||||||
//manual friction to not lose rotational velocity
|
//manual friction to not lose rotational velocity
|
||||||
Matter.Body.setVelocity(this, {
|
Matter.Body.setVelocity(this, { x: this.velocity.x * 0.95, y: this.velocity.y * 0.95 });
|
||||||
x: this.velocity.x * 0.95,
|
|
||||||
y: this.velocity.y * 0.95
|
|
||||||
});
|
|
||||||
//find targets
|
//find targets
|
||||||
if (!(simulation.cycle % this.lookFrequency)) {
|
if (!(simulation.cycle % this.lookFrequency)) {
|
||||||
this.lockedOn = null;
|
this.lockedOn = null;
|
||||||
@@ -5858,11 +5608,13 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//randomize position relative to player
|
//randomize position relative to player
|
||||||
if (Math.random() < 0.15) {
|
if (Math.random() < 0.1) {
|
||||||
const range = 110 + 4 * b.totalBots()
|
if (isKeep) {
|
||||||
this.offPlayer = {
|
const range = 110 + 4 * b.totalBots()
|
||||||
x: range * (Math.random() - 0.5),
|
this.offPlayer = { x: range * (Math.random() - 0.5), y: range * (Math.random() - 0.5) - 20, }
|
||||||
y: range * (Math.random() - 0.5) - 20,
|
} else {
|
||||||
|
const range = 110 + 4 * b.totalBots() + 100 * Math.random()
|
||||||
|
this.offPlayer = Vector.mult(Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random()), range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6040,11 +5792,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
boomBot(position = {
|
boomBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.boomBot()`);
|
||||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
|
||||||
}, isConsole = true) {
|
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.boomBot()`);
|
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
const RADIUS = (7 + 2 * Math.random())
|
const RADIUS = (7 + 2 * Math.random())
|
||||||
@@ -6059,9 +5808,9 @@ const b = {
|
|||||||
dmg: 0,
|
dmg: 0,
|
||||||
minDmgSpeed: 0,
|
minDmgSpeed: 0,
|
||||||
lookFrequency: 43 + Math.floor(7 * Math.random()) - 13 * tech.isBoomBotUpgrade,
|
lookFrequency: 43 + Math.floor(7 * Math.random()) - 13 * tech.isBoomBotUpgrade,
|
||||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
|
||||||
attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade,
|
attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade,
|
||||||
range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade,
|
range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade + !isKeep * 100,
|
||||||
endCycle: Infinity,
|
endCycle: Infinity,
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
@@ -6131,8 +5880,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
plasmaBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
plasmaBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.plasmaBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.plasmaBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const dir = m.angle;
|
const dir = m.angle;
|
||||||
const RADIUS = 21
|
const RADIUS = 21
|
||||||
@@ -6305,8 +6054,8 @@ const b = {
|
|||||||
})
|
})
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
orbitBot(position = player.position, isConsole = true) {
|
orbitBot(position = player.position, isKeep = true) {
|
||||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.orbitBot()`);
|
// if (isKeep) simulation.makeTextLog(`<span class='color-var'>b</span>.orbitBot()`);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.polygon(position.x, position.y, 9, 12, {
|
bullet[me] = Bodies.polygon(position.x, position.y, 9, 12, {
|
||||||
isUpgraded: tech.isOrbitBotUpgrade,
|
isUpgraded: tech.isOrbitBotUpgrade,
|
||||||
@@ -6316,6 +6065,7 @@ const b = {
|
|||||||
frictionAir: 1,
|
frictionAir: 1,
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
isSensor: true,
|
isSensor: true,
|
||||||
|
isKeep: isKeep,
|
||||||
restitution: 0,
|
restitution: 0,
|
||||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||||
minDmgSpeed: 0,
|
minDmgSpeed: 0,
|
||||||
@@ -6330,17 +6080,17 @@ const b = {
|
|||||||
//reorder orbital bot positions around a circle
|
//reorder orbital bot positions around a circle
|
||||||
let totalOrbitalBots = 0
|
let totalOrbitalBots = 0
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'orbit' && bullet[i] !== this) totalOrbitalBots++
|
if (bullet[i].botType === 'orbit' && bullet[i] !== this && bullet[i].isKeep) totalOrbitalBots++
|
||||||
}
|
}
|
||||||
let index = 0
|
let index = 0
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'orbit' && bullet[i] !== this) {
|
if (bullet[i].botType === 'orbit' && bullet[i] !== this && bullet[i].isKeep) {
|
||||||
bullet[i].phase = (index / totalOrbitalBots) * 2 * Math.PI
|
bullet[i].phase = (index / totalOrbitalBots) * 2 * Math.PI
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
range: 190 + 130 * tech.isOrbitBotUpgrade, //range is set in bot upgrade too!
|
range: 190 + 130 * tech.isOrbitBotUpgrade + !isKeep * 60 * (0.5 - Math.random()), //range is set in bot upgrade too!
|
||||||
orbitalSpeed: 0,
|
orbitalSpeed: 0,
|
||||||
phase: 2 * Math.PI * Math.random(),
|
phase: 2 * Math.PI * Math.random(),
|
||||||
do() {
|
do() {
|
||||||
@@ -6377,10 +6127,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
//orbit player
|
//orbit player
|
||||||
const time = simulation.cycle * this.orbitalSpeed + this.phase
|
const time = simulation.cycle * this.orbitalSpeed + this.phase
|
||||||
const orbit = {
|
const orbit = { x: Math.cos(time), y: Math.sin(time) }
|
||||||
x: Math.cos(time),
|
|
||||||
y: Math.sin(time) //*1.1
|
|
||||||
}
|
|
||||||
Matter.Body.setPosition(this, Vector.add(m.pos, Vector.mult(orbit, this.range))) //bullets move with player
|
Matter.Body.setPosition(this, Vector.add(m.pos, Vector.mult(orbit, this.range))) //bullets move with player
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -6392,11 +6139,11 @@ const b = {
|
|||||||
//reorder orbital bot positions around a circle
|
//reorder orbital bot positions around a circle
|
||||||
let totalOrbitalBots = 0
|
let totalOrbitalBots = 0
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'orbit') totalOrbitalBots++
|
if (bullet[i].botType === 'orbit' && bullet[i].isKeep) totalOrbitalBots++
|
||||||
}
|
}
|
||||||
let index = 0
|
let index = 0
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
if (bullet[i].botType === 'orbit') {
|
if (bullet[i].botType === 'orbit' && bullet[i].isKeep) {
|
||||||
bullet[i].phase = (index / totalOrbitalBots) * 2 * Math.PI
|
bullet[i].phase = (index / totalOrbitalBots) * 2 * Math.PI
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
@@ -6739,7 +6486,7 @@ const b = {
|
|||||||
name: "shotgun", //1
|
name: "shotgun", //1
|
||||||
// description: `fire a wide <strong>burst</strong> of short range <strong> bullets</strong><br>with a low <strong><em>fire rate</em></strong><br><strong>3-4</strong> nails per ${powerUps.orb.ammo()}`,
|
// description: `fire a wide <strong>burst</strong> of short range <strong> bullets</strong><br>with a low <strong><em>fire rate</em></strong><br><strong>3-4</strong> nails per ${powerUps.orb.ammo()}`,
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `fire a wide <strong>burst</strong> of short range <strong> bullets</strong><br>has a slow <strong><em>fire rate</em></strong><br><strong>${this.ammoPack.toFixed(1)}</strong> nails per ${powerUps.orb.ammo()}`
|
return `fire a wide <strong>burst</strong> of short range <strong> bullets</strong><br>has a slow <strong><em>fire rate</em></strong><br><strong>${this.ammoPack.toFixed(1)}</strong> shots per ${powerUps.orb.ammo()}`
|
||||||
},
|
},
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 3.5,
|
ammoPack: 3.5,
|
||||||
@@ -7995,7 +7742,6 @@ const b = {
|
|||||||
}
|
}
|
||||||
//fire
|
//fire
|
||||||
if ((!input.fire && this.charge > 0.6)) {
|
if ((!input.fire && this.charge > 0.6)) {
|
||||||
// tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
|
||||||
const where = {
|
const where = {
|
||||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
x: m.pos.x + 30 * Math.cos(m.angle),
|
||||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
y: m.pos.y + 30 * Math.sin(m.angle)
|
||||||
@@ -8067,8 +7813,6 @@ const b = {
|
|||||||
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.03 : 0.06)
|
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.03 : 0.06)
|
||||||
player.force.x -= recoil.x
|
player.force.x -= recoil.x
|
||||||
player.force.y -= recoil.y
|
player.force.y -= recoil.y
|
||||||
// tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
|
||||||
|
|
||||||
const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
|
const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
|
||||||
const thrust = 0.15 * (this.charge)
|
const thrust = 0.15 * (this.charge)
|
||||||
if (tech.extraHarpoons) {
|
if (tech.extraHarpoons) {
|
||||||
@@ -8263,12 +8007,8 @@ const b = {
|
|||||||
count++
|
count++
|
||||||
if (!(count % delay) && this.ammo > 0) {
|
if (!(count % delay) && this.ammo > 0) {
|
||||||
this.ammo--
|
this.ammo--
|
||||||
b.harpoon({
|
b.harpoon({ x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, null, angle, harpoonSize, true, totalCycles)
|
||||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
|
||||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
|
||||||
}, null, angle, harpoonSize, true, totalCycles)
|
|
||||||
angle += SPREAD
|
angle += SPREAD
|
||||||
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
|
||||||
}
|
}
|
||||||
if (count < num * delay && m.alive) requestAnimationFrame(harpoonDelay);
|
if (count < num * delay && m.alive) requestAnimationFrame(harpoonDelay);
|
||||||
}
|
}
|
||||||
@@ -8298,7 +8038,6 @@ const b = {
|
|||||||
} else {
|
} else {
|
||||||
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
|
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
|
||||||
}
|
}
|
||||||
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
|
||||||
}
|
}
|
||||||
m.fireCDcycle = m.cycle + 5 + 35 * b.fireCDscale + 60 * (m.energy < 0.05) + tech.extraHarpoons // cool down is set when harpoon bullet returns to player
|
m.fireCDcycle = m.cycle + 5 + 35 * b.fireCDscale + 60 * (m.energy < 0.05) + tech.extraHarpoons // cool down is set when harpoon bullet returns to player
|
||||||
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.015 : 0.035)
|
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.015 : 0.035)
|
||||||
|
|||||||
@@ -967,7 +967,6 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
|||||||
startExperiment() { //start playing the game after exiting the experiment menu
|
startExperiment() { //start playing the game after exiting the experiment menu
|
||||||
build.isExperimentSelection = false;
|
build.isExperimentSelection = false;
|
||||||
spawn.setSpawnList(); //gives random mobs, not starter mobs
|
spawn.setSpawnList(); //gives random mobs, not starter mobs
|
||||||
spawn.setSpawnList();
|
|
||||||
if (b.inventory.length > 0) {
|
if (b.inventory.length > 0) {
|
||||||
b.activeGun = b.inventory[0] //set first gun to active gun
|
b.activeGun = b.inventory[0] //set first gun to active gun
|
||||||
b.inventoryGun = 0;
|
b.inventoryGun = 0;
|
||||||
|
|||||||
526
js/level.js
526
js/level.js
@@ -11,7 +11,7 @@ const level = {
|
|||||||
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
||||||
//see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , subway, final) added later
|
//see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , subway, final) added later
|
||||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
|
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
|
||||||
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave"],
|
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo"],
|
||||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon", "diamagnetism"],
|
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon", "diamagnetism"],
|
||||||
levels: [],
|
levels: [],
|
||||||
start() {
|
start() {
|
||||||
@@ -19,17 +19,15 @@ 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(5 * 4) //30 is near max on hard //60 is near max on why
|
// level.difficultyIncrease(8 * 2) //30 is near max on hard //60 is near max on why
|
||||||
// spawn.setSpawnList();
|
// m.maxHealth = m.health = 1
|
||||||
// spawn.setSpawnList();
|
|
||||||
// m.maxHealth = m.health = 100
|
|
||||||
// m.maxEnergy = m.energy = 10000000
|
// m.maxEnergy = m.energy = 10000000
|
||||||
// tech.isRerollDamage = true
|
// tech.isRerollDamage = true
|
||||||
// powerUps.research.changeRerolls(99999)
|
// powerUps.research.changeRerolls(99999)
|
||||||
// m.immuneCycle = Infinity //you can't take damage
|
// m.immuneCycle = Infinity //you can't take damage
|
||||||
// tech.tech[297].frequency = 100
|
// tech.tech[297].frequency = 100
|
||||||
// m.couplingChange(10)
|
// m.couplingChange(10)
|
||||||
// m.setField("grappling hook") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
// m.setField("metamaterial cloaking") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||||
// tech.isHookWire = true
|
// tech.isHookWire = true
|
||||||
// m.energy = 0
|
// m.energy = 0
|
||||||
// simulation.molecularMode = 2
|
// simulation.molecularMode = 2
|
||||||
@@ -37,22 +35,23 @@ const level = {
|
|||||||
// b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
// b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||||
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||||
// b.guns[8].ammo = 100000000
|
// b.guns[8].ammo = 100000000
|
||||||
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
|
// requestAnimationFrame(() => { tech.giveTech("Higgs mechanism") });
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("degenerate matter")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("Higgs mechanism")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("reel")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("topological defect")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("tokamak")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("Hilbert space")
|
||||||
// requestAnimationFrame(() => { for (let i = 0; i < 30; i++) tech.giveTech("laser-bot") });
|
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) tech.giveTech("orbital-bot") });
|
||||||
// for (let i = 0; i < 1; i++) tech.giveTech("laser-bot upgrade")
|
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("rupture")
|
|
||||||
|
// for (let i = 0; i < 1; i++) tech.giveTech("cascading failure")
|
||||||
|
// for (let i = 0; i < 1; ++i) tech.giveTech("induction furnace")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
|
||||||
// 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");
|
||||||
|
// level.skyscrapers();
|
||||||
// level.unchartedCave();
|
|
||||||
|
|
||||||
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
||||||
// for (let i = 0; i < 5; ++i) spawn.starter(1900, -500)
|
// for (let i = 0; i < 10; ++i) spawn.starter(1900, -500, 50)
|
||||||
// for (let i = 0; i < 1; ++i) spawn.timeSkipBoss(1900, -2500)
|
// for (let i = 0; i < 1; ++i) spawn.timeSkipBoss(1900, -2500)
|
||||||
// spawn.beetleBoss(1900, -500, 25)
|
// spawn.beetleBoss(1900, -500, 25)
|
||||||
// spawn.slasher2(2000, -1150)
|
// spawn.slasher2(2000, -1150)
|
||||||
@@ -64,13 +63,14 @@ const level = {
|
|||||||
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
||||||
|
|
||||||
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
|
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
|
||||||
|
|
||||||
// spawn.bodyRect(2425, -120, 200, 200);
|
// spawn.bodyRect(2425, -120, 200, 200);
|
||||||
// console.log(body[body.length - 1].mass)
|
// console.log(body[body.length - 1].mass)
|
||||||
// simulation.isAutoZoom = false; //look in close
|
// simulation.isAutoZoom = false; //look in close
|
||||||
// simulation.zoomScale *= 0.5;
|
// simulation.zoomScale *= 0.5;
|
||||||
// simulation.setZoom();
|
// simulation.setZoom();
|
||||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
|
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
|
||||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "boost");
|
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "boost");
|
||||||
// for (let i = 0; i < 20; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
|
// for (let i = 0; i < 20; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
|
||||||
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
|
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
|
||||||
//lore testing
|
//lore testing
|
||||||
@@ -2159,8 +2159,9 @@ const level = {
|
|||||||
spawn.mapRect(475, -25, 25, 50); //edge shelf
|
spawn.mapRect(475, -25, 25, 50); //edge shelf
|
||||||
},
|
},
|
||||||
intro() {
|
intro() {
|
||||||
// console.log(level.levelsCleared)
|
|
||||||
if (level.levelsCleared === 0) { //if this is the 1st level of the game
|
if (level.levelsCleared === 0) { //if this is the 1st level of the game
|
||||||
|
if (simulation.difficultyMode > 2) spawn.setSpawnList() // hard and why difficulty don't begin with starter mobs
|
||||||
|
|
||||||
//wait to spawn power ups until unpaused
|
//wait to spawn power ups until unpaused
|
||||||
//power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
|
//power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
|
||||||
const goal = simulation.cycle + 10
|
const goal = simulation.cycle + 10
|
||||||
@@ -2172,10 +2173,17 @@ const level = {
|
|||||||
} else {
|
} else {
|
||||||
powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
|
powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
|
||||||
}
|
}
|
||||||
if (simulation.difficultyMode < 5) {
|
if (simulation.difficultyMode < 5) { //hard, normal and easy
|
||||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 25, "heal", false);
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 25, "heal", false);
|
||||||
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
|
||||||
|
}
|
||||||
|
if (simulation.difficultyMode < 3) { //normal and easy
|
||||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
|
||||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false); //not on why difficulty
|
}
|
||||||
|
if (simulation.difficultyMode < 2) { //easy
|
||||||
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
|
||||||
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
|
||||||
|
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
requestAnimationFrame(cycle);
|
requestAnimationFrame(cycle);
|
||||||
@@ -2548,7 +2556,6 @@ const level = {
|
|||||||
|
|
||||||
|
|
||||||
if (mobs.mobDeaths < level.levelsCleared && !simulation.isCheating) { //pacifist run
|
if (mobs.mobDeaths < level.levelsCleared && !simulation.isCheating) { //pacifist run
|
||||||
// spawn.setSpawnList();
|
|
||||||
spawn.pickList.splice(0, 1);
|
spawn.pickList.splice(0, 1);
|
||||||
spawn.pickList.push('starter');
|
spawn.pickList.push('starter');
|
||||||
spawn.pickList.splice(0, 1);
|
spawn.pickList.splice(0, 1);
|
||||||
@@ -2662,6 +2669,7 @@ const level = {
|
|||||||
if (gateButton.isUp) {
|
if (gateButton.isUp) {
|
||||||
gateButton.query();
|
gateButton.query();
|
||||||
if (!gateButton.isUp) {
|
if (!gateButton.isUp) {
|
||||||
|
simulation.makeTextLog(`station gate opened`, 360);
|
||||||
if (stationNumber > 0) {
|
if (stationNumber > 0) {
|
||||||
if (!isExitOpen && gatesOpenRight < stationNumber) level.newLevelOrPhase() //run some new level tech effects
|
if (!isExitOpen && gatesOpenRight < stationNumber) level.newLevelOrPhase() //run some new level tech effects
|
||||||
gatesOpenRight = stationNumber
|
gatesOpenRight = stationNumber
|
||||||
@@ -2673,7 +2681,7 @@ const level = {
|
|||||||
gatesOpenRight = stationNumber
|
gatesOpenRight = stationNumber
|
||||||
}
|
}
|
||||||
if (Math.abs(stationNumber) > 0 && ((Math.abs(stationNumber) + 1) % stationList.length) === 0) {
|
if (Math.abs(stationNumber) > 0 && ((Math.abs(stationNumber) + 1) % stationList.length) === 0) {
|
||||||
simulation.makeTextLog(`exit opened`);
|
simulation.makeTextLog(`level exit opened`, 360);
|
||||||
isExitOpen = true;
|
isExitOpen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2725,13 +2733,12 @@ const level = {
|
|||||||
var gate = level.doorMap(x - 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
|
var gate = level.doorMap(x - 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spawn.mapRect(x + -1500, -210, 3000, 400);//station floor
|
spawn.mapRect(x + -1500, -210, 3000, 400);//station floor
|
||||||
spawn.mapRect(x + -1775, -1600, 3400, 1100); //center pillar
|
spawn.mapRect(x + -1775, -1600, 3400, 1000); //center pillar
|
||||||
spawn.mapRect(x + -4100, -3325, 8000, 700); //roof
|
spawn.mapRect(x + -4100, -3325, 8000, 700); //roof
|
||||||
spawn.mapRect(x + -4100, -3325, 325, 1500);
|
spawn.mapRect(x + -4100, -3325, 325, 1500);
|
||||||
spawn.mapRect(x + 3500, -3325, 400, 1500);
|
spawn.mapRect(x + 3500, -3325, 400, 1500);
|
||||||
spawn.mapRect(x + -225, -575, 450, 425); //lower portal blocks
|
spawn.mapRect(x + -225, -700, 450, 600); //lower portal blocks
|
||||||
|
|
||||||
//upper parts
|
//upper parts
|
||||||
spawn.mapRect(x + -1425, -2400, 1900, 50);
|
spawn.mapRect(x + -1425, -2400, 1900, 50);
|
||||||
@@ -3025,7 +3032,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => { //portal fling
|
() => { //portal fling
|
||||||
const buttonsCoords = [{ x: x + 775, y: -1695 }, { x: x - 775, y: -800 }, { x: x - 375, y: -2083 },]
|
const buttonsCoords = [{ x: x + 775, y: -1695 }, { x: x - 775, y: -800 }, { x: x - 375, y: -2080 },]
|
||||||
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
|
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
|
||||||
if (isExitOpen) {
|
if (isExitOpen) {
|
||||||
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
|
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
|
||||||
@@ -3219,7 +3226,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => { //jump pads and 6 sided platforms
|
() => { //jump pads and 6 sided platforms
|
||||||
const buttonsCoords = [{ x: x + 275, y: -1817 }, { x: x + 2025, y: -1995 }, { x: x - 2025, y: -2420 }, { x: x - 2100, y: -1995 }]
|
const buttonsCoords = [{ x: x + 278, y: -1814 }, { x: x + 778, y: -1814 }, { x: x + 2025, y: -1995 }, { x: x - 2025, y: -2425 }, { x: x - 2100, y: -1995 }]
|
||||||
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
|
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
|
||||||
if (isExitOpen) {
|
if (isExitOpen) {
|
||||||
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
|
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
|
||||||
@@ -3375,7 +3382,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
// stations[1]() //for testing a specific station
|
// stations[4]() //for testing a specific station
|
||||||
stations[stationList[Math.abs(stationNumber % stationList.length)]]() //*************** run this one when uploading
|
stations[stationList[Math.abs(stationNumber % stationList.length)]]() //*************** run this one when uploading
|
||||||
//add in standard station map infrastructure
|
//add in standard station map infrastructure
|
||||||
spawn.mapRect(x + -8000, 0, 16000, 800);//tunnel floor
|
spawn.mapRect(x + -8000, 0, 16000, 800);//tunnel floor
|
||||||
@@ -5034,10 +5041,12 @@ const level = {
|
|||||||
powerUps.directSpawn(x + 1950, y - 1525, "ammo");
|
powerUps.directSpawn(x + 1950, y - 1525, "ammo");
|
||||||
powerUps.directSpawn(x + 1900, y - 1525, "ammo");
|
powerUps.directSpawn(x + 1900, y - 1525, "ammo");
|
||||||
spawn.hopMotherBoss(x + 800, y + -2200)
|
spawn.hopMotherBoss(x + 800, y + -2200)
|
||||||
for (let i = 0; i < 6; ++i) spawn.hopBullet(x + 150 + 750 * Math.random(), y + -1600)
|
for (let i = 0; i < 4; ++i) spawn.hopBullet(x + 150 + 750 * Math.random(), y + -1600)
|
||||||
for (let i = 0; i < 6; ++i) spawn.hopBullet(x + 1100 + 750 * Math.random(), y + -1600)
|
for (let i = 0; i < 4; ++i) spawn.hopBullet(x + 1100 + 750 * Math.random(), y + -1600)
|
||||||
spawn.hopper(x + 1550, y + -775);
|
spawn.hopper(x + 1550, y + -775);
|
||||||
spawn.hopper(x + 500, y + -775);
|
spawn.hopper(x + 500, y + -775);
|
||||||
|
spawn.hopper(x + 500, y + -2200);
|
||||||
|
spawn.hopper(x + 1100, y + -2200);
|
||||||
spawn.hopMother(x + 1400, y + -775);
|
spawn.hopMother(x + 1400, y + -775);
|
||||||
spawn.hopMother(x + 550, y + -775);
|
spawn.hopMother(x + 550, y + -775);
|
||||||
spawn.hopMother(x + 525, y + -1475);
|
spawn.hopMother(x + 525, y + -1475);
|
||||||
@@ -30084,9 +30093,6 @@ const level = {
|
|||||||
},
|
},
|
||||||
unchartedCave() {
|
unchartedCave() {
|
||||||
simulation.makeTextLog(`<strong>unchartedCave</strong> by <span class='color-var'>3xionDev</span>`);
|
simulation.makeTextLog(`<strong>unchartedCave</strong> by <span class='color-var'>3xionDev</span>`);
|
||||||
//lore.unlockTesting();
|
|
||||||
//simulation.enableConstructMode();
|
|
||||||
level.difficultyIncrease(15);
|
|
||||||
level.setPosToSpawn(0, -50); //normal spawn
|
level.setPosToSpawn(0, -50); //normal spawn
|
||||||
level.exit.x = 20985;
|
level.exit.x = 20985;
|
||||||
level.exit.y = 2816;
|
level.exit.y = 2816;
|
||||||
@@ -30095,7 +30101,6 @@ const level = {
|
|||||||
level.defaultZoom = 1900
|
level.defaultZoom = 1900
|
||||||
simulation.zoomTransition(level.defaultZoom)
|
simulation.zoomTransition(level.defaultZoom)
|
||||||
document.body.style.backgroundColor = "#979797";
|
document.body.style.backgroundColor = "#979797";
|
||||||
// color.map = "#444" //custom map color
|
|
||||||
|
|
||||||
spawn.randomMob(1000, -975, 0);
|
spawn.randomMob(1000, -975, 0);
|
||||||
spawn.randomMob(2550, -575, 0);
|
spawn.randomMob(2550, -575, 0);
|
||||||
@@ -30490,15 +30495,462 @@ const level = {
|
|||||||
spawn.randomGroup(5835, -532, 0.4);
|
spawn.randomGroup(5835, -532, 0.4);
|
||||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(18823, 2191);
|
if (simulation.difficulty > 1) spawn.randomLevelBoss(18823, 2191);
|
||||||
spawn.secondaryBossChance(20217, 1913)
|
spawn.secondaryBossChance(20217, 1913)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
level.custom = () => {
|
level.custom = () => {
|
||||||
level.exit.drawAndCheck();
|
level.exit.drawAndCheck();
|
||||||
|
|
||||||
level.enter.draw();
|
level.enter.draw();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
dojo() { // By weird_pusheen
|
||||||
|
simulation.makeTextLog(`<strong>dojo</strong> by <span class='color-var'>werid_pusheen</span>, fixed by <span class='color-var'>Cornbread 2100</span>`)
|
||||||
|
const vanishes = [];
|
||||||
|
const smoofes = [];
|
||||||
|
const leftRotor = level.rotor(-550, 900, 950, 25);
|
||||||
|
leftRotor.frictionAir = 0.01;
|
||||||
|
var leftSchwoof = level.boost(-20, -60, -2000);
|
||||||
|
var rightSchwoof = level.button(2550, -50);
|
||||||
|
var rightSchwoofState = false;
|
||||||
|
var rightSchwoofLive = true;
|
||||||
|
spawn.mapRect(2513, -39, 200, 100);
|
||||||
|
var pathPoints = [
|
||||||
|
[0, 0], // Index 0 is owned by M and is set to M's position during play
|
||||||
|
// this means that occasionally the boss will bonk M on the way to somewhere else, which gives it a chance to hurt M and gives the player a chance to hurt it
|
||||||
|
[250, -750], /* Left bases */
|
||||||
|
[250, -2500],
|
||||||
|
[350, -1500], // Left doorway
|
||||||
|
[1150, -1500], // Home base
|
||||||
|
[1150, -2750], // Upper base
|
||||||
|
[1950, -1500], // Right doorway
|
||||||
|
[2050, -750], /* Right bases */
|
||||||
|
[2050, -2500],
|
||||||
|
[-150, -250], // Left porthole
|
||||||
|
];
|
||||||
|
function isntIn(point, array) {
|
||||||
|
for (var x = 0; x < array.length; x++) {
|
||||||
|
if (point[0] == array[x][0] && point[1] == array[x][1]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function isObstructed(v1, v2) {
|
||||||
|
var ret = Matter.Query.ray(map,
|
||||||
|
{
|
||||||
|
x: v1[0],
|
||||||
|
y: v1[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: v2[0],
|
||||||
|
y: v2[1]
|
||||||
|
}).length != 0;
|
||||||
|
return ret; // Kinda-ish stolen from mob.js
|
||||||
|
}
|
||||||
|
function pythag(p1, p2) {
|
||||||
|
var dx = p1[0] - p2[0];
|
||||||
|
var dy = p1[1] - p2[1];
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
var path = undefined; // This is a stupid way to go about pathfinding code. I might even clean it up!
|
||||||
|
function pathFind(goalPoint, startPoint, curPath = []) {
|
||||||
|
var myPoint = startPoint;
|
||||||
|
if (curPath.length) {
|
||||||
|
myPoint = curPath[curPath.length - 1];
|
||||||
|
}
|
||||||
|
if (path && (curPath.length >= path.length)) { // If we've already found a shorter or equal path, no reason to continue and waste CPU time
|
||||||
|
return; // Minimizes for HOP COUNT, not PATH LENGTH - path length was buggy
|
||||||
|
}
|
||||||
|
if (!isObstructed(myPoint, goalPoint)) { // If the line to the goal point ain't blocked by a map object, we've arrived!
|
||||||
|
path = [...curPath];
|
||||||
|
path.push(goalPoint);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pathPoints.forEach(testPoint => {
|
||||||
|
if (isntIn(testPoint, curPath)) { // If it's reusing points, there's clearly something wrong
|
||||||
|
if (!isObstructed(myPoint, testPoint)) { // If the line to the test point ain't blocked by a map object
|
||||||
|
var thing = [...curPath];
|
||||||
|
thing.push(testPoint);
|
||||||
|
pathFind(goalPoint, startPoint, thing); // Branch to a valid test point
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
level.setPosToSpawn(1200, 500);
|
||||||
|
level.exit.x = 51500;
|
||||||
|
level.exit.y = -1875;
|
||||||
|
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||||
|
level.defaultZoom = 1500;
|
||||||
|
simulation.zoomTransition(level.defaultZoom)
|
||||||
|
document.body.style.backgroundColor = "#d8dadf";
|
||||||
|
|
||||||
|
spawn.mapRect(-500, 0, 3300, 300); // Floor
|
||||||
|
spawn.mapRect(-100, -3000, 2500, 100); // Ceiling
|
||||||
|
spawn.mapRect(-200, -3000, 100, 2600); // Left wall
|
||||||
|
spawn.mapRect(2400, -3000, 100, 3000); // Right wall
|
||||||
|
|
||||||
|
spawn.mapRect(500, -1000, 100, 500); /* obstruction blocks */
|
||||||
|
smoofes.push(map[map.length - 1]);
|
||||||
|
spawn.mapRect(500, -2500, 100, 500);
|
||||||
|
smoofes.push(map[map.length - 1]);
|
||||||
|
spawn.mapRect(1700, -1000, 100, 500);
|
||||||
|
smoofes.push(map[map.length - 1]);
|
||||||
|
spawn.mapRect(1700, -2500, 100, 500);
|
||||||
|
smoofes.push(map[map.length - 1]);
|
||||||
|
|
||||||
|
spawn.mapRect(-1000, 550, 200, 50); // Left chonky stepppp low
|
||||||
|
spawn.mapRect(-800, 300, 200, 50); // Left chonky stepppp high
|
||||||
|
spawn.mapVertex(-1000, 1200, "0 0 100 0 700 500 700 700 0 700"); // Left chonky
|
||||||
|
spawn.mapRect(3100, 550, 200, 50); // Right chonky stepppp low
|
||||||
|
spawn.mapRect(2900, 300, 200, 50); // Right chonky stepppp high
|
||||||
|
spawn.mapVertex(3300, 1200, "0 0 -100 0 -700 500 -700 700 0 700"); // Right chonky
|
||||||
|
const leftElevator = level.elevator(-1400 - 300, 1450, 300, 100, 500);
|
||||||
|
const rightElevator = level.elevator(-1400 + 5100, 1450, 300, 100, 500);
|
||||||
|
|
||||||
|
spawn.mapRect(-150, -1700, 200, 50);
|
||||||
|
spawn.mapRect(400, -2050, 200, 50);
|
||||||
|
spawn.mapRect(1600, -1000, 200, 50);
|
||||||
|
|
||||||
|
spawn.randomMob(1200, 700);
|
||||||
|
spawn.randomMob(600, 1000);
|
||||||
|
spawn.randomMob(1800, 1000);
|
||||||
|
spawn.randomMob(3200, 400);
|
||||||
|
spawn.randomMob(3000, 200);
|
||||||
|
spawn.randomMob(-900, 400);
|
||||||
|
spawn.randomMob(-700, 200);
|
||||||
|
spawn.randomMob(1200, 1000);
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
spawn.randomSmallMob(Math.random() * 600 - 600, Math.random() * 3000 - 400);
|
||||||
|
}
|
||||||
|
spawn.grenadier(-300, -1000);
|
||||||
|
spawn.grenadier(2600, -1000);
|
||||||
|
|
||||||
|
spawn.mapRect(-1400, 1450, 5100, 100); // The True Floor
|
||||||
|
|
||||||
|
const slime = level.hazard(-1250, 1400, 4800, 50);
|
||||||
|
slime.maxHeight = 600;
|
||||||
|
simulation.draw.body = function () {
|
||||||
|
ctx.beginPath();
|
||||||
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
|
if (!body[i].hidden) {
|
||||||
|
let vertices = body[i].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 = 2;
|
||||||
|
ctx.fillStyle = color.block;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.strokeStyle = color.blockS;
|
||||||
|
ctx.stroke();
|
||||||
|
} // Override the old draw code to allow intelligent hiding of blocks - preferably this becomes official code because it's just a single added if statement and makes a lot of things cleaner and more intelligent
|
||||||
|
|
||||||
|
const vanish = function (x, y, width, height) { // normal vanishes don't work well on my map for some reason, so I rewrote
|
||||||
|
x += width / 2;
|
||||||
|
y += height / 2;
|
||||||
|
const getVertices = function (bX, bY, bW, bH) { return [{ x: bX, y: bY, index: 0, isInternal: false }, { x: bX + bW, y: bY, index: 1, isInternal: false }, { x: bX + bW, y: bY + bH, index: 4, isInternal: false }, { x: bX, y: bY + bH, index: 3, isInternal: false }] };
|
||||||
|
const cMask = cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||||
|
const vertices = getVertices(x, y, width, height);
|
||||||
|
const block = body[body.length] = Bodies.fromVertices(x, y, vertices, {
|
||||||
|
collisionFilter: {
|
||||||
|
category: cat.map,
|
||||||
|
mask: cMask
|
||||||
|
},
|
||||||
|
isNoSetCollision: true,
|
||||||
|
inertia: Infinity, //prevents rotation
|
||||||
|
isNotHoldable: true,
|
||||||
|
isNonStick: true, //this keep sporangium from sticking
|
||||||
|
isTouched: false,
|
||||||
|
cWidth: width,
|
||||||
|
hiddenCycle: 0,
|
||||||
|
isStatic: true,
|
||||||
|
query() {
|
||||||
|
if (this.cWidth <= 0) {
|
||||||
|
if (this.cWidth > -100) {
|
||||||
|
this.cWidth = -100;
|
||||||
|
Matter.Body.setVertices(this, vertices);
|
||||||
|
}
|
||||||
|
this.isTouched = false;
|
||||||
|
this.collisionFilter.mask = undefined;
|
||||||
|
this.hidden = true;
|
||||||
|
this.hiddenCycle++;
|
||||||
|
if (this.hiddenCycle > 100) {
|
||||||
|
if (Matter.Query.collides(this, [player]).length) {
|
||||||
|
this.hiddenCycle = 50;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.hiddenCycle = 0;
|
||||||
|
this.cWidth = width;
|
||||||
|
this.collisionFilter.mask = cMask;
|
||||||
|
this.hidden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.isTouched) {
|
||||||
|
Matter.Body.setVertices(this, getVertices(x, y, this.cWidth, height * (this.cWidth / width)));
|
||||||
|
this.cWidth -= 3;
|
||||||
|
}
|
||||||
|
else if (Matter.Query.collides(this, [player]).length) { // Elseif short circuit avoids expensive collision detection
|
||||||
|
this.isTouched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return block;
|
||||||
|
};
|
||||||
|
|
||||||
|
vanishes.push(vanish(800, 800, 800, 50));
|
||||||
|
vanishes.push(vanish(400, 1100, 400, 50));
|
||||||
|
vanishes.push(vanish(1600, 1100, 400, 50));
|
||||||
|
for (const vanishBlock of vanishes) Composite.add(engine.world, vanishBlock);
|
||||||
|
spawn.bodyRect(1700, 812, 300, 25, 1, {
|
||||||
|
collisionFilter: {
|
||||||
|
category: cat.body,
|
||||||
|
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.map
|
||||||
|
},
|
||||||
|
isNoSetCollision: true,
|
||||||
|
isNotHoldable: true,
|
||||||
|
isNonStick: true, //this keep sporangium from sticking
|
||||||
|
restitution: 1,
|
||||||
|
friction: 0,
|
||||||
|
frictionAir: 0,
|
||||||
|
frictionStatic: 0,
|
||||||
|
query() {
|
||||||
|
Matter.Body.setAngularVelocity(this, 0);
|
||||||
|
Matter.Body.applyForce(this, this.position, {
|
||||||
|
x: 0,
|
||||||
|
y: -(this.position.y - 812) * 0.002
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const zigzag = body[body.length - 1];
|
||||||
|
Matter.Body.applyForce(zigzag, zigzag.position, {
|
||||||
|
x: 0.1,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
var buttonWasDown = false;
|
||||||
|
level.customTopLayer = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
level.custom = () => {
|
||||||
|
rightSchwoof.isUp = false;
|
||||||
|
level.exit.drawAndCheck();
|
||||||
|
leftSchwoof.query();
|
||||||
|
level.enter.draw();
|
||||||
|
pathPoints[0][0] = m.pos.x;
|
||||||
|
pathPoints[0][1] = m.pos.y;
|
||||||
|
leftElevator.move();
|
||||||
|
rightElevator.move();
|
||||||
|
slime.query();
|
||||||
|
zigzag.query();
|
||||||
|
slime.levelRise(0.2);
|
||||||
|
for (var i = 0; i < vanishes.length; i++) {
|
||||||
|
vanishes[i].query();
|
||||||
|
}
|
||||||
|
if (!rightSchwoofState) {
|
||||||
|
var math = m.pos.y < leftRotor.position.y;
|
||||||
|
Matter.Body.setAngularVelocity(leftRotor, (math ? 1 : -1) * Math.PI / 45);
|
||||||
|
}
|
||||||
|
if (rightSchwoofLive) {
|
||||||
|
rightSchwoof.query();
|
||||||
|
rightSchwoof.draw();
|
||||||
|
if (rightSchwoofState) {
|
||||||
|
ctx.fillStyle = "lightgreen";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctx.fillStyle = "red";
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(2615, -220, 40, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
if (rightSchwoof.isUp) {
|
||||||
|
buttonWasDown = true;
|
||||||
|
}
|
||||||
|
else if (buttonWasDown) {
|
||||||
|
buttonWasDown = false;
|
||||||
|
rightSchwoofState = !rightSchwoofState;
|
||||||
|
}
|
||||||
|
if (Matter.Query.collides(player, smoofes).length) {
|
||||||
|
Matter.Body.applyForce(player, player.position, {
|
||||||
|
x: 0,
|
||||||
|
y: -0.015
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mobs.spawn(500, -500, 10, 100, "yellow"); /* TacticalBoss
|
||||||
|
Modes:
|
||||||
|
Spawn:
|
||||||
|
Pathfinds to a point above M and starts dropping mobs. Learns which mobs to drop to cause the most damage, of course.
|
||||||
|
Occasionally strikes at M.
|
||||||
|
Hide:
|
||||||
|
Pathfinds to the point furthest from M
|
||||||
|
Strike:
|
||||||
|
Pathfind really, really fast to M
|
||||||
|
Recharge:
|
||||||
|
Stop moving for a bit to "recharge" (this is so the player has a chance to hit it)
|
||||||
|
|
||||||
|
It must always Hide or Recharge after Spawning or Striking. Which one it does is based on some factor I'll figure out.
|
||||||
|
Pathfinding is a hypersimplified algorithm with hard-coded "points" that it can travel between. M is one of these.
|
||||||
|
*/
|
||||||
|
var boss = mob[mob.length - 1];
|
||||||
|
boss.isBoss = true;
|
||||||
|
boss.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
|
boss.onDeath = function () {
|
||||||
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y);
|
||||||
|
level.exit.x = 2560;
|
||||||
|
level.exit.y = -90;
|
||||||
|
rightSchwoofLive = false;
|
||||||
|
};
|
||||||
|
var spawnables = {};
|
||||||
|
["hopper", "stabber", "springer", "striker", "sneaker", "grower"].forEach((m) => { /* Used to be spawn.fullPickList, but some of those mobs don't do collision-only damage and would thus never be properly selected for */
|
||||||
|
if (spawn[m]) {
|
||||||
|
spawnables[m] = {
|
||||||
|
fun: spawn[m],
|
||||||
|
name: m,
|
||||||
|
weight: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
boss.stabCycle = 0;
|
||||||
|
boss.spawnCycle = 0;
|
||||||
|
function spawny() {
|
||||||
|
var totalWeight = 0;
|
||||||
|
Object.keys(spawnables).forEach(key => {
|
||||||
|
totalWeight += spawnables[key].weight;
|
||||||
|
});
|
||||||
|
var cursorWeight = 0;
|
||||||
|
var choice = Math.random();
|
||||||
|
var mC = undefined;
|
||||||
|
Object.values(spawnables).forEach((thing) => {
|
||||||
|
var lower = cursorWeight / totalWeight;
|
||||||
|
cursorWeight += thing.weight;
|
||||||
|
var upper = cursorWeight / totalWeight;
|
||||||
|
if ((choice > lower && choice <= upper) || !mC) {
|
||||||
|
mC = thing;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mC.fun(boss.position.x, boss.position.y);
|
||||||
|
var sp = mob[mob.length - 1];
|
||||||
|
sp.typeName = mC.name;
|
||||||
|
sp.onHit = () => {
|
||||||
|
spawnables[sp.typeName].weight += 1;
|
||||||
|
};
|
||||||
|
var oldFun = sp.onDeath;
|
||||||
|
sp.onDeath = () => { /* Mobs that die are worth less */
|
||||||
|
oldFun.call(sp);
|
||||||
|
spawnables[sp.typeName].weight -= 0.3; /* But not too much less */
|
||||||
|
};
|
||||||
|
}
|
||||||
|
boss.spawnDelay = 40;
|
||||||
|
boss.mode = "hide";
|
||||||
|
boss.modeSwitch = -1; // Randomize mode immediately
|
||||||
|
boss.damageReduction = 0.1;
|
||||||
|
var oldOnHit = boss.onHit;
|
||||||
|
boss.onHit = () => {
|
||||||
|
boss.modeSwitch = -1; // After striking the player, always switch modes
|
||||||
|
oldOnHit.call(boss); //this is the line that is bugging <-----
|
||||||
|
};
|
||||||
|
boss.do = () => {
|
||||||
|
path = undefined;
|
||||||
|
var pfGoal = [0, 0];
|
||||||
|
boss.modeSwitch--;
|
||||||
|
if (boss.modeSwitch < 0) {
|
||||||
|
if (!boss.isShielded) {
|
||||||
|
spawn.shield(boss, boss.position.x, boss.position.y, 0.75); // Every time the mode switches, have a 75% chance to gain a new shield
|
||||||
|
}
|
||||||
|
if (boss.mode == "hide" || boss.mode == "recharge") {
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
boss.mode = "spawn";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boss.mode = "strike";
|
||||||
|
}
|
||||||
|
boss.modeSwitch = 600;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (boss.mode == "strike") {
|
||||||
|
boss.mode = "hide"; // Always hides after striking
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
boss.mode = "hide";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boss.mode = "recharge"; // same when it goes into recharge mode
|
||||||
|
spawn.shield(boss, boss.position.x, boss.position.y, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boss.modeSwitch = 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (boss.mode == "hide") { /* Find the furthest point from M and get to it */
|
||||||
|
var longest = 0;
|
||||||
|
pathPoints.forEach(item => {
|
||||||
|
if (item[0] == 1150) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var iL = pythag(item, [m.pos.x, m.pos.y]);
|
||||||
|
if (iL > longest) {
|
||||||
|
longest = iL;
|
||||||
|
pfGoal = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (boss.mode == "strike") {
|
||||||
|
pfGoal = pathPoints[0]; // Target M
|
||||||
|
}
|
||||||
|
else if (boss.mode == "spawn") {
|
||||||
|
pfGoal = pathPoints[4]; // Go to Home Base to spawn
|
||||||
|
}
|
||||||
|
if (boss.mode != "recharge") {
|
||||||
|
if (m.pos.x > 2350 || m.pos.x < -150 || m.pos.y > 50) {
|
||||||
|
boss.mode = "hide";
|
||||||
|
}
|
||||||
|
pathFind(pfGoal, [boss.position.x, boss.position.y]);
|
||||||
|
if (!path) {
|
||||||
|
return; // If it couldn't pathfind, just drift
|
||||||
|
}
|
||||||
|
var goalX = path[0][0];
|
||||||
|
var goalY = path[0][1];
|
||||||
|
|
||||||
|
var dX = goalX - boss.position.x;
|
||||||
|
var dY = goalY - boss.position.y;
|
||||||
|
var hyp = Math.sqrt(dX * dX + dY * dY);
|
||||||
|
Matter.Body.applyForce(boss, {
|
||||||
|
x: goalX,
|
||||||
|
y: goalY
|
||||||
|
}, {
|
||||||
|
x: dX / hyp * 0.04 * (boss.mode == "strike" ? 2 : 1),
|
||||||
|
y: dY / hyp * 0.04 * (boss.mode == "strike" ? 2 : 1)// - 0.005
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (boss.mode == "spawn") {
|
||||||
|
boss.stabCycle++;
|
||||||
|
if (boss.stabCycle > 25) {
|
||||||
|
if (Math.abs(dX) < 200 && dY > 0) {
|
||||||
|
Matter.Body.applyForce(boss, {
|
||||||
|
x: player.position.x,
|
||||||
|
y: player.position.y
|
||||||
|
}, {
|
||||||
|
x: 0,
|
||||||
|
y: 5
|
||||||
|
});
|
||||||
|
}
|
||||||
|
boss.stabCycle = 0;
|
||||||
|
}
|
||||||
|
boss.spawnCycle++;
|
||||||
|
if (boss.spawnCycle > boss.spawnDelay) {
|
||||||
|
spawny();
|
||||||
|
boss.spawnDelay += 4;
|
||||||
|
boss.spawnCycle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
boss.showHealthBar = true;
|
||||||
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
|
},
|
||||||
// ********************************************************************************************************
|
// ********************************************************************************************************
|
||||||
// ********************************************************************************************************
|
// ********************************************************************************************************
|
||||||
// ***************************************** training levels **********************************************
|
// ***************************************** training levels **********************************************
|
||||||
|
|||||||
97
js/mob.js
97
js/mob.js
@@ -242,7 +242,7 @@ const mobs = {
|
|||||||
deathCount: 0,
|
deathCount: 0,
|
||||||
mobSpawnWithHealth: 1,
|
mobSpawnWithHealth: 1,
|
||||||
setMobSpawnHealth() {
|
setMobSpawnHealth() {
|
||||||
mobs.mobSpawnWithHealth = 0.89 ** (tech.mobSpawnWithHealth)
|
mobs.mobSpawnWithHealth = 0.88 ** (tech.mobSpawnWithHealth)
|
||||||
},
|
},
|
||||||
//**********************************************************************************************
|
//**********************************************************************************************
|
||||||
//**********************************************************************************************
|
//**********************************************************************************************
|
||||||
@@ -1133,6 +1133,85 @@ const mobs = {
|
|||||||
if ((!this.isShielded || isBypassShield) && this.alive) {
|
if ((!this.isShielded || isBypassShield) && this.alive) {
|
||||||
if (dmg !== Infinity) {
|
if (dmg !== Infinity) {
|
||||||
dmg *= tech.damageFromTech()
|
dmg *= tech.damageFromTech()
|
||||||
|
if (this.isDropPowerUp) {
|
||||||
|
if (this.health === 1) {
|
||||||
|
if (tech.isMobFullHealth) {
|
||||||
|
dmg *= 1.55
|
||||||
|
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "damage outline",
|
||||||
|
count: 5, //cycles before it self removes
|
||||||
|
vertices: this.vertices,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||||
|
//draw body
|
||||||
|
ctx.beginPath();
|
||||||
|
const vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1, len = vertices.length; j < len; ++j) {
|
||||||
|
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
ctx.lineWidth = 3 //60 * (0.25 - this.damageReductionGoal)
|
||||||
|
ctx.strokeStyle = `#f05` //"rgba(150,150,225,0.5)";
|
||||||
|
ctx.stroke();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if (tech.isMobFullHealthCloak) {
|
||||||
|
dmg *= 1.88
|
||||||
|
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "damage outline",
|
||||||
|
count: 7, //cycles before it self removes
|
||||||
|
vertices: this.vertices,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||||
|
//draw body
|
||||||
|
ctx.beginPath();
|
||||||
|
const vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1, len = vertices.length; j < len; ++j) {
|
||||||
|
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
ctx.fillStyle = `rgba(255,0,100,0.15)` //"rgba(150,150,225,0.5)";
|
||||||
|
ctx.fill()
|
||||||
|
ctx.lineWidth = 3 //60 * (0.25 - this.damageReductionGoal)
|
||||||
|
ctx.strokeStyle = `#f08` //"rgba(150,150,225,0.5)";
|
||||||
|
ctx.stroke();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (tech.isMobLowHealth && this.health < 0.25) {
|
||||||
|
dmg *= 3.22
|
||||||
|
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "damage outline",
|
||||||
|
count: 2, //cycles before it self removes
|
||||||
|
vertices: this.vertices,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||||
|
//draw body
|
||||||
|
ctx.beginPath();
|
||||||
|
const vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1, len = vertices.length; j < len; ++j) {
|
||||||
|
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
ctx.fillStyle = `rgba(255,50,100,0.2)` //"rgba(150,150,225,0.5)";
|
||||||
|
ctx.fill()
|
||||||
|
ctx.lineWidth = 3 //60 * (0.25 - this.damageReductionGoal)
|
||||||
|
ctx.strokeStyle = `#f38` //"rgba(150,150,225,0.5)";
|
||||||
|
ctx.stroke();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//mobs specific damage changes
|
//mobs specific damage changes
|
||||||
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000
|
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000
|
||||||
dmg *= this.damageReduction
|
dmg *= this.damageReduction
|
||||||
@@ -1143,6 +1222,7 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
dmg /= Math.sqrt(this.mass)
|
dmg /= Math.sqrt(this.mass)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.health -= dmg
|
this.health -= dmg
|
||||||
//this.fill = this.color + this.health + ')';
|
//this.fill = this.color + this.health + ')';
|
||||||
this.onDamage(dmg); //custom damage effects
|
this.onDamage(dmg); //custom damage effects
|
||||||
@@ -1187,7 +1267,7 @@ const mobs = {
|
|||||||
leaveBody: true,
|
leaveBody: true,
|
||||||
isDropPowerUp: true,
|
isDropPowerUp: true,
|
||||||
death() {
|
death() {
|
||||||
if (tech.collidePowerUps && Math.random() < tech.collidePowerUps && this.isDropPowerUp) powerUps.randomize(this.position) //needs to run before onDeath spawns power ups
|
if (tech.collidePowerUps && this.isDropPowerUp) powerUps.randomize(this.position) //needs to run before onDeath spawns power ups
|
||||||
this.onDeath(this); //custom death effects
|
this.onDeath(this); //custom death effects
|
||||||
this.removeConsBB();
|
this.removeConsBB();
|
||||||
this.alive = false; //triggers mob removal in mob[i].replace(i)
|
this.alive = false; //triggers mob removal in mob[i].replace(i)
|
||||||
@@ -1261,22 +1341,23 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
if (tech.isBotSpawnerReset) {
|
if (tech.isBotSpawnerReset) {
|
||||||
for (let i = 0, len = bullet.length; i < len; i++) {
|
for (let i = 0, len = bullet.length; i < len; i++) {
|
||||||
if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 780 //13 seconds
|
if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 900 //15 seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Math.random() < tech.botSpawner) {
|
if (Math.random() < tech.botSpawner) {
|
||||||
b.randomBot(this.position, false)
|
b.randomBot(this.position, false)
|
||||||
bullet[bullet.length - 1].endCycle = simulation.cycle + 780 //13 seconds
|
bullet[bullet.length - 1].endCycle = simulation.cycle + 900 //15 seconds
|
||||||
this.leaveBody = false; // no body since it turned into the bot
|
this.leaveBody = false; // no body since it turned into the bot
|
||||||
}
|
}
|
||||||
if (tech.isAddRemoveMaxHealth) {
|
if (tech.isAddRemoveMaxHealth) {
|
||||||
if (this.isBoss && this.isDropPowerUp) {
|
if (this.isBoss && this.isDropPowerUp) {
|
||||||
powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
|
powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
|
||||||
powerUps.spawn(this.position.x - 20, this.position.y, "ammo", false)
|
powerUps.spawn(this.position.x - 20, this.position.y, "research", false)
|
||||||
|
powerUps.spawn(this.position.x - 40, this.position.y, "research", false)
|
||||||
|
powerUps.spawn(this.position.x + 40, this.position.y, "research", false)
|
||||||
powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
|
powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
|
||||||
powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
|
powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
|
||||||
powerUps.spawn(this.position.x - 40, this.position.y, "ammo", false)
|
powerUps.spawn(this.position.x, this.position.y + 40, "heal", false)
|
||||||
powerUps.spawn(this.position.x, this.position.y + 40, "research", false)
|
|
||||||
powerUps.spawn(this.position.x, this.position.y - 40, "heal", false)
|
powerUps.spawn(this.position.x, this.position.y - 40, "heal", false)
|
||||||
} else {
|
} else {
|
||||||
const amount = 0.005
|
const amount = 0.005
|
||||||
@@ -1292,7 +1373,7 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tech.cloakDuplication && !this.isBoss) {
|
if (tech.cloakDuplication && !this.isBoss) {
|
||||||
tech.cloakDuplication -= 0.02
|
tech.cloakDuplication -= 0.01
|
||||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||||
}
|
}
|
||||||
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {
|
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {
|
||||||
|
|||||||
288
js/player.js
288
js/player.js
@@ -393,7 +393,7 @@ const m = {
|
|||||||
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
||||||
if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.15 + 0.3 * (Math.random() - 0.5))))
|
if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.15 + 0.3 * (Math.random() - 0.5))))
|
||||||
}
|
}
|
||||||
console.log(b.activeGun)
|
// console.log(b.activeGun)
|
||||||
//randomize tech
|
//randomize tech
|
||||||
for (let i = 0; i < totalTech; i++) {
|
for (let i = 0; i < totalTech; i++) {
|
||||||
//find what tech I could get
|
//find what tech I could get
|
||||||
@@ -568,7 +568,7 @@ const m = {
|
|||||||
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
||||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
||||||
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55
|
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55
|
||||||
if (tech.isHarmReduce && input.field) dmg *= 0.15
|
if (tech.isHarmReduce && input.field) dmg *= 0.12
|
||||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
||||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||||
@@ -935,83 +935,6 @@ const m = {
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// resetSkin() {
|
|
||||||
// simulation.isAutoZoom = true;
|
|
||||||
// m.yOffWhen.jump = 70
|
|
||||||
// m.yOffWhen.stand = 49
|
|
||||||
// m.yOffWhen.crouch = 22
|
|
||||||
// m.isAltSkin = false
|
|
||||||
// m.color = {
|
|
||||||
// hue: 0,
|
|
||||||
// sat: 0,
|
|
||||||
// light: 100,
|
|
||||||
// }
|
|
||||||
// m.setFillColors();
|
|
||||||
// m.draw = function () {
|
|
||||||
// ctx.fillStyle = m.fillColor;
|
|
||||||
// m.walk_cycle += m.flipLegs * m.Vx;
|
|
||||||
// ctx.save();
|
|
||||||
// ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
|
|
||||||
// ctx.translate(m.pos.x, m.pos.y);
|
|
||||||
// m.calcLeg(Math.PI, -3);
|
|
||||||
// m.drawLeg("#4a4a4a");
|
|
||||||
// m.calcLeg(0, 0);
|
|
||||||
// m.drawLeg("#333");
|
|
||||||
// ctx.rotate(m.angle);
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
|
||||||
// ctx.fillStyle = m.bodyGradient
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
|
||||||
// ctx.strokeStyle = "#333";
|
|
||||||
// ctx.lineWidth = 2;
|
|
||||||
// ctx.stroke();
|
|
||||||
// ctx.restore();
|
|
||||||
// m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
|
|
||||||
// powerUps.boost.draw()
|
|
||||||
// }
|
|
||||||
// m.drawLeg = function (stroke) {
|
|
||||||
// // if (simulation.mouseInGame.x > m.pos.x) {
|
|
||||||
// if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
|
|
||||||
// m.flipLegs = 1;
|
|
||||||
// } else {
|
|
||||||
// m.flipLegs = -1;
|
|
||||||
// }
|
|
||||||
// ctx.save();
|
|
||||||
// ctx.scale(m.flipLegs, 1); //leg lines
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(m.hip.x, m.hip.y);
|
|
||||||
// ctx.lineTo(m.knee.x, m.knee.y);
|
|
||||||
// ctx.lineTo(m.foot.x, m.foot.y);
|
|
||||||
// ctx.strokeStyle = stroke;
|
|
||||||
// ctx.lineWidth = 7;
|
|
||||||
// ctx.stroke();
|
|
||||||
|
|
||||||
// //toe lines
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(m.foot.x, m.foot.y);
|
|
||||||
// ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
|
|
||||||
// ctx.moveTo(m.foot.x, m.foot.y);
|
|
||||||
// ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
|
|
||||||
// ctx.lineWidth = 4;
|
|
||||||
// ctx.stroke();
|
|
||||||
|
|
||||||
// //hip joint
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
|
|
||||||
// //knee joint
|
|
||||||
// ctx.moveTo(m.knee.x + 7, m.knee.y);
|
|
||||||
// ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
|
|
||||||
// //foot joint
|
|
||||||
// ctx.moveTo(m.foot.x + 6, m.foot.y);
|
|
||||||
// ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
|
|
||||||
// ctx.fillStyle = m.fillColor;
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.lineWidth = 2;
|
|
||||||
// ctx.stroke();
|
|
||||||
// ctx.restore();
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
skin: {
|
skin: {
|
||||||
none() {
|
none() {
|
||||||
m.isAltSkin = true
|
m.isAltSkin = true
|
||||||
@@ -1146,6 +1069,96 @@ const m = {
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
strokeGap() {
|
||||||
|
m.isAltSkin = true
|
||||||
|
m.yOffWhen.stand = 52
|
||||||
|
m.yOffWhen.jump = 72
|
||||||
|
// m.yOffWhen.crouch = 22
|
||||||
|
// m.color = {
|
||||||
|
// hue: 184,
|
||||||
|
// sat: 0,
|
||||||
|
// light: 55,
|
||||||
|
// }
|
||||||
|
// m.setFillColors();
|
||||||
|
m.draw = function () {
|
||||||
|
m.walk_cycle += m.flipLegs * m.Vx;
|
||||||
|
ctx.save();
|
||||||
|
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
|
||||||
|
ctx.translate(m.pos.x, m.pos.y);
|
||||||
|
m.calcLeg(Math.PI, -1.25);
|
||||||
|
m.drawLeg("#606070");
|
||||||
|
m.calcLeg(0, 0);
|
||||||
|
m.drawLeg("#445");
|
||||||
|
|
||||||
|
|
||||||
|
ctx.rotate(m.angle);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
|
// ctx.arc(0, 0, 30, m.angle + 1, m.angle - 1);
|
||||||
|
ctx.fillStyle = "#fff"//m.bodyGradient
|
||||||
|
ctx.fill();
|
||||||
|
ctx.beginPath();
|
||||||
|
const arc = 0.7 + 0.17 * Math.sin(m.cycle * 0.012)
|
||||||
|
ctx.arc(0, 0, 30, -arc, arc, true); //- Math.PI / 2
|
||||||
|
ctx.strokeStyle = "#445";
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(13, 0)
|
||||||
|
ctx.lineTo(20, 0)
|
||||||
|
// ctx.beginPath();
|
||||||
|
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
|
ctx.lineWidth = 5;
|
||||||
|
ctx.strokeStyle = "#445";
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
|
||||||
|
powerUps.boost.draw()
|
||||||
|
}
|
||||||
|
m.drawLeg = function (stroke) {
|
||||||
|
// if (simulation.mouseInGame.x > m.pos.x) {
|
||||||
|
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
|
||||||
|
m.flipLegs = 1;
|
||||||
|
} else {
|
||||||
|
m.flipLegs = -1;
|
||||||
|
}
|
||||||
|
ctx.save();
|
||||||
|
ctx.scale(m.flipLegs, 1); //leg lines
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(m.hip.x, m.hip.y);
|
||||||
|
ctx.lineTo(m.knee.x, m.knee.y);
|
||||||
|
ctx.lineTo(m.foot.x, m.foot.y);
|
||||||
|
ctx.strokeStyle = stroke;
|
||||||
|
ctx.lineWidth = 5;
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
//toe lines
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(m.foot.x, m.foot.y);
|
||||||
|
ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
|
||||||
|
ctx.moveTo(m.foot.x, m.foot.y);
|
||||||
|
ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
|
||||||
|
ctx.lineWidth = 4;
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
//hip joint
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.hip.x, m.hip.y, 8, 0, 2 * Math.PI);
|
||||||
|
//knee joint
|
||||||
|
ctx.moveTo(m.knee.x + 4, m.knee.y);
|
||||||
|
ctx.arc(m.knee.x, m.knee.y, 4, 0, 2 * Math.PI);
|
||||||
|
//foot joint
|
||||||
|
ctx.moveTo(m.foot.x + 4, m.foot.y + 1);
|
||||||
|
ctx.arc(m.foot.x, m.foot.y + 1, 4, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = m.fillColor;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
},
|
||||||
energy() {
|
energy() {
|
||||||
m.isAltSkin = true
|
m.isAltSkin = true
|
||||||
m.color = {
|
m.color = {
|
||||||
@@ -1333,17 +1346,9 @@ const m = {
|
|||||||
sat: 14,
|
sat: 14,
|
||||||
light: 65,
|
light: 65,
|
||||||
}
|
}
|
||||||
// m.setFillColors();
|
|
||||||
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
|
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
|
||||||
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 50}%)`
|
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 50}%)`
|
||||||
// let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
|
||||||
const grd = ctx.createRadialGradient(16, 0, 0, 0, 0, 40);
|
const grd = ctx.createRadialGradient(16, 0, 0, 0, 0, 40);
|
||||||
|
|
||||||
// grd.addColorStop(0, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`);
|
|
||||||
// grd.addColorStop(0.25, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 20}%)`);
|
|
||||||
// grd.addColorStop(0.5, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`);
|
|
||||||
// grd.addColorStop(1, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 10}%)`);
|
|
||||||
|
|
||||||
grd.addColorStop(0, `#c78034`);
|
grd.addColorStop(0, `#c78034`);
|
||||||
grd.addColorStop(0.04, `#bd5235`);
|
grd.addColorStop(0.04, `#bd5235`);
|
||||||
grd.addColorStop(0.08, `#ab554d`);
|
grd.addColorStop(0.08, `#ab554d`);
|
||||||
@@ -1369,10 +1374,8 @@ const m = {
|
|||||||
grd.addColorStop(0.92, `#00e19b`);
|
grd.addColorStop(0.92, `#00e19b`);
|
||||||
grd.addColorStop(0.96, `#19f5aa`);
|
grd.addColorStop(0.96, `#19f5aa`);
|
||||||
grd.addColorStop(1, `#aaf5af`);
|
grd.addColorStop(1, `#aaf5af`);
|
||||||
|
|
||||||
m.bodyGradient = grd
|
m.bodyGradient = grd
|
||||||
|
|
||||||
|
|
||||||
m.draw = function () {
|
m.draw = function () {
|
||||||
ctx.fillStyle = m.fillColor;
|
ctx.fillStyle = m.fillColor;
|
||||||
m.walk_cycle += m.flipLegs * m.Vx;
|
m.walk_cycle += m.flipLegs * m.Vx;
|
||||||
@@ -1410,7 +1413,7 @@ const m = {
|
|||||||
ctx.lineTo(m.knee.x, m.knee.y);
|
ctx.lineTo(m.knee.x, m.knee.y);
|
||||||
ctx.lineTo(m.foot.x, m.foot.y);
|
ctx.lineTo(m.foot.x, m.foot.y);
|
||||||
ctx.strokeStyle = stroke;
|
ctx.strokeStyle = stroke;
|
||||||
ctx.lineWidth = 7;
|
ctx.lineWidth = 5;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
//toe lines
|
//toe lines
|
||||||
@@ -1424,21 +1427,22 @@ const m = {
|
|||||||
|
|
||||||
//hip joint
|
//hip joint
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
|
ctx.arc(m.hip.x, m.hip.y, 9, 0, 2 * Math.PI);
|
||||||
ctx.fillStyle = "#1b85cf";
|
ctx.fillStyle = "#222";
|
||||||
|
// ctx.fillStyle = "#1b85cf";
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
//knee joint
|
//knee joint
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
|
ctx.arc(m.knee.x, m.knee.y, 5, 0, 2 * Math.PI);
|
||||||
ctx.fillStyle = "#ffa050";
|
// ctx.fillStyle = "#ffa050";
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
//foot joint
|
//foot joint
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
|
ctx.arc(m.foot.x, m.foot.y, 4, 0, 2 * Math.PI);
|
||||||
ctx.fillStyle = "#878cf0";
|
// ctx.fillStyle = "#878cf0";
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.lineWidth = 2;
|
// ctx.lineWidth = 3;
|
||||||
ctx.stroke();
|
// ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2636,7 +2640,7 @@ const m = {
|
|||||||
},
|
},
|
||||||
fieldUpgrades: [{
|
fieldUpgrades: [{
|
||||||
name: "field emitter",
|
name: "field emitter",
|
||||||
imageNumber: Math.floor(Math.random() * 23),
|
imageNumber: Math.floor(Math.random() * 26), //pick one of the 25 field emitter image files at random
|
||||||
description: `<em>initial field</em><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong>
|
description: `<em>initial field</em><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong>
|
||||||
<br>generate <strong>4</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
|
<br>generate <strong>4</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -2934,7 +2938,6 @@ const m = {
|
|||||||
// if (m.energy < m.fieldRegen) m.fieldCDcycle = m.cycle + 90;
|
// if (m.energy < m.fieldRegen) m.fieldCDcycle = m.cycle + 90;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
|
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
|
||||||
m.grabPowerUp();
|
m.grabPowerUp();
|
||||||
m.lookForPickUp();
|
m.lookForPickUp();
|
||||||
@@ -3998,7 +4001,7 @@ const m = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "metamaterial cloaking",
|
name: "metamaterial cloaking",
|
||||||
description: "<strong>+50%</strong> <strong class='color-defense'>defense</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>+333%</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
description: "<strong>+66%</strong> <strong class='color-defense'>defense</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>+333%</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
m.fieldFire = true;
|
m.fieldFire = true;
|
||||||
m.fieldMeterColor = "#333";
|
m.fieldMeterColor = "#333";
|
||||||
@@ -4013,29 +4016,6 @@ const m = {
|
|||||||
m.walk_cycle -= m.flipLegs * m.Vx;
|
m.walk_cycle -= m.flipLegs * m.Vx;
|
||||||
m.pos.x += 4
|
m.pos.x += 4
|
||||||
m.draw();
|
m.draw();
|
||||||
|
|
||||||
// let history = m.history[(m.cycle - 1) % 600]
|
|
||||||
// m.pos.x = history.position.x
|
|
||||||
// m.pos.y = history.position.y + m.yPosDifference - history.yOff
|
|
||||||
|
|
||||||
// m.pos.x += 4
|
|
||||||
// ctx.fillStyle = m.fillColor;
|
|
||||||
// ctx.save();
|
|
||||||
// ctx.translate(m.pos.x, m.pos.y);
|
|
||||||
// m.calcLeg(Math.PI, -3);
|
|
||||||
// m.drawLeg("#ccc");
|
|
||||||
// m.calcLeg(0, 0);
|
|
||||||
// m.drawLeg("#ccc");
|
|
||||||
// ctx.rotate(m.angle);
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
|
||||||
// ctx.fillStyle = "#fff"
|
|
||||||
// ctx.fill();
|
|
||||||
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
|
||||||
// ctx.strokeStyle = "#333";
|
|
||||||
// ctx.lineWidth = 2;
|
|
||||||
// ctx.stroke();
|
|
||||||
// ctx.restore()
|
|
||||||
}
|
}
|
||||||
m.drawCloak = function () {
|
m.drawCloak = function () {
|
||||||
m.fieldPhase += 0.007
|
m.fieldPhase += 0.007
|
||||||
@@ -4067,27 +4047,27 @@ const m = {
|
|||||||
}
|
}
|
||||||
//not shooting (or using field) enable cloak
|
//not shooting (or using field) enable cloak
|
||||||
if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle
|
if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle
|
||||||
if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing
|
if (m.fireCDcycle + 10 < m.cycle && !input.fire) { //automatically cloak if not firing
|
||||||
const drain = 0.02
|
const drain = 0.02
|
||||||
if (!m.isCloak && m.energy > drain + 0.03) {
|
if (!m.isCloak && m.energy > drain + 0.03) {
|
||||||
m.energy -= drain
|
m.energy -= drain
|
||||||
m.isCloak = true //enter cloak
|
m.isCloak = true //enter cloak
|
||||||
m.fieldHarmReduction = 0.5;
|
m.fieldHarmReduction = 0.33; //66% reduction
|
||||||
m.enterCloakCycle = m.cycle
|
m.enterCloakCycle = m.cycle
|
||||||
if (tech.isCloakHealLastHit && m.lastHit > 0) {
|
if (tech.isCloakHealLastHit && m.lastHit > 0) {
|
||||||
const heal = Math.min(0.75 * m.lastHit, m.energy)
|
const heal = Math.min(0.75 * m.lastHit, m.energy)
|
||||||
if (m.energy > heal) {
|
// if (m.energy > heal) {
|
||||||
m.energy -= heal
|
// m.energy -= heal * 0.8
|
||||||
m.addHealth(heal); //heal from last hit
|
m.addHealth(heal); //heal from last hit
|
||||||
m.lastHit = 0
|
m.lastHit = 0
|
||||||
simulation.drawList.push({ //add dmg to draw queue
|
simulation.drawList.push({ //add dmg to draw queue
|
||||||
x: m.pos.x,
|
x: m.pos.x,
|
||||||
y: m.pos.y,
|
y: m.pos.y,
|
||||||
radius: Math.sqrt(heal) * 200,
|
radius: Math.sqrt(heal) * 200,
|
||||||
color: "rgba(0,255,200,0.6)",
|
color: "rgba(0,255,200,0.6)",
|
||||||
time: 16
|
time: 16
|
||||||
});
|
});
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
if (tech.isIntangible) {
|
if (tech.isIntangible) {
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
@@ -4133,9 +4113,16 @@ const m = {
|
|||||||
m.fieldRange = m.fieldRange * 0.85 + 130
|
m.fieldRange = m.fieldRange * 0.85 + 130
|
||||||
m.fieldDrawRadius = m.fieldRange * 1.1 //* 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
|
m.fieldDrawRadius = m.fieldRange * 1.1 //* 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
|
||||||
m.drawCloak()
|
m.drawCloak()
|
||||||
ctx.globalCompositeOperation = "lighter";
|
// ctx.globalCompositeOperation = "lighter";
|
||||||
m.drawCloakedM()
|
// m.drawCloakedM()
|
||||||
ctx.globalCompositeOperation = "source-over";
|
// ctx.globalCompositeOperation = "source-over";
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.pos.x, m.pos.y, 35, 0, 2 * Math.PI);
|
||||||
|
ctx.strokeStyle = "rgba(255,255,255,0.25)";//"rgba(0,0,0,0.7)";//"rgba(255,255,255,0.7)";//"rgba(255,0,100,0.7)";
|
||||||
|
ctx.lineWidth = 10
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
} else if (m.fieldRange < 4000) {
|
} else if (m.fieldRange < 4000) {
|
||||||
m.fieldRange += 90
|
m.fieldRange += 90
|
||||||
m.fieldDrawRadius = m.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
|
m.fieldDrawRadius = m.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
|
||||||
@@ -4148,8 +4135,8 @@ const m = {
|
|||||||
if (inPlayer.length > 0) {
|
if (inPlayer.length > 0) {
|
||||||
for (let i = 0; i < inPlayer.length; i++) {
|
for (let i = 0; i < inPlayer.length; i++) {
|
||||||
if (m.energy > 0) {
|
if (m.energy > 0) {
|
||||||
if (!inPlayer[i].isUnblockable) m.energy -= 0.007;
|
if (!inPlayer[i].isUnblockable) m.energy -= 0.003;
|
||||||
if (inPlayer[i].shield) m.energy -= 0.025;
|
if (inPlayer[i].shield) m.energy -= 0.011;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4158,10 +4145,17 @@ const m = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.drawRegenEnergyCloaking()
|
this.drawRegenEnergyCloaking()
|
||||||
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
|
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
|
||||||
ctx.globalCompositeOperation = "multiply";
|
const timeLeft = (m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) - m.cycle) * 0.5
|
||||||
m.drawCloakedM()
|
ctx.beginPath();
|
||||||
ctx.globalCompositeOperation = "source-over";
|
ctx.arc(m.pos.x, m.pos.y, 32, 0, 2 * Math.PI);
|
||||||
|
ctx.strokeStyle = "rgba(180,30,70,0.5)";//"rgba(0,0,0,0.7)";//"rgba(255,255,255,0.7)";//"rgba(255,0,100,0.7)";
|
||||||
|
ctx.lineWidth = Math.max(Math.min(10, timeLeft), 3);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// ctx.globalCompositeOperation = "multiply";
|
||||||
|
// m.drawCloakedM()
|
||||||
|
// ctx.globalCompositeOperation = "source-over";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -534,26 +534,24 @@ const powerUps = {
|
|||||||
if (!tech.isEnergyHealth && m.alive) {
|
if (!tech.isEnergyHealth && m.alive) {
|
||||||
powerUps.animatePowerUpGrab('rgba(0, 238, 187,0.25)')
|
powerUps.animatePowerUpGrab('rgba(0, 238, 187,0.25)')
|
||||||
let heal = (this.size / 40 / (simulation.healScale ** 0.25)) ** 2 //simulation.healScale is undone here because heal scale is already properly affected on m.addHealth()
|
let heal = (this.size / 40 / (simulation.healScale ** 0.25)) ** 2 //simulation.healScale is undone here because heal scale is already properly affected on m.addHealth()
|
||||||
// console.log("size = " + this.size, "heal = " + heal)
|
|
||||||
if (heal > 0) {
|
if (heal > 0) {
|
||||||
const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal
|
const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal
|
||||||
const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale
|
const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale
|
||||||
m.addHealth(heal);
|
m.addHealth(heal);
|
||||||
if (healOutput > 0) simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
|
if (healOutput > 0) simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
|
||||||
if (tech.isOverHeal && overHeal > 0) { //tech quenching
|
if (tech.isOverHeal && overHeal > 0) { //tech quenching
|
||||||
const scaledOverHeal = overHeal // * 0.9
|
m.damage(overHeal);
|
||||||
m.damage(scaledOverHeal);
|
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(overHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)}
|
||||||
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(scaledOverHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)}
|
|
||||||
simulation.drawList.push({ //add dmg to draw queue
|
simulation.drawList.push({ //add dmg to draw queue
|
||||||
x: m.pos.x,
|
x: m.pos.x,
|
||||||
y: m.pos.y,
|
y: m.pos.y,
|
||||||
radius: scaledOverHeal * 500 * simulation.healScale,
|
radius: overHeal * 500 * simulation.healScale,
|
||||||
color: simulation.mobDmgColor,
|
color: simulation.mobDmgColor,
|
||||||
time: simulation.drawTime
|
time: simulation.drawTime
|
||||||
});
|
});
|
||||||
tech.extraMaxHealth += scaledOverHeal * simulation.healScale //increase max health
|
tech.extraMaxHealth += overHeal * Math.sqrt(simulation.healScale) //increase max health
|
||||||
m.setMaxHealth();
|
m.setMaxHealth();
|
||||||
} else if (overHeal > 0.1) {
|
} else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
|
powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1272,7 +1272,7 @@ const simulation = {
|
|||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
if (mob[i].isDropPowerUp && mob[i].alive) count++
|
if (mob[i].isDropPowerUp && mob[i].alive) count++
|
||||||
}
|
}
|
||||||
count *= 0.17 //to fake the chance, this makes it not random, and maybe less confusing
|
count *= 0.22 //to fake the 20% chance, this makes it not random, and more predictable
|
||||||
let cycle = () => { //run after waiting a cycle for the map to be cleared
|
let cycle = () => { //run after waiting a cycle for the map to be cleared
|
||||||
const types = ["heal", "ammo", "heal", "ammo", "research", "coupling", "boost", "tech", "gun", "field"]
|
const types = ["heal", "ammo", "heal", "ammo", "research", "coupling", "boost", "tech", "gun", "field"]
|
||||||
for (let i = 0; i < count; i++) powerUps.spawnDelay(types[Math.floor(Math.random() * types.length)], 1)
|
for (let i = 0; i < count; i++) powerUps.spawnDelay(types[Math.floor(Math.random() * types.length)], 1)
|
||||||
|
|||||||
200
js/spawn.js
200
js/spawn.js
@@ -200,7 +200,7 @@ const spawn = {
|
|||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (mob[i].alive && !mob[i].isShielded) {
|
if (mob[i].alive && !mob[i].isShielded) {
|
||||||
if (Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius < this.radius) {
|
if (Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius < this.radius) {
|
||||||
mob[i].damage(0.02 * m.dmgScale);
|
mob[i].damage(0.025 * m.dmgScale);
|
||||||
// mob[i].locatePlayer();//
|
// mob[i].locatePlayer();//
|
||||||
|
|
||||||
simulation.drawList.push({ //add dmg to draw queue
|
simulation.drawList.push({ //add dmg to draw queue
|
||||||
@@ -366,7 +366,7 @@ const spawn = {
|
|||||||
me.maxMobs = 400
|
me.maxMobs = 400
|
||||||
me.mode = [{
|
me.mode = [{
|
||||||
name: "boulders",
|
name: "boulders",
|
||||||
spawnRate: 170 - 6 * simulation.difficultyMode,
|
spawnRate: Math.max(30, 170 - 5 * simulation.difficultyMode),
|
||||||
do() {
|
do() {
|
||||||
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
||||||
me.boulder(me.position.x, me.position.y + 250)
|
me.boulder(me.position.x, me.position.y + 250)
|
||||||
@@ -374,10 +374,11 @@ const spawn = {
|
|||||||
},
|
},
|
||||||
enter() { },
|
enter() { },
|
||||||
exit() { },
|
exit() { },
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: "mobs",
|
name: "mobs",
|
||||||
// whoSpawn: spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)],
|
// whoSpawn: spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)],
|
||||||
spawnRate: 280 - 20 * simulation.difficultyMode,
|
spawnRate: Math.max(60, 240 - 20 * simulation.difficultyMode),
|
||||||
do() {
|
do() {
|
||||||
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
||||||
me.torque += 0.000015 * me.inertia; //spin
|
me.torque += 0.000015 * me.inertia; //spin
|
||||||
@@ -397,7 +398,7 @@ const spawn = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "hoppers",
|
name: "hoppers",
|
||||||
spawnRate: 480 - 16 * simulation.difficultyMode,
|
spawnRate: Math.max(90, 480 - 16 * simulation.difficultyMode),
|
||||||
do() {
|
do() {
|
||||||
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
|
||||||
me.torque += 0.00002 * me.inertia; //spin
|
me.torque += 0.00002 * me.inertia; //spin
|
||||||
@@ -422,7 +423,7 @@ const spawn = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "seekers",
|
name: "seekers",
|
||||||
spawnRate: 100 - 3 * simulation.difficultyMode,
|
spawnRate: Math.max(15, 100 - 3 * simulation.difficultyMode),
|
||||||
do() {
|
do() {
|
||||||
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) { //spawn seeker
|
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) { //spawn seeker
|
||||||
const index = Math.floor((me.cycle % 360) / 60)
|
const index = Math.floor((me.cycle % 360) / 60)
|
||||||
@@ -440,7 +441,7 @@ const spawn = {
|
|||||||
{
|
{
|
||||||
name: "mines",
|
name: "mines",
|
||||||
bombCycle: 0,
|
bombCycle: 0,
|
||||||
bombInterval: 10 - simulation.difficultyMode,
|
bombInterval: Math.max(2, 10 - simulation.difficultyMode),
|
||||||
do() {
|
do() {
|
||||||
const yOff = 120
|
const yOff = 120
|
||||||
this.bombCycle++
|
this.bombCycle++
|
||||||
@@ -498,7 +499,7 @@ const spawn = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "orbiters",
|
name: "orbiters",
|
||||||
spawnRate: Math.ceil(4 - 0.25 * simulation.difficultyMode),
|
spawnRate: Math.ceil(Math.max(2, 5 - 0.2 * simulation.difficultyMode)),
|
||||||
orbitersCycle: 0,
|
orbitersCycle: 0,
|
||||||
do() {
|
do() {
|
||||||
this.orbitersCycle++
|
this.orbitersCycle++
|
||||||
@@ -522,7 +523,7 @@ const spawn = {
|
|||||||
this.fadeCycle++
|
this.fadeCycle++
|
||||||
if (this.fadeCycle > 0) {
|
if (this.fadeCycle > 0) {
|
||||||
me.torque += this.spinForce * me.inertia; //spin //0.00000015
|
me.torque += this.spinForce * me.inertia; //spin //0.00000015
|
||||||
if (this.fadeCycle > 360) this.fadeCycle = -150 + 2 * simulation.difficultyMode * simulation.difficultyMode //turn laser off and reset
|
if (this.fadeCycle > 360) this.fadeCycle = -200 + simulation.difficultyMode * simulation.difficultyMode //turn laser off and reset
|
||||||
ctx.strokeStyle = "#50f";
|
ctx.strokeStyle = "#50f";
|
||||||
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
||||||
ctx.lineWidth = 1.5;
|
ctx.lineWidth = 1.5;
|
||||||
@@ -561,7 +562,7 @@ const spawn = {
|
|||||||
{
|
{
|
||||||
name: "black hole",
|
name: "black hole",
|
||||||
eventHorizon: 0,
|
eventHorizon: 0,
|
||||||
eventHorizonRadius: 1900,
|
eventHorizonRadius: 1700,
|
||||||
eventHorizonCycle: 0,
|
eventHorizonCycle: 0,
|
||||||
do() {
|
do() {
|
||||||
this.eventHorizonCycle++
|
this.eventHorizonCycle++
|
||||||
@@ -629,15 +630,121 @@ const spawn = {
|
|||||||
spawn.shield(me, me.position.x, me.position.y, 1);
|
spawn.shield(me, me.position.x, me.position.y, 1);
|
||||||
},
|
},
|
||||||
exit() { this.waveCycle = 0 },
|
exit() { this.waveCycle = 0 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "slow zone",
|
||||||
|
waveCycle: 0,
|
||||||
|
whereX: simulation.isHorizontalFlipped ? -3000 : 3000,
|
||||||
|
width: 1200,
|
||||||
|
// isActive: false,
|
||||||
|
cycle: 0,
|
||||||
|
cycleDuration: 150,
|
||||||
|
zone: 0,
|
||||||
|
isMovingRight: true,
|
||||||
|
playerSlowTime: 0,
|
||||||
|
do() {
|
||||||
|
// console.log(zone)
|
||||||
|
this.cycle++
|
||||||
|
if (this.cycle % this.cycleDuration === 0) { //next zone
|
||||||
|
this.zone += this.isMovingRight ? 1 : -1
|
||||||
|
if (this.zone > 0) this.isMovingRight = false
|
||||||
|
if (this.zone < -1) this.isMovingRight = true
|
||||||
|
this.whereX = (simulation.isHorizontalFlipped ? -3000 : 3000) + this.width * this.zone
|
||||||
|
}
|
||||||
|
//draw slow zone
|
||||||
|
if (this.cycle % this.cycleDuration > 0.45 * this.cycleDuration) {
|
||||||
|
ctx.fillStyle = `rgba(0, 100, 255, ${0.19 + 0.015 * Math.sin(simulation.cycle * 0.36)})`;
|
||||||
|
ctx.fillRect(this.whereX, -1500, this.width, 1500);
|
||||||
|
//check for player in range and apply slow debuff
|
||||||
|
if (player.position.x > this.whereX && player.position.x < this.whereX + this.width) {
|
||||||
|
this.playerSlowTime = 180
|
||||||
|
//damage player
|
||||||
|
const dmg = 0.0001 * simulation.dmgScale
|
||||||
|
m.damage(dmg);
|
||||||
|
}
|
||||||
|
} else { //show where slow zone is about to show up
|
||||||
|
ctx.fillStyle = `rgba(0, 100, 255, ${0.2 + 0.25 * Math.random()})`;
|
||||||
|
ctx.fillRect(this.whereX, -1500, this.width, 12);
|
||||||
|
ctx.fillRect(this.whereX, -12, this.width, 12);
|
||||||
|
}
|
||||||
|
if (this.playerSlowTime > 0) {
|
||||||
|
this.playerSlowTime-- //warm up player when outside of slow zone
|
||||||
|
//slow player
|
||||||
|
// Matter.Body.setVelocity(player, Vector.mult(player.velocity, (1 - 0.01 * this.playerSlowTime)));
|
||||||
|
// Matter.Body.setVelocity(player, { x: (1 - 0.01 * this.playerSlowTime) * player.velocity.x, y: (1 - 0.0025 * this.playerSlowTime) * player.velocity.y }); //makes the player get stuck slow when walking horizontally
|
||||||
|
Matter.Body.setVelocity(player, { x: Math.max(0.05, 1 - 0.01 * Math.max(10, this.playerSlowTime)) * player.velocity.x, y: Math.max(0.2, 1 - 0.0025 * this.playerSlowTime) * player.velocity.y });
|
||||||
|
//draw effect on player
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.pos.x, m.pos.y, 45, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = `rgba(0,100,255,${(0.003 * Math.max(10, this.playerSlowTime))})`;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enter() {
|
||||||
|
},
|
||||||
|
exit() { },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "antigravity",
|
||||||
|
cycle: 0,
|
||||||
|
startCycle: 420,
|
||||||
|
totalCycles: 600,
|
||||||
|
rectX: simulation.isHorizontalFlipped ? -5400 : -150, //for positioning graphics
|
||||||
|
do() {
|
||||||
|
this.cycle++
|
||||||
|
if (this.cycle > this.totalCycles) this.cycle = 0
|
||||||
|
if (this.cycle === this.startCycle) {
|
||||||
|
//initial push up
|
||||||
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
|
body[i].force.y -= 0.05 * body[i].mass
|
||||||
|
}
|
||||||
|
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||||
|
powerUp[i].force.y -= 0.07 * powerUp[i].mass
|
||||||
|
}
|
||||||
|
for (let i = 0, len = bullet.length; i < len; ++i) {
|
||||||
|
bullet[i].force.y -= 0.05 * bullet[i].mass
|
||||||
|
}
|
||||||
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
|
mob[i].force.y -= 0.15 * mob[i].mass
|
||||||
|
}
|
||||||
|
player.force.y -= 0.04 * player.mass
|
||||||
|
} else if (this.cycle > this.startCycle) { //antigravity
|
||||||
|
for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally
|
||||||
|
body[i].force.y -= simulation.g * body[i].mass
|
||||||
|
Matter.Body.setVelocity(body[i], Vector.mult(body[i].velocity, 0.98)); //friction
|
||||||
|
}
|
||||||
|
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||||
|
powerUp[i].force.y -= simulation.g * powerUp[i].mass
|
||||||
|
}
|
||||||
|
// for (let i = 0, len = bullet.length; i < len; ++i) {
|
||||||
|
// bullet[i].force.y -= simulation.g * bullet[i].mass
|
||||||
|
// Matter.Body.setVelocity(bullet[i], Vector.mult(bullet[i].velocity, 0.98)); //friction
|
||||||
|
// }
|
||||||
|
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
|
// mob[i].force.y -= 0.7 * simulation.g * mob[i].mass
|
||||||
|
// }
|
||||||
|
player.force.y -= simulation.g * player.mass //g = 0.0024
|
||||||
|
Matter.Body.setVelocity(player, Vector.mult(player.velocity, 0.985)); //friction
|
||||||
|
//graphics
|
||||||
|
ctx.fillStyle = `rgba(0, 0, 0, ${0.03 + 0.03 * Math.random()})`;
|
||||||
|
ctx.fillRect(this.rectX, -1500, 5650, 1500); //cover everything
|
||||||
|
} else if (this.cycle > this.startCycle - 60) {
|
||||||
|
//graphical warning of antigravity
|
||||||
|
ctx.fillStyle = `rgba(0, 0, 0, ${0.2 + 0.25 * Math.random()})`;
|
||||||
|
ctx.fillRect(this.rectX, -25, 5650, 25); //cover floor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enter() { spawn.shield(me, me.position.x, me.position.y, 1); },
|
||||||
|
exit() { this.cycle = 0 },
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// name: "__",
|
// name: "__",
|
||||||
// do() {},
|
// do() { },
|
||||||
// enter() {},
|
// enter() { },
|
||||||
// exit() {},
|
// exit() { },
|
||||||
// },
|
// },
|
||||||
]
|
]
|
||||||
shuffle(me.mode); //THIS SHOULDN'T BE COMMENTED OUT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
shuffle(me.mode); //THIS SHOULD NOT BE COMMENTED OUT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.fill = `hsl(${360 * Math.sin(this.cycle * 0.011)},${80 + 20 * Math.sin(this.cycle * 0.004)}%,${60 + 20 * Math.sin(this.cycle * 0.009)}%)`
|
this.fill = `hsl(${360 * Math.sin(this.cycle * 0.011)},${80 + 20 * Math.sin(this.cycle * 0.004)}%,${60 + 20 * Math.sin(this.cycle * 0.009)}%)`
|
||||||
if (this.health < 1) {
|
if (this.health < 1) {
|
||||||
@@ -648,7 +755,8 @@ const spawn = {
|
|||||||
this.damageReductionDecay();
|
this.damageReductionDecay();
|
||||||
for (let i = 0; i < this.totalModes; i++) this.mode[i].do()
|
for (let i = 0; i < this.totalModes; i++) this.mode[i].do()
|
||||||
}
|
}
|
||||||
// this.mode[5].do() //deelete this
|
// this.mode[10].do() //comment out this
|
||||||
|
// console.log(this.mode[9].name)
|
||||||
// this.cycle++;
|
// this.cycle++;
|
||||||
// this.mode[4].do()
|
// this.mode[4].do()
|
||||||
// this.mode[7].do()
|
// this.mode[7].do()
|
||||||
@@ -719,7 +827,7 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Matter.Body.setDensity(me, 0.003); //normal is 0.001
|
Matter.Body.setDensity(me, 0.003); //normal is 0.001
|
||||||
me.timeLeft = 360;
|
me.timeLeft = 300;
|
||||||
me.g = 0.0005; //required if using this.gravity
|
me.g = 0.0005; //required if using this.gravity
|
||||||
me.frictionAir = 0.005;
|
me.frictionAir = 0.005;
|
||||||
me.friction = 1;
|
me.friction = 1;
|
||||||
@@ -740,6 +848,12 @@ const spawn = {
|
|||||||
this.torque += this.spin;
|
this.torque += this.spin;
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
|
if (this.timeLeft < 60) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(this.position.x, this.position.y, this.explodeRange, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = `rgba(255,255,255,0.15)`;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
me.orbitalNoVelocity = function (who, radius, phase, speed) { //orbitals that don't include their host velocity //specifically for finalBoss
|
me.orbitalNoVelocity = function (who, radius, phase, speed) { //orbitals that don't include their host velocity //specifically for finalBoss
|
||||||
@@ -2502,7 +2616,7 @@ const spawn = {
|
|||||||
spawn.hopBullet(this.position.x, this.position.y)
|
spawn.hopBullet(this.position.x, this.position.y)
|
||||||
this.death();
|
this.death();
|
||||||
}
|
}
|
||||||
if (Matter.Query.collides(this, [player]).length > 0) this.isExploding = true
|
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible) && m.immuneCycle < m.cycle) this.isExploding = true
|
||||||
if (this.isExploding) {
|
if (this.isExploding) {
|
||||||
if (this.countDown-- < 0) { //explode
|
if (this.countDown-- < 0) { //explode
|
||||||
this.death();
|
this.death();
|
||||||
@@ -2538,7 +2652,7 @@ const spawn = {
|
|||||||
// me.isBadTarget = true;
|
// me.isBadTarget = true;
|
||||||
me.isMobBullet = true;
|
me.isMobBullet = true;
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
me.timeLeft = 1140 + Math.floor(480 * Math.random());
|
me.timeLeft = 1020 + Math.floor(480 * Math.random());
|
||||||
|
|
||||||
me.isRandomMove = Math.random() < 0.3 //most chase player, some don't
|
me.isRandomMove = Math.random() < 0.3 //most chase player, some don't
|
||||||
me.accelMag = 0.01; //jump height
|
me.accelMag = 0.01; //jump height
|
||||||
@@ -2547,7 +2661,7 @@ const spawn = {
|
|||||||
me.friction = 1
|
me.friction = 1
|
||||||
me.frictionStatic = 1
|
me.frictionStatic = 1
|
||||||
me.restitution = 0;
|
me.restitution = 0;
|
||||||
me.delay = 130 + 60 * simulation.CDScale;
|
me.delay = 120 + 60 * simulation.CDScale;
|
||||||
// Matter.Body.rotate(me, Math.random() * Math.PI);
|
// Matter.Body.rotate(me, Math.random() * Math.PI);
|
||||||
me.collisionFilter.category = cat.mobBullet;
|
me.collisionFilter.category = cat.mobBullet;
|
||||||
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||||
@@ -3673,12 +3787,54 @@ const spawn = {
|
|||||||
} else if (c < -threshold) {
|
} else if (c < -threshold) {
|
||||||
this.torque -= turn;
|
this.torque -= turn;
|
||||||
}
|
}
|
||||||
const flapArc = 0.7 //don't go past 1.57 for normal flaps
|
|
||||||
|
|
||||||
|
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)";
|
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
// else { //flocking behavior (not working yet)
|
||||||
|
// 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)) {
|
||||||
|
// //find nearest mob and maintain a distance
|
||||||
|
// let nearestMob = null
|
||||||
|
// let nearestMobDistance = Infinity
|
||||||
|
// for (let i = 0; i < mob.length; i++) {
|
||||||
|
// const newMobDistance = Vector.magnitude(Vector.sub(this.position, mob[i].position))
|
||||||
|
// if (mob[i].isDropPowerUp && mob[i].alive && newMobDistance < nearestMobDistance) { //&& !mob[i].isBoss
|
||||||
|
// nearestMobDistance = newMobDistance
|
||||||
|
// nearestMob = mob[i]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (nearestMob) {
|
||||||
|
// // console.log(nearestMob)
|
||||||
|
// this.fireDir = Vector.normalise(Vector.sub(nearestMob.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(nearestMob.position, 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.000025 * 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 = 50) {
|
beetleBoss(x, y, radius = 50) {
|
||||||
@@ -5237,9 +5393,7 @@ const spawn = {
|
|||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
|
|
||||||
if (Matter.Query.collides(this, [player]).length > 0) {
|
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible) && m.immuneCycle < m.cycle) this.isExploding = true
|
||||||
this.isExploding = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isExploding) {
|
if (this.isExploding) {
|
||||||
if (this.countDown-- < 0) { //explode
|
if (this.countDown-- < 0) { //explode
|
||||||
|
|||||||
273
js/tech.js
273
js/tech.js
@@ -237,7 +237,7 @@ const tech = {
|
|||||||
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
|
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
|
||||||
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
|
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
|
||||||
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling
|
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling
|
||||||
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.033 * m.coupling)
|
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.033 * m.coupling)
|
||||||
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
|
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
|
||||||
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount // if (tech.isTechDebt) dmg *= Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount)
|
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount // if (tech.isTechDebt) dmg *= Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount)
|
||||||
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
||||||
@@ -365,6 +365,57 @@ const tech = {
|
|||||||
if (this.count) m.resetSkin();
|
if (this.count) m.resetSkin();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Higgs mechanism",
|
||||||
|
description: "<strong>+77%</strong> <strong><em>fire rate</em></strong><br>while <strong>firing</strong> your <strong>position</strong> is fixed",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
isSkin: true,
|
||||||
|
allowed() {
|
||||||
|
return !m.isAltSkin && !m.isShipMode && !tech.isAlwaysFire
|
||||||
|
},
|
||||||
|
requires: "not skinned, ship mode, automatic",
|
||||||
|
effect() {
|
||||||
|
tech.isFireMoveLock = true;
|
||||||
|
b.setFireCD();
|
||||||
|
b.setFireMethod();
|
||||||
|
m.skin.strokeGap();
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
if (tech.isFireMoveLock) {
|
||||||
|
tech.isFireMoveLock = false
|
||||||
|
b.setFireCD();
|
||||||
|
b.setFireMethod();
|
||||||
|
if (this.count) m.resetSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Hilbert space",
|
||||||
|
description: "<strong>+142%</strong> <strong class='color-d'>damage</strong><br>after a <strong>collision</strong> enter an <strong class='alt'>alternate reality</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
isAltRealityTech: true,
|
||||||
|
isSkin: true,
|
||||||
|
allowed() {
|
||||||
|
return !tech.isResearchReality && !tech.isSwitchReality
|
||||||
|
},
|
||||||
|
requires: "not Ψ(t) collapse, many-worlds",
|
||||||
|
damage: 2.42,
|
||||||
|
effect() {
|
||||||
|
m.skin.anodize();
|
||||||
|
tech.damage *= this.damage
|
||||||
|
tech.isCollisionRealitySwitch = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
if (this.count) tech.damage /= this.damage
|
||||||
|
tech.isCollisionRealitySwitch = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "aperture",
|
name: "aperture",
|
||||||
description: "every <strong>6</strong> seconds your <strong class='color-d'>damage</strong> cycles<br>between <strong>-10%</strong> and <strong>+110%</strong> <strong class='color-d'>damage</strong>",
|
description: "every <strong>6</strong> seconds your <strong class='color-d'>damage</strong> cycles<br>between <strong>-10%</strong> and <strong>+110%</strong> <strong class='color-d'>damage</strong>",
|
||||||
@@ -460,9 +511,9 @@ const tech = {
|
|||||||
frequency: 4,
|
frequency: 4,
|
||||||
frequencyDefault: 4,
|
frequencyDefault: 4,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.isEnergyHealth
|
return tech.isEnergyHealth && !tech.isOverHeal
|
||||||
},
|
},
|
||||||
requires: "mass-energy equivalence",
|
requires: "mass-energy equivalence, not quenching",
|
||||||
effect() {
|
effect() {
|
||||||
powerUps.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up
|
powerUps.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up
|
||||||
powerUps.heal.color = "#ff0" //"#0ae"
|
powerUps.heal.color = "#ff0" //"#0ae"
|
||||||
@@ -947,30 +998,6 @@ const tech = {
|
|||||||
tech.isFarAwayDmg = false;
|
tech.isFarAwayDmg = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Higgs mechanism",
|
|
||||||
description: "<strong>+45%</strong> <strong><em>fire rate</em></strong><br>while <strong>firing</strong> your <strong>position</strong> is fixed",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
frequencyDefault: 1,
|
|
||||||
allowed() {
|
|
||||||
return !m.isShipMode && !tech.isAlwaysFire
|
|
||||||
},
|
|
||||||
requires: "not ship mode, automatic",
|
|
||||||
effect() {
|
|
||||||
tech.isFireMoveLock = true;
|
|
||||||
b.setFireCD();
|
|
||||||
b.setFireMethod();
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
if (tech.isFireMoveLock) {
|
|
||||||
tech.isFireMoveLock = false
|
|
||||||
b.setFireCD();
|
|
||||||
b.setFireMethod();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "integrated armament",
|
name: "integrated armament",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Weapon' class="link">integrated armament</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Weapon' class="link">integrated armament</a>`,
|
||||||
@@ -1278,21 +1305,21 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "collider",
|
name: "collider",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `after mobs <strong>die</strong> there is a <strong>+50%</strong> chance to<br>collide <strong>power ups</strong> to form different <strong>power ups</strong>`
|
return `after mobs <strong>die</strong> <strong>power ups</strong><br>randomly collide to form different <strong>power ups</strong>`
|
||||||
// return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance to convert<br>${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, ${powerUps.orb.research(1)}, <strong class='color-m'>tech</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>gun</strong> into other types`
|
// return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance to convert<br>${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, ${powerUps.orb.research(1)}, <strong class='color-m'>tech</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>gun</strong> into other types`
|
||||||
},
|
},
|
||||||
|
|
||||||
maxCount: 2,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
frequencyDefault: 1,
|
frequencyDefault: 1,
|
||||||
allowed: () => true,
|
allowed: () => true,
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
tech.collidePowerUps += 0.5
|
tech.collidePowerUps = true
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.collidePowerUps = 0
|
tech.collidePowerUps = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1316,17 +1343,53 @@ const tech = {
|
|||||||
tech.isShieldAmmo = false;
|
tech.isShieldAmmo = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "yield stress",
|
||||||
|
description: "<strong>+55%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
allowed() {
|
||||||
|
return m.fieldMode !== 7 && tech.mobSpawnWithHealth === 0
|
||||||
|
},
|
||||||
|
requires: "not cloaking, reaction inhibitor",
|
||||||
|
effect() {
|
||||||
|
tech.isMobFullHealth = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isMobFullHealth = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cascading failure",
|
||||||
|
description: "<strong>+222%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> below <strong>25%</strong> <strong>health</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 3,
|
||||||
|
frequencyDefault: 3,
|
||||||
|
allowed() {
|
||||||
|
return tech.mobSpawnWithHealth > 0
|
||||||
|
},
|
||||||
|
requires: "reaction inhibitor",
|
||||||
|
effect() {
|
||||||
|
tech.isMobLowHealth = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isMobLowHealth = false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "reaction inhibitor",
|
name: "reaction inhibitor",
|
||||||
description: "<strong>-11%</strong> maximum mob <strong>health</strong>", //<strong class='color-h'>health</strong>
|
description: "<strong>mobs</strong> spawn with <strong>-12%</strong> initial <strong>health</strong>",
|
||||||
maxCount: 3,
|
maxCount: 3,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
frequencyDefault: 1,
|
frequencyDefault: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true //tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner || tech.isMobBlockFling || tech.iceIXOnDeath
|
return !tech.isMobFullHealth
|
||||||
},
|
},
|
||||||
requires: "", //"any mob death tech",
|
requires: "not topological defect",
|
||||||
effect() {
|
effect() {
|
||||||
tech.mobSpawnWithHealth++
|
tech.mobSpawnWithHealth++
|
||||||
mobs.setMobSpawnHealth()
|
mobs.setMobSpawnHealth()
|
||||||
@@ -1343,7 +1406,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "scrap bots",
|
name: "scrap bots",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap bots</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap bots</a>`,
|
||||||
description: "after mobs <strong>die</strong> you have a <strong>+33%</strong> chance<br>to build scrap <strong class='color-bot'>bots</strong> that operate for <strong>13</strong> seconds",
|
description: "after mobs <strong>die</strong> you have a <strong>+33%</strong> chance<br>to build scrap <strong class='color-bot'>bots</strong> that operate for <strong>15</strong> seconds",
|
||||||
maxCount: 3,
|
maxCount: 3,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -1363,7 +1426,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "scrap refit",
|
name: "scrap refit",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap refit</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap refit</a>`,
|
||||||
description: "after mobs <strong>die</strong><br>reset scrap <strong class='color-bot'>bots</strong> to <strong>13</strong> seconds of operation",
|
description: "after mobs <strong>die</strong><br>reset scrap <strong class='color-bot'>bots</strong> to <strong>15</strong> seconds of operation",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 3,
|
frequency: 3,
|
||||||
@@ -3108,9 +3171,9 @@ const tech = {
|
|||||||
frequencyDefault: 1,
|
frequencyDefault: 1,
|
||||||
isHealTech: true,
|
isHealTech: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true
|
return !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "",
|
requires: "not mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isOverHeal = true;
|
tech.isOverHeal = true;
|
||||||
},
|
},
|
||||||
@@ -3121,7 +3184,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "accretion",
|
name: "accretion",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(5)}`
|
return `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(7)}`
|
||||||
},
|
},
|
||||||
// description: `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(5)}`,
|
// description: `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(5)}`,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -3136,7 +3199,7 @@ const tech = {
|
|||||||
effect() {
|
effect() {
|
||||||
tech.isHealAttract = true
|
tech.isHealAttract = true
|
||||||
powerUps.setPowerUpMode();
|
powerUps.setPowerUpMode();
|
||||||
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal");
|
for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal");
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.isHealAttract = false
|
tech.isHealAttract = false
|
||||||
@@ -3295,28 +3358,6 @@ const tech = {
|
|||||||
tech.isImmortal = false;
|
tech.isImmortal = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Hilbert space",
|
|
||||||
description: "<strong>+99%</strong> <strong class='color-d'>damage</strong><br>after a <strong>collision</strong> enter an <strong class='alt'>alternate reality</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
frequencyDefault: 1,
|
|
||||||
isAltRealityTech: true,
|
|
||||||
allowed() {
|
|
||||||
return !tech.isResearchReality && !tech.isSwitchReality
|
|
||||||
},
|
|
||||||
requires: "not Ψ(t) collapse, many-worlds",
|
|
||||||
damage: 1.99,
|
|
||||||
effect() {
|
|
||||||
tech.damage *= this.damage
|
|
||||||
tech.isCollisionRealitySwitch = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
if (this.count) tech.damage /= this.damage
|
|
||||||
tech.isCollisionRealitySwitch = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "many-worlds",
|
name: "many-worlds",
|
||||||
// description: "each <strong>level</strong> is an <strong class='alt'>alternate reality</strong>, where you<br>find a <strong class='color-m'>tech</strong> at the start of each level",
|
// description: "each <strong>level</strong> is an <strong class='alt'>alternate reality</strong>, where you<br>find a <strong class='color-m'>tech</strong> at the start of each level",
|
||||||
@@ -3415,7 +3456,10 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "perturbation theory",
|
name: "perturbation theory",
|
||||||
description: `if you have no ${powerUps.orb.research(1)} in your inventory<br><strong>+70%</strong> <strong><em>fire rate</em></strong>`,
|
description: `if you have no ${powerUps.orb.research(1)} in your inventory<br><strong>+60%</strong> <strong><em>fire rate</em></strong>`,
|
||||||
|
// descriptionFunction() {
|
||||||
|
// return `<strong>+40%</strong> <strong class='color-d'>damage</strong>, but <strong>-10%</strong> <strong class='color-d'>damage</strong><br>for each ${powerUps.orb.research(1)} in your inventory <em>(${40 - 10 * powerUps.research.count}% damage)</em>`
|
||||||
|
// },
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -3426,7 +3470,7 @@ const tech = {
|
|||||||
requires: "no research",
|
requires: "no research",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isRerollHaste = true;
|
tech.isRerollHaste = true;
|
||||||
tech.researchHaste = 0.3;
|
tech.researchHaste = 0.4; //+60% fire rate
|
||||||
b.setFireCD();
|
b.setFireCD();
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
@@ -3482,7 +3526,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "mass production",
|
name: "mass production",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(8)} ${powerUps.orb.heal(8)} or ${powerUps.orb.research(5)}`
|
return `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(10)} ${powerUps.orb.heal(10)} or ${powerUps.orb.research(7)}`
|
||||||
},
|
},
|
||||||
// description: `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(8)} ${powerUps.orb.heal(8)} or ${powerUps.orb.research(5)}`,
|
// description: `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(8)} ${powerUps.orb.heal(8)} or ${powerUps.orb.research(5)}`,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -3500,7 +3544,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "research",
|
name: "research",
|
||||||
description: `spawn ${powerUps.orb.research(5)}`,
|
description: `spawn ${powerUps.orb.research(7)}`,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -3510,13 +3554,13 @@ const tech = {
|
|||||||
allowed() { return true },
|
allowed() { return true },
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
powerUps.spawnDelay("research", 5);
|
powerUps.spawnDelay("research", 7);
|
||||||
},
|
},
|
||||||
remove() { }
|
remove() { }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ammo",
|
name: "ammo",
|
||||||
description: `spawn ${powerUps.orb.ammo(8)}`,
|
description: `spawn ${powerUps.orb.ammo(10)}`,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -3526,14 +3570,14 @@ const tech = {
|
|||||||
allowed() { return true },
|
allowed() { return true },
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
powerUps.spawnDelay("ammo", 8);
|
powerUps.spawnDelay("ammo", 10);
|
||||||
},
|
},
|
||||||
remove() { }
|
remove() { }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "heals",
|
name: "heals",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `spawn ${powerUps.orb.heal(8)}`
|
return `spawn ${powerUps.orb.heal(10)}`
|
||||||
},
|
},
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -3544,7 +3588,7 @@ const tech = {
|
|||||||
allowed() { return true },
|
allowed() { return true },
|
||||||
requires: "mass production",
|
requires: "mass production",
|
||||||
effect() {
|
effect() {
|
||||||
powerUps.spawnDelay("heal", 8);
|
powerUps.spawnDelay("heal", 10);
|
||||||
},
|
},
|
||||||
remove() { }
|
remove() { }
|
||||||
},
|
},
|
||||||
@@ -5339,7 +5383,7 @@ const tech = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "phonon", //longitudinal //gravitational wave?
|
name: "phonon",
|
||||||
description: "waves are low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through <strong>solids</strong>",
|
description: "waves are low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through <strong>solids</strong>",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -6818,7 +6862,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.railChargeRate = 0.97;
|
tech.railChargeRate = 0.97;
|
||||||
tech.harpoonDensity = 0.007
|
tech.harpoonDensity = tech.isRailGun ? 0.007 : 0.004
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -6837,6 +6881,7 @@ const tech = {
|
|||||||
ammoBonus: 9,
|
ammoBonus: 9,
|
||||||
effect() {
|
effect() {
|
||||||
tech.isRailGun = true;
|
tech.isRailGun = true;
|
||||||
|
tech.harpoonDensity = tech.isRailGun ? 0.007 : 0.004
|
||||||
b.guns[9].chooseFireMethod()
|
b.guns[9].chooseFireMethod()
|
||||||
b.guns[9].ammoPack = 5;
|
b.guns[9].ammoPack = 5;
|
||||||
b.guns[9].ammo = b.guns[9].ammo * 6;
|
b.guns[9].ammo = b.guns[9].ammo * 6;
|
||||||
@@ -6845,6 +6890,7 @@ const tech = {
|
|||||||
remove() {
|
remove() {
|
||||||
if (tech.isRailGun) {
|
if (tech.isRailGun) {
|
||||||
tech.isRailGun = false;
|
tech.isRailGun = false;
|
||||||
|
tech.harpoonDensity = tech.isRailGun ? 0.007 : 0.004
|
||||||
b.guns[9].chooseFireMethod()
|
b.guns[9].chooseFireMethod()
|
||||||
b.guns[9].ammoPack = 1.7;
|
b.guns[9].ammoPack = 1.7;
|
||||||
b.guns[9].ammo = Math.ceil(b.guns[9].ammo / 6);
|
b.guns[9].ammo = Math.ceil(b.guns[9].ammo / 6);
|
||||||
@@ -7025,21 +7071,41 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "induction furnace",
|
name: "induction furnace",
|
||||||
description: "after using <strong>harpoon</strong> to collect a <strong>power up</strong><br><strong>+600%</strong> <strong>harpoon</strong> <strong class='color-d'>damage</strong>",
|
description: "after using <strong>harpoon</strong> or <strong>grapple</strong> to collect <strong>power ups</strong><br><strong>+77%</strong> <strong>harpoon</strong> or <strong>grapple</strong> <strong class='color-d'>damage</strong> for 8 seconds",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.haveGunCheck("harpoon") && !tech.isRailGun
|
return ((tech.haveGunCheck("harpoon") && !tech.isRailGun) || m.fieldMode === 10) && !tech.isHarpoonFullHealth
|
||||||
},
|
},
|
||||||
requires: "harpoon, not railgun",
|
requires: "harpoon, grappling hook, not railgun, brittle",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isHarpoonPowerUp = true
|
tech.isHarpoonPowerUp = true
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.isHarpoonPowerUp = false
|
tech.isHarpoonPowerUp = false
|
||||||
|
tech.harpoonPowerUpCycle = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "brittle",
|
||||||
|
description: "<strong>+88%</strong> <strong>harpoon</strong> and <strong>grapple</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return (tech.haveGunCheck("harpoon") || m.fieldMode === 10) && !tech.isHarpoonPowerUp
|
||||||
|
},
|
||||||
|
requires: "harpoon, grappling hook, not induction furnace",
|
||||||
|
effect() {
|
||||||
|
tech.isHarpoonFullHealth = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isHarpoonFullHealth = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -7437,7 +7503,7 @@ const tech = {
|
|||||||
//**************************************************
|
//**************************************************
|
||||||
{
|
{
|
||||||
name: "spherical harmonics",
|
name: "spherical harmonics",
|
||||||
description: "<strong>+50%</strong> <strong>standing wave</strong> deflection efficiency<br>shield deflection radius maintains it's maximum range", //<strong>standing wave</strong> oscillates in a 3rd dimension<br>
|
description: "<strong>+50%</strong> <strong>standing wave</strong> deflection efficiency<br>shield deflection radius holds it's max range", //<strong>standing wave</strong> oscillates in a 3rd dimension<br>
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8133,7 +8199,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "degenerate matter",
|
name: "degenerate matter",
|
||||||
description: "if your <strong class='color-f'>field</strong> is active<br><strong>+85%</strong> <strong class='color-defense'>defense</strong>",
|
description: "if your <strong class='color-f'>field</strong> is active<br><strong>+88%</strong> <strong class='color-defense'>defense</strong>",
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8400,7 +8466,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "no-cloning theorem",
|
name: "no-cloning theorem",
|
||||||
// descriptionFunction() { return `<strong>+45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>–2%</strong> <strong class='color-dup'>duplication</strong> <em>(${tech.duplicationChance()})</em>` },
|
// descriptionFunction() { return `<strong>+45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>–2%</strong> <strong class='color-dup'>duplication</strong> <em>(${tech.duplicationChance()})</em>` },
|
||||||
description: `<strong>+45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>–2%</strong> <strong class='color-dup'>duplication</strong>`,
|
description: `<strong>+40%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>–1%</strong> <strong class='color-dup'>duplication</strong>`,
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8411,7 +8477,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
requires: "cloaking, time dilation",
|
requires: "cloaking, time dilation",
|
||||||
effect() {
|
effect() {
|
||||||
tech.cloakDuplication = 0.45
|
tech.cloakDuplication = 0.4
|
||||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
|
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
|
||||||
},
|
},
|
||||||
@@ -8423,7 +8489,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "metamaterial absorber", //quantum eraser
|
name: "metamaterial absorber", //quantum eraser
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>there is a <strong>17%</strong> chance to spawn a random <strong>power up</strong>`
|
return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>there is a <strong>22%</strong> chance to spawn a random <strong>power up</strong>`
|
||||||
},
|
},
|
||||||
// descriptionFunction() {
|
// descriptionFunction() {
|
||||||
// return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>`
|
// return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>`
|
||||||
@@ -8447,7 +8513,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "symbiosis",
|
name: "symbiosis",
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(3)}${powerUps.orb.heal(3)} and a <strong class='color-m'>tech</strong><br>after a <strong>mob</strong> <strong>dies</strong> <strong>–0.5</strong> maximum ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}`
|
return `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(4)}${powerUps.orb.heal(3)} and a <strong class='color-m'>tech</strong><br>after a <strong>mob</strong> <strong>dies</strong> <strong>–0.5</strong> maximum ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}`
|
||||||
},
|
},
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -8491,7 +8557,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "patch",
|
name: "patch",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Patch_(computing)' class="link">patch</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Patch_(computing)' class="link">patch</a>`,
|
||||||
description: "after <strong class='color-cloaked'>cloaking</strong> recover <strong>75%</strong> of your<br>last <strong class='color-h'>health</strong> loss using that much <strong class='color-f'>energy</strong>",
|
description: "after <strong class='color-cloaked'>cloaking</strong> recover <strong>75%</strong><br>of your last <strong class='color-h'>health</strong> lost",
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8528,6 +8594,25 @@ const tech = {
|
|||||||
tech.isCloakStun = false;
|
tech.isCloakStun = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "topological defect",
|
||||||
|
description: "<strong>+88%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||||
|
isFieldTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
allowed() {
|
||||||
|
return (m.fieldMode === 8 || m.fieldMode === 7) && tech.mobSpawnWithHealth === 0 && !tech.isMobFullHealth
|
||||||
|
},
|
||||||
|
requires: "cloaking, pilot wave, not reaction inhibitor, yield stress",
|
||||||
|
effect() {
|
||||||
|
tech.isMobFullHealthCloak = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isMobFullHealthCloak = false
|
||||||
|
}
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// name: "ambush",
|
// name: "ambush",
|
||||||
// description: "metamaterial cloaking field <strong class='color-d'>damage</strong> effect<br>is increased from <span style = 'text-decoration: line-through;'>333%</span> to <strong>555%</strong>",
|
// description: "metamaterial cloaking field <strong class='color-d'>damage</strong> effect<br>is increased from <span style = 'text-decoration: line-through;'>333%</span> to <strong>555%</strong>",
|
||||||
@@ -9192,6 +9277,23 @@ const tech = {
|
|||||||
},
|
},
|
||||||
remove() { }
|
remove() { }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "planned obsolescence",
|
||||||
|
description: "build <strong>100</strong> scrap <strong class='color-bot'>bots</strong><br>bots might last for <strong>30</strong> seconds",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 0,
|
||||||
|
isJunk: true,
|
||||||
|
allowed: () => true,
|
||||||
|
requires: "",
|
||||||
|
effect() {
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
b.randomBot(m.pos, false)
|
||||||
|
bullet[bullet.length - 1].endCycle = simulation.cycle + 800 + 1000 * Math.random() //15 seconds
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove() { }
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// name: "synchrotron",
|
// name: "synchrotron",
|
||||||
// descriptionFunction() {
|
// descriptionFunction() {
|
||||||
@@ -11921,4 +12023,9 @@ const tech = {
|
|||||||
isHookExplosion: null,
|
isHookExplosion: null,
|
||||||
isHarpoonDefense: null,
|
isHarpoonDefense: null,
|
||||||
isReel: null,
|
isReel: null,
|
||||||
|
harpoonPowerUpCycle: null,
|
||||||
|
isHarpoonFullHealth: null,
|
||||||
|
isMobFullHealth: null,
|
||||||
|
isMobFullHealthCloak: null,
|
||||||
|
isMobLowHealth: null
|
||||||
}
|
}
|
||||||
154
todo.txt
154
todo.txt
@@ -1,24 +1,64 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
why mode is now 20% easier, but still 25% harder than hard mode
|
mob health tech
|
||||||
easy:1, normal:2, hard:4, why:6->5
|
tech: cascading failure - +222% damage to mobs below 25% health
|
||||||
|
tech: yield stress - +55% damage to mobs at maximum health
|
||||||
|
cloaking tech: topological defect - +88% damage to mobs at maximum health
|
||||||
|
harpoon tech: brittle - +88% harpoon/grapple damage to mobs at maximum health
|
||||||
|
|
||||||
new community map unchartedCave by 3xionDev!
|
cloaking buffs
|
||||||
|
50->66% defense while cloaked
|
||||||
|
recloak 0.25s faster
|
||||||
|
simplified cloaking field graphics
|
||||||
|
boson composite drains much less energy while moving through mobs and shields
|
||||||
|
fixed bug where mines and egg mobs were colliding with player while intangible
|
||||||
|
patch no longer drains energy when you heal on cloaking
|
||||||
|
metamaterial absorber gets 17->22% chance to spawn a power up for each mob alive
|
||||||
|
no-cloning theorem changes to 45->40% duplication and 2->1% duplication loss on killing a mob
|
||||||
|
|
||||||
Newtons 1st law 66->88% defense when moving fast
|
finalBoss phases:
|
||||||
Newtons 2nd law 66->88% damage when moving fast
|
new: slow zone, antigravity pulse
|
||||||
CIWS energy 20->18 per shot
|
nerfed: laser, black hole, orbitals
|
||||||
rupture disables reel and tokamak
|
buffed: oscillation, mobs
|
||||||
|
improved graphics: boulder
|
||||||
|
|
||||||
|
Hilbert space has a skin. 99->142% damage increase, but randomize tech after taking damage
|
||||||
|
Higgs mechanism has a skin. +45->77% fire rate, player can't move while firing
|
||||||
|
induction furnace gives +77% harpoon/grapple damage for 8 seconds after picking up a power up
|
||||||
|
collider 50->100% chance to combine and randomize power ups
|
||||||
|
quenching gives more bonus max health at high difficulty level (maybe around 30% more health)
|
||||||
|
accretion gives 5->7 heal power ups
|
||||||
|
dynamo bots follow player much closer when you have many of them
|
||||||
|
scrap-bots don't follow the player as accurately or as quickly
|
||||||
|
scrap bot duration 13->15 seconds
|
||||||
|
JUNK tech: planned obsolescence - make 100 scrap bots that last for about 30 seconds
|
||||||
|
|
||||||
|
community map dojo by werid_pusheen
|
||||||
|
fixed by Cornbread 2100
|
||||||
|
|
||||||
|
hard mode gets 1 less heal at the start
|
||||||
|
hard and why difficulty don't begin with starter mobs
|
||||||
|
hopBullet mobs last 2 seconds less time
|
||||||
|
adjusted button heights on train station level to be consistently the same height
|
||||||
|
|
||||||
*********************************************************** TODO *****************************************************
|
*********************************************************** TODO *****************************************************
|
||||||
|
|
||||||
|
hexagon head skin
|
||||||
|
maybe give defense
|
||||||
|
|
||||||
scrap bots don't follow player
|
|
||||||
adjust spawn rates to balance
|
|
||||||
|
|
||||||
|
foam tech: increase size of foam and increase duration, but drop speed down, so they come to a stop and just hang
|
||||||
|
allow them to harm player?
|
||||||
|
this is probably just too annoying
|
||||||
|
|
||||||
|
make a flutter variant
|
||||||
|
just move the wings to the back?
|
||||||
|
slow flap, and acceleration that increases when the flap occurs, like swimming
|
||||||
|
|
||||||
make grappling hook of different shapes
|
make grappling hook of different shapes
|
||||||
|
shapes
|
||||||
|
longer
|
||||||
|
circular with spikes
|
||||||
indicate tech upgrades?
|
indicate tech upgrades?
|
||||||
rupture, reel, tokamak
|
rupture, reel, tokamak
|
||||||
do this in draw or in verticies?
|
do this in draw or in verticies?
|
||||||
@@ -31,8 +71,6 @@ grappling hook field
|
|||||||
field tech ideas
|
field tech ideas
|
||||||
Buoyancy - aerostat, but for defense: +70% defense while off the ground
|
Buoyancy - aerostat, but for defense: +70% defense while off the ground
|
||||||
too similar to degenerate matter
|
too similar to degenerate matter
|
||||||
generate ___ after destroying blocks
|
|
||||||
energy, drones, iceIX, explosion, nails, junk bots?
|
|
||||||
|
|
||||||
tech - killing a mob heals for the last damage you took
|
tech - killing a mob heals for the last damage you took
|
||||||
disable cloaking heal? maybe you don't need to disable, just don't heal twice
|
disable cloaking heal? maybe you don't need to disable, just don't heal twice
|
||||||
@@ -43,9 +81,6 @@ on sucker mob death trigger radiation damage AoE and a graphic (Hawking radiati
|
|||||||
|
|
||||||
tech prismatic laser - cycles between different laser colors every 1-2 seconds
|
tech prismatic laser - cycles between different laser colors every 1-2 seconds
|
||||||
|
|
||||||
make phonon the default wave gun type and make a tech to switch to the normal wave beam
|
|
||||||
nerf phonon, buff wave
|
|
||||||
|
|
||||||
sword slash for plasma torch (giving up on this for now, had trouble making graphics look good)
|
sword slash for plasma torch (giving up on this for now, had trouble making graphics look good)
|
||||||
activates when mouse is close to player
|
activates when mouse is close to player
|
||||||
gradual activation
|
gradual activation
|
||||||
@@ -83,12 +118,6 @@ use cross product rotation for other mobs?
|
|||||||
|
|
||||||
super-bot: fires super balls
|
super-bot: fires super balls
|
||||||
|
|
||||||
tech - only allow 1,2 turrets at time. spawning a new mine removes the oldest mine
|
|
||||||
turrets never run out of ammo
|
|
||||||
or turrets automatically use one of your mine ammos when they run out?
|
|
||||||
good with multi gun builds
|
|
||||||
conflict with booby trap?
|
|
||||||
|
|
||||||
tech: after a needle hits a mobs
|
tech: after a needle hits a mobs
|
||||||
the needle splits into 3 needles?
|
the needle splits into 3 needles?
|
||||||
reset your fire CD?
|
reset your fire CD?
|
||||||
@@ -183,32 +212,6 @@ hookBoss fires a hook that pulls player towards it
|
|||||||
player targeted unless cloaking
|
player targeted unless cloaking
|
||||||
also add effect to finalBoss
|
also add effect to finalBoss
|
||||||
|
|
||||||
finalBoss
|
|
||||||
add synergies between modes:
|
|
||||||
new modes:
|
|
||||||
something that needs to be killed quickly
|
|
||||||
if you don't kill it boss gets a shield
|
|
||||||
rotating quadrant immunity shield, can't take damage from that quadrant
|
|
||||||
maybe also attack player near that quadrant
|
|
||||||
but how to tell the angle of incoming damage
|
|
||||||
maybe a physics body like the shield but it only covers 1/3 of mob?
|
|
||||||
falling object warps to ceiling after hitting floor
|
|
||||||
doesn't end, player needs to kill it
|
|
||||||
slowly grows?
|
|
||||||
slow effect zones
|
|
||||||
random placement or place over player or both!
|
|
||||||
draw white dot and an outline of area of effect
|
|
||||||
expanding circle stroke, freeze effect triggers when stroke circle hits fill circle
|
|
||||||
after 1-2 seconds freeze player if in the zone
|
|
||||||
also freeze mobs
|
|
||||||
effect that makes player have to be close to boss
|
|
||||||
hook that tries to yank the player into hitting finalBoss
|
|
||||||
does damage
|
|
||||||
pulls player into center
|
|
||||||
counter with wormhole, negative mass
|
|
||||||
player targeted unless cloaking
|
|
||||||
|
|
||||||
|
|
||||||
mob status effect - emit - mobs fire lasers for a few seconds
|
mob status effect - emit - mobs fire lasers for a few seconds
|
||||||
tech: phosphorescence - mobs emit after being hit with laser beams
|
tech: phosphorescence - mobs emit after being hit with laser beams
|
||||||
|
|
||||||
@@ -226,7 +229,7 @@ tech increase max energy and energy to 5000, but you can no longer regen energy
|
|||||||
it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing
|
it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing
|
||||||
add some css based visual effects for opening up a tech,gun,field
|
add some css based visual effects for opening up a tech,gun,field
|
||||||
|
|
||||||
make a new coupling effect for perfect diamagnetism or standing wave
|
make a new coupling effect for perfect diamagnetism
|
||||||
|
|
||||||
make a faster smaller version of cell boss that also has map collisions
|
make a faster smaller version of cell boss that also has map collisions
|
||||||
|
|
||||||
@@ -237,22 +240,11 @@ JUNK tech description that changes similar to cards in inscription
|
|||||||
that changes based on mouse position
|
that changes based on mouse position
|
||||||
can you tell if mouse is over card?
|
can you tell if mouse is over card?
|
||||||
|
|
||||||
tech - buff MACHO range, effect, move speed?
|
|
||||||
while you are inside MACHO it will damage mobs?
|
|
||||||
|
|
||||||
PWA?
|
PWA?
|
||||||
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps
|
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps
|
||||||
https://codeburst.io/how-to-easily-turn-your-static-website-to-a-progressive-web-app-pwa-b0af08da9693
|
https://codeburst.io/how-to-easily-turn-your-static-website-to-a-progressive-web-app-pwa-b0af08da9693
|
||||||
https://github.com/landgreen/n-gon/pull/32/files
|
https://github.com/landgreen/n-gon/pull/32/files
|
||||||
|
|
||||||
bug blocks and power ups falling through map
|
|
||||||
always foam gun (4-5 times)
|
|
||||||
might be about tech pressure vessel
|
|
||||||
happens rarely, doesn't repeat
|
|
||||||
only occurs for 3 people so far
|
|
||||||
normally after level 6
|
|
||||||
occurred once on the first level, didn't fire gun and was able to walk through a body
|
|
||||||
|
|
||||||
Tech:when relay switch/flip flop is on, turn ammo powerups into boosts, when relay swicth/flip flop is off, ammo powerups remain ammo powerups
|
Tech:when relay switch/flip flop is on, turn ammo powerups into boosts, when relay swicth/flip flop is off, ammo powerups remain ammo powerups
|
||||||
or toggle other power ups
|
or toggle other power ups
|
||||||
health/ammo
|
health/ammo
|
||||||
@@ -260,9 +252,6 @@ Tech:when relay switch/flip flop is on, turn ammo powerups into boosts, when rel
|
|||||||
JUNK: what the golf?
|
JUNK: what the golf?
|
||||||
trying to throw a block throws you instead
|
trying to throw a block throws you instead
|
||||||
|
|
||||||
tech for lens - you can only fire through the lens
|
|
||||||
and some buff? damage or energy?
|
|
||||||
|
|
||||||
complete blowSuckBoss... or don't
|
complete blowSuckBoss... or don't
|
||||||
|
|
||||||
tech: laser reflections increase damage
|
tech: laser reflections increase damage
|
||||||
@@ -272,18 +261,6 @@ JUNK tech different effects based on night or day
|
|||||||
|
|
||||||
Boss that shoots out a ring of bullets, then after a few seconds it gravitates the bullets back
|
Boss that shoots out a ring of bullets, then after a few seconds it gravitates the bullets back
|
||||||
|
|
||||||
coupling
|
|
||||||
put coupling description as 4th line on field description
|
|
||||||
raw text no function call
|
|
||||||
no need for coupling description in power ups, pause
|
|
||||||
negative coupling?
|
|
||||||
wouldn't work for iceIX
|
|
||||||
coupling tech
|
|
||||||
names: strongly coupled, Vibronic coupling, NMR coupling
|
|
||||||
tech: +x% field coupling, your field changes randomly every y seconds
|
|
||||||
tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use
|
|
||||||
some fields aren't used much (that's ok?)
|
|
||||||
|
|
||||||
tech give laser mines more lasers (3->4? 5?)
|
tech give laser mines more lasers (3->4? 5?)
|
||||||
|
|
||||||
rewindBoss: after hitting 1/5 damage thresholds the boss rewinds back in time to where it was a few seconds ago
|
rewindBoss: after hitting 1/5 damage thresholds the boss rewinds back in time to where it was a few seconds ago
|
||||||
@@ -307,11 +284,6 @@ immediately fire all of your ammo
|
|||||||
after taking damage explode while invulnerable
|
after taking damage explode while invulnerable
|
||||||
scale explosion radius with damage
|
scale explosion radius with damage
|
||||||
|
|
||||||
quantum immortality: send you to a new tab after you die with a random load out
|
|
||||||
basically everything is the same as it is now, but you switch tabs
|
|
||||||
|
|
||||||
Tech: Tech/guns/fields can no longer be duplicated. Duplication applies twice
|
|
||||||
|
|
||||||
tech: get sent to a new tab that closes in 3 minutes
|
tech: get sent to a new tab that closes in 3 minutes
|
||||||
in the new tab you play reactor
|
in the new tab you play reactor
|
||||||
if you die in reactor you die in game, if you win you get 2-3 tech in the original game?
|
if you die in reactor you die in game, if you win you get 2-3 tech in the original game?
|
||||||
@@ -319,31 +291,8 @@ tech: get sent to a new tab that closes in 3 minutes
|
|||||||
count guns, field, tech and give random stuff on new tab
|
count guns, field, tech and give random stuff on new tab
|
||||||
i-frame instead of tab?
|
i-frame instead of tab?
|
||||||
|
|
||||||
reduce the amount of research and nerf anti randomization tech
|
|
||||||
increase possible synergies that go nuts
|
|
||||||
|
|
||||||
tech expansion: field coupling also expands each fields in different ways
|
|
||||||
how to make the description work
|
|
||||||
change description based on your current field?
|
|
||||||
perfect diamagnetism moves forward when you hold down the shield
|
|
||||||
it's great, but maybe annoying?
|
|
||||||
maybe only with crouch?
|
|
||||||
perfect diamagnetism just replace or increase Messier effect
|
|
||||||
time dilation drains 1/2 as much energy when paused
|
|
||||||
grow plasma torch as you hold it down
|
|
||||||
negative mass effects much more space
|
|
||||||
needs more benefit?
|
|
||||||
reduces the cloaking vision effect?
|
|
||||||
needs more benefit?
|
|
||||||
|
|
||||||
tech: missiles explode a 2nd time after 1/2 a second (with a slightly different position determined by original velocity)
|
tech: missiles explode a 2nd time after 1/2 a second (with a slightly different position determined by original velocity)
|
||||||
|
|
||||||
The tech that makes blocks that fall into a wormhole give energy should scale with block size, with the same formula as tokomak
|
|
||||||
|
|
||||||
junk suggestion: useless machine - ejects itself and removes itself from the item pool
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
seed isn't working right from shared URL
|
seed isn't working right from shared URL
|
||||||
|
|
||||||
mob mechanics
|
mob mechanics
|
||||||
@@ -359,8 +308,6 @@ mob mechanics
|
|||||||
spawns new nodes
|
spawns new nodes
|
||||||
draws connections as quad lines
|
draws connections as quad lines
|
||||||
|
|
||||||
tech: You can place an extra perfect diamagnatism field on the map
|
|
||||||
|
|
||||||
standing wave no longer pushes mobs away, but it can do damage to mobs caught in area effect
|
standing wave no longer pushes mobs away, but it can do damage to mobs caught in area effect
|
||||||
Standing wave harmonics no longer deflects, but instead discharges excess energy as lightning toward nearby enemies
|
Standing wave harmonics no longer deflects, but instead discharges excess energy as lightning toward nearby enemies
|
||||||
negative mass field does damage to mobs inside field
|
negative mass field does damage to mobs inside field
|
||||||
@@ -1157,6 +1104,7 @@ possible names for tech
|
|||||||
Josephson junction - superconducting junction
|
Josephson junction - superconducting junction
|
||||||
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
|
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
|
||||||
perturbation
|
perturbation
|
||||||
|
Unruh effect - accelerating makes heat/thermal particles
|
||||||
|
|
||||||
******************************************************** CARS IMAGES ********************************************************
|
******************************************************** CARS IMAGES ********************************************************
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user