abiogenesis
tech: abiogenesis - spawn a second level boss on each level, but costs 5 research or if you don't have the research add 49 JUNK tech to the pool note to level builders I rewrote the add duplicate boss code in all levels: spawn.secondaryBossChance(x,y) foam tech: uncertainty principle - foam bullets change position randomly, increase foam damage by 66% throwing blocks now charges faster with reduced fire cooldown tech renormalization now has a 40% chance to refund a research (was 37%) performance- now precalculate player gradient fill
This commit is contained in:
102
js/bullet.js
102
js/bullet.js
@@ -216,18 +216,18 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
fireProps(cd, speed, dir, me) {
|
fireProps(cd, speed, dir, me) {
|
||||||
m.fireCDcycle = m.cycle + Math.floor(cd * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(cd * b.fireCDscale); // cool down
|
||||||
Matter.Body.setVelocity(bullet[me], {
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
x: m.Vx / 2 + speed * Math.cos(dir),
|
x: m.Vx / 2 + speed * Math.cos(dir),
|
||||||
y: m.Vy / 2 + speed * Math.sin(dir)
|
y: m.Vy / 2 + speed * Math.sin(dir)
|
||||||
});
|
});
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
},
|
},
|
||||||
fireCD: 1,
|
fireCDscale: 1,
|
||||||
setFireCD() {
|
setFireCD() {
|
||||||
b.fireCD = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime
|
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime
|
||||||
if (tech.isFireRateForGuns) b.fireCD *= Math.pow(0.86, b.inventory.length)
|
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.86, b.inventory.length)
|
||||||
if (tech.isFireMoveLock) b.fireCD *= 0.5
|
if (tech.isFireMoveLock) b.fireCDscale *= 0.5
|
||||||
},
|
},
|
||||||
fireAttributes(dir, rotate = true) {
|
fireAttributes(dir, rotate = true) {
|
||||||
if (rotate) {
|
if (rotate) {
|
||||||
@@ -2435,7 +2435,7 @@ const b = {
|
|||||||
// friction: 0.2,
|
// friction: 0.2,
|
||||||
// restitution: 0.2,
|
// restitution: 0.2,
|
||||||
dmg: 0, //damage on impact
|
dmg: 0, //damage on impact
|
||||||
damage: tech.isFastFoam ? 0.048 : 0.012, //damage done over time
|
damage: (tech.isFastFoam ? 0.048 : 0.012) * (tech.isFoamTeleport ? 1.66 : 1), //damage done over time
|
||||||
scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.6 : 1),
|
scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.6 : 1),
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
@@ -2449,6 +2449,8 @@ const b = {
|
|||||||
target: null,
|
target: null,
|
||||||
targetVertex: null,
|
targetVertex: null,
|
||||||
targetRelativePosition: null,
|
targetRelativePosition: null,
|
||||||
|
portFrequency: 5 + Math.floor(5 * Math.random()),
|
||||||
|
nextPortCycle: Infinity, //disabled unless you have the teleport tech
|
||||||
beforeDmg(who) {
|
beforeDmg(who) {
|
||||||
if (!this.target && who.alive) {
|
if (!this.target && who.alive) {
|
||||||
this.target = who;
|
this.target = who;
|
||||||
@@ -2494,6 +2496,8 @@ const b = {
|
|||||||
if (this.radius < 8) this.endCycle = 0;
|
if (this.radius < 8) this.endCycle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (this.target && this.target.alive) { //if stuck to a target
|
if (this.target && this.target.alive) { //if stuck to a target
|
||||||
const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector
|
const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector
|
||||||
if (this.target.isVerticesChange) {
|
if (this.target.isVerticesChange) {
|
||||||
@@ -2577,9 +2581,15 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport
|
||||||
|
this.nextPortCycle = simulation.cycle + this.portFrequency
|
||||||
|
const range = 10 * Math.sqrt(this.radius) * Math.random()
|
||||||
|
Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (tech.isFoamTeleport) bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
Matter.Body.setVelocity(bullet[me], velocity);
|
Matter.Body.setVelocity(bullet[me], velocity);
|
||||||
},
|
},
|
||||||
@@ -3502,9 +3512,9 @@ const b = {
|
|||||||
fireNormal() {
|
fireNormal() {
|
||||||
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
|
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
|
||||||
const CD = Math.max(11 - 0.06 * (m.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down
|
const CD = Math.max(11 - 0.06 * (m.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down
|
||||||
this.nextFireCycle = m.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down
|
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
|
||||||
|
|
||||||
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
|
||||||
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
||||||
},
|
},
|
||||||
fireNeedles() {
|
fireNeedles() {
|
||||||
@@ -3575,13 +3585,13 @@ const b = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
m.fireCDcycle = m.cycle + 45 * b.fireCD; // cool down
|
m.fireCDcycle = m.cycle + 45 * b.fireCDscale; // cool down
|
||||||
makeNeedle()
|
makeNeedle()
|
||||||
for (let i = 1; i < 4; i++) { //4 total needles
|
for (let i = 1; i < 4; i++) { //4 total needles
|
||||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m.fireCDcycle = m.cycle + 25 * b.fireCD; // cool down
|
m.fireCDcycle = m.cycle + 25 * b.fireCDscale; // cool down
|
||||||
makeNeedle()
|
makeNeedle()
|
||||||
for (let i = 1; i < 3; i++) { //3 total needles
|
for (let i = 1; i < 3; i++) { //3 total needles
|
||||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||||
@@ -3595,7 +3605,7 @@ const b = {
|
|||||||
// makeNeedle(m.angle - spread)
|
// makeNeedle(m.angle - spread)
|
||||||
},
|
},
|
||||||
fireRivets() {
|
fireRivets() {
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCDscale); // cool down
|
||||||
|
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const size = tech.rivetSize * 7.5
|
const size = tech.rivetSize * 7.5
|
||||||
@@ -3640,13 +3650,13 @@ const b = {
|
|||||||
fireNailFireRate() {
|
fireNailFireRate() {
|
||||||
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
|
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
|
||||||
const CD = Math.max(7.5 - 0.06 * (m.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down
|
const CD = Math.max(7.5 - 0.06 * (m.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down
|
||||||
this.nextFireCycle = m.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down
|
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
|
||||||
|
|
||||||
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
|
||||||
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
||||||
},
|
},
|
||||||
fireInstantFireRate() {
|
fireInstantFireRate() {
|
||||||
m.fireCDcycle = m.cycle + Math.floor(2 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(2 * b.fireCDscale); // cool down
|
||||||
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / 2)
|
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / 2)
|
||||||
},
|
},
|
||||||
baseFire(angle) {
|
baseFire(angle) {
|
||||||
@@ -3685,18 +3695,18 @@ const b = {
|
|||||||
let knock, spread
|
let knock, spread
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
spread = 0.65
|
spread = 0.65
|
||||||
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down
|
||||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to damage for 30 cycles
|
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCDscale); //player is immune to damage for 30 cycles
|
||||||
knock = 0.01
|
knock = 0.01
|
||||||
} else {
|
} else {
|
||||||
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCDscale); // cool down
|
||||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCD); //player is immune to damage for 30 cycles
|
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCDscale); //player is immune to damage for 30 cycles
|
||||||
spread = 1.3
|
spread = 1.3
|
||||||
knock = 0.1
|
knock = 0.1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tech.isShotgunRecoil) {
|
if (tech.isShotgunRecoil) {
|
||||||
m.fireCDcycle -= 0.66 * (45 * b.fireCD)
|
m.fireCDcycle -= 0.66 * (45 * b.fireCDscale)
|
||||||
player.force.x -= 2 * knock * Math.cos(m.angle)
|
player.force.x -= 2 * knock * Math.cos(m.angle)
|
||||||
player.force.y -= 2 * knock * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
|
player.force.y -= 2 * knock * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
|
||||||
} else {
|
} else {
|
||||||
@@ -3848,7 +3858,7 @@ const b = {
|
|||||||
do() {},
|
do() {},
|
||||||
fireOne() {
|
fireOne() {
|
||||||
const SPEED = m.crouch ? 43 : 36
|
const SPEED = m.crouch ? 43 : 36
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
|
||||||
let dir = m.angle
|
let dir = m.angle
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false));
|
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false));
|
||||||
@@ -3875,7 +3885,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
fireMulti() {
|
fireMulti() {
|
||||||
const SPEED = m.crouch ? 43 : 36
|
const SPEED = m.crouch ? 43 : 36
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
|
||||||
const SPREAD = m.crouch ? 0.08 : 0.13
|
const SPREAD = m.crouch ? 0.08 : 0.13
|
||||||
let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2;
|
let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2;
|
||||||
for (let i = 0; i < tech.superBallNumber; i++) {
|
for (let i = 0; i < tech.superBallNumber; i++) {
|
||||||
@@ -3908,7 +3918,7 @@ const b = {
|
|||||||
const dir = m.angle
|
const dir = m.angle
|
||||||
const x = m.pos.x + 30 * Math.cos(m.angle)
|
const x = m.pos.x + 30 * Math.cos(m.angle)
|
||||||
const y = m.pos.y + 30 * Math.sin(m.angle)
|
const y = m.pos.y + 30 * Math.sin(m.angle)
|
||||||
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCD)
|
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale)
|
||||||
m.fireCDcycle = m.cycle + delay; // cool down
|
m.fireCDcycle = m.cycle + delay; // cool down
|
||||||
|
|
||||||
for (let i = 0; i < tech.superBallNumber; i++) {
|
for (let i = 0; i < tech.superBallNumber; i++) {
|
||||||
@@ -3960,7 +3970,7 @@ const b = {
|
|||||||
do() {
|
do() {
|
||||||
if (this.wavePacketCycle && !input.fire) {
|
if (this.wavePacketCycle && !input.fire) {
|
||||||
this.wavePacketCycle = 0;
|
this.wavePacketCycle = 0;
|
||||||
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
damage: 1,
|
damage: 1,
|
||||||
@@ -4060,7 +4070,7 @@ const b = {
|
|||||||
//fire a packet of bullets then delay for a while
|
//fire a packet of bullets then delay for a while
|
||||||
this.wavePacketCycle++
|
this.wavePacketCycle++
|
||||||
if (this.wavePacketCycle > tech.wavePacketLength) {
|
if (this.wavePacketCycle > tech.wavePacketLength) {
|
||||||
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
|
||||||
this.wavePacketCycle = 0;
|
this.wavePacketCycle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4076,7 +4086,7 @@ const b = {
|
|||||||
fire() {
|
fire() {
|
||||||
const countReduction = Math.pow(0.9, tech.missileCount)
|
const countReduction = Math.pow(0.9, tech.missileCount)
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
m.fireCDcycle = m.cycle + 10 * b.fireCD / countReduction; // cool down
|
m.fireCDcycle = m.cycle + 10 * b.fireCDscale / countReduction; // cool down
|
||||||
|
|
||||||
// for (let i = 0; i < tech.missileCount; i++) {
|
// for (let i = 0; i < tech.missileCount; i++) {
|
||||||
// b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5) * Math.sqrt(tech.missileCount), -2, Math.sqrt(countReduction))
|
// b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5) * Math.sqrt(tech.missileCount), -2, Math.sqrt(countReduction))
|
||||||
@@ -4102,7 +4112,7 @@ const b = {
|
|||||||
b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5), -2)
|
b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5), -2)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m.fireCDcycle = m.cycle + 50 * b.fireCD / countReduction; // cool down
|
m.fireCDcycle = m.cycle + 50 * b.fireCDscale / countReduction; // cool down
|
||||||
const direction = {
|
const direction = {
|
||||||
x: Math.cos(m.angle),
|
x: Math.cos(m.angle),
|
||||||
y: Math.sin(m.angle)
|
y: Math.sin(m.angle)
|
||||||
@@ -4147,7 +4157,7 @@ const b = {
|
|||||||
// bullet[bullet.length - 1].force.x -= 0.015 * (i - 1);
|
// bullet[bullet.length - 1].force.x -= 0.015 * (i - 1);
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// m.fireCDcycle = m.cycle + 80 * b.fireCD; // cool down
|
// m.fireCDcycle = m.cycle + 80 * b.fireCDscale; // cool down
|
||||||
// const direction = {
|
// const direction = {
|
||||||
// x: Math.cos(m.angle),
|
// x: Math.cos(m.angle),
|
||||||
// y: Math.sin(m.angle)
|
// y: Math.sin(m.angle)
|
||||||
@@ -4164,7 +4174,7 @@ const b = {
|
|||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// if (m.crouch) {
|
// if (m.crouch) {
|
||||||
// m.fireCDcycle = m.cycle + 10 * b.fireCD; // cool down
|
// m.fireCDcycle = m.cycle + 10 * b.fireCDscale; // cool down
|
||||||
// const off = Math.random() - 0.5
|
// const off = Math.random() - 0.5
|
||||||
// b.missile({
|
// b.missile({
|
||||||
// x: m.pos.x,
|
// x: m.pos.x,
|
||||||
@@ -4174,7 +4184,7 @@ const b = {
|
|||||||
// bullet[bullet.length - 1].force.x += off * 0.03;
|
// bullet[bullet.length - 1].force.x += off * 0.03;
|
||||||
// // bullet[bullet.length - 1].force.y += push.y * (i - 1);
|
// // bullet[bullet.length - 1].force.y += push.y * (i - 1);
|
||||||
// } else {
|
// } else {
|
||||||
// m.fireCDcycle = m.cycle + 55 * b.fireCD; // cool down
|
// m.fireCDcycle = m.cycle + 55 * b.fireCDscale; // cool down
|
||||||
|
|
||||||
// // bullet[bullet.length - 1].force.y += 0.01; //a small push down at first to make it seem like the missile is briefly falling
|
// // bullet[bullet.length - 1].force.y += 0.01; //a small push down at first to make it seem like the missile is briefly falling
|
||||||
// }
|
// }
|
||||||
@@ -4189,7 +4199,7 @@ const b = {
|
|||||||
have: false,
|
have: false,
|
||||||
do() {},
|
do() {},
|
||||||
fire() {
|
fire() {
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale); // cool down
|
||||||
b.grenade()
|
b.grenade()
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
@@ -4218,7 +4228,7 @@ const b = {
|
|||||||
y: speed * Math.sin(m.angle)
|
y: speed * Math.sin(m.angle)
|
||||||
}, 0, tech.isMineAmmoBack)
|
}, 0, tech.isMineAmmoBack)
|
||||||
}
|
}
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 50 : 25) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 50 : 25) * b.fireCDscale); // cool down
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "spores",
|
name: "spores",
|
||||||
@@ -4362,18 +4372,18 @@ const b = {
|
|||||||
if (tech.isDroneRadioactive) {
|
if (tech.isDroneRadioactive) {
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
||||||
m.fireCDcycle = m.cycle + Math.floor(5 * 13 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(5 * 13 * b.fireCDscale); // cool down
|
||||||
} else {
|
} else {
|
||||||
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 10)
|
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 10)
|
||||||
m.fireCDcycle = m.cycle + Math.floor(5 * 6 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(5 * 6 * b.fireCDscale); // cool down
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
||||||
m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCDscale); // cool down
|
||||||
} else {
|
} else {
|
||||||
b.drone()
|
b.drone()
|
||||||
m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCDscale); // cool down
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4388,10 +4398,10 @@ const b = {
|
|||||||
// fire() {
|
// fire() {
|
||||||
// if (m.crouch) {
|
// if (m.crouch) {
|
||||||
// b.iceIX(10, 0.3)
|
// b.iceIX(10, 0.3)
|
||||||
// m.fireCDcycle = m.cycle + Math.floor(8 * b.fireCD); // cool down
|
// m.fireCDcycle = m.cycle + Math.floor(8 * b.fireCDscale); // cool down
|
||||||
// } else {
|
// } else {
|
||||||
// b.iceIX(2)
|
// b.iceIX(2)
|
||||||
// m.fireCDcycle = m.cycle + Math.floor(3 * b.fireCD); // cool down
|
// m.fireCDcycle = m.cycle + Math.floor(3 * b.fireCDscale); // cool down
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// }
|
// }
|
||||||
@@ -4427,7 +4437,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
fire() {
|
fire() {
|
||||||
this.charge++
|
this.charge++
|
||||||
m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCD);
|
m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCDscale);
|
||||||
},
|
},
|
||||||
fireFoam() {
|
fireFoam() {
|
||||||
const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5)
|
const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5)
|
||||||
@@ -4517,7 +4527,7 @@ const b = {
|
|||||||
if (tech.isCapacitor) {
|
if (tech.isCapacitor) {
|
||||||
if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
|
if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
|
||||||
m.energy += 0.16 * (tech.isRailEnergyGain ? 6 : -1)
|
m.energy += 0.16 * (tech.isRailEnergyGain ? 6 : -1)
|
||||||
m.fireCDcycle = m.cycle + Math.floor(30 * b.fireCD);
|
m.fireCDcycle = m.cycle + Math.floor(30 * b.fireCDscale);
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, {
|
bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, {
|
||||||
density: 0.005, //0.001 is normal
|
density: 0.005, //0.001 is normal
|
||||||
@@ -4552,7 +4562,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEnd() {},
|
onEnd() {},
|
||||||
drawCycle: Math.floor(10 * b.fireCD),
|
drawCycle: Math.floor(10 * b.fireCDscale),
|
||||||
do() {
|
do() {
|
||||||
this.force.y += this.mass * 0.0003; // low gravity that scales with charge
|
this.force.y += this.mass * 0.0003; // low gravity that scales with charge
|
||||||
if (this.drawCycle > 0) {
|
if (this.drawCycle > 0) {
|
||||||
@@ -4693,7 +4703,7 @@ const b = {
|
|||||||
|
|
||||||
m.fireCDcycle = Infinity //can't fire until mouse is released
|
m.fireCDcycle = Infinity //can't fire until mouse is released
|
||||||
const previousCharge = this.charge
|
const previousCharge = this.charge
|
||||||
let smoothRate = 0.98 * (m.crouch ? 0.99 : 1) * (0.98 + 0.02 * b.fireCD) //small b.fireCD = faster shots, b.fireCD=1 = normal shot, big b.fireCD = slower chot
|
let smoothRate = 0.98 * (m.crouch ? 0.99 : 1) * (0.98 + 0.02 * b.fireCDscale) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
|
||||||
this.charge = this.charge * smoothRate + 1 * (1 - smoothRate)
|
this.charge = this.charge * smoothRate + 1 * (1 - smoothRate)
|
||||||
if (tech.isRailEnergyGain) {
|
if (tech.isRailEnergyGain) {
|
||||||
if (m.immuneCycle < m.cycle) m.energy += (this.charge - previousCharge) * 2 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
if (m.immuneCycle < m.cycle) m.energy += (this.charge - previousCharge) * 2 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||||
@@ -4827,12 +4837,12 @@ const b = {
|
|||||||
this.do = () => {};
|
this.do = () => {};
|
||||||
if (tech.isPulseLaser) {
|
if (tech.isPulseLaser) {
|
||||||
this.fire = () => {
|
this.fire = () => {
|
||||||
const drain = 0.01 * tech.isLaserDiode / b.fireCD
|
const drain = 0.01 * tech.isLaserDiode / b.fireCDscale
|
||||||
if (m.energy > drain) {
|
if (m.energy > drain) {
|
||||||
m.energy -= m.fieldRegen
|
m.energy -= m.fieldRegen
|
||||||
if (this.charge < 50 * m.maxEnergy) {
|
if (this.charge < 50 * m.maxEnergy) {
|
||||||
m.energy -= drain
|
m.energy -= drain
|
||||||
this.charge += 1 / b.fireCD
|
this.charge += 1 / b.fireCDscale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4905,7 +4915,7 @@ const b = {
|
|||||||
// this.fire = this.firePhoton
|
// this.fire = this.firePhoton
|
||||||
},
|
},
|
||||||
// firePhoton() {
|
// firePhoton() {
|
||||||
// m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCD); // cool down
|
// m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCDscale); // cool down
|
||||||
// b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle)
|
// b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle)
|
||||||
// },
|
// },
|
||||||
fireLaser() {
|
fireLaser() {
|
||||||
@@ -5041,7 +5051,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// firePulse() {
|
// firePulse() {
|
||||||
// m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCD); // cool down
|
// m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCDscale); // cool down
|
||||||
// let energy = 0.3 * Math.min(m.energy, 1.5)
|
// let energy = 0.3 * Math.min(m.energy, 1.5)
|
||||||
// m.energy -= energy * tech.isLaserDiode
|
// m.energy -= energy * tech.isLaserDiode
|
||||||
// if (tech.beamSplitter) {
|
// if (tech.beamSplitter) {
|
||||||
@@ -5082,7 +5092,7 @@ const b = {
|
|||||||
if (this.rewindCount > 599 || m.energy < DRAIN || history.activeGun !== this.activeGunIndex) {
|
if (this.rewindCount > 599 || m.energy < DRAIN || history.activeGun !== this.activeGunIndex) {
|
||||||
this.rewindCount = 0;
|
this.rewindCount = 0;
|
||||||
m.resetHistory();
|
m.resetHistory();
|
||||||
m.fireCDcycle = m.cycle + Math.floor(120 * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor(120 * b.fireCDscale); // cool down
|
||||||
} else {
|
} else {
|
||||||
m.energy -= DRAIN
|
m.energy -= DRAIN
|
||||||
if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 5 cycles
|
if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 5 cycles
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ window.addEventListener('load', () => {
|
|||||||
const canvas = document.getElementById("canvas");
|
const canvas = document.getElementById("canvas");
|
||||||
//using "const" causes problems in safari when an ID shares the same name.
|
//using "const" causes problems in safari when an ID shares the same name.
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
|
// const ctx = canvas.getContext('2d', { alpha: false }); //optimization, but doesn't work
|
||||||
|
|
||||||
document.body.style.backgroundColor = "#fff";
|
document.body.style.backgroundColor = "#fff";
|
||||||
|
|
||||||
//disable pop up menu on right click
|
//disable pop up menu on right click
|
||||||
@@ -195,7 +197,7 @@ const build = {
|
|||||||
${simulation.isCheating? "<em>lore disabled</em><br><br>": ""}
|
${simulation.isCheating? "<em>lore disabled</em><br><br>": ""}
|
||||||
<strong class='color-d'>damage</strong> increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}%
|
<strong class='color-d'>damage</strong> increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}%
|
||||||
<br><strong class='color-harm'>harm</strong> reduction: ${harm.toFixed(harm > 90 ? 2 : 0)}%
|
<br><strong class='color-harm'>harm</strong> reduction: ${harm.toFixed(harm > 90 ? 2 : 0)}%
|
||||||
<br><strong><em>fire delay</em></strong> decrease: ${((1-b.fireCD)*100).toFixed(b.fireCD < 0.1 ? 2 : 0)}%
|
<br><strong><em>fire delay</em></strong> decrease: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
|
||||||
<br><strong class='color-dup'>duplication</strong> chance: ${(Math.min(1,tech.duplicationChance())*100).toFixed(0)}%
|
<br><strong class='color-dup'>duplication</strong> chance: ${(Math.min(1,tech.duplicationChance())*100).toFixed(0)}%
|
||||||
${botText}
|
${botText}
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
69
js/level.js
69
js/level.js
@@ -15,9 +15,9 @@ const level = {
|
|||||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.difficultyIncrease(30)
|
// level.difficultyIncrease(30)
|
||||||
// simulation.isHorizontalFlipped = true
|
// simulation.isHorizontalFlipped = true
|
||||||
// m.setField("time dilation")
|
// m.setField("metamaterial cloaking")
|
||||||
// b.giveGuns("grenades")
|
// b.giveGuns("foam")
|
||||||
// tech.giveTech("neutron bomb")
|
// tech.giveTech("uncertainty principle")
|
||||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||||
// tech.giveTech("supertemporal")
|
// tech.giveTech("supertemporal")
|
||||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||||
@@ -1273,7 +1273,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 2000 - 650, y + -875);
|
|
||||||
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||||
@@ -1281,6 +1280,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 2000 - 650, y + -875)
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||||
@@ -1305,7 +1305,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 650, y + -875);
|
|
||||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||||
@@ -1313,6 +1312,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 650, y + -875)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(x = offset.x, y = offset.y) => { //spawn block and fire it
|
(x = offset.x, y = offset.y) => { //spawn block and fire it
|
||||||
@@ -1365,7 +1365,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 650, y + -875);
|
|
||||||
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||||
@@ -1373,6 +1372,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 650, y + -875)
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||||
@@ -1422,7 +1422,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 650, y + -875);
|
|
||||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||||
@@ -1430,6 +1429,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 650, y - 875)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(x = offset.x, y = offset.y) => { //fire an "ammo clip" of blocks
|
(x = offset.x, y = offset.y) => { //fire an "ammo clip" of blocks
|
||||||
@@ -1493,7 +1493,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 650, y + -875);
|
|
||||||
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||||
@@ -1501,6 +1500,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 650, y - 875)
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||||
@@ -1561,7 +1561,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(x + 650, y + -875);
|
|
||||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||||
@@ -1569,6 +1568,7 @@ const level = {
|
|||||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||||
|
spawn.secondaryBossChance(x + 650, y - 875)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -2169,7 +2169,6 @@ const level = {
|
|||||||
// spawn.randomGroup(1700, -900, 0.4);
|
// spawn.randomGroup(1700, -900, 0.4);
|
||||||
// if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
|
// if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
// if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
|
|
||||||
},
|
},
|
||||||
final() {
|
final() {
|
||||||
level.custom = () => {
|
level.custom = () => {
|
||||||
@@ -2219,7 +2218,7 @@ const level = {
|
|||||||
spawn.mapRect(5700, -3300, 1800, 5100); //right wall
|
spawn.mapRect(5700, -3300, 1800, 5100); //right wall
|
||||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||||
spawn.mapRect(5425, -650, 375, 450); //blocking exit
|
spawn.mapRect(5425, -650, 375, 450); //blocking exit
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
|
spawn.secondaryBossChance(4800, -500)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -2289,7 +2288,7 @@ const level = {
|
|||||||
if (simulation.difficulty * Math.random() > 7 * i) spawn.randomGroup(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
if (simulation.difficulty * Math.random() > 7 * i) spawn.randomGroup(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4125, -350);
|
spawn.secondaryBossChance(4125, -350)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -2509,7 +2508,6 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.spawnStartingPowerUps(2300, -150);
|
powerUps.spawnStartingPowerUps(2300, -150);
|
||||||
// if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(1900, -675);
|
|
||||||
},
|
},
|
||||||
testChamber() {
|
testChamber() {
|
||||||
level.setPosToSpawn(0, -50); //lower start
|
level.setPosToSpawn(0, -50); //lower start
|
||||||
@@ -2705,8 +2703,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(1925, -1250);
|
spawn.secondaryBossChance(1925, -1250)
|
||||||
|
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -2913,8 +2910,7 @@ const level = {
|
|||||||
spawn.randomMob(2825, 400, 0.9);
|
spawn.randomMob(2825, 400, 0.9);
|
||||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "historyBoss", "orbitalBoss", "shieldingBoss"]);
|
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "historyBoss", "orbitalBoss", "shieldingBoss"]);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
|
spawn.secondaryBossChance(7725, 2275)
|
||||||
|
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -3101,7 +3097,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3950, -850);
|
spawn.secondaryBossChance(3950, -850)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -3272,7 +3268,7 @@ const level = {
|
|||||||
spawn.randomGroup(4900, -1200, 0);
|
spawn.randomGroup(4900, -1200, 0);
|
||||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -1900);
|
if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -1900);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(2175, -2425);
|
spawn.secondaryBossChance(2175, -2425)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -3489,7 +3485,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(5350, -325);
|
spawn.secondaryBossChance(5350, -325)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -3657,7 +3653,7 @@ const level = {
|
|||||||
spawn.randomGroup(1700, -900, 0.4);
|
spawn.randomGroup(1700, -900, 0.4);
|
||||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300);
|
if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3075, -2050);
|
spawn.secondaryBossChance(3075, -2050)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -3899,7 +3895,7 @@ const level = {
|
|||||||
|
|
||||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -2650);
|
if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -2650);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(-1825, -1975);
|
spawn.secondaryBossChance(-1825, -1975)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -4206,8 +4202,8 @@ const level = {
|
|||||||
spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head
|
spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(300, -800);
|
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
|
spawn.secondaryBossChance(300, -800)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -4438,7 +4434,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(1875, -675);
|
spawn.secondaryBossChance(1875, -675)
|
||||||
|
|
||||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||||
@@ -5920,7 +5916,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
|
spawn.secondaryBossChance(7725, 2275)
|
||||||
},
|
},
|
||||||
coliseum() {
|
coliseum() {
|
||||||
level.custom = () => {
|
level.custom = () => {
|
||||||
@@ -6070,8 +6066,7 @@ const level = {
|
|||||||
powerUps.spawn(200, 50, "ammo");
|
powerUps.spawn(200, 50, "ammo");
|
||||||
|
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
|
spawn.secondaryBossChance(6600, 600)
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(6600, 600, ["historyBoss", "powerUpBoss", "pulsarBoss", "orbitalBoss"]);
|
|
||||||
},
|
},
|
||||||
crossfire() {
|
crossfire() {
|
||||||
//*1.5
|
//*1.5
|
||||||
@@ -6179,12 +6174,8 @@ const level = {
|
|||||||
// spawn.randomGroup(7700, -1100, 0.5);
|
// spawn.randomGroup(7700, -1100, 0.5);
|
||||||
spawn.randomGroup(9800, -1100, 0.5);
|
spawn.randomGroup(9800, -1100, 0.5);
|
||||||
|
|
||||||
if (simulation.difficulty > 10) {
|
if (simulation.difficulty > 10) spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "snakeBoss", "spiderBoss", "historyBoss"])
|
||||||
spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "snakeBoss", "spiderBoss", "historyBoss"]);
|
spawn.secondaryBossChance(7900, -400)
|
||||||
}
|
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) {
|
|
||||||
spawn.randomLevelBoss(7900, -400, ["powerUpBoss", "spiderBoss", "historyBoss"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Boss Spawning
|
//Boss Spawning
|
||||||
if (simulation.difficulty > 10) {
|
if (simulation.difficulty > 10) {
|
||||||
@@ -6422,7 +6413,7 @@ const level = {
|
|||||||
} else {
|
} else {
|
||||||
exitDoor.isOpen = false;
|
exitDoor.isOpen = false;
|
||||||
}
|
}
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(800, -800);
|
spawn.secondaryBossChance(800, -800)
|
||||||
|
|
||||||
powerUps.spawn(4450, 1050, "heal");
|
powerUps.spawn(4450, 1050, "heal");
|
||||||
if (Math.random() > (0.2 + (simulation.difficulty / 60))) {
|
if (Math.random() > (0.2 + (simulation.difficulty / 60))) {
|
||||||
@@ -6933,15 +6924,7 @@ const level = {
|
|||||||
spawn.randomLevelBoss(850 + Math.random() * 250, -1100 + Math.random() * 200, bosses);
|
spawn.randomLevelBoss(850 + Math.random() * 250, -1100 + Math.random() * 200, bosses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) {
|
spawn.secondaryBossChance(850 + Math.random() * 250, -1100 + Math.random() * 200)
|
||||||
if (abc < 0.6 * 5 / 8 || abc >= 1 - 0.15 * 5 / 17) {
|
|
||||||
spawn.laserBoss(-350 + Math.random() * 300, -600 + Math.random() * 200);
|
|
||||||
} else if (abc < 0.65) {
|
|
||||||
spawn.randomLevelBoss(850 + Math.random() * 250, -1100 + Math.random() * 200, bosses);
|
|
||||||
} else {
|
|
||||||
spawn.randomLevelBoss(-1500 + Math.random() * 250, -1100 + Math.random() * 200, bosses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw leg for statue
|
//draw leg for statue
|
||||||
function statueLeg(shift, color) {
|
function statueLeg(shift, color) {
|
||||||
|
|||||||
29
js/player.js
29
js/player.js
@@ -49,6 +49,7 @@ const m = {
|
|||||||
eyeFillColor: null,
|
eyeFillColor: null,
|
||||||
fillColor: null, //set by setFillColors
|
fillColor: null, //set by setFillColors
|
||||||
fillColorDark: null, //set by setFillColors
|
fillColorDark: null, //set by setFillColors
|
||||||
|
bodyGradient: null, //set by setFillColors
|
||||||
color: {
|
color: {
|
||||||
hue: 0,
|
hue: 0,
|
||||||
sat: 0,
|
sat: 0,
|
||||||
@@ -57,6 +58,10 @@ const m = {
|
|||||||
setFillColors() {
|
setFillColors() {
|
||||||
this.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
|
this.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
|
||||||
this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light-25}%)`
|
this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light-25}%)`
|
||||||
|
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
||||||
|
grd.addColorStop(0, m.fillColorDark);
|
||||||
|
grd.addColorStop(1, m.fillColor);
|
||||||
|
this.bodyGradient = grd
|
||||||
},
|
},
|
||||||
height: 42,
|
height: 42,
|
||||||
yOffWhen: {
|
yOffWhen: {
|
||||||
@@ -803,10 +808,7 @@ const m = {
|
|||||||
ctx.rotate(m.angle);
|
ctx.rotate(m.angle);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient;
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
@@ -838,10 +840,7 @@ const m = {
|
|||||||
ctx.rotate(m.angle);
|
ctx.rotate(m.angle);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
@@ -873,10 +872,7 @@ const m = {
|
|||||||
ctx.rotate(m.angle);
|
ctx.rotate(m.angle);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
@@ -1091,8 +1087,8 @@ const m = {
|
|||||||
if (input.field) {
|
if (input.field) {
|
||||||
if (m.energy > 0.001) {
|
if (m.energy > 0.001) {
|
||||||
if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle
|
if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle
|
||||||
m.energy -= 0.001 / tech.throwChargeRate;
|
m.throwCharge += 0.5 * (tech.throwChargeRate / b.fireCDscale + 2 * tech.isAddBlockMass) / m.holdingTarget.mass
|
||||||
m.throwCharge += 0.5 * (tech.throwChargeRate + 2 * tech.isAddBlockMass) / m.holdingTarget.mass
|
if (m.throwCharge < 6) m.energy -= 0.001 / tech.throwChargeRate / b.fireCDscale; // m.throwCharge caps at 5
|
||||||
//draw charge
|
//draw charge
|
||||||
const x = m.pos.x + 15 * Math.cos(m.angle);
|
const x = m.pos.x + 15 * Math.cos(m.angle);
|
||||||
const y = m.pos.y + 15 * Math.sin(m.angle);
|
const y = m.pos.y + 15 * Math.sin(m.angle);
|
||||||
@@ -2996,10 +2992,7 @@ const m = {
|
|||||||
//body
|
//body
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ const powerUps = {
|
|||||||
b.randomBot()
|
b.randomBot()
|
||||||
if (tech.renormalization) {
|
if (tech.renormalization) {
|
||||||
for (let i = 0; i < limit; i++) {
|
for (let i = 0; i < limit; i++) {
|
||||||
if (Math.random() < 0.37) {
|
if (Math.random() < 0.4) {
|
||||||
m.fieldCDcycle = m.cycle + 30;
|
m.fieldCDcycle = m.cycle + 30;
|
||||||
powerUps.spawn(m.pos.x, m.pos.y, "research");
|
powerUps.spawn(m.pos.x, m.pos.y, "research");
|
||||||
}
|
}
|
||||||
@@ -234,7 +234,7 @@ const powerUps = {
|
|||||||
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
|
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
|
||||||
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
|
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
|
||||||
}
|
}
|
||||||
if (tech.renormalization && Math.random() < 0.37 && amount < 0) {
|
if (tech.renormalization && Math.random() < 0.4 && amount < 0) {
|
||||||
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
|
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
|
||||||
}
|
}
|
||||||
if (tech.isRerollHaste) {
|
if (tech.isRerollHaste) {
|
||||||
|
|||||||
13
js/spawn.js
13
js/spawn.js
@@ -87,6 +87,19 @@ const spawn = {
|
|||||||
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
|
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
|
||||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||||
},
|
},
|
||||||
|
secondaryBossChance(x, y) {
|
||||||
|
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) {
|
||||||
|
spawn.randomLevelBoss(x, y);
|
||||||
|
} else if (tech.isResearchBoss) {
|
||||||
|
if (powerUps.research.count > 4) {
|
||||||
|
powerUps.research.changeRerolls(-5)
|
||||||
|
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 5<br>${powerUps.research.count}`)
|
||||||
|
} else {
|
||||||
|
tech.addJunkTechToPool(49)
|
||||||
|
}
|
||||||
|
spawn.randomLevelBoss(x, y);
|
||||||
|
}
|
||||||
|
},
|
||||||
//mob templates *********************************************************************************************
|
//mob templates *********************************************************************************************
|
||||||
//***********************************************************************************************************
|
//***********************************************************************************************************
|
||||||
MACHO(x = m.pos.x, y = m.pos.y) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the player
|
MACHO(x = m.pos.x, y = m.pos.y) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the player
|
||||||
|
|||||||
170
js/tech.js
170
js/tech.js
@@ -66,6 +66,7 @@
|
|||||||
if (options.length) {
|
if (options.length) {
|
||||||
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++
|
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++
|
||||||
}
|
}
|
||||||
|
simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num} <span class='color-text'>JUNK</span>)`)
|
||||||
},
|
},
|
||||||
removeJunkTechFromPool(num = 1) {
|
removeJunkTechFromPool(num = 1) {
|
||||||
for (let j = 0; j < num; j++) {
|
for (let j = 0; j < num; j++) {
|
||||||
@@ -77,11 +78,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// removeJunkTechFromPool() {
|
|
||||||
// for (let i = tech.tech.length - 1; i > 0; i--) {
|
|
||||||
// if (tech.tech[i].isJunk && tech.tech[i].count === 0) tech.tech.splice(i, 1)
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
giveTech(index = 'random') {
|
giveTech(index = 'random') {
|
||||||
if (index === 'random') {
|
if (index === 'random') {
|
||||||
let options = [];
|
let options = [];
|
||||||
@@ -93,7 +89,6 @@
|
|||||||
let newTech = options[Math.floor(Math.random() * options.length)]
|
let newTech = options[Math.floor(Math.random() * options.length)]
|
||||||
tech.giveTech(newTech)
|
tech.giveTech(newTech)
|
||||||
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[newTech].name}</span>")<em> //random tech</em>`);
|
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[newTech].name}</span>")<em> //random tech</em>`);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isNaN(index)) { //find index by name
|
if (isNaN(index)) { //find index by name
|
||||||
@@ -704,6 +699,24 @@
|
|||||||
tech.isRadioactive = false
|
tech.isRadioactive = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "water shielding",
|
||||||
|
description: "<strong class='color-p'>radioactive</strong> effects on you are reduced by 75%<br><em>neutron bomb, drones, explosions, slime</em>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return tech.isNeutronBomb || tech.isDroneRadioactive || tech.isExplodeRadio
|
||||||
|
},
|
||||||
|
requires: "neutron bomb or irradiated drones or iridium-192",
|
||||||
|
effect() {
|
||||||
|
tech.isRadioactiveResistance = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isRadioactiveResistance = false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "iridium-192",
|
name: "iridium-192",
|
||||||
description: "<strong class='color-e'>explosions</strong> release <strong class='color-p'>gamma radiation</strong><br><strong>100%</strong> more <strong class='color-d'>damage</strong>, but over 4 seconds",
|
description: "<strong class='color-e'>explosions</strong> release <strong class='color-p'>gamma radiation</strong><br><strong>100%</strong> more <strong class='color-d'>damage</strong>, but over 4 seconds",
|
||||||
@@ -951,15 +964,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "decorrelation",
|
name: "decorrelation",
|
||||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong><br>after not using your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
|
description: "reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong> after not <strong>activating</strong><br>your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
|
return ((m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" && (tech.blockingIce !== 0 || tech.blockDmg !== 0)) || b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "drones, spores, mines, or bots",
|
requires: "drones, spores, mines, or bots, ",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isNoFireDefense = true
|
tech.isNoFireDefense = true
|
||||||
},
|
},
|
||||||
@@ -2244,7 +2257,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "overcharge",
|
name: "overcharge",
|
||||||
description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>60</strong><br>add <strong>10</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>60</strong><br><strong>+10</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -2266,7 +2279,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Maxwell's demon",
|
name: "Maxwell's demon",
|
||||||
description: "<strong class='color-f'>energy</strong> above your max decays <strong>92%</strong> slower<br>add <strong>18</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "<strong class='color-f'>energy</strong> above your max decays <strong>92%</strong> slower<br><strong>+18</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
@@ -2712,7 +2725,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "renormalization",
|
name: "renormalization",
|
||||||
description: "using a <strong class='color-r'>research</strong> for <strong>any</strong> purpose<br>has a <strong>37%</strong> chance to spawn a <strong class='color-r'>research</strong>",
|
description: "using a <strong class='color-r'>research</strong> for <strong>any</strong> purpose<br>has a <strong>40%</strong> chance to spawn a <strong class='color-r'>research</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
@@ -2819,6 +2832,24 @@
|
|||||||
},
|
},
|
||||||
remove() {}
|
remove() {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "abiogenesis",
|
||||||
|
description: "at the start of a level spawn a 2nd <strong>boss</strong> for<br><strong>5</strong> <strong class='color-r'>research</strong> or <strong>+49</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
allowed() {
|
||||||
|
return (build.isExperimentSelection || powerUps.research.count > 4) && !tech.isDuplicateBoss
|
||||||
|
},
|
||||||
|
requires: "at least 5 research and not parthenogenesis",
|
||||||
|
effect() {
|
||||||
|
tech.isResearchBoss = true; //abiogenesis
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isResearchBoss = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "bubble fusion",
|
name: "bubble fusion",
|
||||||
description: "after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
|
description: "after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
|
||||||
@@ -2857,7 +2888,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "replication",
|
name: "replication",
|
||||||
description: "<strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>18</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "<strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+18</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -2983,9 +3014,9 @@
|
|||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.duplicationChance() > 0
|
return tech.duplicationChance() > 0 && !tech.isResearchBoss
|
||||||
},
|
},
|
||||||
requires: "some duplication chance",
|
requires: "some duplication chance, not abiogenesis",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isDuplicateBoss = true;
|
tech.isDuplicateBoss = true;
|
||||||
},
|
},
|
||||||
@@ -3259,7 +3290,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dark patterns",
|
name: "dark patterns",
|
||||||
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>21</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br><strong>+21</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -4058,25 +4089,6 @@
|
|||||||
b.setGrenadeMode()
|
b.setGrenadeMode()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "water shielding",
|
|
||||||
description: "<strong class='color-p'>radioactive</strong> effects on you are reduced by 75%<br><em>neutron bomb, drones, explosions, slime</em>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
frequencyDefault: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.isNeutronBomb || tech.isDroneRadioactive || tech.isExplodeRadio
|
|
||||||
},
|
|
||||||
requires: "neutron bomb or irradiated drones or iridium-192",
|
|
||||||
effect() {
|
|
||||||
tech.isRadioactiveResistance = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isRadioactiveResistance = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "vacuum permittivity",
|
name: "vacuum permittivity",
|
||||||
description: "increase <strong class='color-p'>radioactive</strong> range by <strong>20%</strong><br>objects in range of the bomb are <strong>slowed</strong>",
|
description: "increase <strong class='color-p'>radioactive</strong> range by <strong>20%</strong><br>objects in range of the bomb are <strong>slowed</strong>",
|
||||||
@@ -4155,7 +4167,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "booby trap",
|
name: "booby trap",
|
||||||
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br>add <strong>13</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br><strong>+13</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
@@ -4410,6 +4422,25 @@
|
|||||||
tech.droneRadioDamage = 1
|
tech.droneRadioDamage = 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "uncertainty principle",
|
||||||
|
description: "<strong>foam</strong> bubbles randomly change <strong>position</strong><br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>66%</strong>",
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1)
|
||||||
|
},
|
||||||
|
requires: "foam, not electrostatic induction",
|
||||||
|
effect() {
|
||||||
|
tech.isFoamTeleport = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isFoamTeleport = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "necrophoresis",
|
name: "necrophoresis",
|
||||||
description: "<strong>foam</strong> bubbles grow and split into 3 <strong>copies</strong><br> when the mob they are stuck to <strong>dies</strong>",
|
description: "<strong>foam</strong> bubbles grow and split into 3 <strong>copies</strong><br> when the mob they are stuck to <strong>dies</strong>",
|
||||||
@@ -4450,25 +4481,6 @@
|
|||||||
tech.foamGravity = 0.00008
|
tech.foamGravity = 0.00008
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "electrostatic induction",
|
|
||||||
description: "<strong>foam</strong> bullets are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
frequencyDefault: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1
|
|
||||||
},
|
|
||||||
requires: "foam",
|
|
||||||
effect() {
|
|
||||||
tech.isFoamAttract = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isFoamAttract = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "quantum foam",
|
name: "quantum foam",
|
||||||
description: "<strong>foam</strong> gun fires <strong>0.30</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>90%</strong>",
|
description: "<strong>foam</strong> gun fires <strong>0.30</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>90%</strong>",
|
||||||
@@ -4507,6 +4519,25 @@
|
|||||||
tech.isAmmoFoamSize = false;
|
tech.isAmmoFoamSize = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "electrostatic induction",
|
||||||
|
description: "<strong>foam</strong> bullets are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1)
|
||||||
|
},
|
||||||
|
requires: "foam, not uncertainty",
|
||||||
|
effect() {
|
||||||
|
tech.isFoamAttract = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isFoamAttract = false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "half-wave rectifier",
|
name: "half-wave rectifier",
|
||||||
description: "charging the <strong>rail gun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>",
|
description: "charging the <strong>rail gun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>",
|
||||||
@@ -6454,7 +6485,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "expert system",
|
name: "expert system",
|
||||||
description: "spawn a <strong class='color-m'>tech</strong> power up<br>add <strong>64</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
description: "spawn a <strong class='color-m'>tech</strong> power up<br><strong>+64</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -6604,10 +6635,7 @@
|
|||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
@@ -6652,10 +6680,7 @@
|
|||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
@@ -6694,10 +6719,7 @@
|
|||||||
ctx.rotate(m.angle);
|
ctx.rotate(m.angle);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
ctx.fillStyle = this.bodyGradient
|
||||||
grd.addColorStop(0, m.fillColorDark);
|
|
||||||
grd.addColorStop(1, m.fillColor);
|
|
||||||
ctx.fillStyle = grd;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.strokeStyle = "#333";
|
ctx.strokeStyle = "#333";
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
@@ -6909,7 +6931,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quantum black hole",
|
name: "quantum black hole",
|
||||||
description: "use all your <strong class='color-f'>energy</strong> to <strong>spawn</strong><br>inside the event horizon of a huge <strong>black hole</strong>",
|
description: "use your <strong class='color-f'>energy</strong> and <strong>1</strong> <strong class='color-r'>research</strong> to <strong>spawn</strong><br>inside the event horizon of a huge <strong>black hole</strong>",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -6917,12 +6939,14 @@
|
|||||||
isExperimentHide: true,
|
isExperimentHide: true,
|
||||||
isJunk: true,
|
isJunk: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true
|
return powerUps.research.count > 0
|
||||||
},
|
},
|
||||||
requires: "",
|
requires: "at least 1 research",
|
||||||
effect() {
|
effect() {
|
||||||
m.energy = 0
|
m.energy = 0
|
||||||
spawn.suckerBoss(m.pos.x, m.pos.y - 1000)
|
spawn.suckerBoss(m.pos.x, m.pos.y - 1000)
|
||||||
|
powerUps.research.changeRerolls(-1)
|
||||||
|
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>--</span><br>${powerUps.research.count}`)
|
||||||
},
|
},
|
||||||
remove() {}
|
remove() {}
|
||||||
},
|
},
|
||||||
@@ -7267,5 +7291,7 @@
|
|||||||
isBlockExplode: null,
|
isBlockExplode: null,
|
||||||
isOverHeal: null,
|
isOverHeal: null,
|
||||||
isDroneRadioactive: null,
|
isDroneRadioactive: null,
|
||||||
droneRadioDamage: null
|
droneRadioDamage: null,
|
||||||
|
isFoamTeleport: null,
|
||||||
|
isResearchBoss: null
|
||||||
}
|
}
|
||||||
289
todo.txt
289
todo.txt
@@ -1,170 +1,19 @@
|
|||||||
******************************************************** NEXT PATCH ********************************************************
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
irradiated drones
|
tech: abiogenesis - spawn a second level boss on each level, but costs 5 research or if you don't have the research add 49 JUNK tech to the pool
|
||||||
new tech: beta radiation - double damage and half lifespan
|
note to level builders I rewrote the add duplicate boss code in all levels: spawn.secondaryBossChance(x,y)
|
||||||
now don't clump as often, to make the graphics look better
|
|
||||||
effective radius now includes edges of mobs, not just centers
|
|
||||||
so they work better on large radius mobs
|
|
||||||
do 50% more damage, but have a 10% smaller radius and last 3 second shorter time and 80% less ammo (was 75%)
|
|
||||||
irradiated drones can't get a slowing effect anymore
|
|
||||||
it was just too annoying
|
|
||||||
nano-scale can now unlock irradiated drone tech properly
|
|
||||||
nano-scale now drains more energy per irradiated drone, to scale with the higher ammo costs
|
|
||||||
|
|
||||||
time dilation field is now just called "time dilation"
|
foam tech: uncertainty principle - foam bullets change position randomly, increase foam damage by 66%
|
||||||
constraints under time dilation is less buggy, but still a bit buggy
|
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
throwing blocks now charges faster with reduced fire cooldown
|
||||||
|
tech renormalization now has a 40% chance to refund a research (was 37%)
|
||||||
player can become crouched while not touching the ground if they exit the ground while crouched
|
performance- now precalculate player gradient fill
|
||||||
|
|
||||||
a couple times people have reported the final boss dropping extra bodies on death
|
|
||||||
|
|
||||||
Why does micro-extruder lag so much
|
|
||||||
|
|
||||||
blue triangle boss can move backwards and aim away from you if set up properly
|
|
||||||
issues with dot product probably, but might not be worth fixing
|
|
||||||
|
|
||||||
mouse event e.which is deprecated
|
|
||||||
|
|
||||||
fix door.isOpen actually meaning isClosed?
|
|
||||||
|
|
||||||
make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
|
||||||
|
|
||||||
is there a way to check if the player is stuck inside the map or block
|
|
||||||
trigger a short term non-collide if that occurs
|
|
||||||
|
|
||||||
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
|
|
||||||
|
|
||||||
******************************************************** LEVELS ********************************************************
|
|
||||||
|
|
||||||
labs - procedural generation
|
|
||||||
bugs
|
|
||||||
mob spawns shouldn't be based on probability?
|
|
||||||
style
|
|
||||||
graphics look too bright?
|
|
||||||
add shadows and lighting and graphic details?
|
|
||||||
what about performance?
|
|
||||||
with the mobs staggered spawning it should be fine
|
|
||||||
feel
|
|
||||||
disrupt the flat ground
|
|
||||||
less platforming / easier platforming
|
|
||||||
the spinners on exit are still too hard...
|
|
||||||
make combat more interesting
|
|
||||||
is it laggy?
|
|
||||||
in loot room, spawn mobs after power up is grabbed
|
|
||||||
more background graphics, better colors
|
|
||||||
loot room:
|
|
||||||
make it more interesting to get the power up
|
|
||||||
slow player and reduce damage in region
|
|
||||||
increase the size of the region
|
|
||||||
don't have space for much
|
|
||||||
make graphics more unique
|
|
||||||
push player away, so that normal pick up methods don't work, but add a button to disable region
|
|
||||||
room ideas -
|
|
||||||
portal room
|
|
||||||
endlessly falling blocks down a slide, that the player has to climb up
|
|
||||||
portal + rotor + falling blocks = perpetual motion
|
|
||||||
slime room
|
|
||||||
sound room, with buttons to control sound
|
|
||||||
color room with r,g,b buttons to control color
|
|
||||||
mob buff zone: Map element: "Orbital Pickup Zone": Mobs that enter a specific area of the map gain +1 orbital per second, or a shield
|
|
||||||
could put in the loot room
|
|
||||||
|
|
||||||
buttons can now on/off boosts
|
|
||||||
|
|
||||||
repeat map in vertical when you fall teleport to above the mab, as if the map repeats
|
|
||||||
camera looks strange when you teleport player with a high velocity
|
|
||||||
|
|
||||||
map element - player rotates a rotor that makes a platform go up or down
|
|
||||||
|
|
||||||
level element: a zone with wind, anti-gravity, extra gravity
|
|
||||||
control with button
|
|
||||||
|
|
||||||
map: observatory
|
|
||||||
button controls rotation of telescope
|
|
||||||
laser beam shoots out of telescope
|
|
||||||
button opens the dome
|
|
||||||
|
|
||||||
******************************************************** MOBS ********************************************************
|
|
||||||
|
|
||||||
mob mechanics
|
|
||||||
use the force at a location effect, like the plasma field
|
|
||||||
Matter.Body.applyForce(who, path[1], force)
|
|
||||||
|
|
||||||
mob - after taking damage
|
|
||||||
release seekers
|
|
||||||
teleports
|
|
||||||
|
|
||||||
hop boss:
|
|
||||||
AoE damage when landing
|
|
||||||
pull in player? and blocks?
|
|
||||||
extra gravity on falling?
|
|
||||||
immune to damage while falling?
|
|
||||||
|
|
||||||
mob: molecule shapes - 2 separate mobs joined by a bond
|
|
||||||
use constraints: just spawn 2x or 3x groupings
|
|
||||||
low friction so they can spin around
|
|
||||||
spin when attacking player?
|
|
||||||
increase constraint length when attacking
|
|
||||||
|
|
||||||
mob vision: look at player history
|
|
||||||
build a new type of attraction for mobs
|
|
||||||
if mobs can't see player, they check to see if they can see where the player was in the history
|
|
||||||
if mobs can't see player, they could check to see if they can find player in the past
|
|
||||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
|
||||||
write find in spawn undo exploder, but commented out
|
|
||||||
|
|
||||||
Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage.
|
|
||||||
maybe it could be immune to damage? but it is spawned by an actual mob
|
|
||||||
|
|
||||||
level Boss: fractal Sierpiński triangle
|
|
||||||
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
|
|
||||||
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
|
|
||||||
they spawn once at the start of the level
|
|
||||||
if a version dies, one can be replaced every ten seconds by the largest version
|
|
||||||
|
|
||||||
give mobs more animal-like behaviors like rain world
|
|
||||||
mobs play, look for food, explore
|
|
||||||
mobs some times aren't aggressive
|
|
||||||
when low on life or after taking a large hit
|
|
||||||
mobs can fight each other
|
|
||||||
this might be hard to code
|
|
||||||
isolated mobs try to group up
|
|
||||||
|
|
||||||
mob: wall mounted guns / lasers
|
|
||||||
not part of randomized mob pool, customized to each level
|
|
||||||
|
|
||||||
level boss: fires a line intersection in a random direction every few seconds.
|
|
||||||
the last two intersections have a destructive laser between them.
|
|
||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
tech - shorter cloaking delay
|
|
||||||
|
|
||||||
irradiated drones, get annoying when they go after mobs near the player...
|
|
||||||
should they only follow mouse? or at least show a preference for targets near mouse, not near player
|
|
||||||
|
|
||||||
tech - 1/2 your drone ammo/efficiency double the damage?
|
|
||||||
|
|
||||||
tech foam teleports around, like a quantum wave function collapse
|
|
||||||
|
|
||||||
should ammo apply to all guns, or just one of your guns?
|
should ammo apply to all guns, or just one of your guns?
|
||||||
if one gun only, it would make multi-gun builds weaker
|
if one gun only, it would make multi-gun builds weaker
|
||||||
|
|
||||||
nail bots should benefit from nail gun tech
|
|
||||||
|
|
||||||
tech: picking up heal power ups at max health does harm, but increases max health
|
|
||||||
scales with heal value
|
|
||||||
|
|
||||||
let standing wave harmonics get tech decorrelation
|
|
||||||
|
|
||||||
tech: cloaking field - decrease/increase cooldown on sneak attack?
|
|
||||||
decrease/increase damage bonus?
|
|
||||||
decrease/increase visual radius?
|
|
||||||
|
|
||||||
have throw charge scale with fire delay
|
|
||||||
|
|
||||||
in testing mode console log the body you click on
|
in testing mode console log the body you click on
|
||||||
|
|
||||||
throwing a block removes the block and rewinds time 10 seconds (including health and energy)
|
throwing a block removes the block and rewinds time 10 seconds (including health and energy)
|
||||||
@@ -174,8 +23,6 @@ tech plasma : plasma length increases then decreases as you hold down the field
|
|||||||
grows to 1.5 longer after 0.3 seconds, then returns to normal length over 1 second, until field is pressed again
|
grows to 1.5 longer after 0.3 seconds, then returns to normal length over 1 second, until field is pressed again
|
||||||
extra energy is drained when field is longer
|
extra energy is drained when field is longer
|
||||||
|
|
||||||
tech: at the start of a new level remove 5 research and spawn a second boss
|
|
||||||
|
|
||||||
energy conservation 6% damage recovered as energy
|
energy conservation 6% damage recovered as energy
|
||||||
add a negative effect:
|
add a negative effect:
|
||||||
junk tech
|
junk tech
|
||||||
@@ -335,6 +182,129 @@ n-gon outreach ideas
|
|||||||
hacker news - show hacker news post
|
hacker news - show hacker news post
|
||||||
twitch - lets play
|
twitch - lets play
|
||||||
|
|
||||||
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
|
player can become crouched while not touching the ground if they exit the ground while crouched
|
||||||
|
|
||||||
|
a couple times people have reported the final boss dropping extra bodies on death
|
||||||
|
|
||||||
|
Why does micro-extruder lag so much
|
||||||
|
|
||||||
|
blue triangle boss can move backwards and aim away from you if set up properly
|
||||||
|
issues with dot product probably, but might not be worth fixing
|
||||||
|
|
||||||
|
mouse event e.which is deprecated
|
||||||
|
|
||||||
|
fix door.isOpen actually meaning isClosed?
|
||||||
|
|
||||||
|
make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
||||||
|
|
||||||
|
is there a way to check if the player is stuck inside the map or block
|
||||||
|
trigger a short term non-collide if that occurs
|
||||||
|
|
||||||
|
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
|
||||||
|
|
||||||
|
******************************************************** LEVELS ********************************************************
|
||||||
|
|
||||||
|
labs - procedural generation
|
||||||
|
bugs
|
||||||
|
mob spawns shouldn't be based on probability?
|
||||||
|
style
|
||||||
|
graphics look too bright?
|
||||||
|
add shadows and lighting and graphic details?
|
||||||
|
what about performance?
|
||||||
|
with the mobs staggered spawning it should be fine
|
||||||
|
feel
|
||||||
|
disrupt the flat ground
|
||||||
|
less platforming / easier platforming
|
||||||
|
the spinners on exit are still too hard...
|
||||||
|
make combat more interesting
|
||||||
|
is it laggy?
|
||||||
|
in loot room, spawn mobs after power up is grabbed
|
||||||
|
more background graphics, better colors
|
||||||
|
loot room:
|
||||||
|
make it more interesting to get the power up
|
||||||
|
slow player and reduce damage in region
|
||||||
|
increase the size of the region
|
||||||
|
don't have space for much
|
||||||
|
make graphics more unique
|
||||||
|
push player away, so that normal pick up methods don't work, but add a button to disable region
|
||||||
|
room ideas -
|
||||||
|
portal room
|
||||||
|
endlessly falling blocks down a slide, that the player has to climb up
|
||||||
|
portal + rotor + falling blocks = perpetual motion
|
||||||
|
slime room
|
||||||
|
sound room, with buttons to control sound
|
||||||
|
color room with r,g,b buttons to control color
|
||||||
|
mob buff zone: Map element: "Orbital Pickup Zone": Mobs that enter a specific area of the map gain +1 orbital per second, or a shield
|
||||||
|
could put in the loot room
|
||||||
|
|
||||||
|
buttons can now on/off boosts
|
||||||
|
|
||||||
|
repeat map in vertical when you fall teleport to above the mab, as if the map repeats
|
||||||
|
camera looks strange when you teleport player with a high velocity
|
||||||
|
|
||||||
|
map element - player rotates a rotor that makes a platform go up or down
|
||||||
|
|
||||||
|
level element: a zone with wind, anti-gravity, extra gravity
|
||||||
|
control with button
|
||||||
|
|
||||||
|
map: observatory
|
||||||
|
button controls rotation of telescope
|
||||||
|
laser beam shoots out of telescope
|
||||||
|
button opens the dome
|
||||||
|
|
||||||
|
******************************************************** MOBS ********************************************************
|
||||||
|
|
||||||
|
mob mechanics
|
||||||
|
use the force at a location effect, like the plasma field
|
||||||
|
Matter.Body.applyForce(who, path[1], force)
|
||||||
|
|
||||||
|
mob - after taking damage
|
||||||
|
release seekers
|
||||||
|
teleports
|
||||||
|
|
||||||
|
hop boss:
|
||||||
|
AoE damage when landing
|
||||||
|
pull in player? and blocks?
|
||||||
|
extra gravity on falling?
|
||||||
|
immune to damage while falling?
|
||||||
|
|
||||||
|
mob: molecule shapes - 2 separate mobs joined by a bond
|
||||||
|
use constraints: just spawn 2x or 3x groupings
|
||||||
|
low friction so they can spin around
|
||||||
|
spin when attacking player?
|
||||||
|
increase constraint length when attacking
|
||||||
|
|
||||||
|
mob vision: look at player history
|
||||||
|
build a new type of attraction for mobs
|
||||||
|
if mobs can't see player, they check to see if they can see where the player was in the history
|
||||||
|
if mobs can't see player, they could check to see if they can find player in the past
|
||||||
|
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||||
|
write find in spawn undo exploder, but commented out
|
||||||
|
|
||||||
|
Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage.
|
||||||
|
maybe it could be immune to damage? but it is spawned by an actual mob
|
||||||
|
|
||||||
|
level Boss: fractal Sierpiński triangle
|
||||||
|
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
|
||||||
|
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
|
||||||
|
they spawn once at the start of the level
|
||||||
|
if a version dies, one can be replaced every ten seconds by the largest version
|
||||||
|
|
||||||
|
give mobs more animal-like behaviors like rain world
|
||||||
|
mobs play, look for food, explore
|
||||||
|
mobs some times aren't aggressive
|
||||||
|
when low on life or after taking a large hit
|
||||||
|
mobs can fight each other
|
||||||
|
this might be hard to code
|
||||||
|
isolated mobs try to group up
|
||||||
|
|
||||||
|
mob: wall mounted guns / lasers
|
||||||
|
not part of randomized mob pool, customized to each level
|
||||||
|
|
||||||
|
level boss: fires a line intersection in a random direction every few seconds.
|
||||||
|
the last two intersections have a destructive laser between them.
|
||||||
|
|
||||||
******************************************************** LORE ********************************************************
|
******************************************************** LORE ********************************************************
|
||||||
|
|
||||||
@@ -342,7 +312,6 @@ possible names for tech
|
|||||||
strange loop
|
strange loop
|
||||||
holonomy - parallel transport of a vector leads to movement (applies to curved space)
|
holonomy - parallel transport of a vector leads to movement (applies to curved space)
|
||||||
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
||||||
uncertainty principle
|
|
||||||
swarm intelligence - for a drone tech
|
swarm intelligence - for a drone tech
|
||||||
genetic algorithm
|
genetic algorithm
|
||||||
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
|
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
|
||||||
|
|||||||
Reference in New Issue
Block a user