laserLayer
mob: laserLayer - leaves behind lasers that persist for a few seconds
ghoster mobs do 66% less damage, but they eject your ammo
grappling hook tech rupture renamed swarf
fires several nails at nearby mobs, not explosions
grappling hook 6->9 energy per second
CIWS 18->10 energy
reel +40->75 energy reeling blocks
wormhole 5->7% duplication
cloaking no longer drains energy, this fixes a can't cloak bug
dazzler no longer drains energy
dazzler range reduced by 15%
dazzler stuns for 3->2 seconds
zero point energy 100->166 max energy
expansion 40->77 max energy
annihilation -33% of max energy -> 10 energy
dynamical systems is no longer a field tech 35->30 damage
tessellation is no longer a field tech 50->35 defense
yield stress removed
topological defect 80->111% damage
brittle 80->111% damage
commodities exchange 6-12 -> 10-14 power ups
heat engine 50->40% damage
flame test grenades clusters explode 40% faster
alternator uses 10->0% energy for harpoon
finally made a shared vertexCollision function
this might cause some bugs with laser-like effects...
This commit is contained in:
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 57 KiB |
496
js/bullet.js
496
js/bullet.js
@@ -558,46 +558,6 @@ const b = {
|
||||
y: where.y + range * Math.sin(angle)
|
||||
}
|
||||
];
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//check for collisions
|
||||
best = {
|
||||
x: null,
|
||||
@@ -607,28 +567,8 @@ const b = {
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
// if (tech.isPulseAim && !m.crouch) { //find mobs in line of sight
|
||||
// let dist = 2200
|
||||
// for (let i = 0, len = mob.length; i < len; i++) {
|
||||
// const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
|
||||
// if (
|
||||
// explosionRadius < newDist &&
|
||||
// newDist < dist &&
|
||||
// !mob[i].isBadTarget &&
|
||||
// Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
||||
// Matter.Query.ray(body, path[0], mob[i].position).length === 0 &&
|
||||
// !mob[i].isInvulnerable
|
||||
// ) {
|
||||
// dist = newDist
|
||||
// best.who = mob[i]
|
||||
// path[path.length - 1] = mob[i].position
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (!best.who) {
|
||||
vertexCollision(path[0], path[1], mob);
|
||||
vertexCollision(path[0], path[1], map);
|
||||
vertexCollision(path[0], path[1], body);
|
||||
best = vertexCollision(path[0], path[1], [mob, map, body]);
|
||||
if (best.dist2 != Infinity) { //if hitting something
|
||||
path[path.length - 1] = {
|
||||
x: best.x,
|
||||
@@ -678,135 +618,20 @@ const b = {
|
||||
});
|
||||
}
|
||||
},
|
||||
// photon(where, angle = m.angle) {
|
||||
// let best;
|
||||
// const path = [{
|
||||
// x: m.pos.x + 20 * Math.cos(angle),
|
||||
// y: m.pos.y + 20 * Math.sin(angle)
|
||||
// },
|
||||
// {
|
||||
// x: m.pos.x + range * Math.cos(angle),
|
||||
// y: m.pos.y + range * Math.sin(angle)
|
||||
// }
|
||||
// ];
|
||||
// const vertexCollision = function(v1, v1End, domain) {
|
||||
// for (let i = 0; i < domain.length; ++i) {
|
||||
// let vertices = domain[i].vertices;
|
||||
// const len = vertices.length - 1;
|
||||
// for (let j = 0; j < len; j++) {
|
||||
// results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
// if (results.onLine1 && results.onLine2) {
|
||||
// const dx = v1.x - results.x;
|
||||
// const dy = v1.y - results.y;
|
||||
// const dist2 = dx * dx + dy * dy;
|
||||
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
// best = {
|
||||
// x: results.x,
|
||||
// y: results.y,
|
||||
// dist2: dist2,
|
||||
// who: domain[i],
|
||||
// v1: vertices[j],
|
||||
// v2: vertices[j + 1]
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
// if (results.onLine1 && results.onLine2) {
|
||||
// const dx = v1.x - results.x;
|
||||
// const dy = v1.y - results.y;
|
||||
// const dist2 = dx * dx + dy * dy;
|
||||
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
// best = {
|
||||
// x: results.x,
|
||||
// y: results.y,
|
||||
// dist2: dist2,
|
||||
// who: domain[i],
|
||||
// v1: vertices[0],
|
||||
// v2: vertices[len]
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// //check for collisions
|
||||
// best = {
|
||||
// x: null,
|
||||
// y: null,
|
||||
// dist2: Infinity,
|
||||
// who: null,
|
||||
// v1: null,
|
||||
// v2: null
|
||||
// };
|
||||
// if (tech.isPulseAim) { //find mobs in line of sight
|
||||
// let dist = 2200
|
||||
// for (let i = 0, len = mob.length; i < len; i++) {
|
||||
// const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
|
||||
// if (explosionRadius < newDist &&
|
||||
// newDist < dist &&
|
||||
// Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
||||
// Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
|
||||
// dist = newDist
|
||||
// best.who = mob[i]
|
||||
// path[path.length - 1] = mob[i].position
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (!best.who) {
|
||||
// vertexCollision(path[0], path[1], mob);
|
||||
// vertexCollision(path[0], path[1], map);
|
||||
// vertexCollision(path[0], path[1], body);
|
||||
// if (best.dist2 != Infinity) { //if hitting something
|
||||
// path[path.length - 1] = {
|
||||
// x: best.x,
|
||||
// y: best.y
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// if (best.who) b.explosion(path[1], explosionRadius)
|
||||
|
||||
// //draw laser beam
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(path[0].x, path[0].y);
|
||||
// ctx.lineTo(path[1].x, path[1].y);
|
||||
// ctx.strokeStyle = "rgba(255,0,0,0.13)"
|
||||
// ctx.lineWidth = 60 * energy / 0.2
|
||||
// ctx.stroke();
|
||||
// ctx.strokeStyle = "rgba(255,0,0,0.2)"
|
||||
// ctx.lineWidth = 18
|
||||
// ctx.stroke();
|
||||
// ctx.strokeStyle = "#f00";
|
||||
// ctx.lineWidth = 4
|
||||
// ctx.stroke();
|
||||
|
||||
// //draw little dots along the laser path
|
||||
// const sub = Vector.sub(path[1], path[0])
|
||||
// const mag = Vector.magnitude(sub)
|
||||
// for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
|
||||
// const dist = Math.random()
|
||||
// simulation.drawList.push({
|
||||
// x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
||||
// y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
|
||||
// radius: 1 + 4 * Math.random(),
|
||||
// color: "rgba(255,0,0,0.5)",
|
||||
// time: Math.floor(2 + 33 * Math.random() * Math.random())
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
fireworks(where, size) { //can occur after grenades detonate
|
||||
clusterExplode(where, size) { //can occur after grenades detonate
|
||||
const cycle = () => {
|
||||
if (m.alive) {
|
||||
if (simulation.paused || m.isBodiesAsleep) {
|
||||
requestAnimationFrame(cycle)
|
||||
} else {
|
||||
count++
|
||||
if (count < 130) requestAnimationFrame(cycle);
|
||||
if (!(count % 10)) {
|
||||
if (count < 84) requestAnimationFrame(cycle);
|
||||
if (!(count % 7)) {
|
||||
const unit = Vector.rotate({
|
||||
x: 1,
|
||||
y: 0
|
||||
}, 6.28 * Math.random())
|
||||
b.explosion(Vector.add(where, Vector.mult(unit, size * (count * 0.01 + 0.02 * Math.random()))), size * (0.4 + Math.random() * 0.35), `hsla(${360 * Math.random()},100%,66%,0.6)`); //makes bullet do explosive damage at end
|
||||
b.explosion(Vector.add(where, Vector.mult(unit, size * (count * 0.01 + 0.03 * Math.random()))), size * (0.4 + Math.random() * 0.35), `hsla(${360 * Math.random()},100%,66%,0.6)`); //makes bullet do explosive damage at end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -884,7 +709,7 @@ const b = {
|
||||
} else if (tech.isPetalsExplode) {
|
||||
b.fireFlower(this.position, this.explodeRad)
|
||||
} else if (tech.isClusterExplode) {
|
||||
b.fireworks(this.position, this.explodeRad)
|
||||
b.clusterExplode(this.position, this.explodeRad)
|
||||
} else {
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
}
|
||||
@@ -1501,7 +1326,7 @@ const b = {
|
||||
drawStringControlMagnitude: 1000 + 1000 * Math.random(),
|
||||
drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
|
||||
attached: false,
|
||||
glowColor: tech.isHookExplosion ? "rgba(200,0,0,0.07)" : tech.isHarmReduce ? "rgba(50,100,255,0.1)" : "rgba(0,200,255,0.07)",
|
||||
glowColor: tech.hookNails ? "rgba(200,0,0,0.07)" : tech.isHarmReduce ? "rgba(50,100,255,0.1)" : "rgba(0,200,255,0.07)",
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
|
||||
@@ -1598,14 +1423,20 @@ const b = {
|
||||
});
|
||||
}
|
||||
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
||||
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.hookNails) {
|
||||
// if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + 5; //player is immune to damage for 5 cycles
|
||||
// b.explosion(this.position, 300 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
b.targetedNail(this.position, tech.hookNails)
|
||||
const ANGLE = 2 * Math.PI * Math.random() //make a few random ones
|
||||
for (let i = 0; i < 4; i++) b.nail(this.position, { x: 10.5 * Math.cos(ANGLE), y: 10.5 * Math.sin(ANGLE) }, 1.2)
|
||||
}
|
||||
// if (this.powerUpDamage) this.density = 2 * 0.004 //double damage after pick up power up for 8 seconds
|
||||
|
||||
|
||||
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) {
|
||||
Matter.Body.setDensity(this, 1.8 * 0.004); //+90% damage after pick up power up for 8 seconds
|
||||
} else if (tech.isHarpoonFullHealth && who.health === 1) {
|
||||
Matter.Body.setDensity(this, 1.9 * 0.004); //+90% damage if mob has full health do
|
||||
Matter.Body.setDensity(this, 2.11 * 0.004); //+90% damage if mob has full health do
|
||||
simulation.ephemera.push({
|
||||
name: "grapple outline",
|
||||
count: 3, //cycles before it self removes
|
||||
@@ -1688,7 +1519,7 @@ const b = {
|
||||
if (this.pickUpTarget) {
|
||||
if (tech.isReel && this.blockDist > 150) {
|
||||
// console.log(0.0003 * Math.min(this.blockDist, 1000))
|
||||
m.energy += 0.00044 * Math.min(this.blockDist, 800) //max 0.352 energy
|
||||
m.energy += 0.0009 * Math.min(this.blockDist, 800) //max 0.352 energy
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: m.pos.x,
|
||||
y: m.pos.y,
|
||||
@@ -1758,10 +1589,15 @@ const b = {
|
||||
if (blocks.length) {
|
||||
// console.log(blocks)
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
if (blocks[i].bodyA.classType === "body" && !blocks[i].bodyA.isNotHoldable && !blocks[0].bodyA.mass < 60) {
|
||||
if (blocks[i].bodyA.classType === "body" && !blocks[i].bodyA.isNotHoldable && blocks[0].bodyA.mass < 60) {
|
||||
this.retract()
|
||||
if (tech.isHookExplosion) {
|
||||
b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.hookNails) {
|
||||
// if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + 5; //player is immune to damage for 5 cycles
|
||||
// b.explosion(this.position, 300 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
b.targetedNail(this.position, 3 * tech.hookNails)
|
||||
const ANGLE = 2 * Math.PI * Math.random() //make a few random ones
|
||||
for (let i = 0; i < 13; i++) b.nail(this.position, { x: 10.5 * Math.cos(ANGLE), y: 10.5 * Math.sin(ANGLE) }, 1.2)
|
||||
|
||||
const blockVertices = blocks[i].bodyA.vertices
|
||||
Composite.remove(engine.world, blocks[i].bodyA)
|
||||
body.splice(body.indexOf(blocks[i].bodyA), 1)
|
||||
@@ -1785,12 +1621,20 @@ const b = {
|
||||
this.pickUpTarget = blocks[i].bodyA
|
||||
this.blockDist = Vector.magnitude(Vector.sub(this.pickUpTarget.position, m.pos))
|
||||
}
|
||||
} else if (blocks[i].bodyB.classType === "body" && !blocks[i].bodyB.isNotHoldable && !blocks[0].bodyB.mass < 60) {
|
||||
this.retract()
|
||||
this.pickUpTarget = blocks[i].bodyB
|
||||
this.blockDist = Vector.magnitude(Vector.sub(this.pickUpTarget.position, m.pos))
|
||||
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
}
|
||||
// else if (blocks[i].bodyB.classType === "body" && !blocks[i].bodyB.isNotHoldable && blocks[0].bodyB.mass < 60) {
|
||||
// this.retract()
|
||||
// this.pickUpTarget = blocks[i].bodyB
|
||||
// this.blockDist = Vector.magnitude(Vector.sub(this.pickUpTarget.position, m.pos))
|
||||
// if (tech.hookNails) {
|
||||
// // if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + 5; //player is immune to damage for 5 cycles
|
||||
// // b.explosion(this.position, 300 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
// b.targetedNail(this.position, tech.hookNails)
|
||||
// const ANGLE = 2 * Math.PI * Math.random() //make a few random ones
|
||||
// for (let i = 0; i < 4; i++) b.nail(this.position, { x: 10.5 * Math.cos(ANGLE), y: 10.5 * Math.sin(ANGLE) }, 1.2)
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// if (blocks[0].bodyA.mass > 2.5 && blocks[0].bodyA.mass > 15) {
|
||||
|
||||
@@ -1855,7 +1699,14 @@ const b = {
|
||||
if (input.field && Matter.Query.collides(this, map).length) {
|
||||
Matter.Body.setPosition(this, Vector.add(this.position, { x: -20 * Math.cos(this.angle), y: -20 * Math.sin(this.angle) }))
|
||||
if (Matter.Query.collides(this, map).length) {
|
||||
if (tech.isHookExplosion) b.explosion(this.position, 150 + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.hookNails) {
|
||||
// if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + 5; //player is immune to damage for 5 cycles
|
||||
// b.explosion(this.position, 200 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||
b.targetedNail(this.position, tech.hookNails)
|
||||
const ANGLE = 2 * Math.PI * Math.random() //make a few random ones
|
||||
for (let i = 0; i < 4; i++) b.nail(this.position, { x: 10.5 * Math.cos(ANGLE), y: 10.5 * Math.sin(ANGLE) }, 1.2)
|
||||
|
||||
}
|
||||
this.attached = true
|
||||
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
||||
Matter.Sleeping.set(this, true)
|
||||
@@ -1976,7 +1827,7 @@ const b = {
|
||||
friction: 1,
|
||||
frictionAir: 0.4,
|
||||
// thrustMag: 0.1,
|
||||
drain: tech.isRailEnergy ? 0.0006 : 0.006,
|
||||
drain: tech.isRailEnergy ? 0 : 0.006,
|
||||
turnRate: isReturn ? 0.1 : 0.03, //0.015
|
||||
drawStringControlMagnitude: 3000 + 5000 * Math.random(),
|
||||
drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
|
||||
@@ -2022,7 +1873,7 @@ const b = {
|
||||
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) {
|
||||
Matter.Body.setDensity(this, 1.8 * tech.harpoonDensity); //+90% damage after pick up power up for 8 seconds
|
||||
} else if (tech.isHarpoonFullHealth && who.health === 1) {
|
||||
Matter.Body.setDensity(this, 1.9 * tech.harpoonDensity); //+90% damage if mob has full health do
|
||||
Matter.Body.setDensity(this, 2.11 * tech.harpoonDensity); //+90% damage if mob has full health do
|
||||
simulation.ephemera.push({
|
||||
name: "harpoon outline",
|
||||
count: 2, //cycles before it self removes
|
||||
@@ -2435,7 +2286,6 @@ const b = {
|
||||
}
|
||||
|
||||
//calculate laser collision
|
||||
let best;
|
||||
let range = tech.isPlasmaRange * (120 + (m.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(m.cycle * 0.3);
|
||||
// const dir = m.angle // + 0.04 * (Math.random() - 0.5)
|
||||
const path = [{
|
||||
@@ -2447,49 +2297,8 @@ const b = {
|
||||
y: m.pos.y + range * Math.sin(m.angle)
|
||||
}
|
||||
];
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//check for collisions
|
||||
best = {
|
||||
let best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
@@ -2497,14 +2306,9 @@ const b = {
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
vertexCollision(path[0], path[1], mob);
|
||||
vertexCollision(path[0], path[1], map);
|
||||
vertexCollision(path[0], path[1], body);
|
||||
best = vertexCollision(path[0], path[1], [mob, map, body]);
|
||||
if (best.dist2 != Infinity) { //if hitting something
|
||||
path[path.length - 1] = {
|
||||
x: best.x,
|
||||
y: best.y
|
||||
};
|
||||
path[path.length - 1] = { x: best.x, y: best.y };
|
||||
if (best.who.alive) {
|
||||
const dmg = 0.9 * m.dmgScale; //********** SCALE DAMAGE HERE *********************
|
||||
best.who.damage(dmg);
|
||||
@@ -2571,6 +2375,7 @@ const b = {
|
||||
}, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) {
|
||||
const reflectivity = 1 - 1 / (reflections * 3)
|
||||
let damage = m.dmgScale * dmg
|
||||
|
||||
let best = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
@@ -2586,59 +2391,9 @@ const b = {
|
||||
x: whereEnd.x,
|
||||
y: whereEnd.y
|
||||
}];
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const checkForCollisions = function () {
|
||||
best = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: 1,
|
||||
v2: 1
|
||||
};
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], mob);
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], map);
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], body);
|
||||
best = vertexCollision(path[path.length - 2], path[path.length - 1], [mob, map, body]);
|
||||
};
|
||||
const laserHitMob = function () {
|
||||
if (best.who.alive) {
|
||||
@@ -2895,7 +2650,7 @@ const b = {
|
||||
} else if (tech.isSuperMine) {
|
||||
b.targetedBall(this.position, 22 + 2 * tech.extraSuperBalls)
|
||||
} else {
|
||||
b.targetedNail(this.position, 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
|
||||
b.targetedNail(this.position, 22, 40 + 10 * Math.random(), 1200, 2.2)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2993,7 +2748,7 @@ const b = {
|
||||
if (Math.random() < 0.33) b.targetedBall(this.position, 1, 42 + 12 * Math.random(), 1200, false)
|
||||
}
|
||||
} else {
|
||||
this.shots -= b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
|
||||
this.shots -= b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, 2.3)
|
||||
}
|
||||
if (this.shots < 0) this.endCycle = 0
|
||||
if (!(simulation.cycle % (this.lookFrequency * 6))) {
|
||||
@@ -3508,10 +3263,7 @@ const b = {
|
||||
}
|
||||
requestAnimationFrame(respawnDrones);
|
||||
},
|
||||
drone(where = {
|
||||
x: m.pos.x + 30 * Math.cos(m.angle) + 20 * (Math.random() - 0.5),
|
||||
y: m.pos.y + 30 * Math.sin(m.angle) + 20 * (Math.random() - 0.5)
|
||||
}, speed = 1) {
|
||||
drone(where = { x: m.pos.x + 30 * Math.cos(m.angle) + 20 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 20 * (Math.random() - 0.5) }, speed = 1) {
|
||||
const me = bullet.length;
|
||||
const THRUST = 0.0015
|
||||
const dir = m.angle + 0.2 * (Math.random() - 0.5);
|
||||
@@ -3688,7 +3440,7 @@ const b = {
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) { //grab, but don't lock onto nearby power up
|
||||
if (
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.97 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
@@ -3719,7 +3471,7 @@ const b = {
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.97 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
@@ -3748,8 +3500,7 @@ const b = {
|
||||
}
|
||||
//look for power ups to lock onto
|
||||
if (
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 //&& Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
@@ -4545,7 +4296,7 @@ const b = {
|
||||
Matter.Body.setVelocity(who, velocity);
|
||||
}
|
||||
},
|
||||
targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
|
||||
targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, damage = 1.4) {
|
||||
let shotsFired = 0
|
||||
const targets = [] //target nearby mobs
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
@@ -4570,7 +4321,7 @@ const b = {
|
||||
}
|
||||
b.nail(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed), damage)
|
||||
shotsFired++
|
||||
} else if (isRandomAim) { // aim in random direction
|
||||
} else { // aim in random direction
|
||||
const ANGLE = 2 * Math.PI * Math.random()
|
||||
b.nail(position, {
|
||||
x: speed * Math.cos(ANGLE),
|
||||
@@ -5634,59 +5385,9 @@ const b = {
|
||||
const perp2 = Vector.mult(Vector.rotate({ x: 1, y: 0 }, m.angle + Math.PI / 2), 0.6 * this.lockedOn.radius * Math.sin(simulation.cycle / this.lookFrequency))
|
||||
const path = [{ x: this.vertices[0].x, y: this.vertices[0].y }, Vector.add(this.lockedOn.position, perp2)];
|
||||
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const checkForCollisions = function () {
|
||||
best = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: 1,
|
||||
v2: 1
|
||||
};
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], mob);
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], map);
|
||||
vertexCollision(path[path.length - 2], path[path.length - 1], body);
|
||||
best = { x: 1, y: 1, dist2: Infinity, who: null, v1: 1, v2: 1 };
|
||||
best = vertexCollision(path[path.length - 2], path[path.length - 1], [mob, map, body]);
|
||||
};
|
||||
const laserHitMob = function () {
|
||||
if (best.who.alive) {
|
||||
@@ -5717,19 +5418,13 @@ const b = {
|
||||
}
|
||||
if (tech.isLaserPush) { //push mobs away
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, {
|
||||
x: best.who.velocity.x * 0.97,
|
||||
y: best.who.velocity.y * 0.97
|
||||
});
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.97, y: best.who.velocity.y * 0.97 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
} else if (tech.isLaserPush && best.who.classType === "body") {
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, {
|
||||
x: best.who.velocity.x * 0.97,
|
||||
y: best.who.velocity.y * 0.97
|
||||
});
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.97, y: best.who.velocity.y * 0.97 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
@@ -5746,20 +5441,14 @@ const b = {
|
||||
let lastBestOdd
|
||||
let lastBestEven = best.who //used in hack below
|
||||
if (best.dist2 !== Infinity) { //if hitting something
|
||||
path[path.length - 1] = {
|
||||
x: best.x,
|
||||
y: best.y
|
||||
};
|
||||
path[path.length - 1] = { x: best.x, y: best.y };
|
||||
laserHitMob();
|
||||
for (let i = 0; i < tech.laserReflections; i++) {
|
||||
reflection();
|
||||
checkForCollisions();
|
||||
if (best.dist2 !== Infinity) { //if hitting something
|
||||
lastReflection = best
|
||||
path[path.length - 1] = {
|
||||
x: best.x,
|
||||
y: best.y
|
||||
};
|
||||
path[path.length - 1] = { x: best.x, y: best.y };
|
||||
damage *= reflectivity
|
||||
laserHitMob();
|
||||
//I'm not clear on how this works, but it gets rid of a bug where the laser reflects inside a block, often vertically.
|
||||
@@ -5947,51 +5636,9 @@ const b = {
|
||||
let best;
|
||||
let range = tech.isPlasmaRange * (120 + 300 * Math.sqrt(Math.random()))
|
||||
const path = [{ x: this.position.x, y: this.position.y }, { x: this.position.x + range * unit.x, y: this.position.y + range * unit.y }];
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//check for collisions
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
vertexCollision(path[0], path[1], mob);
|
||||
vertexCollision(path[0], path[1], map);
|
||||
vertexCollision(path[0], path[1], body);
|
||||
best = vertexCollision(path[0], path[1], [mob, map, body]);
|
||||
if (best.dist2 != Infinity) { //if hitting something
|
||||
path[path.length - 1] = { x: best.x, y: best.y };
|
||||
if (best.who.alive) {
|
||||
@@ -6001,12 +5648,7 @@ const b = {
|
||||
//push mobs away
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.007 * Math.min(5, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[1], force)
|
||||
if (best.who.speed > 2.5) {
|
||||
Matter.Body.setVelocity(best.who, { //friction
|
||||
x: best.who.velocity.x * 0.75,
|
||||
y: best.who.velocity.y * 0.75
|
||||
});
|
||||
}
|
||||
if (best.who.speed > 2.5) Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.75, y: best.who.velocity.y * 0.75 });
|
||||
//draw mob damage circle
|
||||
if (best.who.damageReduction) {
|
||||
simulation.drawList.push({
|
||||
@@ -7729,7 +7371,7 @@ const b = {
|
||||
charge: 0,
|
||||
railDo() {
|
||||
if (this.charge > 0) {
|
||||
const DRAIN = (tech.isRailEnergy ? 0.0002 : 0.002)
|
||||
const DRAIN = (tech.isRailEnergy ? 0 : 0.002)
|
||||
//exit railgun charging without firing
|
||||
if (m.energy < DRAIN) {
|
||||
// m.energy += 0.025 + this.charge * 22 * this.drain
|
||||
|
||||
@@ -229,8 +229,8 @@ function collisionChecks(event) {
|
||||
y: mob[k].velocity.y - 8 * Math.sin(angle)
|
||||
});
|
||||
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.34 * m.maxEnergy && mob[k].damageReduction > 0) {
|
||||
m.energy -= 0.33 * Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
|
||||
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.1 && mob[k].damageReduction > 0) {
|
||||
m.energy -= 0.1 //* Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
|
||||
if (m.immuneCycle === m.cycle + m.collisionImmuneCycles) m.immuneCycle = 0; //player doesn't go immune to collision damage
|
||||
mob[k].death();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
|
||||
90
js/index.js
90
js/index.js
@@ -39,6 +39,96 @@ function shuffle(array) {
|
||||
}
|
||||
return array;
|
||||
}
|
||||
// function vertexCollision(v1, v1End, domain, best) {
|
||||
// let results
|
||||
// for (let i = 0; i < domain.length; ++i) {
|
||||
// let vertices = domain[i].vertices;
|
||||
// const len = vertices.length - 1;
|
||||
// for (let j = 0; j < len; j++) {
|
||||
// results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
// if (results.onLine1 && results.onLine2) {
|
||||
// const dx = v1.x - results.x;
|
||||
// const dy = v1.y - results.y;
|
||||
// const dist2 = dx * dx + dy * dy;
|
||||
// if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
// best = {
|
||||
// x: results.x,
|
||||
// y: results.y,
|
||||
// dist2: dist2,
|
||||
// who: domain[i],
|
||||
// v1: vertices[j],
|
||||
// v2: vertices[j + 1]
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
// if (results.onLine1 && results.onLine2) {
|
||||
// const dx = v1.x - results.x;
|
||||
// const dy = v1.y - results.y;
|
||||
// const dist2 = dx * dx + dy * dy;
|
||||
// if (dist2 < best.dist2) {
|
||||
// best = {
|
||||
// x: results.x,
|
||||
// y: results.y,
|
||||
// dist2: dist2,
|
||||
// who: domain[i],
|
||||
// v1: vertices[0],
|
||||
// v2: vertices[len]
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return best
|
||||
// }
|
||||
//this function is used for finding the point where a ray hits things, used for lasers mostly
|
||||
function vertexCollision(v1, v1End, domains) { //= [map, body, [playerBody, playerHead]] //m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]
|
||||
let results
|
||||
let best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
for (let j = 0; j < domains.length; j++) {
|
||||
let domain = domains[j]
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
|
||||
//collision groups
|
||||
// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield | cat.phased
|
||||
|
||||
92
js/level.js
92
js/level.js
@@ -19,26 +19,26 @@ const level = {
|
||||
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// tech.giveTech("performance")
|
||||
// level.difficultyIncrease(8 * 2) //30 is near max on hard //60 is near max on why
|
||||
// m.maxHealth = m.health = 1
|
||||
// level.difficultyIncrease(3 * 2) //30 is near max on hard //60 is near max on why
|
||||
// m.maxHealth = m.health = 100000000
|
||||
// m.maxEnergy = m.energy = 10000000
|
||||
// tech.isRerollDamage = true
|
||||
// powerUps.research.changeRerolls(99999)
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// tech.tech[297].frequency = 100
|
||||
// m.couplingChange(10)
|
||||
// m.setField("metamaterial cloaking") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.setField("plasma torch") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.energy = 0
|
||||
// tech.isHookWire = true
|
||||
// m.energy = 0
|
||||
// simulation.molecularMode = 2
|
||||
// m.damage(0.1);
|
||||
// b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||
// b.giveGuns("drones") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||
// b.guns[8].ammo = 100000000
|
||||
// requestAnimationFrame(() => { tech.giveTech("Higgs mechanism") });
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("optical amplifier")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("depolarization")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("flame test")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("dazzler")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("mass production")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) tech.giveTech("orbital-bot") });
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
|
||||
@@ -46,26 +46,30 @@ const level = {
|
||||
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
|
||||
// m.lastKillCycle = m.cycle
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("depolarization")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("swarf")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("CPT symmetry")
|
||||
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||
// level.arena();
|
||||
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
|
||||
// level.testing();
|
||||
|
||||
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
||||
// for (let i = 0; i < 4; ++i) spawn.stinger(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.timeSkipBoss(1900, -2500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
|
||||
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
|
||||
// for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
|
||||
// for (let i = 0; i < 3; ++i) spawn.laser(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.laserBombingBoss(1900, -2500)
|
||||
// spawn.beetleBoss(1900, -500, 25)
|
||||
// spawn.slasher2(2000, -1150)
|
||||
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
|
||||
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
|
||||
// tech.addJunkTechToPool(2)
|
||||
// tech.tech[322].frequency = 100
|
||||
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
|
||||
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
||||
|
||||
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
||||
|
||||
// for (let i = 0; i < 2; i++) spawn.ghoster(1300, -500) //ghosters need to spawn after the map loads
|
||||
// spawn.bodyRect(2425, -120, 200, 200);
|
||||
// console.log(body[body.length - 1].mass)
|
||||
// simulation.isAutoZoom = false; //look in close
|
||||
@@ -289,8 +293,8 @@ const level = {
|
||||
simulation.updateTechHUD();
|
||||
simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
|
||||
|
||||
//pop up new level info screen for a few seconds
|
||||
if (!localSettings.isHideHUD && !simulation.isChoosing && !simulation.isCheating && m.alive && (level.levels[level.onLevel] === "final" || level.levels[level.onLevel] === "reactor" || level.levels[level.onLevel] === "subway")) {
|
||||
//pop up new level info screen for a few seconds //|| level.levels[level.onLevel] === "subway"
|
||||
if (!localSettings.isHideHUD && !simulation.isCheating && m.alive && (level.levels[level.onLevel] === "final" || level.levels[level.onLevel] === "reactor")) {
|
||||
//pause
|
||||
if (!simulation.paused) {
|
||||
simulation.paused = true;
|
||||
@@ -325,7 +329,7 @@ const level = {
|
||||
simulation.draw.cons();
|
||||
simulation.draw.body();
|
||||
level.customTopLayer();
|
||||
let count = countMax = simulation.testing ? 0 : 180
|
||||
let count = countMax = simulation.testing ? 0 : 240
|
||||
let newLevelDraw = () => {
|
||||
count--
|
||||
if (count > 0) {
|
||||
@@ -346,40 +350,46 @@ const level = {
|
||||
simulation.wipe();
|
||||
m.look();
|
||||
simulation.camera();
|
||||
// if (count < 30) {
|
||||
// }
|
||||
// if (count < 60) {
|
||||
// simulation.draw.cons();
|
||||
// simulation.draw.body();
|
||||
// level.customTopLayer();
|
||||
// simulation.draw.body();
|
||||
// simulation.draw.drawMapPath();
|
||||
// mobs.draw();
|
||||
// } else
|
||||
// if (count < 240) {
|
||||
|
||||
// ctx.lineDashOffset = 900 * Math.random()
|
||||
// ctx.setLineDash([3, -8 + 0.5 * count]);
|
||||
|
||||
const scale = 10
|
||||
const scale = 15
|
||||
ctx.setLineDash([scale * (countMax - count), scale * count]);
|
||||
simulation.draw.wireFrame();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
|
||||
// }
|
||||
// else if (count === 91) { //hide text boss
|
||||
// document.getElementById("choose-grid").style.opacity = "0"
|
||||
// setTimeout(() => {
|
||||
// document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
// }, 1000);
|
||||
// }
|
||||
ctx.restore();
|
||||
simulation.drawCursor();
|
||||
}
|
||||
requestAnimationFrame(newLevelDraw);
|
||||
|
||||
}
|
||||
// else {
|
||||
// //pause
|
||||
// if (!simulation.paused) {
|
||||
// simulation.paused = true;
|
||||
// simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
// }
|
||||
// let count = countMax = simulation.testing ? 0 : 60
|
||||
// let newLevelDraw = () => {
|
||||
// count--
|
||||
// if (count > 0) {
|
||||
// requestAnimationFrame(newLevelDraw);
|
||||
// } else { //unpause
|
||||
// // if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
|
||||
// if (simulation.paused) requestAnimationFrame(cycle);
|
||||
// if (m.alive) simulation.paused = false;
|
||||
// simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
// build.unPauseGrid()
|
||||
// }
|
||||
// //draw
|
||||
// simulation.wipe();
|
||||
// m.look();
|
||||
// simulation.camera();
|
||||
// const scale = 30
|
||||
// ctx.setLineDash([scale * (countMax - count), scale * count]);
|
||||
// simulation.draw.wireFrame();
|
||||
// ctx.setLineDash([]);
|
||||
// ctx.restore();
|
||||
// simulation.drawCursor();
|
||||
// }
|
||||
// requestAnimationFrame(newLevelDraw);
|
||||
// }
|
||||
}
|
||||
},
|
||||
unPause() {
|
||||
|
||||
197
js/mob.js
197
js/mob.js
@@ -505,89 +505,48 @@ const mobs = {
|
||||
ctx.fill();
|
||||
}
|
||||
},
|
||||
laser() {
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (this.seePlayer.recall && !this.isSlowed) {
|
||||
const seeRange = 2500;
|
||||
best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
const look = {
|
||||
x: this.position.x + seeRange * Math.cos(this.angle),
|
||||
y: this.position.y + seeRange * Math.sin(this.angle)
|
||||
};
|
||||
vertexCollision(this.position, look, map);
|
||||
vertexCollision(this.position, look, body);
|
||||
if (!m.isCloak) vertexCollision(this.position, look, [player]);
|
||||
// hitting player
|
||||
if (best.who === player) {
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
const dmg = 0.0014 * simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
ctx.fillStyle = "#f00"; //draw damage
|
||||
ctx.beginPath();
|
||||
ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
//draw beam
|
||||
if (best.dist2 === Infinity) {
|
||||
best = look;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(best.x, best.y);
|
||||
ctx.strokeStyle = "#f00"; // Purple path
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||
ctx.stroke(); // Draw it
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
},
|
||||
// laser() {
|
||||
// if (this.seePlayer.recall && !this.isSlowed) {
|
||||
// const seeRange = 2500;
|
||||
// best = {
|
||||
// x: null,
|
||||
// y: null,
|
||||
// dist2: Infinity,
|
||||
// who: null,
|
||||
// v1: null,
|
||||
// v2: null
|
||||
// };
|
||||
// const look = {
|
||||
// x: this.position.x + seeRange * Math.cos(this.angle),
|
||||
// y: this.position.y + seeRange * Math.sin(this.angle)
|
||||
// };
|
||||
// best = vertexCollision(this.position, look, m.isCloak ? [map, body] : [map, body, [player]]);
|
||||
|
||||
// // hitting player
|
||||
// if (best.who === player) {
|
||||
// if (m.immuneCycle < m.cycle) {
|
||||
// const dmg = 0.0014 * simulation.dmgScale;
|
||||
// m.damage(dmg);
|
||||
// ctx.fillStyle = "#f00"; //draw damage
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
|
||||
// ctx.fill();
|
||||
// }
|
||||
// }
|
||||
// //draw beam
|
||||
// if (best.dist2 === Infinity) {
|
||||
// best = look;
|
||||
// }
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(this.position.x, this.position.y);
|
||||
// ctx.lineTo(best.x, best.y);
|
||||
// ctx.strokeStyle = "#f00"; // Purple path
|
||||
// ctx.lineWidth = 1;
|
||||
// ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||
// ctx.stroke(); // Draw it
|
||||
// ctx.setLineDash([]);
|
||||
// }
|
||||
// },
|
||||
wing(a, radius = 250, ellipticity = 0.4, dmg = 0.0006) {
|
||||
const minorRadius = radius * ellipticity
|
||||
const perp = { x: Math.cos(a), y: Math.sin(a) } //
|
||||
@@ -658,47 +617,6 @@ const mobs = {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.07)";
|
||||
ctx.fill();
|
||||
//spring to random place on map
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//move to a random location
|
||||
if (!(simulation.cycle % (this.seePlayerFreq * 4))) {
|
||||
best = {
|
||||
x: null,
|
||||
@@ -713,8 +631,7 @@ const mobs = {
|
||||
x: this.position.x + seeRange * Math.cos(this.angle),
|
||||
y: this.position.y + seeRange * Math.sin(this.angle)
|
||||
};
|
||||
vertexCollision(this.position, look, map);
|
||||
vertexCollision(this.position, look, body);
|
||||
best = vertexCollision(this.position, look, [map, body]);
|
||||
if (best.dist2 != Infinity) {
|
||||
if (Math.random() > 0.5) {
|
||||
this.springTarget.x = best.x;
|
||||
@@ -1135,32 +1052,8 @@ const mobs = {
|
||||
dmg *= tech.damageFromTech()
|
||||
if (this.isDropPowerUp) {
|
||||
if (this.health === 1) {
|
||||
if (tech.isMobFullHealth) {
|
||||
dmg *= 1.55
|
||||
|
||||
simulation.ephemera.push({
|
||||
name: "damage outline",
|
||||
count: 5, //cycles before it self removes
|
||||
vertices: this.vertices,
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||
//draw body
|
||||
ctx.beginPath();
|
||||
const vertices = this.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1, len = vertices.length; j < len; ++j) {
|
||||
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
}
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 3 //60 * (0.25 - this.damageReductionGoal)
|
||||
ctx.strokeStyle = `#f05` //"rgba(150,150,225,0.5)";
|
||||
ctx.stroke();
|
||||
},
|
||||
})
|
||||
} else if (tech.isMobFullHealthCloak) {
|
||||
dmg *= 1.88
|
||||
|
||||
if (tech.isMobFullHealthCloak) {
|
||||
dmg *= 2.11
|
||||
simulation.ephemera.push({
|
||||
name: "damage outline",
|
||||
count: 7, //cycles before it self removes
|
||||
|
||||
92
js/player.js
92
js/player.js
@@ -559,7 +559,7 @@ const m = {
|
||||
// 1.25 + Math.sin(m.cycle * 0.01)
|
||||
if (tech.isDiaphragm) dmg *= 0.56 + 0.36 * Math.sin(m.cycle * 0.0075);
|
||||
if (tech.isZeno) dmg *= 0.15
|
||||
if (tech.isFieldHarmReduction) dmg *= 0.5
|
||||
if (tech.isFieldHarmReduction) dmg *= 0.65
|
||||
if (tech.isHarmMACHO) dmg *= 0.4
|
||||
if (tech.isImmortal) dmg *= 0.7
|
||||
if (tech.energyRegen === 0) dmg *= 0.34
|
||||
@@ -2192,7 +2192,7 @@ const m = {
|
||||
}
|
||||
},
|
||||
setMaxEnergy(isMessage = true) {
|
||||
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.4 * tech.isStandingWaveExpand
|
||||
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
|
||||
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
|
||||
},
|
||||
fieldMeterColor: "#0cf",
|
||||
@@ -2243,6 +2243,8 @@ const m = {
|
||||
m.fieldRegen = 0.001667 //10 energy per second plasma torch
|
||||
} else if (m.fieldMode === 8) {
|
||||
m.fieldRegen = 0.001667 //10 energy per second pilot wave
|
||||
} else if (m.fieldMode === 10) {
|
||||
m.fieldRegen = 0.0015 //9 energy per second grappling hook
|
||||
} else {
|
||||
m.fieldRegen = 0.001 //6 energy per second
|
||||
}
|
||||
@@ -3631,15 +3633,9 @@ const m = {
|
||||
// if (!this.isAttached && !mob[i].isMobBullet) this.isPopping = true
|
||||
mob[i].damage(dmg);
|
||||
if (mob[i].speed > 5) {
|
||||
Matter.Body.setVelocity(mob[i], { //friction
|
||||
x: mob[i].velocity.x * 0.6,
|
||||
y: mob[i].velocity.y * 0.6
|
||||
});
|
||||
Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.6, y: mob[i].velocity.y * 0.6 });
|
||||
} else {
|
||||
Matter.Body.setVelocity(mob[i], { //friction
|
||||
x: mob[i].velocity.x * 0.93,
|
||||
y: mob[i].velocity.y * 0.93
|
||||
});
|
||||
Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.93, y: mob[i].velocity.y * 0.93 });
|
||||
}
|
||||
} else if (sub < dischargeRange + mob[i].radius && Matter.Query.ray(map, mob[i].position, this.position).length === 0) {
|
||||
arcList.push(mob[i]) //populate electrical arc list
|
||||
@@ -3684,10 +3680,7 @@ const m = {
|
||||
//slowly slow down if too fast
|
||||
if (this.speed > 10) {
|
||||
const scale = 0.998
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: scale * this.velocity.x,
|
||||
y: scale * this.velocity.y
|
||||
});
|
||||
Matter.Body.setVelocity(this, { x: scale * this.velocity.x, y: scale * this.velocity.y });
|
||||
}
|
||||
|
||||
//graphics
|
||||
@@ -3703,10 +3696,7 @@ const m = {
|
||||
ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
//draw arcs
|
||||
const unit = Vector.rotate({
|
||||
x: 1,
|
||||
y: 0
|
||||
}, Math.random() * 6.28)
|
||||
const unit = Vector.rotate({ x: 1, y: 0 }, Math.random() * 6.28)
|
||||
let len = 8
|
||||
const step = this.circleRadius / len
|
||||
let x = this.position.x
|
||||
@@ -3761,13 +3751,6 @@ const m = {
|
||||
// m.plasmaBall.reset()
|
||||
|
||||
}
|
||||
// const scale = 0.7
|
||||
// Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast
|
||||
// if (m.plasmaBall.circleRadius < m.plasmaBall.radiusLimit) {
|
||||
// m.plasmaBall.isAttached = true
|
||||
// m.plasmaBall.isOn = true
|
||||
// m.plasmaBall.setPositionToNose()
|
||||
// }
|
||||
} else if (m.energy > m.plasmaBall.drain) { //charge up when attached
|
||||
if (tech.isCapacitor) {
|
||||
m.energy -= m.plasmaBall.drain * 2;
|
||||
@@ -4233,16 +4216,14 @@ const m = {
|
||||
//not shooting (or using field) enable cloak
|
||||
if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle
|
||||
if (m.fireCDcycle + 10 < m.cycle && !input.fire) { //automatically cloak if not firing
|
||||
const drain = 0.02
|
||||
if (!m.isCloak && m.energy > drain + 0.03) {
|
||||
m.energy -= drain
|
||||
// const drain = 0.02
|
||||
if (!m.isCloak) { //&& m.energy > drain + 0.03
|
||||
// m.energy -= drain
|
||||
m.isCloak = true //enter cloak
|
||||
m.fieldHarmReduction = 0.33; //66% reduction
|
||||
m.enterCloakCycle = m.cycle
|
||||
if (tech.isCloakHealLastHit && m.lastHit > 0) {
|
||||
const heal = Math.min(0.75 * m.lastHit, m.energy)
|
||||
// if (m.energy > heal) {
|
||||
// m.energy -= heal * 0.8
|
||||
m.addHealth(heal); //heal from last hit
|
||||
m.lastHit = 0
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -4252,7 +4233,6 @@ const m = {
|
||||
color: "rgba(0,255,200,0.6)",
|
||||
time: 16
|
||||
});
|
||||
// }
|
||||
}
|
||||
if (tech.isIntangible) {
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
@@ -4272,26 +4252,26 @@ const m = {
|
||||
}
|
||||
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
|
||||
let isMobsAround = false
|
||||
const stunRange = m.fieldDrawRadius * 1.5
|
||||
const drain = 0.1
|
||||
if (m.energy > drain) {
|
||||
const stunRange = m.fieldDrawRadius * 1.25
|
||||
// const drain = 0.01
|
||||
// if (m.energy > drain) {
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) < stunRange && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 && !mob[i].isBadTarget) {
|
||||
isMobsAround = true
|
||||
mobs.statusStun(mob[i], 180)
|
||||
}
|
||||
}
|
||||
if (isMobsAround) {
|
||||
m.energy -= drain
|
||||
simulation.drawList.push({
|
||||
x: m.pos.x,
|
||||
y: m.pos.y,
|
||||
radius: stunRange,
|
||||
color: "hsla(0,50%,100%,0.7)",
|
||||
time: 7
|
||||
});
|
||||
mobs.statusStun(mob[i], 120)
|
||||
}
|
||||
}
|
||||
// if (isMobsAround) {
|
||||
// m.energy -= drain
|
||||
// simulation.drawList.push({
|
||||
// x: m.pos.x,
|
||||
// y: m.pos.y,
|
||||
// radius: stunRange,
|
||||
// color: "hsla(0,50%,100%,0.7)",
|
||||
// time: 7
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4580,13 +4560,13 @@ const m = {
|
||||
{
|
||||
name: "wormhole",
|
||||
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
drain: 0,
|
||||
effect: function () {
|
||||
m.fieldMeterColor = "#bbf" //"#0c5"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
|
||||
m.duplicateChance = 0.05
|
||||
m.duplicateChance = 0.07
|
||||
m.fieldRange = 0
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
|
||||
@@ -4639,10 +4619,7 @@ const m = {
|
||||
if (dist2 < 600000) { //&& !(m.health === m.maxHealth && powerUp[i].name === "heal")
|
||||
powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
|
||||
powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
|
||||
Matter.Body.setVelocity(powerUp[i], { //extra friction
|
||||
x: powerUp[i].velocity.x * 0.05,
|
||||
y: powerUp[i].velocity.y * 0.05
|
||||
});
|
||||
Matter.Body.setVelocity(powerUp[i], { x: powerUp[i].velocity.x * 0.05, y: powerUp[i].velocity.y * 0.05 });
|
||||
if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
|
||||
|
||||
// if (true) { //AoE radiation effect
|
||||
@@ -4811,10 +4788,7 @@ const m = {
|
||||
this.drain = tech.isFreeWormHole ? 0 : 0.05 + 0.005 * Math.sqrt(mag)
|
||||
}
|
||||
const unit = Vector.perp(Vector.normalise(sub))
|
||||
const where = {
|
||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
||||
}
|
||||
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||
m.fieldRange = 0.97 * m.fieldRange + 0.03 * (50 + 10 * Math.sin(simulation.cycle * 0.025))
|
||||
const edge2a = Vector.add(Vector.mult(unit, 1.5 * m.fieldRange), simulation.mouseInGame)
|
||||
const edge2b = Vector.add(Vector.mult(unit, -1.5 * m.fieldRange), simulation.mouseInGame)
|
||||
@@ -5135,7 +5109,7 @@ const m = {
|
||||
{
|
||||
name: "grappling hook",
|
||||
// description: `use <strong class='color-f'>energy</strong> to pull yourself towards the <strong>map</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to fire a hook that <strong>pulls</strong> player<br><strong class='color-d'>damages</strong> mobs and grabs <strong class='color-block'>blocks</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to fire a hook that <strong>pulls</strong> player<br><strong class='color-d'>damages</strong> mobs and grabs <strong class='color-block'>blocks</strong><br>generate <strong>9</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||
@@ -5159,7 +5133,7 @@ const m = {
|
||||
m.grabPowerUp();
|
||||
} else {
|
||||
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
if (tech.isHookDefense && m.energy > 0.33 && m.fieldCDcycle < m.cycle) {
|
||||
if (tech.isHookDefense && m.energy > 0.15 && m.fieldCDcycle < m.cycle) {
|
||||
const range = 300
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (!mob[i].isBadTarget &&
|
||||
@@ -5167,7 +5141,7 @@ const m = {
|
||||
Vector.magnitude(Vector.sub(m.pos, mob[i].position)) < range &&
|
||||
Matter.Query.ray(map, m.pos, mob[i].position).length === 0
|
||||
) {
|
||||
m.energy -= 0.18
|
||||
m.energy -= 0.1
|
||||
if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
|
||||
const angle = Math.atan2(mob[i].position.y - player.position.y, mob[i].position.x - player.position.x);
|
||||
b.harpoon(m.pos, mob[i], angle, 0.75, true, 20) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
||||
|
||||
@@ -332,7 +332,7 @@ const powerUps = {
|
||||
simulation.circleFlare(0.043);
|
||||
}
|
||||
if (tech.isCancelRerolls) {
|
||||
for (let i = 0, len = 6 + 6 * Math.random(); i < len; i++) {
|
||||
for (let i = 0, len = 10 + 4 * Math.random(); i < len; i++) {
|
||||
let spawnType
|
||||
if (Math.random() < 0.4 && !tech.isEnergyNoAmmo) {
|
||||
spawnType = "ammo"
|
||||
|
||||
1217
js/spawn.js
1217
js/spawn.js
File diff suppressed because it is too large
Load Diff
226
js/tech.js
226
js/tech.js
@@ -218,7 +218,7 @@ const tech = {
|
||||
}
|
||||
},
|
||||
hasExplosiveDamageCheck() {
|
||||
return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isHookExplosion
|
||||
return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
|
||||
},
|
||||
damage: 1, //used for tech changes to player damage that don't have complex conditions
|
||||
damageFromTech() {
|
||||
@@ -1215,6 +1215,38 @@ const tech = {
|
||||
b.setFireCD();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "dynamical systems",
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+30%</strong> <strong class='color-d'>damage</strong>`,
|
||||
// isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return powerUps.research.count > 1 || build.isExperimentSelection
|
||||
},
|
||||
requires: "",
|
||||
// allowed() {
|
||||
// return (m.fieldMode === 5 || m.fieldMode === 7 || m.fieldMode === 8) && (build.isExperimentSelection || powerUps.research.count > 1)
|
||||
// },
|
||||
// requires: "cloaking, pilot wave, or plasma torch",
|
||||
damage: 1.3,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
tech.isCloakingDamage = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isCloakingDamage = false
|
||||
if (this.count > 0) {
|
||||
tech.damage /= this.damage
|
||||
powerUps.research.changeRerolls(2)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "heuristics",
|
||||
description: "<strong>+22%</strong> <strong><em>fire rate</em></strong><br>spawn a <strong class='color-g'>gun</strong>",
|
||||
@@ -1412,24 +1444,24 @@ const tech = {
|
||||
tech.healSpawn = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "yield stress",
|
||||
description: "<strong>+55%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return m.fieldMode !== 7 && tech.mobSpawnWithHealth === 0
|
||||
},
|
||||
requires: "not cloaking, reaction inhibitor",
|
||||
effect() {
|
||||
tech.isMobFullHealth = true
|
||||
},
|
||||
remove() {
|
||||
tech.isMobFullHealth = false
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "yield stress",
|
||||
// description: "<strong>+55%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// frequencyDefault: 1,
|
||||
// allowed() {
|
||||
// return m.fieldMode !== 7 && tech.mobSpawnWithHealth === 0
|
||||
// },
|
||||
// requires: "not cloaking, reaction inhibitor",
|
||||
// effect() {
|
||||
// tech.isMobFullHealth = true
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isMobFullHealth = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "cascading failure",
|
||||
description: "<strong>+222%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> below <strong>25%</strong> <strong>health</strong>",
|
||||
@@ -1456,7 +1488,7 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isMobFullHealth
|
||||
return !tech.isMobFullHealthCloak
|
||||
},
|
||||
requires: "not topological defect",
|
||||
effect() {
|
||||
@@ -2676,6 +2708,34 @@ const tech = {
|
||||
tech.isHarmArmor = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "tessellation",
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+35%</strong> <strong class='color-defense'>defense</strong>`,
|
||||
// description: "use <strong>4</strong> <strong class='color-r'>research</strong><br>reduce <strong class='color-defense'>defense</strong> by <strong>50%</strong>",
|
||||
// isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return powerUps.research.count > 1 || build.isExperimentSelection
|
||||
},
|
||||
requires: "",
|
||||
// allowed() {
|
||||
// return (m.fieldMode === 8 || m.fieldMode === 2 || m.fieldMode === 3 || m.fieldMode === 10) && (build.isExperimentSelection || powerUps.research.count > 3)
|
||||
// },
|
||||
// requires: "perfect diamagnetism, negative mass, grappling hook, pilot wave",
|
||||
effect() {
|
||||
tech.isFieldHarmReduction = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isFieldHarmReduction = false
|
||||
if (this.count > 0) powerUps.research.changeRerolls(2)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Pauli exclusion",
|
||||
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3.5</strong> seconds`,
|
||||
@@ -2796,14 +2856,14 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "heat engine",
|
||||
description: `<strong>+50%</strong> <strong class='color-d'>damage</strong><br><strong>–50</strong> maximum <strong class='color-f'>energy</strong>`,
|
||||
description: `<strong>+40%</strong> <strong class='color-d'>damage</strong><br><strong>–50</strong> maximum <strong class='color-f'>energy</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed: () => true,
|
||||
requires: "not CPT",
|
||||
damage: 1.5,
|
||||
damage: 1.4,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
tech.isMaxEnergyTech = true;
|
||||
@@ -4184,7 +4244,7 @@ const tech = {
|
||||
{
|
||||
name: "commodities exchange",
|
||||
descriptionFunction() {
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>6-12</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
|
||||
return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>10-14</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4912,7 +4972,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isFoamMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1
|
||||
return tech.hookNails + tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isFoamMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1
|
||||
},
|
||||
requires: "nails, nail gun, rivets, shotgun, super balls, mine",
|
||||
effect() {
|
||||
@@ -4951,7 +5011,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || ((tech.isMineDrop || tech.haveGunCheck("mine")) && !(tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
|
||||
return tech.isNailBotUpgrade || tech.hookNails || tech.fragments || tech.nailsDeathMob || ((tech.isMineDrop || tech.haveGunCheck("mine")) && !(tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
|
||||
},
|
||||
requires: "nail gun, nails, rivets, mine, not ceramic needles",
|
||||
effect() {
|
||||
@@ -5842,7 +5902,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 1) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || tech.isHookExplosion || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
|
||||
return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 1) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
|
||||
},
|
||||
requires: "an explosive damage source, not rocket propelled grenade",
|
||||
effect() {
|
||||
@@ -6123,7 +6183,7 @@ const tech = {
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
// return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines"))
|
||||
return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles)
|
||||
return tech.isMineDrop || tech.isNailBotUpgrade || tech.hookNails || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles)
|
||||
},
|
||||
//
|
||||
requires: "nail gun, not rotary cannon, rivets, or needles",
|
||||
@@ -7074,7 +7134,7 @@ const tech = {
|
||||
// },
|
||||
{
|
||||
name: "alternator",
|
||||
description: "<strong>+90%</strong> <strong>harpoon</strong> <strong class='color-f'>energy</strong> efficiency",
|
||||
description: "<strong>harpoon</strong> no longer uses any <strong class='color-f'>energy</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7113,7 +7173,7 @@ const tech = {
|
||||
{
|
||||
name: "Bessemer process",
|
||||
descriptionFunction() {
|
||||
return `+${(10 * Math.sqrt(b.guns[9].ammo)).toFixed(0)}% <strong>harpoon</strong> size and <strong class='color-d'>damage</strong><br><em>(1/10 √ harpoon <strong class='color-ammo'>ammo</strong>)</em>`
|
||||
return `+${(10 * Math.sqrt(b.guns[9].ammo)).toFixed(0)}% <strong>harpoon</strong> size and <strong class='color-d'>damage</strong><br><em>(effect scales by 1/10 √ harpoon <strong class='color-ammo'>ammo</strong>)</em>`
|
||||
},
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
@@ -7179,7 +7239,7 @@ const tech = {
|
||||
{
|
||||
name: "UHMWPE",
|
||||
descriptionFunction() {
|
||||
return `+${(b.guns[9].ammo * 1.25).toFixed(0)}% <strong>harpoon</strong> <strong>rope</strong> <strong>length</strong><br><em>(1/80 of harpoon <strong class='color-ammo'>ammo</strong>)</em>`
|
||||
return `+${(b.guns[9].ammo * 1.25).toFixed(0)}% <strong>harpoon</strong> <strong>rope</strong> <strong>length</strong><br><em>(effect scales by 1/80 of harpoon <strong class='color-ammo'>ammo</strong>)</em>`
|
||||
},
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
@@ -7219,7 +7279,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "brittle",
|
||||
description: "<strong>+88%</strong> <strong>harpoon</strong>/<strong>grapple</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
description: "<strong>+111%</strong> <strong>harpoon</strong>/<strong>grapple</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7673,7 +7733,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "zero point energy",
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+100</strong> maximum <strong class='color-f'>energy</strong>`,
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+166</strong> maximum <strong class='color-f'>energy</strong>`,
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7684,7 +7744,7 @@ const tech = {
|
||||
},
|
||||
requires: "standing wave, pilot wave, time dilation",
|
||||
effect() {
|
||||
tech.harmonicEnergy = 1
|
||||
tech.harmonicEnergy = 1.66
|
||||
m.setMaxEnergy()
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
@@ -7698,7 +7758,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "expansion",
|
||||
description: "using <strong>standing wave</strong> field <strong>expands</strong> its <strong>radius</strong><br><strong>+40</strong> maximum <strong class='color-f'>energy</strong>",
|
||||
description: "using <strong>standing wave</strong> field <strong>expands</strong> its <strong>radius</strong><br><strong>+77</strong> maximum <strong class='color-f'>energy</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7860,30 +7920,6 @@ const tech = {
|
||||
tech.isBigField = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "tessellation",
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+50%</strong> <strong class='color-defense'>defense</strong>`,
|
||||
// description: "use <strong>4</strong> <strong class='color-r'>research</strong><br>reduce <strong class='color-defense'>defense</strong> by <strong>50%</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 2 || m.fieldMode === 3 || m.fieldMode === 10) && (build.isExperimentSelection || powerUps.research.count > 3)
|
||||
},
|
||||
requires: "perfect diamagnetism, negative mass, grappling hook, pilot wave",
|
||||
effect() {
|
||||
tech.isFieldHarmReduction = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isFieldHarmReduction = false
|
||||
if (this.count > 0) powerUps.research.changeRerolls(2)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "radiative equilibrium",
|
||||
descriptionFunction() {
|
||||
@@ -7978,7 +8014,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "annihilation",
|
||||
description: "after <strong>colliding</strong> with non-boss mobs<br>they are <strong>annihilated</strong> and <strong>–33%</strong> <strong class='color-f'>energy</strong>",
|
||||
description: "after <strong>colliding</strong> with non-boss mobs<br>they are <strong>annihilated</strong> and <strong>–10</strong> <strong class='color-f'>energy</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -8291,9 +8327,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 5 || m.fieldMode === 6 || m.fieldMode === 7 || m.fieldMode === 8 || m.fieldMode === 4
|
||||
return m.fieldMode === 6 || m.fieldMode === 7 || m.fieldMode === 8
|
||||
},
|
||||
requires: "cloaking, molecular assembler, plasma torch, pilot wave",
|
||||
requires: "time dilation, cloaking, pilot wave",
|
||||
damage: 1.35,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
@@ -8315,9 +8351,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 10) && !tech.isPrinter && !tech.isReel && !tech.isHookExplosion
|
||||
return (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 10) && !tech.isPrinter && !tech.isReel && !tech.hookNails
|
||||
},
|
||||
requires: "plasma torch, molecular assembler, grappling hook, not printer, reel, rupture",
|
||||
requires: "plasma torch, molecular assembler, grappling hook, not printer, reel, swarf",
|
||||
effect() {
|
||||
tech.isTokamak = true;
|
||||
},
|
||||
@@ -8705,7 +8741,7 @@ const tech = {
|
||||
{
|
||||
name: "dazzler",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Dazzler_(weapon)' class="link">dazzler</a>`,
|
||||
description: "after <strong class='color-cloaked'>decloaking</strong> <strong>stun</strong> nearby mobs<br>and drain <strong>–10</strong> <strong class='color-f'>energy</strong>",
|
||||
description: "after <strong class='color-cloaked'>decloaking</strong><br><strong>stun</strong> nearby mobs for 2 second",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -8724,16 +8760,16 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "topological defect",
|
||||
description: "<strong>+88%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
description: "<strong>+111%</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 7) && tech.mobSpawnWithHealth === 0 && !tech.isMobFullHealth
|
||||
return (m.fieldMode === 8 || m.fieldMode === 7) && tech.mobSpawnWithHealth === 0
|
||||
},
|
||||
requires: "cloaking, pilot wave, not reaction inhibitor, yield stress",
|
||||
requires: "cloaking, pilot wave, not reaction inhibitor",
|
||||
effect() {
|
||||
tech.isMobFullHealthCloak = true
|
||||
},
|
||||
@@ -8760,34 +8796,6 @@ const tech = {
|
||||
// tech.sneakAttackDmg = 4.33 //333% + 100%
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "dynamical systems",
|
||||
description: `use ${powerUps.orb.research(2)}<br><strong>+35%</strong> <strong class='color-d'>damage</strong>`,
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 5 || m.fieldMode === 7 || m.fieldMode === 8) && (build.isExperimentSelection || powerUps.research.count > 1)
|
||||
},
|
||||
requires: "cloaking, pilot wave, or plasma torch",
|
||||
damage: 1.35,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
tech.isCloakingDamage = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isCloakingDamage = false
|
||||
if (this.count > 0) {
|
||||
tech.damage /= this.damage
|
||||
powerUps.research.changeRerolls(2)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "WIMPs",
|
||||
description: `at the end of each <strong>level</strong> spawn ${powerUps.orb.research(4)}<br> and a dangerous particle that slowly <strong>chases</strong> you`,
|
||||
@@ -8818,9 +8826,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 6 || m.fieldMode === 9 || m.fieldMode === 10) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
return (m.fieldMode === 8 || m.fieldMode === 6 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
},
|
||||
requires: "wormhole, time dilation, negative mass, pilot wave, grappling hook",
|
||||
requires: "wormhole, time dilation, negative mass, pilot wave",
|
||||
effect() {
|
||||
tech.fieldDuplicate = 0.11
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
@@ -8988,7 +8996,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "CIWS",
|
||||
description: "<strong>grappling hook</strong> uses <strong>18</strong> <strong class='color-f'>energy</strong><br> to fire <strong>harpoons</strong> at nearby mobs",
|
||||
description: "<strong>grappling hook</strong> uses <strong>10</strong> <strong class='color-f'>energy</strong><br> to fire <strong>harpoons</strong> at nearby mobs",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -9006,10 +9014,11 @@ const tech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "rupture",
|
||||
description: "after <strong>grappling hook</strong> impacts solid objects<br>generate an <strong class='color-e'>explosion</strong>",
|
||||
name: "swarf",
|
||||
// description: "after <strong>grappling hook</strong> impacts solid objects generate an <strong class='color-e'>explosion</strong> and become briefly <strong>invulnerable</strong>",
|
||||
description: "after <strong>grappling hook</strong> impacts something<br>eject <strong>nails</strong> splinters towards nearby mobs",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
@@ -9018,24 +9027,24 @@ const tech = {
|
||||
},
|
||||
requires: "grappling hook, not reel, tokamak",
|
||||
effect() {
|
||||
tech.isHookExplosion = true
|
||||
tech.hookNails += 4
|
||||
},
|
||||
remove() {
|
||||
tech.isHookExplosion = false
|
||||
tech.hookNails = 0
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "reel",
|
||||
description: "<strong>+400%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong><br><strong>+30</strong> <strong class='color-f'>energy</strong> when reeling in far away <strong class='color-block'>blocks</strong>",
|
||||
description: "<strong>+400%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong><br>up to <strong>+75</strong> <strong class='color-f'>energy</strong> after reeling in <strong class='color-block'>blocks</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return m.fieldMode === 10 && !tech.isTokamak && tech.blockDamage === 0.075 && !tech.isHookExplosion
|
||||
return m.fieldMode === 10 && !tech.isTokamak && tech.blockDamage === 0.075 && !tech.hookNails
|
||||
},
|
||||
requires: "grappling hook, not mass driver, rupture, tokamak",
|
||||
requires: "grappling hook, not mass driver, swarf, tokamak",
|
||||
effect() {
|
||||
tech.blockDamage = 0.375
|
||||
tech.isReel = true
|
||||
@@ -11910,7 +11919,7 @@ const tech = {
|
||||
isFastFoam: null,
|
||||
isSporeGrowth: null,
|
||||
isStimulatedEmission: null,
|
||||
nailGun: null,
|
||||
// nailGun: null,
|
||||
nailInstantFireRate: null,
|
||||
isCapacitor: null,
|
||||
isEnergyNoAmmo: null,
|
||||
@@ -12148,12 +12157,11 @@ const tech = {
|
||||
isPrinter: null,
|
||||
// isHookWire: null,
|
||||
isHookDefense: null,
|
||||
isHookExplosion: null,
|
||||
hookNails: null,
|
||||
isHarpoonDefense: null,
|
||||
isReel: null,
|
||||
harpoonPowerUpCycle: null,
|
||||
isHarpoonFullHealth: null,
|
||||
isMobFullHealth: null,
|
||||
isMobFullHealthCloak: null,
|
||||
isMobLowHealth: null,
|
||||
isDamageCooldown: null,
|
||||
|
||||
70
todo.txt
70
todo.txt
@@ -1,16 +1,71 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
tech: hyperpolarization - reduce the CD on depolarization by 1 second
|
||||
mob: laserLayer - leaves behind lasers that persist for a few seconds
|
||||
ghoster mobs do 66% less damage, but they eject your ammo
|
||||
|
||||
metamaterial absorber 22->25% chance to get power up for mobs not killed
|
||||
symbiosis -0.5 -> 0.25 max health after killing a mob
|
||||
dazzler -15->10 energy after decloaking and stunning mobs
|
||||
Hilbert space 142->300% damage
|
||||
grappling hook tech rupture renamed swarf
|
||||
fires several nails at nearby mobs, not explosions
|
||||
grappling hook 6->9 energy per second
|
||||
CIWS 18->10 energy
|
||||
reel +40->75 energy reeling blocks
|
||||
wormhole 5->7% duplication
|
||||
cloaking no longer drains energy, this fixes a can't cloak bug
|
||||
dazzler no longer drains energy
|
||||
dazzler range reduced by 15%
|
||||
dazzler stuns for 3->2 seconds
|
||||
zero point energy 100->166 max energy
|
||||
expansion 40->77 max energy
|
||||
annihilation -33% of max energy -> 10 energy
|
||||
dynamical systems is no longer a field tech 35->30 damage
|
||||
tessellation is no longer a field tech 50->35 defense
|
||||
yield stress removed
|
||||
topological defect 80->111% damage
|
||||
brittle 80->111% damage
|
||||
commodities exchange 6-12 -> 10-14 power ups
|
||||
heat engine 50->40% damage
|
||||
flame test grenades clusters explode 40% faster
|
||||
alternator uses 10->0% energy for harpoon
|
||||
|
||||
finally made a shared vertexCollision function
|
||||
this might cause some bugs with laser-like effects...
|
||||
|
||||
fixed bug with 1000x more frequent enthalpy
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
increase damage for each not picked up power up on the level
|
||||
|
||||
make a laserLayerBoss
|
||||
add lasers on player's history
|
||||
|
||||
button/switch input ideas from Cocoon game
|
||||
pick up blocks that have a rubber band attached to a sliding switch
|
||||
as player moves the vector direction of the rubber band will move the slider left or right
|
||||
use this to open doors, move larger blocks, ...
|
||||
switches that toggle left, right when player presses input.field while standing nearby
|
||||
replace laser off on switch?
|
||||
platform that rises up when player presses input.field while standing
|
||||
How to instruct player to use field on these?
|
||||
color with field #0ff
|
||||
draw field effect
|
||||
make it still functional without the field button
|
||||
|
||||
tech: - getting a new gun also gives you 2 random tech for that gun
|
||||
or a field?
|
||||
can these guntech tech be converted into a player choice?
|
||||
|
||||
tech: interest - research and ammo increases by 10% at the start of each level?
|
||||
spawn research and ammo at start of new level
|
||||
extend to current health?
|
||||
|
||||
how to reduce the number of clicks and keypresses
|
||||
auto fire mode
|
||||
player shoots at whatever is nearby
|
||||
should player have to look towards mobs?
|
||||
increase ammo?
|
||||
|
||||
animate egg laying mobs
|
||||
just draw a circle when it happens?
|
||||
|
||||
improve new player experience
|
||||
training is too long to be a tutorial
|
||||
before nail gun level offer player option to continue or switch to normal game
|
||||
@@ -51,7 +106,7 @@ make grappling hook of different shapes
|
||||
longer
|
||||
circular with spikes
|
||||
indicate tech upgrades?
|
||||
rupture, reel, tokamak
|
||||
swarf, reel, tokamak
|
||||
do this in draw or in verticies?
|
||||
draw can have different colors
|
||||
|
||||
@@ -1097,6 +1152,7 @@ possible names for tech
|
||||
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
|
||||
Unruh effect - accelerating makes heat/thermal particles
|
||||
configuration space - holds the position of everything
|
||||
stress–energy tensor
|
||||
|
||||
|
||||
******************************************************** CARS IMAGES ********************************************************
|
||||
|
||||
Reference in New Issue
Block a user