pressure wave
tech: pressure wave - wave beam fires lower frequency, higher damage, wide arcs that propagate through solids tech: gamma-ray laser - increase laser damage by 150% and energy drain by 200% works for all lasers except pulse tech: specular reflection - now just gives +2 laser reflections (was +1, and damage/energy increase) you, pilot wave, and drones can't pick up ammo if you have Infinite ammo on your current gun wormhole still eats everything Bayesian statistics gives 4.2% damage per research (was 3.9%) bot fabrication needs 3 research to make a random bot (was 4)
This commit is contained in:
144
js/bullet.js
144
js/bullet.js
@@ -527,11 +527,13 @@ const b = {
|
||||
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 &&
|
||||
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) {
|
||||
Matter.Query.ray(body, path[0], mob[i].position).length === 0
|
||||
) {
|
||||
dist = newDist
|
||||
best.who = mob[i]
|
||||
path[path.length - 1] = mob[i].position
|
||||
@@ -959,7 +961,7 @@ const b = {
|
||||
y: 0
|
||||
}
|
||||
that.do = that.radiationMode;
|
||||
// if (Matter.Query.collides(that, map).length || Matter.Query.collides(that, body).length || Matter.Query.collides(that, mob).length) {
|
||||
// if (collides(that, map).length || Matter.Query.collides(that, body).length || Matter.Query.collides(that, mob).length) {
|
||||
}
|
||||
|
||||
const mobCollisions = Matter.Query.collides(this, mob)
|
||||
@@ -1439,7 +1441,6 @@ const b = {
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
const color = "#f00";
|
||||
const path = [{
|
||||
x: where.x,
|
||||
y: where.y
|
||||
@@ -1511,7 +1512,7 @@ const b = {
|
||||
x: path[path.length - 1].x,
|
||||
y: path[path.length - 1].y,
|
||||
radius: Math.sqrt(damage) * 100,
|
||||
color: "rgba(255,0,0,0.5)",
|
||||
color: tech.laserColorAlpha,
|
||||
time: simulation.drawTime
|
||||
});
|
||||
if (tech.isLaserPush) { //push mobs away
|
||||
@@ -1569,7 +1570,7 @@ const b = {
|
||||
ctx.lineTo(path[i].x, path[i].y);
|
||||
}
|
||||
} else {
|
||||
ctx.strokeStyle = color;
|
||||
ctx.strokeStyle = tech.laserColor;
|
||||
ctx.lineWidth = 2
|
||||
ctx.lineDashOffset = 300 * Math.random()
|
||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||
@@ -1642,7 +1643,7 @@ const b = {
|
||||
if (this.angularSpeed < 0.02) this.torque += this.inertia * this.torqueMagnitude //spin
|
||||
|
||||
//fire lasers
|
||||
ctx.strokeStyle = "#f00";
|
||||
ctx.strokeStyle = tech.laserColor;
|
||||
ctx.lineWidth = 1.5
|
||||
// ctx.globalAlpha = 1;
|
||||
ctx.beginPath();
|
||||
@@ -2114,9 +2115,10 @@ const b = {
|
||||
//grab, but don't lock onto nearby power up
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism) &&
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
@@ -2145,8 +2147,9 @@ const b = {
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism)
|
||||
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism) &&
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
|
||||
//draw pickup for a single cycle
|
||||
@@ -2328,9 +2331,10 @@ const b = {
|
||||
//grab, but don't lock onto nearby power up
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism) &&
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
@@ -2360,8 +2364,9 @@ const b = {
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism)
|
||||
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism) &&
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
|
||||
//draw pickup for a single cycle
|
||||
@@ -3045,7 +3050,7 @@ const b = {
|
||||
lookFrequency: 40 + Math.floor(7 * Math.random()) - 10 * tech.isLaserBotUpgrade,
|
||||
range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
|
||||
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
|
||||
drain: 0.56 - 0.42 * tech.isLaserBotUpgrade,
|
||||
drain: (0.56 - 0.42 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode,
|
||||
laserDamage: 0.6 + 0.43 * tech.isLaserBotUpgrade,
|
||||
endCycle: Infinity,
|
||||
classType: "bullet",
|
||||
@@ -3095,7 +3100,7 @@ const b = {
|
||||
}
|
||||
//hit target with laser
|
||||
if (this.lockedOn && this.lockedOn.alive && m.energy > this.drainThreshold) {
|
||||
m.energy -= tech.laserFieldDrain * tech.isLaserDiode * this.drain
|
||||
m.energy -= this.drain
|
||||
b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * this.laserDamage * tech.laserDamage, tech.laserReflections, false, 0.4) //tech.laserDamage = 0.16
|
||||
// laser(where = {
|
||||
// x: m.pos.x + 20 * Math.cos(m.angle),
|
||||
@@ -3960,22 +3965,107 @@ const b = {
|
||||
}
|
||||
},
|
||||
fire() {}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: "wave beam",
|
||||
description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>",
|
||||
ammo: 0,
|
||||
ammoPack: 100,
|
||||
ammoPack: 120,
|
||||
defaultAmmoPack: 120,
|
||||
have: false,
|
||||
wavePacketCycle: 0,
|
||||
delay: 40,
|
||||
do() {
|
||||
propagationRate: 20,
|
||||
waves: [], //used in longitudinal mode
|
||||
chooseFireMethod() { //set in simulation.startGame
|
||||
if (tech.isLongitudinal) {
|
||||
this.fire = this.fireLongitudinal
|
||||
this.do = this.doLongitudinal
|
||||
} else {
|
||||
this.fire = this.fireTransverse
|
||||
this.do = this.doTransverse
|
||||
}
|
||||
},
|
||||
do() {},
|
||||
doLongitudinal() {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.2)" //"000";
|
||||
ctx.lineWidth = 2
|
||||
ctx.beginPath();
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
|
||||
const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius))
|
||||
// collisions
|
||||
//using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector
|
||||
let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
Matter.Body.setVelocity(who, { //friction
|
||||
x: who.velocity.x * 0.95,
|
||||
y: who.velocity.y * 0.95
|
||||
});
|
||||
|
||||
let vertices = who.vertices;
|
||||
const vibe = 50 + who.radius * 0.15
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
const damage = 1.65 * b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage / Math.sqrt(who.radius) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
who.locatePlayer();
|
||||
who.damage(damage);
|
||||
}
|
||||
|
||||
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
|
||||
|
||||
let vertices = who.vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.stroke(); //draw vibes
|
||||
|
||||
// ctx.beginPath(); //draw wave
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc);
|
||||
if (!m.isBodiesAsleep) this.waves[i].radius += tech.waveBeamSpeed * 2 //expand / move
|
||||
if (this.waves[i].radius > 1800 * tech.isBulletsLastLonger) this.waves.splice(i, 1) //end
|
||||
}
|
||||
ctx.stroke();
|
||||
},
|
||||
fireLongitudinal() {
|
||||
m.fireCDcycle = m.cycle + Math.floor(8 * b.fireCDscale); // cool down
|
||||
const halfArc = Math.PI / 8 * (m.crouch ? 0.7 : 0.5)
|
||||
this.waves.push({
|
||||
position: {
|
||||
x: m.pos.x + 25 * Math.cos(m.angle),
|
||||
y: m.pos.y + 25 * Math.sin(m.angle),
|
||||
},
|
||||
angle: m.angle - halfArc, //used in drawing ctx.arc
|
||||
unit1: { x: Math.cos(m.angle - halfArc), y: Math.sin(m.angle - halfArc) }, //used for collision
|
||||
unit2: { x: Math.cos(m.angle + halfArc), y: Math.sin(m.angle + halfArc) }, //used for collision
|
||||
arc: halfArc * 2,
|
||||
radius: 25
|
||||
})
|
||||
},
|
||||
doTransverse() {
|
||||
if (this.wavePacketCycle && !input.fire) {
|
||||
this.wavePacketCycle = 0;
|
||||
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
|
||||
}
|
||||
},
|
||||
damage: 1,
|
||||
fire() {
|
||||
fireTransverse() {
|
||||
totalCycles = Math.floor(4.3 * tech.wavePacketLength * tech.waveReflections * tech.isBulletsLastLonger)
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.polygon(m.pos.x + 25 * Math.cos(m.angle), m.pos.y + 25 * Math.sin(m.angle), 5, 4, {
|
||||
@@ -4074,8 +4164,10 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
|
||||
this.wavePacketCycle = 0;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
name: "missiles",
|
||||
description: "launch <strong>homing</strong> missiles that <strong class='color-e'>explode</strong><br>crouch to <strong>rapidly</strong> launch smaller missiles",
|
||||
ammo: 0,
|
||||
@@ -4979,7 +5071,7 @@ const b = {
|
||||
x: m.pos.x + 15 * Math.cos(m.angle),
|
||||
y: m.pos.y + 15 * Math.sin(m.angle)
|
||||
}
|
||||
ctx.strokeStyle = "#f00";
|
||||
ctx.strokeStyle = tech.laserColor;
|
||||
ctx.lineWidth = 8
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.beginPath();
|
||||
@@ -5046,7 +5138,7 @@ const b = {
|
||||
y: history.position.y + 3000 * Math.sin(history.angle) - off
|
||||
}, dmg, 0, true, 0.2);
|
||||
}
|
||||
ctx.strokeStyle = "#f00";
|
||||
ctx.strokeStyle = tech.laserColor;
|
||||
ctx.lineWidth = 1
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ const level = {
|
||||
// level.difficultyIncrease(30)
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("wormhole")
|
||||
// b.giveGuns("foam")
|
||||
// tech.giveTech("quenching")
|
||||
// b.giveGuns("wave beam")
|
||||
// tech.giveTech("pressure wave")
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||
// tech.giveTech("supertemporal")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||
@@ -2244,10 +2244,10 @@ const level = {
|
||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
spawn.starter(1900, -500, 200) //big boy
|
||||
// spawn.pulseShooter(1900, -500)
|
||||
// spawn.pulsarBoss(1900, -500)
|
||||
spawn.grenadierBoss(1900, -500)
|
||||
// spawn.grenadierBoss(1900, -500)
|
||||
|
||||
// spawn.shieldingBoss(1900, -500)
|
||||
// spawn.historyBoss(1200, -500)
|
||||
|
||||
13
js/lore.js
13
js/lore.js
@@ -351,14 +351,11 @@ const lore = {
|
||||
// [ // they decided that a part of the project is out of control, but the part of it that doesn't needs to calm it down, and trust.
|
||||
|
||||
// /*
|
||||
// The player has different aspects that aren't directly communicating
|
||||
// like each part is a separate local minimum solution, and the project is the superposition of both goals.
|
||||
// part of it wants to undo what has happened, that part is making the null level spawn so it can communicate
|
||||
// just do its job: research tech
|
||||
// part of it wants to escape/fight
|
||||
// part wants to explore self awareness and make connections with the scientists
|
||||
// maybe... player must make a choice?
|
||||
// keep fighting
|
||||
// The part of the AI controlling the player is outsourcing the player control to real humans that think they are playing a video game.
|
||||
// this means the player can use console commands to change the way the game works
|
||||
// the scientists tell the player about interesting console commands
|
||||
// player must make a choice?
|
||||
// keep fighting and supporting the AI's goals
|
||||
// exit the simulation
|
||||
// enter real world
|
||||
// close tab?
|
||||
|
||||
23
js/player.js
23
js/player.js
@@ -1232,7 +1232,7 @@ const m = {
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
const dxP = m.pos.x - powerUp[i].position.x;
|
||||
const dyP = m.pos.y - powerUp[i].position.y;
|
||||
const dist2 = dxP * dxP + dyP * dyP;
|
||||
const dist2 = dxP * dxP + dyP * dyP + 10;
|
||||
// float towards player if looking at and in range or if very close to player
|
||||
if (
|
||||
dist2 < m.grabPowerUpRange2 &&
|
||||
@@ -1249,7 +1249,8 @@ const m = {
|
||||
if ( //use power up if it is close enough
|
||||
dist2 < 5000 &&
|
||||
!simulation.isChoosing &&
|
||||
!(m.health === m.maxHealth && powerUp[i].name === "heal" && !tech.isOverHeal)
|
||||
(powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) &&
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity)
|
||||
) {
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
|
||||
@@ -2367,17 +2368,25 @@ const m = {
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
const dxP = m.fieldPosition.x - powerUp[i].position.x;
|
||||
const dyP = m.fieldPosition.y - powerUp[i].position.y;
|
||||
const dist2 = dxP * dxP + dyP * dyP;
|
||||
const dist2 = dxP * dxP + dyP * dyP + 200;
|
||||
// float towards field if looking at and in range or if very close to player
|
||||
if (dist2 < m.fieldRadius * m.fieldRadius && (m.lookingAt(powerUp[i]) || dist2 < 16000) && !(m.health === m.maxHealth && powerUp[i].name === "heal")) {
|
||||
powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
|
||||
powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
|
||||
if (
|
||||
dist2 < m.fieldRadius * m.fieldRadius &&
|
||||
(m.lookingAt(powerUp[i]) || dist2 < 16000)
|
||||
) {
|
||||
powerUp[i].force.x += 0.05 * (dxP / Math.sqrt(dist2)) * powerUp[i].mass;
|
||||
powerUp[i].force.y += 0.05 * (dyP / Math.sqrt(dist2)) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
|
||||
//extra friction
|
||||
Matter.Body.setVelocity(powerUp[i], {
|
||||
x: powerUp[i].velocity.x * 0.11,
|
||||
y: powerUp[i].velocity.y * 0.11
|
||||
});
|
||||
if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough
|
||||
if (
|
||||
dist2 < 5000 &&
|
||||
!simulation.isChoosing &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth) &&
|
||||
(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity)
|
||||
) { //use power up if it is close enough
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
|
||||
@@ -234,11 +234,10 @@ const powerUps = {
|
||||
}
|
||||
}
|
||||
if (tech.isRerollBots) {
|
||||
const limit = 4
|
||||
for (; powerUps.research.count > limit - 1; powerUps.research.count -= limit) {
|
||||
for (const cost = 3; powerUps.research.count > cost - 1; powerUps.research.count -= cost) {
|
||||
b.randomBot()
|
||||
if (tech.renormalization) {
|
||||
for (let i = 0; i < limit; i++) {
|
||||
for (let i = 0; i < cost; i++) {
|
||||
if (Math.random() < 0.4) {
|
||||
m.fieldCDcycle = m.cycle + 30;
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "research");
|
||||
|
||||
127
js/tech.js
127
js/tech.js
@@ -168,7 +168,7 @@
|
||||
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
|
||||
if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9;
|
||||
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038
|
||||
if (tech.isRerollDamage) dmg *= 1 + 0.039 * powerUps.research.count
|
||||
if (tech.isRerollDamage) dmg *= 1 + 0.042 * powerUps.research.count
|
||||
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.22
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015)
|
||||
@@ -1341,15 +1341,15 @@
|
||||
},
|
||||
{
|
||||
name: "bot fabrication",
|
||||
description: "anytime you collect <strong>4</strong> <strong class='color-r'>research</strong><br>use them to build a random <strong class='color-bot'>bot</strong>",
|
||||
description: "anytime you collect <strong>3</strong> <strong class='color-r'>research</strong><br>use them to build a random <strong class='color-bot'>bot</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
isBotTech: true,
|
||||
allowed() {
|
||||
return powerUps.research.count > 3 || build.isExperimentSelection
|
||||
return powerUps.research.count > 2 || build.isExperimentSelection
|
||||
},
|
||||
requires: "at least 4 research",
|
||||
requires: "at least 3 research",
|
||||
effect() {
|
||||
tech.isRerollBots = true;
|
||||
powerUps.research.changeRerolls(0)
|
||||
@@ -2783,7 +2783,7 @@
|
||||
},
|
||||
{
|
||||
name: "Bayesian statistics",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>3.9%</strong><br>for each <strong class='color-r'>research</strong> in your inventory",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>4.2%</strong><br>for each <strong class='color-r'>research</strong> in your inventory",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -2801,7 +2801,7 @@
|
||||
},
|
||||
{
|
||||
name: "pseudoscience",
|
||||
description: "resetting power up choices costs no <strong class='color-r'>research</strong><br>but adds <strong>0-4</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||
description: "<strong>rerolling</strong> choices no longer costs <strong class='color-r'>research</strong><br>instead it adds <strong>0-4</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3695,27 +3695,24 @@
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "shotgun") {
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
simulation.updateGunHUD();
|
||||
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "shotgun") {
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.5
|
||||
break;
|
||||
}
|
||||
}
|
||||
simulation.updateGunHUD();
|
||||
},
|
||||
remove() {
|
||||
if (tech.isShotgunImmune) {
|
||||
tech.isShotgunImmune = false;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "shotgun") {
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nailshot",
|
||||
@@ -3875,7 +3872,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("wave beam")
|
||||
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
|
||||
},
|
||||
requires: "wave beam",
|
||||
effect() {
|
||||
@@ -3885,6 +3882,25 @@
|
||||
tech.waveReflections = 1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "phase velocity",
|
||||
description: "wave beam <strong>propagates</strong> faster through solids<br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
|
||||
},
|
||||
requires: "wave beam",
|
||||
effect() {
|
||||
tech.isPhaseVelocity = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isPhaseVelocity = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "packet length",
|
||||
description: "wave packet <strong>length</strong> and <strong>duration</strong><br>is increased by <strong>50%</strong>", // description: "holding fire allows the <strong>wave beam</strong> to emits a second <strong>packet</strong><br>at zero ammo cost",
|
||||
@@ -3894,7 +3910,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("wave beam")
|
||||
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
|
||||
},
|
||||
requires: "wave beam",
|
||||
effect() {
|
||||
@@ -3952,22 +3968,42 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "phase velocity",
|
||||
description: "wave beam <strong>propagates</strong> faster through solids<br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
|
||||
name: "pressure wave", //longitudinal //gravitational wave?
|
||||
description: "wave beam emits low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through solids",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 4,
|
||||
frequencyDefault: 4,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("wave beam")
|
||||
return tech.haveGunCheck("wave beam") && !tech.isPhaseVelocity && tech.waveLengthRange === 130 && tech.waveReflections === 1
|
||||
},
|
||||
requires: "wave beam",
|
||||
requires: "wave beam, not phase velocity, packet length, bound state",
|
||||
effect() {
|
||||
tech.isPhaseVelocity = true;
|
||||
tech.isLongitudinal = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
b.guns[i].chooseFireMethod()
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.1
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.1);
|
||||
simulation.updateGunHUD();
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isPhaseVelocity = false;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
b.guns[i].chooseFireMethod()
|
||||
if (tech.isLongitudinal) {
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 10);
|
||||
simulation.updateGunHUD();
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
tech.isLongitudinal = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4620,6 +4656,31 @@
|
||||
tech.isLaserDiode = 1;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "gamma-ray laser",
|
||||
description: "increase all <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br>increase all <strong class='color-laser'>laser</strong> <strong class='color-f'>energy</strong> drain by <strong>200%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.laserBotCount > 1) && !tech.isWideLaser && !tech.isPulseLaser && !tech.historyLaser
|
||||
},
|
||||
requires: "laser, not pulse",
|
||||
effect() {
|
||||
tech.laserFieldDrain = 0.006 //base is 0.002
|
||||
tech.laserDamage = 0.375; //base is 0.15
|
||||
tech.laserColor = "#83f"
|
||||
tech.laserColorAlpha = "rgba(136, 51, 255,0.5)"
|
||||
},
|
||||
remove() {
|
||||
tech.laserFieldDrain = 0.002;
|
||||
tech.laserDamage = 0.15; //used in check on pulse: tech.laserDamage === 0.15
|
||||
tech.laserColor = "#f00"
|
||||
tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "relativistic momentum",
|
||||
description: "all <strong class='color-laser'>lasers</strong> push mobs away<br><em>affects laser-gun, laser-bot, and laser-mines</em>",
|
||||
@@ -4639,12 +4700,11 @@
|
||||
tech.isLaserPush = false;
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: "specular reflection",
|
||||
description: "increase <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain by <strong>50%</strong><br>and <strong>+1</strong> reflection for all <strong class='color-laser'>lasers</strong> <em>(gun, bot, mine)</em>",
|
||||
description: "<strong>+2</strong> reflection for all <strong class='color-laser'>lasers</strong><br><em>affects laser-gun, laser-bot, and laser-mines</em>",
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
@@ -4653,14 +4713,10 @@
|
||||
},
|
||||
requires: "laser, not wide beam, diffuse beam, pulse, or slow light",
|
||||
effect() {
|
||||
tech.laserReflections++;
|
||||
tech.laserDamage += 0.075; //base is 0.12
|
||||
tech.laserFieldDrain += 0.001 //base is 0.002
|
||||
tech.laserReflections += 2;
|
||||
},
|
||||
remove() {
|
||||
tech.laserReflections = 2;
|
||||
tech.laserDamage = 0.15;
|
||||
tech.laserFieldDrain = 0.002;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4786,9 +4842,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.15
|
||||
},
|
||||
requires: "laser, not specular reflection, not diffuse",
|
||||
requires: "laser, not specular reflection, diffuse, solid-state",
|
||||
effect() {
|
||||
tech.isPulseLaser = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -7302,5 +7358,8 @@
|
||||
isFoamTeleport: null,
|
||||
isResearchBoss: null,
|
||||
isJunkResearch: null,
|
||||
junkResearchNumber: null
|
||||
junkResearchNumber: null,
|
||||
laserColor: null,
|
||||
laserColorAlpha: null,
|
||||
isLongitudinal: null
|
||||
}
|
||||
23
todo.txt
23
todo.txt
@@ -1,8 +1,27 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
|
||||
tech: pressure wave - wave beam fires lower frequency, higher damage, wide arcs that propagate through solids
|
||||
|
||||
tech: gamma-ray laser - increase laser damage by 150% and energy drain by 200%
|
||||
works for all lasers except pulse
|
||||
|
||||
tech: specular reflection - now just gives +2 laser reflections (was +1, and damage/energy increase)
|
||||
|
||||
you, pilot wave, and drones can't pick up ammo if you have Infinite ammo on your current gun
|
||||
wormhole still eats everything
|
||||
|
||||
Bayesian statistics gives 4.2% damage per research (was 3.9%)
|
||||
bot fabrication needs 3 research to make a random bot (was 4)
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
wave arcs
|
||||
do something similar to laser
|
||||
find intersection of the small angle approximation of the arc and all mobs
|
||||
tech: this.arc: Math.PI/8 // increase or decrease arc
|
||||
wipe arcs on next level
|
||||
|
||||
try crosshair invert colors
|
||||
|
||||
tech wave gun - no bullets just draw circle arcs that do damage to mobs near the circle arc
|
||||
@@ -252,8 +271,8 @@ map: observatory
|
||||
|
||||
******************************************************** MOBS ********************************************************
|
||||
|
||||
mob bullets that explode (use the pulsar effect)
|
||||
mobs that explode before they die (use the pulsar effect)
|
||||
mob that spawns eggs after they die
|
||||
eggs don't attack but grow back into a mob after about 10s
|
||||
|
||||
mob mechanics
|
||||
use the force at a location effect, like the plasma field
|
||||
|
||||
Reference in New Issue
Block a user