pulse charge
pulse laser now charges up with energy before you fire, but it fires 3 overlapping explosions please give feedback on balance (too strong, too weak?) tech shockwave: now applies to all explosions foam gun now gets 20% less ammo
This commit is contained in:
370
js/bullet.js
370
js/bullet.js
@@ -51,8 +51,6 @@ const b = {
|
|||||||
if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
|
if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
|
||||||
if (b.guns[b.activeGun].ammo > 0) {
|
if (b.guns[b.activeGun].ammo > 0) {
|
||||||
b.fireWithAmmo()
|
b.fireWithAmmo()
|
||||||
} else {
|
|
||||||
b.outOfAmmo()
|
|
||||||
}
|
}
|
||||||
if (m.holdingTarget) m.drop();
|
if (m.holdingTarget) m.drop();
|
||||||
}
|
}
|
||||||
@@ -297,17 +295,17 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
explosionRange() {
|
explosionRange() {
|
||||||
return tech.explosiveRadius * (tech.isExplosionHarm ? 1.8 : 1) * (tech.isSmallExplosion ? 0.8 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
|
return tech.explosiveRadius * (tech.isExplosionHarm ? 1.8 : 1) * (tech.isSmallExplosion ? 0.66 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
|
||||||
},
|
},
|
||||||
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
|
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
|
||||||
radius *= tech.explosiveRadius
|
radius *= tech.explosiveRadius
|
||||||
let dist, sub, knock;
|
let dist, sub, knock;
|
||||||
let dmg = radius * 0.013;
|
let dmg = radius * 0.013 * (tech.isExplosionStun ? 0.6 : 1);
|
||||||
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
|
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
|
||||||
if (tech.isSmallExplosion) {
|
if (tech.isSmallExplosion) {
|
||||||
color = "rgba(255,0,30,0.7)"
|
color = "rgba(255,0,30,0.7)"
|
||||||
radius *= 0.8
|
radius *= 0.66
|
||||||
dmg *= 1.6
|
dmg *= 1.66
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tech.isExplodeRadio) { //radiation explosion
|
if (tech.isExplodeRadio) { //radiation explosion
|
||||||
@@ -430,6 +428,7 @@ const b = {
|
|||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.01);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.01);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
|
if (tech.isExplosionStun) mobs.statusStun(mob[i], 120)
|
||||||
radius *= 0.95 //reduced range for each additional explosion target
|
radius *= 0.95 //reduced range for each additional explosion target
|
||||||
damageScale *= 0.87 //reduced damage for each additional explosion target
|
damageScale *= 0.87 //reduced damage for each additional explosion target
|
||||||
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
||||||
@@ -437,15 +436,16 @@ const b = {
|
|||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.006);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.006);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
|
if (tech.isExplosionStun) mobs.statusStun(mob[i], 60)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pulse(energy, angle = m.angle) {
|
pulse(charge, angle = m.angle) {
|
||||||
let best;
|
let best;
|
||||||
let explosionRadius = 1250 * energy
|
let explosionRadius = 6 * charge
|
||||||
let range = 3000
|
let range = 5000
|
||||||
const path = [{
|
const path = [{
|
||||||
x: m.pos.x + 20 * Math.cos(angle),
|
x: m.pos.x + 20 * Math.cos(angle),
|
||||||
y: m.pos.y + 20 * Math.sin(angle)
|
y: m.pos.y + 20 * Math.sin(angle)
|
||||||
@@ -529,26 +529,23 @@ const b = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (best.who) b.explosion(path[1], explosionRadius)
|
if (best.who) {
|
||||||
|
b.explosion(path[1], explosionRadius)
|
||||||
if (tech.isPulseStun) {
|
const off = explosionRadius
|
||||||
const range = 100 + 2000 * energy
|
b.explosion({ x: path[1].x + off * (Math.random() - 0.5), y: path[1].y + off * (Math.random() - 0.5) }, explosionRadius)
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
b.explosion({ x: path[1].x + off * (Math.random() - 0.5), y: path[1].y + off * (Math.random() - 0.5) }, explosionRadius)
|
||||||
if (mob[i].alive && !mob[i].isShielded) {
|
|
||||||
dist = Vector.magnitude(Vector.sub(path[1], mob[i].position)) - mob[i].radius;
|
|
||||||
if (dist < range) mobs.statusStun(mob[i], 30 + Math.floor(energy * 60))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//draw laser beam
|
//draw laser beam
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(path[0].x, path[0].y);
|
ctx.moveTo(path[0].x, path[0].y);
|
||||||
ctx.lineTo(path[1].x, path[1].y);
|
ctx.lineTo(path[1].x, path[1].y);
|
||||||
ctx.strokeStyle = "rgba(255,0,0,0.13)"
|
if (charge > 50) {
|
||||||
ctx.lineWidth = 60 * energy / 0.2
|
ctx.strokeStyle = "rgba(255,0,0,0.10)"
|
||||||
ctx.stroke();
|
ctx.lineWidth = 70
|
||||||
ctx.strokeStyle = "rgba(255,0,0,0.2)"
|
ctx.stroke();
|
||||||
ctx.lineWidth = 18
|
}
|
||||||
|
ctx.strokeStyle = "rgba(255,0,0,0.25)"
|
||||||
|
ctx.lineWidth = 20
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.strokeStyle = "#f00";
|
ctx.strokeStyle = "#f00";
|
||||||
ctx.lineWidth = 4
|
ctx.lineWidth = 4
|
||||||
@@ -557,7 +554,7 @@ const b = {
|
|||||||
//draw little dots along the laser path
|
//draw little dots along the laser path
|
||||||
const sub = Vector.sub(path[1], path[0])
|
const sub = Vector.sub(path[1], path[0])
|
||||||
const mag = Vector.magnitude(sub)
|
const mag = Vector.magnitude(sub)
|
||||||
for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
|
for (let i = 0, len = Math.floor(mag * 0.0005 * charge); i < len; i++) {
|
||||||
const dist = Math.random()
|
const dist = Math.random()
|
||||||
simulation.drawList.push({
|
simulation.drawList.push({
|
||||||
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
||||||
@@ -568,121 +565,121 @@ const b = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
photon(where, angle = m.angle) {
|
// photon(where, angle = m.angle) {
|
||||||
let best;
|
// let best;
|
||||||
const path = [{
|
// const path = [{
|
||||||
x: m.pos.x + 20 * Math.cos(angle),
|
// x: m.pos.x + 20 * Math.cos(angle),
|
||||||
y: m.pos.y + 20 * Math.sin(angle)
|
// y: m.pos.y + 20 * Math.sin(angle)
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
x: m.pos.x + range * Math.cos(angle),
|
// x: m.pos.x + range * Math.cos(angle),
|
||||||
y: m.pos.y + range * Math.sin(angle)
|
// y: m.pos.y + range * Math.sin(angle)
|
||||||
}
|
// }
|
||||||
];
|
// ];
|
||||||
const vertexCollision = function(v1, v1End, domain) {
|
// const vertexCollision = function(v1, v1End, domain) {
|
||||||
for (let i = 0; i < domain.length; ++i) {
|
// for (let i = 0; i < domain.length; ++i) {
|
||||||
let vertices = domain[i].vertices;
|
// let vertices = domain[i].vertices;
|
||||||
const len = vertices.length - 1;
|
// const len = vertices.length - 1;
|
||||||
for (let j = 0; j < len; j++) {
|
// for (let j = 0; j < len; j++) {
|
||||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
// results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||||
if (results.onLine1 && results.onLine2) {
|
// if (results.onLine1 && results.onLine2) {
|
||||||
const dx = v1.x - results.x;
|
// const dx = v1.x - results.x;
|
||||||
const dy = v1.y - results.y;
|
// const dy = v1.y - results.y;
|
||||||
const dist2 = dx * dx + dy * dy;
|
// const dist2 = dx * dx + dy * dy;
|
||||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||||
best = {
|
// best = {
|
||||||
x: results.x,
|
// x: results.x,
|
||||||
y: results.y,
|
// y: results.y,
|
||||||
dist2: dist2,
|
// dist2: dist2,
|
||||||
who: domain[i],
|
// who: domain[i],
|
||||||
v1: vertices[j],
|
// v1: vertices[j],
|
||||||
v2: vertices[j + 1]
|
// v2: vertices[j + 1]
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
// results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||||
if (results.onLine1 && results.onLine2) {
|
// if (results.onLine1 && results.onLine2) {
|
||||||
const dx = v1.x - results.x;
|
// const dx = v1.x - results.x;
|
||||||
const dy = v1.y - results.y;
|
// const dy = v1.y - results.y;
|
||||||
const dist2 = dx * dx + dy * dy;
|
// const dist2 = dx * dx + dy * dy;
|
||||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||||
best = {
|
// best = {
|
||||||
x: results.x,
|
// x: results.x,
|
||||||
y: results.y,
|
// y: results.y,
|
||||||
dist2: dist2,
|
// dist2: dist2,
|
||||||
who: domain[i],
|
// who: domain[i],
|
||||||
v1: vertices[0],
|
// v1: vertices[0],
|
||||||
v2: vertices[len]
|
// v2: vertices[len]
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
//check for collisions
|
// //check for collisions
|
||||||
best = {
|
// best = {
|
||||||
x: null,
|
// x: null,
|
||||||
y: null,
|
// y: null,
|
||||||
dist2: Infinity,
|
// dist2: Infinity,
|
||||||
who: null,
|
// who: null,
|
||||||
v1: null,
|
// v1: null,
|
||||||
v2: null
|
// v2: null
|
||||||
};
|
// };
|
||||||
if (tech.isPulseAim) { //find mobs in line of sight
|
// if (tech.isPulseAim) { //find mobs in line of sight
|
||||||
let dist = 2200
|
// let dist = 2200
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
// for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
|
// const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
|
||||||
if (explosionRadius < newDist &&
|
// if (explosionRadius < newDist &&
|
||||||
newDist < dist &&
|
// newDist < dist &&
|
||||||
Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
// Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
||||||
Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
|
// Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
|
||||||
dist = newDist
|
// dist = newDist
|
||||||
best.who = mob[i]
|
// best.who = mob[i]
|
||||||
path[path.length - 1] = mob[i].position
|
// path[path.length - 1] = mob[i].position
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (!best.who) {
|
// if (!best.who) {
|
||||||
vertexCollision(path[0], path[1], mob);
|
// vertexCollision(path[0], path[1], mob);
|
||||||
vertexCollision(path[0], path[1], map);
|
// vertexCollision(path[0], path[1], map);
|
||||||
vertexCollision(path[0], path[1], body);
|
// vertexCollision(path[0], path[1], body);
|
||||||
if (best.dist2 != Infinity) { //if hitting something
|
// if (best.dist2 != Infinity) { //if hitting something
|
||||||
path[path.length - 1] = {
|
// path[path.length - 1] = {
|
||||||
x: best.x,
|
// x: best.x,
|
||||||
y: best.y
|
// y: best.y
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (best.who) b.explosion(path[1], explosionRadius)
|
// if (best.who) b.explosion(path[1], explosionRadius)
|
||||||
|
|
||||||
//draw laser beam
|
// //draw laser beam
|
||||||
ctx.beginPath();
|
// ctx.beginPath();
|
||||||
ctx.moveTo(path[0].x, path[0].y);
|
// ctx.moveTo(path[0].x, path[0].y);
|
||||||
ctx.lineTo(path[1].x, path[1].y);
|
// ctx.lineTo(path[1].x, path[1].y);
|
||||||
ctx.strokeStyle = "rgba(255,0,0,0.13)"
|
// ctx.strokeStyle = "rgba(255,0,0,0.13)"
|
||||||
ctx.lineWidth = 60 * energy / 0.2
|
// ctx.lineWidth = 60 * energy / 0.2
|
||||||
ctx.stroke();
|
// ctx.stroke();
|
||||||
ctx.strokeStyle = "rgba(255,0,0,0.2)"
|
// ctx.strokeStyle = "rgba(255,0,0,0.2)"
|
||||||
ctx.lineWidth = 18
|
// ctx.lineWidth = 18
|
||||||
ctx.stroke();
|
// ctx.stroke();
|
||||||
ctx.strokeStyle = "#f00";
|
// ctx.strokeStyle = "#f00";
|
||||||
ctx.lineWidth = 4
|
// ctx.lineWidth = 4
|
||||||
ctx.stroke();
|
// ctx.stroke();
|
||||||
|
|
||||||
//draw little dots along the laser path
|
// //draw little dots along the laser path
|
||||||
const sub = Vector.sub(path[1], path[0])
|
// const sub = Vector.sub(path[1], path[0])
|
||||||
const mag = Vector.magnitude(sub)
|
// const mag = Vector.magnitude(sub)
|
||||||
for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
|
// for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
|
||||||
const dist = Math.random()
|
// const dist = Math.random()
|
||||||
simulation.drawList.push({
|
// simulation.drawList.push({
|
||||||
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
// x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
||||||
y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
|
// y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
|
||||||
radius: 1 + 4 * Math.random(),
|
// radius: 1 + 4 * Math.random(),
|
||||||
color: "rgba(255,0,0,0.5)",
|
// color: "rgba(255,0,0,0.5)",
|
||||||
time: Math.floor(2 + 33 * Math.random() * Math.random())
|
// time: Math.floor(2 + 33 * Math.random() * Math.random())
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
grenade() {
|
grenade() {
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -2226,7 +2223,7 @@ const b = {
|
|||||||
if (this.target.isShielded) {
|
if (this.target.isShielded) {
|
||||||
this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass
|
this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass
|
||||||
//shrink if mob is shielded
|
//shrink if mob is shielded
|
||||||
const SCALE = 1 - 0.014 / tech.isBulletsLastLonger
|
const SCALE = 1 - 0.01 / tech.isBulletsLastLonger
|
||||||
Matter.Body.scale(this, SCALE, SCALE);
|
Matter.Body.scale(this, SCALE, SCALE);
|
||||||
this.radius *= SCALE;
|
this.radius *= SCALE;
|
||||||
} else {
|
} else {
|
||||||
@@ -2873,7 +2870,7 @@ const b = {
|
|||||||
let closeDist = this.range;
|
let closeDist = this.range;
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
const DIST = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius;
|
const DIST = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius;
|
||||||
if (DIST < closeDist && mob[i].isDropPowerUp &&
|
if (DIST < closeDist &&
|
||||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
|
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
|
||||||
closeDist = DIST;
|
closeDist = DIST;
|
||||||
@@ -4049,16 +4046,18 @@ const b = {
|
|||||||
name: "foam",
|
name: "foam",
|
||||||
description: "spray bubbly foam that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time",
|
description: "spray bubbly foam that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 30,
|
ammoPack: 27,
|
||||||
have: false,
|
have: false,
|
||||||
charge: 0,
|
charge: 0,
|
||||||
isDischarge: false,
|
isDischarge: false,
|
||||||
do() {
|
do() {
|
||||||
if (this.charge > 0) {
|
if (this.charge > 0) {
|
||||||
//draw charge level
|
//draw charge level
|
||||||
ctx.fillStyle = "rgba(0,50,50,0.2)";
|
ctx.fillStyle = "rgba(0,50,50,0.3)";
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 10 * Math.sqrt(this.charge), 0, 2 * Math.PI);
|
const radius = 10 * Math.sqrt(this.charge)
|
||||||
|
const mag = 11 + radius
|
||||||
|
ctx.arc(m.pos.x + mag * Math.cos(m.angle), m.pos.y + mag * Math.sin(m.angle), radius, 0, 2 * Math.PI);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
|
||||||
if (this.isDischarge) {
|
if (this.isDischarge) {
|
||||||
@@ -4094,15 +4093,15 @@ const b = {
|
|||||||
x: position.x,
|
x: position.x,
|
||||||
y: position.y,
|
y: position.y,
|
||||||
radius: 5,
|
radius: 5,
|
||||||
color: "rgba(0,0,0,0.1)",
|
color: "rgba(0,50,50,0.3)",
|
||||||
time: 15 * tech.foamFutureFire
|
time: 15 * tech.foamFutureFire
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!simulation.paused) {
|
if (!simulation.paused) {
|
||||||
b.foam(position, Vector.rotate(velocity, spread), radius)
|
b.foam(position, Vector.rotate(velocity, spread), radius)
|
||||||
bullet[bullet.length - 1].damage = (1 + 1.27 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
|
bullet[bullet.length - 1].damage = (1 + 0.9 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
|
||||||
}
|
}
|
||||||
}, 250 * tech.foamFutureFire);
|
}, 300 * tech.foamFutureFire);
|
||||||
} else {
|
} else {
|
||||||
b.foam(position, Vector.rotate(velocity, spread), radius)
|
b.foam(position, Vector.rotate(velocity, spread), radius)
|
||||||
}
|
}
|
||||||
@@ -4467,14 +4466,43 @@ const b = {
|
|||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: Infinity,
|
ammoPack: Infinity,
|
||||||
have: false,
|
have: false,
|
||||||
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
|
charge: 0,
|
||||||
do() {},
|
do() {},
|
||||||
fire() {
|
fire() {},
|
||||||
|
|
||||||
},
|
|
||||||
chooseFireMethod() {
|
chooseFireMethod() {
|
||||||
|
this.do = () => {};
|
||||||
if (tech.isPulseLaser) {
|
if (tech.isPulseLaser) {
|
||||||
this.fire = this.firePulse
|
this.fire = () => {
|
||||||
|
|
||||||
|
const drain = 0.01 * tech.isLaserDiode / b.fireCD
|
||||||
|
if (m.energy > drain) {
|
||||||
|
m.energy -= m.fieldRegen
|
||||||
|
if (this.charge < 50 * m.maxEnergy) {
|
||||||
|
m.energy -= drain
|
||||||
|
this.charge += 1 / b.fireCD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.do = () => {
|
||||||
|
if (this.charge > 0) {
|
||||||
|
//draw charge level
|
||||||
|
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.pos.x, m.pos.y, 4.2 * Math.sqrt(this.charge), 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
if (!input.fire) {
|
||||||
|
m.fireCDcycle = m.cycle + 10; // cool down
|
||||||
|
if (tech.beamSplitter) {
|
||||||
|
const divergence = m.crouch ? 0.2 : 0.5
|
||||||
|
const angle = m.angle - tech.beamSplitter * divergence / 2
|
||||||
|
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
|
||||||
|
} else {
|
||||||
|
b.pulse(1.75 * this.charge, m.angle)
|
||||||
|
}
|
||||||
|
this.charge = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
} else if (tech.beamSplitter) {
|
} else if (tech.beamSplitter) {
|
||||||
this.fire = this.fireSplit
|
this.fire = this.fireSplit
|
||||||
} else if (tech.historyLaser) {
|
} else if (tech.historyLaser) {
|
||||||
@@ -4627,27 +4655,27 @@ const b = {
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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.fireCD); // 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) {
|
||||||
// energy *= Math.pow(0.9, tech.beamSplitter)
|
// // energy *= Math.pow(0.9, tech.beamSplitter)
|
||||||
// b.pulse(energy, m.angle)
|
// // b.pulse(energy, m.angle)
|
||||||
// for (let i = 1; i < 1 + tech.beamSplitter; i++) {
|
// // for (let i = 1; i < 1 + tech.beamSplitter; i++) {
|
||||||
// b.pulse(energy, m.angle - i * 0.27)
|
// // b.pulse(energy, m.angle - i * 0.27)
|
||||||
// b.pulse(energy, m.angle + i * 0.27)
|
// // b.pulse(energy, m.angle + i * 0.27)
|
||||||
// }
|
// // }
|
||||||
const divergence = m.crouch ? 0.2 : 0.5
|
// const divergence = m.crouch ? 0.2 : 0.5
|
||||||
const angle = m.angle - tech.beamSplitter * divergence / 2
|
// const angle = m.angle - tech.beamSplitter * divergence / 2
|
||||||
for (let i = 0; i < 1 + tech.beamSplitter; i++) {
|
// for (let i = 0; i < 1 + tech.beamSplitter; i++) {
|
||||||
b.pulse(energy, angle + i * divergence)
|
// b.pulse(energy, angle + i * divergence)
|
||||||
}
|
// }
|
||||||
|
|
||||||
} else {
|
// } else {
|
||||||
b.pulse(energy, m.angle)
|
// b.pulse(energy, m.angle)
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
gunRewind: { //this gun is added with a tech
|
gunRewind: { //this gun is added with a tech
|
||||||
|
|||||||
12
js/index.js
12
js/index.js
@@ -794,17 +794,7 @@ window.addEventListener("keydown", function(event) {
|
|||||||
simulation.testing = true;
|
simulation.testing = true;
|
||||||
simulation.loop = simulation.testingLoop
|
simulation.loop = simulation.testingLoop
|
||||||
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
|
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
|
||||||
if (!simulation.isCheating) {
|
if (simulation.testing) tech.setCheating();
|
||||||
simulation.isCheating = true;
|
|
||||||
level.levelAnnounce();
|
|
||||||
lore.techCount = 0;
|
|
||||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
|
||||||
if (tech.tech[i].isLore) {
|
|
||||||
tech.tech[i].frequency = 0;
|
|
||||||
tech.tech[i].count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
simulation.makeTextLog(
|
simulation.makeTextLog(
|
||||||
`<table class="pause-table">
|
`<table class="pause-table">
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
10
js/level.js
10
js/level.js
@@ -12,14 +12,15 @@ const level = {
|
|||||||
start() {
|
start() {
|
||||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.difficultyIncrease(50)
|
// level.difficultyIncrease(30)
|
||||||
// simulation.zoomScale = 1000;
|
// simulation.zoomScale = 1000;
|
||||||
// simulation.setZoom();
|
// simulation.setZoom();
|
||||||
// m.setField("nano-scale manufacturing")
|
// m.setField("nano-scale manufacturing")
|
||||||
// b.giveGuns("foam")
|
// b.giveGuns("foam")
|
||||||
|
// b.giveGuns("laser")
|
||||||
// tech.isExplodeRadio = true
|
// tech.isExplodeRadio = true
|
||||||
// for (let i = 0; i < 9; i++) tech.giveTech("auto-loading heuristics")
|
// for (let i = 0; i < 9; i++) tech.giveTech("auto-loading heuristics")
|
||||||
// tech.giveTech("superfluidity")
|
// tech.giveTech("pulse")
|
||||||
// tech.giveTech("ice crystal nucleation")
|
// tech.giveTech("ice crystal nucleation")
|
||||||
// tech.giveTech("needle gun")
|
// tech.giveTech("needle gun")
|
||||||
// tech.giveTech("cardinality")
|
// tech.giveTech("cardinality")
|
||||||
@@ -1109,9 +1110,8 @@ const level = {
|
|||||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
spawn.mapRect(6700, -1800, 800, 2600); //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
|
||||||
|
|
||||||
// simulation.difficulty = 30
|
spawn.starter(1900, -500, 200) //big boy
|
||||||
spawn.starter(1900, -500, 100) //big boy
|
// spawn.grower(1900, -500)
|
||||||
spawn.grower(1900, -500)
|
|
||||||
// spawn.pulsarBoss(1900, -500)
|
// spawn.pulsarBoss(1900, -500)
|
||||||
// spawn.shooterBoss(1900, -500)
|
// spawn.shooterBoss(1900, -500)
|
||||||
// spawn.launcherBoss(1200, -500)
|
// spawn.launcherBoss(1200, -500)
|
||||||
|
|||||||
@@ -1145,20 +1145,20 @@ const m = {
|
|||||||
m.fieldCDcycle = m.cycle + 15;
|
m.fieldCDcycle = m.cycle + 15;
|
||||||
m.isHolding = false;
|
m.isHolding = false;
|
||||||
//bullet-like collisions
|
//bullet-like collisions
|
||||||
m.holdingTarget.collisionFilter.category = cat.bullet; //cat.body;
|
// m.holdingTarget.collisionFilter.category = cat.bullet; //cat.body;
|
||||||
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
|
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
|
||||||
//check every second to see if player is away from thrown body, and make solid
|
//check every second to see if player is away from thrown body, and make solid
|
||||||
const solid = function(that) {
|
const solid = function(that) {
|
||||||
const dx = that.position.x - player.position.x;
|
const dx = that.position.x - player.position.x;
|
||||||
const dy = that.position.y - player.position.y;
|
const dy = that.position.y - player.position.y;
|
||||||
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
|
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
|
||||||
that.collisionFilter.category = cat.body; //make solid
|
// that.collisionFilter.category = cat.body; //make solid
|
||||||
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
|
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
|
||||||
} else {
|
} else {
|
||||||
setTimeout(solid, 50, that);
|
setTimeout(solid, 40, that);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setTimeout(solid, 500, m.holdingTarget);
|
setTimeout(solid, 200, m.holdingTarget);
|
||||||
|
|
||||||
const charge = Math.min(m.throwCharge / 5, 1)
|
const charge = Math.min(m.throwCharge / 5, 1)
|
||||||
//***** scale throw speed with the first number, 80 *****
|
//***** scale throw speed with the first number, 80 *****
|
||||||
|
|||||||
16
js/spawn.js
16
js/spawn.js
@@ -1621,9 +1621,9 @@ const spawn = {
|
|||||||
ctx.moveTo(this.vertices[1].x, this.vertices[1].y)
|
ctx.moveTo(this.vertices[1].x, this.vertices[1].y)
|
||||||
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
||||||
ctx.lineWidth = 20;
|
ctx.lineWidth = 20;
|
||||||
ctx.strokeStyle = "rgba(120,0,255,0.2)";
|
ctx.strokeStyle = "rgba(120,0,255,0.3)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineWidth = 4;
|
ctx.lineWidth = 5;
|
||||||
ctx.strokeStyle = "rgba(120,0,255,1)";
|
ctx.strokeStyle = "rgba(120,0,255,1)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
} else { //delay before firing
|
} else { //delay before firing
|
||||||
@@ -1631,7 +1631,7 @@ const spawn = {
|
|||||||
//draw explosion outline
|
//draw explosion outline
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
||||||
ctx.fillStyle = "rgba(120,0,255,0.05)";
|
ctx.fillStyle = "rgba(120,0,255,0.07)";
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
//draw path from mob to explosion
|
//draw path from mob to explosion
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -1639,7 +1639,7 @@ const spawn = {
|
|||||||
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
||||||
ctx.setLineDash([40 * Math.random(), 200 * Math.random()]);
|
ctx.setLineDash([40 * Math.random(), 200 * Math.random()]);
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeStyle = "rgba(120,0,255,0.2)";
|
ctx.strokeStyle = "rgba(120,0,255,0.3)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.setLineDash([0, 0]);
|
ctx.setLineDash([0, 0]);
|
||||||
}
|
}
|
||||||
@@ -1741,9 +1741,9 @@ const spawn = {
|
|||||||
ctx.moveTo(this.vertices[1].x, this.vertices[1].y)
|
ctx.moveTo(this.vertices[1].x, this.vertices[1].y)
|
||||||
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
||||||
ctx.lineWidth = 20;
|
ctx.lineWidth = 20;
|
||||||
ctx.strokeStyle = "rgba(255,0,100,0.2)";
|
ctx.strokeStyle = "rgba(255,0,100,0.3)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineWidth = 4;
|
ctx.lineWidth = 5;
|
||||||
ctx.strokeStyle = "rgba(255,0,100,1)";
|
ctx.strokeStyle = "rgba(255,0,100,1)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
} else { //delay before firing
|
} else { //delay before firing
|
||||||
@@ -1754,7 +1754,7 @@ const spawn = {
|
|||||||
//draw explosion outline
|
//draw explosion outline
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
||||||
ctx.fillStyle = "rgba(255,0,100,0.05)";
|
ctx.fillStyle = "rgba(255,0,100,0.07)";
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
//draw path from mob to explosion
|
//draw path from mob to explosion
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -1762,7 +1762,7 @@ const spawn = {
|
|||||||
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
ctx.lineTo(this.fireTarget.x, this.fireTarget.y)
|
||||||
ctx.setLineDash([40 * Math.random(), 200 * Math.random()]);
|
ctx.setLineDash([40 * Math.random(), 200 * Math.random()]);
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeStyle = "rgba(255,0,100,0.2)";
|
ctx.strokeStyle = "rgba(255,0,100,0.3)";
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.setLineDash([0, 0]);
|
ctx.setLineDash([0, 0]);
|
||||||
}
|
}
|
||||||
|
|||||||
221
js/tech.js
221
js/tech.js
@@ -107,6 +107,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setCheating() {
|
||||||
|
simulation.isCheating = true;
|
||||||
|
level.levelAnnounce();
|
||||||
|
lore.techCount = 0;
|
||||||
|
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||||
|
if (tech.tech[i].isLore) {
|
||||||
|
tech.tech[i].frequency = 0;
|
||||||
|
tech.tech[i].count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
haveGunCheck(name) {
|
haveGunCheck(name) {
|
||||||
if (
|
if (
|
||||||
!build.isExperimentSelection &&
|
!build.isExperimentSelection &&
|
||||||
@@ -745,7 +756,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nitroglycerin",
|
name: "nitroglycerin",
|
||||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>60%</strong><br>decrease <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>20%</strong>",
|
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>66%</strong><br>decrease <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>33%</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
@@ -778,6 +789,24 @@
|
|||||||
tech.isExplosionHarm = false;
|
tech.isExplosionHarm = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "shock wave",
|
||||||
|
description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>40%</strong>",
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
allowed() {
|
||||||
|
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1)
|
||||||
|
},
|
||||||
|
requires: "an explosive damage source, not iridium-192",
|
||||||
|
effect() {
|
||||||
|
tech.isExplosionStun = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isExplosionStun = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "electric reactive armor",
|
name: "electric reactive armor",
|
||||||
// description: "<strong class='color-e'>explosions</strong> do no <strong class='color-harm'>harm</strong><br> while your <strong class='color-f'>energy</strong> is above <strong>98%</strong>",
|
// description: "<strong class='color-e'>explosions</strong> do no <strong class='color-harm'>harm</strong><br> while your <strong class='color-f'>energy</strong> is above <strong>98%</strong>",
|
||||||
@@ -1443,9 +1472,9 @@
|
|||||||
frequency: 4,
|
frequency: 4,
|
||||||
frequencyDefault: 4,
|
frequencyDefault: 4,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole"
|
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "mass driver, a field that can hold things",
|
requires: "mass driver, a field that can hold things, not mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isBlockHarm = true
|
tech.isBlockHarm = true
|
||||||
},
|
},
|
||||||
@@ -1687,23 +1716,6 @@
|
|||||||
tech.isHarmFreeze = false;
|
tech.isHarmFreeze = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "osmoprotectant",
|
|
||||||
description: `collisions with <strong>stunned</strong> or <strong class='color-s'>frozen</strong> mobs<br>cause you <strong>no</strong> <strong class='color-harm'>harm</strong>`,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.isStunField || tech.isPulseStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1
|
|
||||||
},
|
|
||||||
requires: "a freezing or stunning effect",
|
|
||||||
effect() {
|
|
||||||
tech.isFreezeHarmImmune = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isFreezeHarmImmune = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "superfluidity",
|
name: "superfluidity",
|
||||||
description: "<strong class='color-s'>freeze</strong> effects are applied to a small area",
|
description: "<strong class='color-s'>freeze</strong> effects are applied to a small area",
|
||||||
@@ -1721,6 +1733,40 @@
|
|||||||
tech.isAoESlow = false
|
tech.isAoESlow = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "osmoprotectant",
|
||||||
|
description: `collisions with <strong>stunned</strong> or <strong class='color-s'>frozen</strong> mobs<br>cause you <strong>no</strong> <strong class='color-harm'>harm</strong>`,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
allowed() {
|
||||||
|
return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1
|
||||||
|
},
|
||||||
|
requires: "a freezing or stunning effect",
|
||||||
|
effect() {
|
||||||
|
tech.isFreezeHarmImmune = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isFreezeHarmImmune = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fracture analysis",
|
||||||
|
description: "bullet impacts do <strong>400%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> mobs",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
allowed() {
|
||||||
|
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isPerpetualStun || tech.isExplosionStun
|
||||||
|
},
|
||||||
|
requires: "a stun effect",
|
||||||
|
effect() {
|
||||||
|
tech.isCrit = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isCrit = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ablative drones",
|
name: "ablative drones",
|
||||||
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
|
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
|
||||||
@@ -2124,9 +2170,9 @@
|
|||||||
frequency: 4,
|
frequency: 4,
|
||||||
frequencyDefault: 4,
|
frequencyDefault: 4,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.isDamageAfterKill
|
return tech.isDamageAfterKill && !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "dormancy",
|
requires: "dormancy, not mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isHarmReduceAfterKill = true;
|
tech.isHarmReduceAfterKill = true;
|
||||||
},
|
},
|
||||||
@@ -2553,6 +2599,7 @@
|
|||||||
if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech
|
if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech
|
||||||
|
|
||||||
tech.setupAllTech(); // remove all tech
|
tech.setupAllTech(); // remove all tech
|
||||||
|
if (simulation.isCheating) tech.setCheating();
|
||||||
lore.techCount = 0;
|
lore.techCount = 0;
|
||||||
// tech.addLoreTechToPool();
|
// tech.addLoreTechToPool();
|
||||||
for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups
|
for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups
|
||||||
@@ -4006,7 +4053,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quantum foam",
|
name: "quantum foam",
|
||||||
description: "<strong>foam</strong> gun fires <strong>0.25</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>127%</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>",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -4302,7 +4349,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pulse",
|
name: "pulse",
|
||||||
description: "use <strong>25%</strong> of your <strong class='color-f'>energy</strong> in a pulsed <strong class='color-laser'>laser</strong><br>that instantly initiates a fusion <strong class='color-e'>explosion</strong>",
|
description: "charge your <strong class='color-f'>energy</strong> and release it as a<br><strong class='color-laser'>laser</strong> pulse that initiates an <strong class='color-e'>explosion</strong> cluster",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -4326,27 +4373,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "shock wave",
|
|
||||||
description: "mobs caught in <strong class='color-laser'>pulse</strong>'s explosion are <strong>stunned</strong><br>for up to <strong>2 seconds</strong>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.isPulseLaser
|
|
||||||
},
|
|
||||||
requires: "pulse",
|
|
||||||
effect() {
|
|
||||||
tech.isPulseStun = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isPulseStun = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "neocognitron",
|
name: "neocognitron",
|
||||||
description: "<strong class='color-laser'>pulse</strong> automatically <strong>aims</strong> at a nearby mob<br><strong>50%</strong> decreased <strong><em>delay</em></strong> after firing",
|
description: "<strong class='color-laser'>pulse</strong> automatically <strong>aims</strong> at a nearby mob",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -4366,6 +4395,28 @@
|
|||||||
//************************************************** field
|
//************************************************** field
|
||||||
//************************************************** tech
|
//************************************************** tech
|
||||||
//**************************************************
|
//**************************************************
|
||||||
|
{
|
||||||
|
name: "frequency resonance",
|
||||||
|
description: "<strong>standing wave harmonics</strong> shield is retuned<br>increase <strong>size</strong> and <strong>blocking</strong> efficiency by <strong>50%</strong>",
|
||||||
|
isFieldTech: true,
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
allowed() {
|
||||||
|
return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics"
|
||||||
|
},
|
||||||
|
requires: "standing wave harmonics",
|
||||||
|
effect() {
|
||||||
|
tech.frequencyResonance = this.count + 1 // +1 because count updates later
|
||||||
|
m.fieldRange = 175 + 175 * 0.25 * tech.frequencyResonance
|
||||||
|
m.fieldShieldingScale = Math.pow(0.5, tech.frequencyResonance)
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
m.fieldRange = 175;
|
||||||
|
m.fieldShieldingScale = 1;
|
||||||
|
tech.frequencyResonance = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "bremsstrahlung",
|
name: "bremsstrahlung",
|
||||||
description: "<strong>blocking</strong> does <strong class='color-d'>damage</strong> to mobs",
|
description: "<strong>blocking</strong> does <strong class='color-d'>damage</strong> to mobs",
|
||||||
@@ -4402,28 +4453,6 @@
|
|||||||
tech.blockingIce = 0;
|
tech.blockingIce = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "frequency resonance",
|
|
||||||
description: "<strong>standing wave harmonics</strong> shield is retuned<br>increase <strong>size</strong> and <strong>blocking</strong> efficiency by <strong>50%</strong>",
|
|
||||||
isFieldTech: true,
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
allowed() {
|
|
||||||
return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics"
|
|
||||||
},
|
|
||||||
requires: "standing wave harmonics",
|
|
||||||
effect() {
|
|
||||||
tech.frequencyResonance = this.count + 1 // +1 because count updates later
|
|
||||||
m.fieldRange = 175 + 175 * 0.25 * tech.frequencyResonance
|
|
||||||
m.fieldShieldingScale = Math.pow(0.5, tech.frequencyResonance)
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
m.fieldRange = 175;
|
|
||||||
m.fieldShieldingScale = 1;
|
|
||||||
tech.frequencyResonance = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "flux pinning",
|
name: "flux pinning",
|
||||||
description: "blocking with your <strong>field</strong><br><strong>stuns</strong> mobs for <strong>+2</strong> second",
|
description: "blocking with your <strong>field</strong><br><strong>stuns</strong> mobs for <strong>+2</strong> second",
|
||||||
@@ -4442,24 +4471,6 @@
|
|||||||
tech.isStunField = 0;
|
tech.isStunField = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "fracture analysis",
|
|
||||||
description: "bullet impacts do <strong>400%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> mobs",
|
|
||||||
isFieldTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isPerpetualStun
|
|
||||||
},
|
|
||||||
requires: "a stun effect",
|
|
||||||
effect() {
|
|
||||||
tech.isCrit = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isCrit = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "eddy current brake",
|
name: "eddy current brake",
|
||||||
description: "project a field that limits the <strong>top speed</strong> of mobs<br>field <strong>radius</strong> scales with stored <strong class='color-f'>energy</strong>",
|
description: "project a field that limits the <strong>top speed</strong> of mobs<br>field <strong>radius</strong> scales with stored <strong class='color-f'>energy</strong>",
|
||||||
@@ -4478,25 +4489,6 @@
|
|||||||
tech.isPerfectBrake = false;
|
tech.isPerfectBrake = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "pair production",
|
|
||||||
description: "picking up a <strong>power up</strong> gives you <strong>250</strong> <strong class='color-f'>energy</strong>",
|
|
||||||
isFieldTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
allowed() {
|
|
||||||
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
|
||||||
},
|
|
||||||
requires: "nano-scale manufacturing",
|
|
||||||
effect: () => {
|
|
||||||
tech.isMassEnergy = true // used in m.grabPowerUp
|
|
||||||
m.energy += 3
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isMassEnergy = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "bot manufacturing",
|
name: "bot manufacturing",
|
||||||
description: "use <strong>nano-scale manufacturing</strong><br>to build <strong>3</strong> random <strong class='color-bot'>bots</strong>",
|
description: "use <strong>nano-scale manufacturing</strong><br>to build <strong>3</strong> random <strong class='color-bot'>bots</strong>",
|
||||||
@@ -4608,6 +4600,25 @@
|
|||||||
},
|
},
|
||||||
remove() {}
|
remove() {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "pair production",
|
||||||
|
description: "picking up a <strong>power up</strong> gives you <strong>250</strong> <strong class='color-f'>energy</strong>",
|
||||||
|
isFieldTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
allowed() {
|
||||||
|
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
||||||
|
},
|
||||||
|
requires: "nano-scale manufacturing",
|
||||||
|
effect: () => {
|
||||||
|
tech.isMassEnergy = true // used in m.grabPowerUp
|
||||||
|
m.energy += 3
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isMassEnergy = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "mycelium manufacturing",
|
name: "mycelium manufacturing",
|
||||||
description: "<strong>nano-scale manufacturing</strong> is repurposed<br>excess <strong class='color-f'>energy</strong> used to grow <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
|
description: "<strong>nano-scale manufacturing</strong> is repurposed<br>excess <strong class='color-f'>energy</strong> used to grow <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
|
||||||
@@ -4688,9 +4699,9 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return m.fieldUpgrades[m.fieldMode].name === "negative mass field"
|
return m.fieldUpgrades[m.fieldMode].name === "negative mass field" && !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "negative mass field",
|
requires: "negative mass field, not mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isHarmReduce = true
|
tech.isHarmReduce = true
|
||||||
},
|
},
|
||||||
@@ -6304,7 +6315,7 @@
|
|||||||
isSporeFollow: null,
|
isSporeFollow: null,
|
||||||
isNailRadiation: null,
|
isNailRadiation: null,
|
||||||
isEnergyHealth: null,
|
isEnergyHealth: null,
|
||||||
isPulseStun: null,
|
isExplosionStun: null,
|
||||||
restDamage: null,
|
restDamage: null,
|
||||||
isRPG: null,
|
isRPG: null,
|
||||||
missileCount: null,
|
missileCount: null,
|
||||||
|
|||||||
22
todo.txt
22
todo.txt
@@ -1,5 +1,11 @@
|
|||||||
******************************************************** NEXT PATCH ********************************************************
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
|
pulse laser now charges up with energy before you fire, but it fires 3 overlapping explosions
|
||||||
|
please give feedback on balance (too strong, too weak?)
|
||||||
|
|
||||||
|
tech shockwave: now applies to all explosions
|
||||||
|
|
||||||
|
foam gun now gets 20% less ammo
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
@@ -18,9 +24,9 @@ fix door.isOpen actually meaning isClosed?
|
|||||||
wasn't able to understand bug after extensive testing
|
wasn't able to understand bug after extensive testing
|
||||||
had tech: complex spin statistics
|
had tech: complex spin statistics
|
||||||
|
|
||||||
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
||||||
|
|
||||||
(always) is there a way to check if the player is stuck inside the map or block
|
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
|
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
|
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
|
||||||
@@ -33,8 +39,16 @@ fix door.isOpen actually meaning isClosed?
|
|||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
edit foam gun text?
|
avoid taking collision damage by teleporting to a random power up
|
||||||
add a foam charge meter would be nice
|
removes the power up
|
||||||
|
|
||||||
|
make a tech that improves all charge guns
|
||||||
|
for: pulse, foam, rail gun
|
||||||
|
effect:
|
||||||
|
faster charge rate?
|
||||||
|
fire speed already does that...
|
||||||
|
harm reduction while charging
|
||||||
|
less ammo/energy used while charging?
|
||||||
|
|
||||||
apply the new gun.do functions to other guns
|
apply the new gun.do functions to other guns
|
||||||
rail gun
|
rail gun
|
||||||
|
|||||||
Reference in New Issue
Block a user