you're a firework
grenade tech: flame test - grenades release a cluster of smaller explosions
grenade tech: pyrotechnics - grenades release a circle of smaller explosions
grenade tech: implosion - explosions pull things in, not out, +25% to grenade explosion damage and radius
chain reaction no longer requires vacuum bomb
bosses and mobs have much less knock back from explosions
invulnerable mobs have no knock back
alternator harpoon/grapple/railgun energy drain reduced by 100->60%
bots no longer unlock tech until you upgrade to a bot type
JUNK tech rule 30 is now sometimes rule 90 instead
disabled testing for why? mode
wave beam
amplitude 50->37% damage
propagation 50->37% damage
worms
annelids 10-120% -> about 37% damage
radiation
nuclear transmutation stacks 9x
gives 70->47% damage per stack
explosions
ammonium nitrate 27->24% damage and radius
This commit is contained in:
619
js/bullet.js
619
js/bullet.js
@@ -352,13 +352,11 @@ const b = {
|
||||
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
|
||||
radius *= tech.explosiveRadius
|
||||
|
||||
// radius = Math.max(0, Math.min(radius, (distanceToPlayer - 70) / b.explosionRange()))
|
||||
|
||||
let dist, sub, knock;
|
||||
let dmg = radius * 0.019 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1);
|
||||
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
|
||||
if (tech.isSmallExplosion) {
|
||||
color = "rgba(255,0,30,0.7)"
|
||||
// color = "rgba(255,0,30,0.7)"
|
||||
radius *= 0.66
|
||||
dmg *= 1.66
|
||||
}
|
||||
@@ -432,18 +430,18 @@ const b = {
|
||||
m.energy -= 0.15
|
||||
m.damage(0.01 * harm); //remove 99% of the damage 1-0.99
|
||||
// console.log(Math.max(0, Math.min(0.15 - 0.01 * player.speed, 0.15)))
|
||||
knock = Vector.mult(Vector.normalise(sub), -0.6 * player.mass * Math.max(0, Math.min(0.15 - 0.002 * player.speed, 0.15)));
|
||||
knock = Vector.mult(Vector.normalise(sub), 0.6 * player.mass * Math.max(0, Math.min(0.15 - 0.002 * player.speed, 0.15)) * tech.implosion);
|
||||
player.force.x = knock.x; // not += so crazy forces can't build up with MIRV
|
||||
player.force.y = knock.y - 0.3; //some extra vertical kick
|
||||
} else {
|
||||
if (simulation.dmgScale) m.damage(harm);
|
||||
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass * 0.013);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * player.mass * 0.013 * tech.implosion);
|
||||
player.force.x += knock.x;
|
||||
player.force.y += knock.y;
|
||||
}
|
||||
}
|
||||
} else if (dist < alertRange) {
|
||||
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass * 0.005);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * player.mass * 0.005 * tech.implosion);
|
||||
player.force.x += knock.x;
|
||||
player.force.y += knock.y;
|
||||
}
|
||||
@@ -455,7 +453,7 @@ const b = {
|
||||
sub = Vector.sub(where, body[i].position);
|
||||
dist = Vector.magnitude(sub);
|
||||
if (dist < radius) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.022);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * body[i].mass * 0.022 * tech.implosion);
|
||||
body[i].force.x += knock.x;
|
||||
body[i].force.y += knock.y;
|
||||
if (tech.isBlockExplode) {
|
||||
@@ -470,7 +468,7 @@ const b = {
|
||||
}, 150 + 300 * Math.random());
|
||||
}
|
||||
} else if (dist < alertRange) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) * 0.011);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * body[i].mass * 0.011 * tech.implosion);
|
||||
body[i].force.x += knock.x;
|
||||
body[i].force.y += knock.y;
|
||||
}
|
||||
@@ -482,11 +480,11 @@ const b = {
|
||||
sub = Vector.sub(where, powerUp[i].position);
|
||||
dist = Vector.magnitude(sub);
|
||||
if (dist < radius) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) * 0.013);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * powerUp[i].mass * 0.013 * tech.implosion);
|
||||
powerUp[i].force.x += knock.x;
|
||||
powerUp[i].force.y += knock.y;
|
||||
} else if (dist < alertRange) {
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) * 0.007);
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg) * powerUp[i].mass * 0.007 * tech.implosion);
|
||||
powerUp[i].force.x += knock.x;
|
||||
powerUp[i].force.y += knock.y;
|
||||
}
|
||||
@@ -503,18 +501,28 @@ const b = {
|
||||
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
|
||||
mob[i].damage(dmg * damageScale * m.dmgScale);
|
||||
mob[i].locatePlayer();
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.01);
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
if (tech.isExplosionStun) mobs.statusStun(mob[i], 120)
|
||||
if (tech.isExplosionStun) {
|
||||
mobs.statusStun(mob[i], 120)
|
||||
knock *= 0.1
|
||||
}
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.005 : 0.01) * tech.implosion);
|
||||
if (!mob[i].isInvulnerable) {
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
}
|
||||
radius *= 0.95 //reduced range for each additional explosion target
|
||||
damageScale *= 0.87 //reduced damage for each additional explosion target
|
||||
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
||||
mob[i].locatePlayer();
|
||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) * 0.006);
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
if (tech.isExplosionStun) mobs.statusStun(mob[i], 60)
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.002 : 0.006) * tech.implosion);
|
||||
if (tech.isExplosionStun) {
|
||||
mobs.statusStun(mob[i], 60)
|
||||
knock *= 0.1
|
||||
}
|
||||
if (!mob[i].isInvulnerable) {
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -761,6 +769,37 @@ const b = {
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
fireworks(where, size) { //can occur after grenades detonate
|
||||
const cycle = () => {
|
||||
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
|
||||
count++
|
||||
if (count < 60 && m.alive) requestAnimationFrame(cycle);
|
||||
if (!(count % 8)) {
|
||||
const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random())
|
||||
b.explosion(Vector.add(where, Vector.mult(unit, size * (count * 0.011 + 0.03 * Math.random()))), size * (0.5 + Math.random() * 0.35), `hsla(${360*Math.random()},100%,66%,0.6)`); //makes bullet do explosive damage at end
|
||||
}
|
||||
}
|
||||
}
|
||||
let count = 7
|
||||
requestAnimationFrame(cycle);
|
||||
},
|
||||
starburst(where, size) { //can occur after grenades detonate
|
||||
const color = `hsla(${360*Math.random()},100%,66%,0.6)`
|
||||
const cycle = () => {
|
||||
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
|
||||
count++
|
||||
if (count < 21 && m.alive) requestAnimationFrame(cycle);
|
||||
if (count % 2) {
|
||||
const unit = Vector.rotate({ x: 1, y: 0 }, curl * 6.28 * count / 18 + off)
|
||||
b.explosion(Vector.add(where, Vector.mult(unit, size * 0.8)), size * 0.75, color); //makes bullet do explosive damage at end
|
||||
}
|
||||
}
|
||||
}
|
||||
const off = 6 * Math.random()
|
||||
const curl = Math.random() < 0.5 ? -1 : 1;
|
||||
let count = 0
|
||||
requestAnimationFrame(cycle);
|
||||
},
|
||||
grenade() {
|
||||
|
||||
},
|
||||
@@ -769,9 +808,15 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0003);
|
||||
bullet[me].explodeRad = 300 * size;
|
||||
bullet[me].explodeRad = (tech.implosion ? 375 : 300) * size + 100 * tech.isBlockExplode;
|
||||
bullet[me].onEnd = function() {
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.isCircleExplode) {
|
||||
b.starburst(this.position, this.explodeRad)
|
||||
} else if (tech.isClusterExplode) {
|
||||
b.fireworks(this.position, this.explodeRad)
|
||||
} else {
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
}
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
}
|
||||
bullet[me].minDmgSpeed = 1;
|
||||
@@ -794,8 +839,13 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0003);
|
||||
bullet[me].explodeRad = 305 * size;
|
||||
bullet[me].explodeRad = (tech.implosion ? 375 : 300) * size + 100 * tech.isBlockExplode;
|
||||
bullet[me].onEnd = function() {
|
||||
if (tech.isCircleExplode) {
|
||||
b.starburst(this.position, this.explodeRad)
|
||||
} else if (tech.isClusterExplode) {
|
||||
b.fireworks(this.position, this.explodeRad)
|
||||
}
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
}
|
||||
@@ -829,8 +879,13 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0003);
|
||||
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110
|
||||
bullet[me].explodeRad = (tech.implosion ? 425 : 350) * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
|
||||
bullet[me].onEnd = function() {
|
||||
if (tech.isCircleExplode) {
|
||||
b.starburst(this.position, this.explodeRad)
|
||||
} else if (tech.isClusterExplode) {
|
||||
b.fireworks(this.position, this.explodeRad)
|
||||
}
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
}
|
||||
@@ -862,7 +917,7 @@ const b = {
|
||||
for (i = 0, len = who.length; i < len; i++) {
|
||||
const sub = Vector.sub(that.position, who[i].position);
|
||||
const dist = Vector.magnitude(sub);
|
||||
if (dist < radius && dist > 150) {
|
||||
if (dist < radius && dist > 150 && !who.isInvulnerable) {
|
||||
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
|
||||
who[i].force.x += knock.x;
|
||||
who[i].force.y += knock.y;
|
||||
@@ -906,8 +961,13 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0002);
|
||||
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
|
||||
bullet[me].explodeRad = (tech.implosion ? 425 : 350) * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
|
||||
bullet[me].onEnd = function() {
|
||||
if (tech.isCircleExplode) {
|
||||
b.starburst(this.position, this.explodeRad)
|
||||
} else if (tech.isClusterExplode) {
|
||||
b.fireworks(this.position, this.explodeRad)
|
||||
}
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
}
|
||||
@@ -926,7 +986,7 @@ const b = {
|
||||
for (i = 0, len = who.length; i < len; i++) {
|
||||
const sub = Vector.sub(that.position, who[i].position);
|
||||
const dist = Vector.magnitude(sub);
|
||||
if (dist < radius && dist > 150) {
|
||||
if (dist < radius && dist > 150 && !who.isInvulnerable) {
|
||||
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
|
||||
who[i].force.x += knock.x;
|
||||
who[i].force.y += knock.y;
|
||||
@@ -1099,7 +1159,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
//aoe damage to mobs
|
||||
const dmg = m.dmgScale * 0.11 * tech.radioactiveDamage
|
||||
let dmg = m.dmgScale * 0.11 * tech.radioactiveDamage
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius + mob[i].radius) {
|
||||
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.25 //reduce damage if a wall is in the way
|
||||
@@ -1140,21 +1200,12 @@ const b = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let gunIndex = null
|
||||
for (let i = 0, len = b.guns.length; i < len; i++) {
|
||||
if (b.guns[i].name === "grenades") {
|
||||
gunIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tech.isNeutronBomb) {
|
||||
b.grenade = grenadeNeutron
|
||||
if (tech.isRPG) {
|
||||
b.guns[gunIndex].do = function() {}
|
||||
b.guns[5].do = function() {}
|
||||
} else {
|
||||
if (gunIndex) b.guns[gunIndex].do = function() {
|
||||
b.guns[5].do = function() {
|
||||
if (!input.field && input.down) {
|
||||
const cycles = 80
|
||||
const speed = input.down ? 35 : 20 //input.down ? 43 : 32
|
||||
@@ -1172,7 +1223,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
} else if (tech.isRPG) {
|
||||
b.guns[gunIndex].do = function() {}
|
||||
b.guns[5].do = function() {}
|
||||
if (tech.isVacuumBomb) {
|
||||
b.grenade = grenadeRPGVacuum
|
||||
} else {
|
||||
@@ -1180,7 +1231,7 @@ const b = {
|
||||
}
|
||||
} else if (tech.isVacuumBomb) {
|
||||
b.grenade = grenadeVacuum
|
||||
if (gunIndex) b.guns[gunIndex].do = function() {
|
||||
b.guns[5].do = function() {
|
||||
if (!input.field && input.down) {
|
||||
const cycles = Math.floor(input.down ? 50 : 30) //30
|
||||
const speed = input.down ? 44 : 35
|
||||
@@ -1197,7 +1248,7 @@ const b = {
|
||||
}
|
||||
} else {
|
||||
b.grenade = grenadeDefault
|
||||
if (gunIndex) b.guns[gunIndex].do = function() {
|
||||
b.guns[5].do = function() {
|
||||
if (!input.field && input.down) {
|
||||
const cycles = Math.floor(input.down ? 120 : 80) //30
|
||||
const speed = input.down ? 43 : 32
|
||||
@@ -1374,7 +1425,7 @@ const b = {
|
||||
minDmgSpeed: 4,
|
||||
lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||
density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
||||
drain: 0.004,
|
||||
drain: tech.isRailEnergyGain ? 0.002 : 0.006,
|
||||
beforeDmg(who) {
|
||||
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||
who.isShielded = false
|
||||
@@ -1467,7 +1518,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!tech.isRailEnergyGain && m.energy > 0.005) m.energy -= 0.005
|
||||
if (m.energy > this.drain) m.energy -= this.drain
|
||||
const sub = Vector.sub(this.position, m.pos)
|
||||
const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
|
||||
const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
|
||||
@@ -1556,13 +1607,13 @@ const b = {
|
||||
dist = 0
|
||||
player.force.y += 5 * player.mass * simulation.g;
|
||||
}
|
||||
if (m.energy > this.drain || tech.isRailEnergyGain) {
|
||||
if (m.energy > this.drain) {
|
||||
Matter.Body.setVelocity(player, { x: player.velocity.x * 0.8, y: player.velocity.y * 0.8 });
|
||||
const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200))
|
||||
player.force.x += pull.x
|
||||
player.force.y += pull.y
|
||||
|
||||
if (!tech.isRailEnergyGain && dist > 500) {
|
||||
if (dist > 500) {
|
||||
m.energy -= this.drain
|
||||
if (m.energy < 0) {
|
||||
this.endCycle = 0;
|
||||
@@ -1626,6 +1677,7 @@ const b = {
|
||||
friction: 1,
|
||||
frictionAir: 0.4,
|
||||
thrustMag: 0.1,
|
||||
drain: tech.isRailEnergyGain ? 0.002 : 0.006,
|
||||
turnRate: isReturn ? 0.1 : 0.03, //0.015
|
||||
drawStringControlMagnitude: 3000 + 5000 * Math.random(),
|
||||
drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
|
||||
@@ -1747,7 +1799,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!tech.isRailEnergyGain && m.energy > 0.005) m.energy -= 0.005
|
||||
if (m.energy > this.drain) m.energy -= this.drain
|
||||
const sub = Vector.sub(this.position, m.pos)
|
||||
const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
|
||||
const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
|
||||
@@ -2621,7 +2673,7 @@ const b = {
|
||||
},
|
||||
worm(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death()
|
||||
const bIndex = bullet.length;
|
||||
const wormSize = 6 + tech.wormSize * 6 * Math.random()
|
||||
const wormSize = 6 + tech.wormSize * 4.2 * Math.random()
|
||||
if (bIndex < 500) { //can't make over 500 spores
|
||||
bullet[bIndex] = Bodies.polygon(where.x, where.y, 3, 3, {
|
||||
inertia: Infinity,
|
||||
@@ -4858,8 +4910,20 @@ const b = {
|
||||
// ******************************** Guns *********************************************
|
||||
// **************************************************************************************************
|
||||
// **************************************************************************************************
|
||||
//0 nail gun
|
||||
//1 shotgun
|
||||
//2 super balls
|
||||
//3 matter wave
|
||||
//4 missiles
|
||||
//5 grenades
|
||||
//6 spores
|
||||
//7 drones
|
||||
//8 foam
|
||||
//9 harpoon
|
||||
//10 mine
|
||||
//11 laser
|
||||
guns: [{
|
||||
name: "nail gun",
|
||||
name: "nail gun", // 0
|
||||
description: "use compressed air to fire a stream of <strong>nails</strong><br><strong><em>delay</em></strong> after firing <strong>decreases</strong> as you shoot",
|
||||
ammo: 0,
|
||||
ammoPack: 50,
|
||||
@@ -5133,7 +5197,7 @@ const b = {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "shotgun",
|
||||
name: "shotgun", //1
|
||||
description: "fire a wide <strong>burst</strong> of short range <strong> bullets</strong>",
|
||||
ammo: 0,
|
||||
ammoPack: 3.5,
|
||||
@@ -5336,10 +5400,10 @@ const b = {
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "super balls",
|
||||
name: "super balls", //2
|
||||
description: "fire <strong>3</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss",
|
||||
ammo: 0,
|
||||
ammoPack: 10,
|
||||
ammoPack: 9,
|
||||
have: false,
|
||||
// num: 5,
|
||||
do() {},
|
||||
@@ -5491,7 +5555,7 @@ const b = {
|
||||
fire() {}
|
||||
},
|
||||
{
|
||||
name: "matter wave",
|
||||
name: "matter wave", //3
|
||||
description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>",
|
||||
ammo: 0,
|
||||
ammoPack: 115,
|
||||
@@ -5830,7 +5894,7 @@ const b = {
|
||||
fire() {}
|
||||
},
|
||||
{
|
||||
name: "missiles",
|
||||
name: "missiles", //6
|
||||
description: "launch <strong>homing</strong> missiles that <strong class='color-e'>explode</strong>",
|
||||
ammo: 0,
|
||||
ammoPack: 5,
|
||||
@@ -5923,7 +5987,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "grenades",
|
||||
name: "grenades", //5
|
||||
description: "lob a single <strong>bouncy</strong> projectile<br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after one second",
|
||||
ammo: 0,
|
||||
ammoPack: 7,
|
||||
@@ -5941,7 +6005,7 @@ const b = {
|
||||
}
|
||||
},
|
||||
}, {
|
||||
name: "spores",
|
||||
name: "spores", //6
|
||||
description: "fire a <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
|
||||
ammo: 0,
|
||||
ammoPack: 2.6,
|
||||
@@ -6072,7 +6136,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "drones",
|
||||
name: "drones", //7
|
||||
description: "deploy drones that <strong>crash</strong> into mobs<br>crashes reduce their <strong>lifespan</strong> by 1 second",
|
||||
ammo: 0,
|
||||
ammoPack: 16,
|
||||
@@ -6100,7 +6164,7 @@ const b = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "foam",
|
||||
name: "foam", //8
|
||||
description: "spray bubbly foam that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time",
|
||||
ammo: 0,
|
||||
ammoPack: 24,
|
||||
@@ -6206,7 +6270,7 @@ const b = {
|
||||
do() {},
|
||||
},
|
||||
{
|
||||
name: "harpoon",
|
||||
name: "harpoon", //9
|
||||
description: "fire a <strong>self-steering</strong> harpoon that uses <strong class='color-f'>energy</strong><br>to <strong>retract</strong> and refund its <strong class='color-ammo'>ammo</strong> cost",
|
||||
ammo: 0,
|
||||
ammoPack: 0.6, //update this in railgun tech
|
||||
@@ -6228,9 +6292,11 @@ const b = {
|
||||
charge: 0,
|
||||
railDo() {
|
||||
if (this.charge > 0) {
|
||||
const DRAIN = (tech.isRailEnergyGain ? 0.0005 : 0.002)
|
||||
//exit railgun charging without firing
|
||||
if (m.energy < 0.005 && !tech.isRailEnergyGain) {
|
||||
m.energy += 0.025 + this.charge * 0.11
|
||||
if (m.energy < DRAIN) {
|
||||
// m.energy += 0.025 + this.charge * 22 * this.drain
|
||||
// m.energy -= this.drain
|
||||
m.fireCDcycle = m.cycle + 120; // cool down if out of energy
|
||||
this.endCycle = 0;
|
||||
this.charge = 0
|
||||
@@ -6365,7 +6431,8 @@ const b = {
|
||||
if (input.down) smoothRate *= 0.995
|
||||
|
||||
this.charge = this.charge * smoothRate + 1 - smoothRate
|
||||
m.energy += (this.charge - previousCharge) * ((tech.isRailEnergyGain ? 0.5 : -0.3)) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
if (m.energy > DRAIN) m.energy -= DRAIN
|
||||
// m.energy += (this.charge - previousCharge) * ((tech.isRailEnergyGain ? 0.5 : -0.3)) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
|
||||
//draw magnetic field
|
||||
const X = m.pos.x
|
||||
@@ -6722,7 +6789,7 @@ const b = {
|
||||
// }
|
||||
// },
|
||||
}, {
|
||||
name: "mine",
|
||||
name: "mine", //10
|
||||
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>refund <strong>undetonated</strong> mines on <strong>exiting</strong> a level", //fires <strong>nails</strong> at mobs within range
|
||||
ammo: 0,
|
||||
ammoPack: 1.25,
|
||||
@@ -6765,393 +6832,8 @@ const b = {
|
||||
}
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "railgun",
|
||||
// description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
|
||||
// ammo: 0,
|
||||
// ammoPack: 3.8,
|
||||
// have: false,
|
||||
// do() {},
|
||||
// fire() {
|
||||
// function pushAway(range) { //push away blocks when firing
|
||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
// const SUB = Vector.sub(mob[i].position, m.pos)
|
||||
// const DISTANCE = Vector.magnitude(SUB)
|
||||
// if (DISTANCE < range) {
|
||||
// const DEPTH = Math.min(range - DISTANCE, 1500)
|
||||
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
|
||||
// mob[i].force.x += FORCE.x;
|
||||
// mob[i].force.y += FORCE.y;
|
||||
// }
|
||||
// }
|
||||
// for (let i = 0, len = body.length; i < len; ++i) {
|
||||
// const SUB = Vector.sub(body[i].position, m.pos)
|
||||
// const DISTANCE = Vector.magnitude(SUB)
|
||||
// if (DISTANCE < range) {
|
||||
// const DEPTH = Math.min(range - DISTANCE, 500)
|
||||
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.002 * Math.sqrt(DEPTH) * body[i].mass)
|
||||
// body[i].force.x += FORCE.x;
|
||||
// body[i].force.y += FORCE.y - body[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (tech.isCapacitor) {
|
||||
// if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
|
||||
// m.energy += 0.16 * (tech.isRailEnergyGain ? 2.5 : -1)
|
||||
// m.fireCDcycle = m.cycle + Math.floor(40 * b.fireCDscale);
|
||||
// const me = bullet.length;
|
||||
// bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, {
|
||||
// density: 0.005, //0.001 is normal
|
||||
// restitution: 0,
|
||||
// frictionAir: 0,
|
||||
// angle: m.angle,
|
||||
// dmg: 0, //damage done in addition to the damage from momentum
|
||||
// classType: "bullet",
|
||||
// collisionFilter: {
|
||||
// category: cat.bullet,
|
||||
// mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
||||
// },
|
||||
// minDmgSpeed: 5,
|
||||
// endCycle: simulation.cycle + 140,
|
||||
// beforeDmg(who) {
|
||||
// if (who.shield) {
|
||||
// for (let i = 0, len = mob.length; i < len; i++) {
|
||||
// if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
|
||||
// Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: -0.5 * this.velocity.x,
|
||||
// y: -0.5 * this.velocity.y
|
||||
// });
|
||||
// // Matter.Body.setDensity(this, 0.001);
|
||||
// }
|
||||
// if (tech.fragments && this.speed > 10) {
|
||||
// b.targetedNail(this.position, tech.fragments * 13)
|
||||
// this.endCycle = 0 //triggers despawn
|
||||
// }
|
||||
// },
|
||||
// onEnd() {},
|
||||
// drawCycle: Math.floor(10 * b.fireCDscale),
|
||||
// do() {
|
||||
// this.force.y += this.mass * 0.0003; // low gravity that scales with charge
|
||||
// if (this.drawCycle > 0) {
|
||||
// this.drawCycle--
|
||||
// //draw magnetic field
|
||||
// const X = m.pos.x
|
||||
// const Y = m.pos.y
|
||||
// // const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
|
||||
// const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
||||
// const unitVectorPerp = Vector.perp(unitVector)
|
||||
|
||||
// function magField(mag, arc) {
|
||||
// ctx.moveTo(X, Y);
|
||||
// ctx.bezierCurveTo(
|
||||
// X + unitVector.x * mag, Y + unitVector.y * mag,
|
||||
// X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
|
||||
// X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
|
||||
// ctx.bezierCurveTo(
|
||||
// X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
|
||||
// X - unitVector.x * mag, Y - unitVector.y * mag,
|
||||
// X, Y)
|
||||
// }
|
||||
// ctx.fillStyle = `rgba(50,0,100,0.05)`;
|
||||
// for (let i = 3; i < 7; i++) {
|
||||
// const MAG = 8 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
|
||||
// const ARC = 6 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
|
||||
// ctx.beginPath();
|
||||
// magField(MAG, ARC)
|
||||
// magField(MAG, -ARC)
|
||||
// ctx.fill();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
|
||||
// const speed = 67
|
||||
// Matter.Body.setVelocity(bullet[me], {
|
||||
// x: m.Vx / 2 + speed * Math.cos(m.angle),
|
||||
// y: m.Vy / 2 + speed * Math.sin(m.angle)
|
||||
// });
|
||||
|
||||
// //knock back
|
||||
// const KNOCK = (input.down ? 0.08 : 0.34)
|
||||
// player.force.x -= KNOCK * Math.cos(m.angle)
|
||||
// player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
|
||||
// pushAway(800)
|
||||
// } else {
|
||||
// b.refundAmmo()
|
||||
// m.fireCDcycle = m.cycle + Math.floor(120);
|
||||
// }
|
||||
// } else {
|
||||
// const me = bullet.length;
|
||||
// bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
|
||||
// density: 0.008, //0.001 is normal
|
||||
// restitution: 0,
|
||||
// frictionAir: 0,
|
||||
// dmg: 0, //damage done in addition to the damage from momentum
|
||||
// classType: "bullet",
|
||||
// collisionFilter: {
|
||||
// category: 0,
|
||||
// mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
||||
// },
|
||||
// minDmgSpeed: 5,
|
||||
// beforeDmg(who) {
|
||||
// if (who.shield) {
|
||||
// for (let i = 0, len = mob.length; i < len; i++) {
|
||||
// if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
|
||||
// Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: -0.5 * this.velocity.x,
|
||||
// y: -0.5 * this.velocity.y
|
||||
// });
|
||||
// }
|
||||
// if (tech.fragments && this.speed > 10) {
|
||||
// b.targetedNail(this.position, tech.fragments * 17)
|
||||
// this.endCycle = 0 //triggers despawn
|
||||
// }
|
||||
// },
|
||||
// onEnd() {}
|
||||
// });
|
||||
// m.fireCDcycle = Infinity; // cool down
|
||||
// Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
// bullet[me].endCycle = Infinity
|
||||
// bullet[me].charge = 0;
|
||||
// bullet[me].do = function() {
|
||||
// if (m.energy < 0.005 && !tech.isRailEnergyGain) {
|
||||
// m.energy += 0.05 + this.charge * 0.2
|
||||
// m.fireCDcycle = m.cycle + 120; // cool down if out of energy
|
||||
// this.endCycle = 0;
|
||||
// b.refundAmmo()
|
||||
// return
|
||||
// }
|
||||
|
||||
// if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
|
||||
// m.fireCDcycle = m.cycle + 2; // set fire cool down
|
||||
// //normal bullet behavior occurs after firing, overwrites this function
|
||||
// Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
|
||||
// this.endCycle = simulation.cycle + 140
|
||||
// this.collisionFilter.category = cat.bullet
|
||||
// Matter.Body.setPosition(this, {
|
||||
// x: m.pos.x,
|
||||
// y: m.pos.y
|
||||
// })
|
||||
// Matter.Body.setAngle(this, m.angle)
|
||||
// const speed = 90
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
|
||||
// y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
|
||||
// });
|
||||
|
||||
// if (tech.isRodAreaDamage) {
|
||||
// this.auraRadius = 800
|
||||
// this.semiMinor = 0.5
|
||||
// this.where = { x: m.pos.x, y: m.pos.y }
|
||||
// this.velocityAura = { x: this.velocity.x, y: this.velocity.y }
|
||||
// this.angleAura = this.angle
|
||||
// this.do = function() {
|
||||
// this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
||||
// this.velocityAura.y += 0.085 / this.charge;
|
||||
// this.where = Vector.add(this.where, this.velocityAura)
|
||||
|
||||
// //draw damage aura
|
||||
// this.semiMinor = this.semiMinor * 0.99
|
||||
// this.auraRadius = this.auraRadius * 0.99
|
||||
// let where = Vector.add(Vector.mult(this.velocityAura, -0.5), this.where)
|
||||
// ctx.beginPath();
|
||||
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.25, this.auraRadius * 0.15 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
|
||||
// ctx.fillStyle = "rgba(255,100,0,0.75)";
|
||||
// ctx.fill();
|
||||
// where = Vector.add(Vector.mult(this.velocity, -1), where)
|
||||
// ctx.beginPath();
|
||||
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.5, this.auraRadius * 0.5 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
|
||||
// ctx.fillStyle = "rgba(255,50,0,0.35)";
|
||||
// ctx.fill();
|
||||
// where = Vector.add(Vector.mult(this.velocity, -1), where)
|
||||
// ctx.beginPath();
|
||||
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.75, this.auraRadius * 0.7 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
|
||||
// ctx.fillStyle = "rgba(255,0,0,0.15)";
|
||||
// ctx.fill();
|
||||
// where = Vector.add(Vector.mult(this.velocity, -1), where)
|
||||
// ctx.beginPath();
|
||||
// ctx.ellipse(where.x, where.y, this.auraRadius, this.auraRadius * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
|
||||
// ctx.fillStyle = "rgba(255,0,0,0.03)";
|
||||
// ctx.fill();
|
||||
// //damage mobs in a circle based on this.semiMinor radius
|
||||
// if (this.auraRadius > 200) {
|
||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
// const dist = Vector.magnitude(Vector.sub(mob[i].position, where))
|
||||
// if (dist < mob[i].radius + this.auraRadius) {
|
||||
// //push mob in direction of bullet
|
||||
// const mag = 0.0001
|
||||
// mob[i].force.x += mag * this.velocity.x;
|
||||
// mob[i].force.y += mag * this.velocity.y;
|
||||
// //damage mob
|
||||
// const damage = m.dmgScale * 0.002 * dist
|
||||
// mob[i].damage(damage);
|
||||
// mob[i].locatePlayer();
|
||||
// simulation.drawList.push({ //add dmg to draw queue
|
||||
// x: mob[i].position.x,
|
||||
// y: mob[i].position.y,
|
||||
// radius: Math.log(2 * damage + 1.1) * 40,
|
||||
// color: "rgba(255,0,0,0.25)",
|
||||
// time: simulation.drawTime
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //push blocks power ups and mobs to the direction the rod is moving
|
||||
|
||||
// }
|
||||
// } else {
|
||||
// this.do = function() {
|
||||
// this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
||||
// }
|
||||
// }
|
||||
|
||||
// //knock back
|
||||
// const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
|
||||
// player.force.x -= KNOCK * Math.cos(m.angle)
|
||||
// player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
|
||||
// pushAway(1200 * this.charge)
|
||||
// } else { // charging on mouse down
|
||||
// if (tech.isFireMoveLock) {
|
||||
// Matter.Body.setVelocity(player, {
|
||||
// x: 0,
|
||||
// y: -55 * player.mass * simulation.g //undo gravity before it is added
|
||||
// });
|
||||
// player.force.x = 0
|
||||
// player.force.y = 0
|
||||
// }
|
||||
|
||||
// m.fireCDcycle = Infinity //can't fire until mouse is released
|
||||
// const previousCharge = this.charge
|
||||
// let smoothRate = Math.min(0.998, (input.down ? 0.98 : 0.985) * (0.98 + 0.02 * b.fireCDscale)) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
|
||||
// this.charge = this.charge * smoothRate + 1 - smoothRate
|
||||
// m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 1 : -0.33) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
// //draw targeting
|
||||
// let best;
|
||||
// let range = 3000
|
||||
// const dir = m.angle
|
||||
// const path = [{
|
||||
// x: m.pos.x + 20 * Math.cos(dir),
|
||||
// y: m.pos.y + 20 * Math.sin(dir)
|
||||
// },
|
||||
// {
|
||||
// x: m.pos.x + range * Math.cos(dir),
|
||||
// y: m.pos.y + range * Math.sin(dir)
|
||||
// }
|
||||
// ];
|
||||
// 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) {
|
||||
// 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]
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// //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);
|
||||
// if (best.dist2 != Infinity) { //if hitting something
|
||||
// path[path.length - 1] = {
|
||||
// x: best.x,
|
||||
// y: best.y
|
||||
// };
|
||||
// }
|
||||
|
||||
// //draw beam
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(path[0].x, path[0].y);
|
||||
// ctx.lineTo(path[1].x, path[1].y);
|
||||
// ctx.strokeStyle = `rgba(100,0,180,0.7)`;
|
||||
// ctx.lineWidth = this.charge * 1
|
||||
// ctx.setLineDash([10, 20]);
|
||||
// ctx.stroke();
|
||||
// ctx.setLineDash([]);
|
||||
|
||||
// //draw magnetic field
|
||||
// const X = m.pos.x
|
||||
// const Y = m.pos.y
|
||||
// const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
||||
// //Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
|
||||
// const unitVectorPerp = Vector.perp(unitVector)
|
||||
|
||||
// function magField(mag, arc) {
|
||||
// ctx.moveTo(X, Y);
|
||||
// ctx.bezierCurveTo(
|
||||
// X + unitVector.x * mag, Y + unitVector.y * mag,
|
||||
// X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
|
||||
// X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
|
||||
// ctx.bezierCurveTo(
|
||||
// X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
|
||||
// X - unitVector.x * mag, Y - unitVector.y * mag,
|
||||
// X, Y)
|
||||
// }
|
||||
// ctx.fillStyle = `rgba(50,0,100,0.05)`;
|
||||
// for (let i = 3; i < 7; i++) {
|
||||
// const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
|
||||
// const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
|
||||
// ctx.beginPath();
|
||||
// magField(MAG, ARC)
|
||||
// magField(MAG, -ARC)
|
||||
// ctx.fill();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "laser",
|
||||
name: "laser", //11
|
||||
description: "emit a <strong>beam</strong> of collimated coherent <strong class='color-laser'>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
|
||||
ammo: 0,
|
||||
ammoPack: Infinity,
|
||||
@@ -7409,47 +7091,4 @@ const b = {
|
||||
// },
|
||||
},
|
||||
],
|
||||
// gunRewind: { //this gun is added with a tech
|
||||
// name: "CPT gun",
|
||||
// description: "use <strong class='color-f'>energy</strong> to <strong>rewind</strong> your <strong class='color-h'>health</strong>, <strong>velocity</strong>,<br> and <strong>position</strong> up to <strong>10</strong> seconds",
|
||||
// ammo: 0,
|
||||
// ammoPack: Infinity,
|
||||
// have: false,
|
||||
// isRewinding: false,
|
||||
// lastFireCycle: 0,
|
||||
// holdCount: 0,
|
||||
// activeGunIndex: null,
|
||||
// do() {},
|
||||
// fire() {
|
||||
// if (this.lastFireCycle === m.cycle - 1) { //button has been held down
|
||||
// this.rewindCount += 8;
|
||||
// const DRAIN = 0.01
|
||||
// let history = m.history[(m.cycle - this.rewindCount) % 600]
|
||||
// if (this.rewindCount > 599 || m.energy < DRAIN || history.activeGun !== this.activeGunIndex) {
|
||||
// this.rewindCount = 0;
|
||||
// m.resetHistory();
|
||||
// m.fireCDcycle = m.cycle + Math.floor(120 * b.fireCDscale); // cool down
|
||||
// } else {
|
||||
// m.energy -= DRAIN
|
||||
// if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 5 cycles
|
||||
// Matter.Body.setPosition(player, history.position);
|
||||
// Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||
// if (m.health !== history.health) {
|
||||
// m.health = history.health
|
||||
// m.displayHealth();
|
||||
// }
|
||||
// m.yOff = history.yOff
|
||||
// if (m.yOff < 48) {
|
||||
// m.doCrouch()
|
||||
// } else {
|
||||
// m.undoCrouch()
|
||||
// }
|
||||
// }
|
||||
// } else { //button is held the first time
|
||||
// this.rewindCount = 0;
|
||||
// this.activeGunIndex = b.activeGun
|
||||
// }
|
||||
// this.lastFireCycle = m.cycle;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
@@ -198,6 +198,7 @@ function collisionChecks(event) {
|
||||
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
|
||||
if (v > 9) {
|
||||
if (tech.blockDmg) { //electricity
|
||||
console.log("hi")
|
||||
Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y });
|
||||
if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) {
|
||||
mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12
|
||||
|
||||
@@ -927,6 +927,10 @@ window.addEventListener("keydown", function(event) {
|
||||
break
|
||||
case input.key.testing:
|
||||
if (m.alive && localSettings.loreCount > 0) {
|
||||
if (simulation.difficultyMode > 4) {
|
||||
simulation.makeTextLog("<em>testing mode disabled for this difficulty</em>");
|
||||
break
|
||||
}
|
||||
if (simulation.testing) {
|
||||
simulation.testing = false;
|
||||
simulation.loop = simulation.normalLoop
|
||||
|
||||
66
js/level.js
66
js/level.js
@@ -17,11 +17,11 @@ const level = {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("perfect diamagnetism")
|
||||
// b.giveGuns("shotgun")
|
||||
// tech.giveTech("bremsstrahlung")
|
||||
// tech.giveTech("cherenkov radiation")
|
||||
// tech.giveTech("enthalpy")
|
||||
// b.giveGuns("grenades")
|
||||
// tech.giveTech("rule 30")
|
||||
// tech.giveTech("cherenkov radiation")
|
||||
// tech.giveTech("flame test")
|
||||
// tech.giveTech("pyrotechnics")
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
||||
// tech.giveTech("decoherence")
|
||||
// tech.giveTech("pneumatic actuator")
|
||||
@@ -39,7 +39,7 @@ const level = {
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// level.difficultyIncrease(15) //30 is near max on hard //60 is near max on why
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.warehouse();
|
||||
// level.temple();
|
||||
// level.testing(); //not in rotation, used for testing
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||
// powerUps.research.changeRerolls(3000)
|
||||
@@ -2644,11 +2644,11 @@ const level = {
|
||||
spawn.mapRect(4850, -275, 50, 175);
|
||||
|
||||
//???
|
||||
level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
m.addHealth(Infinity)
|
||||
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500)
|
||||
// for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500)
|
||||
// spawn.slashBoss(1900, -500)
|
||||
// spawn.launcherBoss(3200, -500)
|
||||
// spawn.laserTargetingBoss(1700, -500)
|
||||
@@ -2663,7 +2663,7 @@ const level = {
|
||||
// spawn.blinkBoss(1700, -500)
|
||||
// spawn.snakeSpitBoss(3200, -500)
|
||||
// spawn.laserBombingBoss(1700, -500)
|
||||
// spawn.launcherBoss(3200, -500)
|
||||
spawn.launcherBoss(3200, -500)
|
||||
// spawn.blockBoss(1700, -500)
|
||||
// spawn.blinkBoss(3200, -500)
|
||||
// spawn.spiderBoss(1700, -500)
|
||||
@@ -9511,22 +9511,14 @@ const level = {
|
||||
|
||||
me.attackCycle = 0;
|
||||
me.lastAttackCycle = 0;
|
||||
Matter.Body.setDensity(me, 0.014); // extra dense, normal is 0.001 // makes effective life much larger
|
||||
Matter.Body.setDensity(me, 0.012); // extra dense, normal is 0.001 // makes effective life much larger
|
||||
me.onDeath = function() {
|
||||
// applying forces to player doesn't seem to work inside this method, not sure why
|
||||
powerUps.spawn(this.position.x + 20, this.position.y, "ammo");
|
||||
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
|
||||
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
|
||||
if (simulation.difficulty > 5) {
|
||||
// fling player to center
|
||||
const SUB = V.sub(this.position, player.position)
|
||||
const DISTANCE = V.magnitude(SUB)
|
||||
if (DISTANCE < this.eventHorizon) {
|
||||
Matter.Body.setVelocity(player, V.mult(SUB, 5e4 / (100 + DISTANCE) / (100 + DISTANCE)))
|
||||
}
|
||||
}
|
||||
};
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
|
||||
me.do = function() {
|
||||
// keep it slow, to stop issues from explosion knock backs
|
||||
if (this.speed > 1) {
|
||||
@@ -9650,12 +9642,13 @@ const level = {
|
||||
me.isBoss = true;
|
||||
|
||||
me.stroke = "transparent";
|
||||
me.eventHorizon = 1000;
|
||||
me.eventHorizon = 950;
|
||||
me.collisionFilter.mask = cat.player | cat.bullet | cat.body;
|
||||
|
||||
me.memory = Infinity;
|
||||
me.attackCycle = 0;
|
||||
me.lastAttackCycle = 0;
|
||||
me.spawnCycle = 0;
|
||||
Matter.Body.setDensity(me, 0.08); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.onDeath = function() {
|
||||
for (let j = 0; j < 8; j++) { //in case some mobs leave things after they die
|
||||
@@ -9763,14 +9756,16 @@ const level = {
|
||||
}
|
||||
}
|
||||
me.periodicSpawns = function() {
|
||||
if (this.isInvulnerable) return;
|
||||
this.spawnCycle++;
|
||||
// Spawn annoying purple thing(s) that chases the player
|
||||
if (!(simulation.cycle % 180)) {
|
||||
if (!(this.spawnCycle % 180)) {
|
||||
spawn.seeker(this.position.x, this.position.y, 15 * (0.7 + 0.5 * Math.random()), 7);
|
||||
spawn.seeker(this.position.x, this.position.y, 4 * (0.7 + 0.5 * Math.random()), 7);
|
||||
spawn.seeker(this.position.x, this.position.y, 4 * (0.7 + 0.5 * Math.random()), 7);
|
||||
}
|
||||
// Spawn the annoying pink (now blue) exploder that doesn't chase the player
|
||||
if (!(simulation.cycle % 300)) {
|
||||
if (!(this.spawnCycle % 300)) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
mobGrenade(1100 + 700 * i, -13030, undefined, Math.min(700, 300 + simulation.difficulty * 4), 10);
|
||||
setVel(mob[mob.length - 1], { x: 0, y: -10 });
|
||||
@@ -9779,19 +9774,30 @@ const level = {
|
||||
}
|
||||
}
|
||||
// Spawn a bunch of mobs
|
||||
if (!(simulation.cycle % 600)) {
|
||||
spawn.nodeGroup(this.position.x, this.position.y, "focuser", 3);
|
||||
if (!(this.spawnCycle % 600)) {
|
||||
// This is just ripped off of spawn.nodeGroup because I don't want the shield
|
||||
const nodes = 3;
|
||||
const radius = Math.ceil(Math.random() * 10) + 18;
|
||||
const sideLength = Math.ceil(Math.random() * 100) + 70;
|
||||
const stiffness = Math.random() * 0.03 + 0.005;
|
||||
spawn.allowShields = false; //don't want shields on individual group mobs
|
||||
const angle = 2 * Math.PI / nodes
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
spawn.focuser(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius);
|
||||
}
|
||||
spawn.constrainAllMobCombos(nodes, stiffness);
|
||||
spawn.allowShields = true;
|
||||
}
|
||||
}
|
||||
me.invulnerableTrap = function() {
|
||||
if (this.trapCycle < 1) return;
|
||||
this.trapCycle++;
|
||||
// 32 is just an arbitrarily large number
|
||||
const spawnCycles = Math.min(32, Math.max(8, 6 + Math.floor(simulation.difficulty / 3)));
|
||||
// 24 is just an arbitrarily large number
|
||||
const spawnCycles = Math.min(24, Math.max(6, 4 + Math.floor(simulation.difficulty / 3)));
|
||||
// I have no idea how to balance at all, please help me
|
||||
const spawnDelay = Math.floor(5 + 10 / (1 + Math.sqrt(simulation.difficulty) / 5));
|
||||
if (this.trapCycle >= 120) {
|
||||
const cycle = this.trapCycle - 120;
|
||||
if (this.trapCycle >= 90) {
|
||||
const cycle = this.trapCycle - 90;
|
||||
if (!(cycle % spawnDelay)) {
|
||||
const radius = Math.min(500, 200 + simulation.difficulty * 3);
|
||||
mobGrenade(600, -13050, 30, radius);
|
||||
@@ -10220,7 +10226,6 @@ const level = {
|
||||
this.pit1.height = this.pit1.width = 0;
|
||||
this.pit2.height = this.pit2.width = 0;
|
||||
}
|
||||
|
||||
},
|
||||
draw() {
|
||||
this.pit1.query();
|
||||
@@ -10412,8 +10417,6 @@ const level = {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// UwU
|
||||
// Will I get timed out for this
|
||||
if (!isInBounds) {
|
||||
m.damage(0.1 * simulation.difficultyMode);
|
||||
trapPlayer(level.enter.x, level.enter.y);
|
||||
@@ -10601,7 +10604,8 @@ const level = {
|
||||
powerUps.addResearchToLevel();
|
||||
}
|
||||
if (templePlayer.room1.cycles % 600 === 0 && templePlayer.room1.cycles <= 2400) {
|
||||
for (let i = 0; i < 3 + Math.pow(simulation.difficulty / 2, 0.7) + Math.floor(templePlayer.room1.cycles / 720); i++) {
|
||||
const spawnAmt = Math.min(3 + Math.pow(simulation.difficulty / 1.7, 0.6), 10) + Math.floor(templePlayer.room1.cycles / 720);
|
||||
for (let i = 0; i < spawnAmt; i++) {
|
||||
if (Math.random() < 0.5 + 0.07 * simulation.difficulty) {
|
||||
spawn.randomMob(800 + Math.random() * 3e3, -2400 - Math.random() * 600, Infinity);
|
||||
}
|
||||
|
||||
13
js/mob.js
13
js/mob.js
@@ -1060,28 +1060,17 @@ const mobs = {
|
||||
dmg *= tech.damageFromTech()
|
||||
//mobs specific damage changes
|
||||
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500
|
||||
// if (this.shield) dmg *= 0.075
|
||||
// if (this.isBoss) dmg *= 0.25
|
||||
// if (this.damageReduction < 1) { //only used for bosses with this.armor() or shields
|
||||
// this.damageReductionGoal += dmg * this.damageReductionScale //reduce damageReductionGoal
|
||||
// dmg *= this.damageReduction
|
||||
// }
|
||||
dmg *= this.damageReduction
|
||||
//energy and heal drain should be calculated after damage boosts
|
||||
if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon
|
||||
if (tech.healthDrain && dmg !== Infinity && this.isDropPowerUp && Math.random() < tech.healthDrain * Math.min(this.health, dmg)) {
|
||||
powerUps.spawn(m.pos.x + 20 * (Math.random() - 0.5), m.pos.y + 20 * (Math.random() - 0.5), "heal");
|
||||
// powerUps.spawn(this.position.x + 20 * (Math.random() - 0.5), this.position.y + 20 * (Math.random() - 0.5), "heal");
|
||||
// m.addHealth(Math.min(this.health, dmg) * tech.healthDrain)
|
||||
// if (m.health > m.maxHealth) m.health = m.maxHealth
|
||||
}
|
||||
dmg /= Math.sqrt(this.mass)
|
||||
this.health -= dmg
|
||||
//this.fill = this.color + this.health + ')';
|
||||
this.onDamage(dmg); //custom damage effects
|
||||
if ((this.health < 0.05 || isNaN(this.health)) && this.alive) {
|
||||
this.death();
|
||||
}
|
||||
if ((this.health < 0.05 || isNaN(this.health)) && this.alive) this.death();
|
||||
}
|
||||
},
|
||||
onDamage() {
|
||||
|
||||
13
js/player.js
13
js/player.js
@@ -543,18 +543,19 @@ const m = {
|
||||
for (let i = 1, len = Math.floor(4 + steps / 40); i < len; i++) {
|
||||
b.grenade(Vector.add(m.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
|
||||
const who = bullet[bullet.length - 1]
|
||||
if (tech.isVacuumBomb) {
|
||||
|
||||
if (tech.isNeutronBomb) {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.3,
|
||||
y: who.velocity.y * 0.3
|
||||
});
|
||||
} else if (tech.isVacuumBomb) {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.5,
|
||||
y: who.velocity.y * 0.5
|
||||
});
|
||||
} else if (tech.isRPG) {
|
||||
who.endCycle = simulation.cycle + 10
|
||||
} else if (tech.isNeutronBomb) {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.3,
|
||||
y: who.velocity.y * 0.3
|
||||
});
|
||||
} else {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.5,
|
||||
|
||||
@@ -300,7 +300,7 @@ const powerUps = {
|
||||
},
|
||||
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
|
||||
if (isCanceled) {
|
||||
if (tech.isCancelTech && Math.random() < 0.9) {
|
||||
if (tech.isCancelTech && Math.random() < 0.94) {
|
||||
// powerUps.research.use('tech')
|
||||
powerUps[type].effect();
|
||||
return
|
||||
|
||||
@@ -838,13 +838,13 @@ const simulation = {
|
||||
|
||||
if (tech.isDronesTravel && m.alive) {
|
||||
//count drones
|
||||
let count = 0
|
||||
let droneCount = 0
|
||||
let sporeCount = 0
|
||||
let wormCount = 0
|
||||
let deliveryCount = 0
|
||||
for (let i = 0; i < bullet.length; ++i) {
|
||||
if (bullet[i].isDrone) {
|
||||
count++
|
||||
droneCount++
|
||||
if (bullet[i].isImproved) deliveryCount++
|
||||
} else if (bullet[i].isSpore) {
|
||||
sporeCount++
|
||||
@@ -855,11 +855,11 @@ const simulation = {
|
||||
|
||||
//respawn drones in animation frame
|
||||
let respawnDrones = () => {
|
||||
if (count > 0) {
|
||||
if (droneCount > 0) {
|
||||
requestAnimationFrame(respawnDrones);
|
||||
if (!simulation.paused && !simulation.isChoosing) {
|
||||
const where = { x: level.enter.x + 50, y: level.enter.y - 60 }
|
||||
count--
|
||||
droneCount--
|
||||
if (tech.isDroneRadioactive) {
|
||||
b.droneRadioactive({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 100 * (Math.random() - 0.5) }, 0)
|
||||
} else {
|
||||
@@ -1037,7 +1037,7 @@ const simulation = {
|
||||
|
||||
if (!(m.cycle % 420)) { //once every 7 seconds
|
||||
if (tech.isZeno) {
|
||||
m.health *= 0.93 //remove 7%
|
||||
m.health *= 0.94 //remove 7%
|
||||
m.displayHealth();
|
||||
}
|
||||
if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to damage for 60 cycles
|
||||
|
||||
277
js/tech.js
277
js/tech.js
@@ -217,7 +217,7 @@ const tech = {
|
||||
}
|
||||
},
|
||||
hasExplosiveDamageCheck() {
|
||||
return tech.haveGunCheck("missiles") || tech.isMissileField || tech.missileBotCount > 0 || tech.boomBotCount > 1 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
|
||||
return tech.haveGunCheck("missiles") || tech.isMissileField || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
|
||||
},
|
||||
damageFromTech() {
|
||||
let dmg = 1 //m.fieldDamage
|
||||
@@ -864,7 +864,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isExplosionStun
|
||||
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.isOrbitBotUpgrade || tech.isExplosionStun
|
||||
},
|
||||
requires: "a stun effect",
|
||||
effect() {
|
||||
@@ -2539,7 +2539,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "Zeno's paradox",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>85%</strong>, but every <strong>5</strong> seconds<br>remove <strong>7%</strong> of your current <strong class='color-h'>health</strong>",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>85%</strong>, but every <strong>5</strong> seconds<br>remove <strong>6%</strong> of your current <strong class='color-h'>health</strong>",
|
||||
// description: "every <strong>5</strong> seconds remove <strong>1/10</strong> of your <strong class='color-h'>health</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>90%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -2704,9 +2704,9 @@ const tech = {
|
||||
frequencyDefault: 1,
|
||||
isHealTech: true,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth
|
||||
return !tech.isNoHeals
|
||||
},
|
||||
requires: "not mass-energy equivalence",
|
||||
requires: "not ergodicity",
|
||||
effect() {
|
||||
tech.healthDrain += 0.02;
|
||||
},
|
||||
@@ -3296,9 +3296,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return level.onLevel > 1 && !tech.isEnergyHealth
|
||||
return level.onLevel > 1 && !tech.isEnergyHealth && !tech.healthDrain
|
||||
},
|
||||
requires: "past level 1, not mass-energy",
|
||||
requires: "past level 1, not mass-energy, enthalpy",
|
||||
effect() {
|
||||
tech.isNoHeals = true;
|
||||
level.difficultyDecrease(simulation.difficultyMode * 2)
|
||||
@@ -3338,7 +3338,7 @@ const tech = {
|
||||
{
|
||||
name: "options exchange",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`,
|
||||
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>90%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
|
||||
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>94%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3961,7 +3961,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1
|
||||
return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1
|
||||
},
|
||||
requires: "nails, nail gun, rivets, shotgun",
|
||||
effect() {
|
||||
@@ -4073,7 +4073,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.isNailShot || tech.isNeedles || tech.nailBotCount > 1 || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary
|
||||
return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary
|
||||
},
|
||||
requires: "nail gun, needles, nails, rivets, not incendiary",
|
||||
effect() {
|
||||
@@ -4093,8 +4093,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
// return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) + tech.isNeedles + tech.isNailShot) * 2 > 1
|
||||
return tech.isMineDrop || tech.nailBotCount || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !tech.isLaserMine) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
|
||||
return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !tech.isLaserMine) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
|
||||
},
|
||||
requires: "nail gun, nails, rivets, mine, not ceramic needles",
|
||||
effect() {
|
||||
@@ -4436,7 +4435,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "amplitude",
|
||||
description: "wave packet <strong>amplitude</strong> is <strong>33%</strong> higher<br>wave <strong class='color-d'>damage</strong> is increased by <strong>50%</strong>",
|
||||
description: "wave packet <strong>amplitude</strong> is <strong>33%</strong> higher<br>wave <strong class='color-d'>damage</strong> is increased by <strong>37%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
@@ -4448,7 +4447,7 @@ const tech = {
|
||||
requires: "matter wave",
|
||||
effect() {
|
||||
tech.waveFrequency *= 0.66
|
||||
tech.wavePacketDamage *= 1.5
|
||||
tech.wavePacketDamage *= 1.37
|
||||
},
|
||||
remove() {
|
||||
tech.waveFrequency = 0.2
|
||||
@@ -4457,7 +4456,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "propagation",
|
||||
description: "wave packet propagation <strong>speed</strong> is <strong>20%</strong> slower<br>wave <strong class='color-d'>damage</strong> is increased by <strong>50%</strong>",
|
||||
description: "wave packet propagation <strong>speed</strong> is <strong>25%</strong> slower<br>wave <strong class='color-d'>damage</strong> is increased by <strong>37%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -4469,11 +4468,11 @@ const tech = {
|
||||
requires: "matter wave",
|
||||
effect() {
|
||||
tech.waveBeamSpeed *= 0.8;
|
||||
tech.waveBeamDamage += 1.5 * 0.5 //this sets base matter wave damage, not used by arcs or circles
|
||||
tech.waveBeamDamage += 1.5 * 0.37 //this sets base matter wave damage
|
||||
},
|
||||
remove() {
|
||||
tech.waveBeamSpeed = 10;
|
||||
tech.waveBeamDamage = 1.5 //this sets base matter wave damage, not used by arcs or circles
|
||||
tech.waveBeamDamage = 1.5 //this sets base matter wave damage
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4662,9 +4661,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isTokamak)
|
||||
return tech.implosion === -1 && tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.isBoomBotUpgrade || tech.isTokamak)
|
||||
},
|
||||
requires: "an explosive damage source, not ammonium nitrate or nitroglycerin",
|
||||
requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation, implosion",
|
||||
effect: () => {
|
||||
tech.isExplodeRadio = true; //iridium-192
|
||||
},
|
||||
@@ -4681,9 +4680,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075)
|
||||
},
|
||||
requires: "grenades, missiles, rivets, harpoon, or mass driver",
|
||||
requires: "grenades, missiles, rivets, harpoon, or mass driver, not iridium-192",
|
||||
effect() {
|
||||
tech.fragments++
|
||||
},
|
||||
@@ -4693,7 +4692,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "ammonium nitrate",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>27%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>27%</strong>",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>24%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>24%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -4704,7 +4703,7 @@ const tech = {
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
tech.explosiveRadius += 0.27;
|
||||
tech.explosiveRadius += 0.24;
|
||||
},
|
||||
remove() {
|
||||
tech.explosiveRadius = 1;
|
||||
@@ -4719,9 +4718,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck()
|
||||
return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isExplosionHarm
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
requires: "an explosive damage source, not iridium-192, acetone peroxide",
|
||||
effect: () => {
|
||||
tech.isSmallExplosion = true;
|
||||
},
|
||||
@@ -4739,9 +4738,9 @@ const tech = {
|
||||
frequencyDefault: 2,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return tech.hasExplosiveDamageCheck()
|
||||
return tech.hasExplosiveDamageCheck() && !tech.isSmallExplosion
|
||||
},
|
||||
requires: "an explosive damage source",
|
||||
requires: "an explosive damage source, not nitroglycerin",
|
||||
effect: () => {
|
||||
tech.isExplosionHarm = true;
|
||||
},
|
||||
@@ -4833,7 +4832,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "MIRV",
|
||||
description: "fire <strong>+1</strong> <strong>missile</strong> and <strong>grenade</strong> per shot<br>decrease <strong class='color-e'>explosion</strong> <strong>radius</strong> up to <strong>12%</strong>",
|
||||
description: "fire <strong>+1</strong> <strong>missile</strong> and <strong>grenade</strong> per shot<br>decrease <strong class='color-e'>explosion</strong> <strong class='color-d'>damage</strong> and <strong>radius</strong> <strong>12%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -4892,6 +4891,25 @@ const tech = {
|
||||
b.setGrenadeMode()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "implosion",
|
||||
description: "<strong class='color-e'>explosions</strong> pull objects towards them<br>increase <strong>grenade</strong> radius and <strong class='color-d'>damage</strong> <strong>25%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.isExplodeRadio && !tech.isNeutronBomb
|
||||
},
|
||||
requires: "grenades, not iridium-192, neutron bomb",
|
||||
effect: () => {
|
||||
tech.implosion = 1;
|
||||
},
|
||||
remove() {
|
||||
tech.implosion = -1;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "chain reaction",
|
||||
description: "increase <strong>grenade</strong> radius and <strong class='color-d'>damage</strong> <strong>33%</strong><br><strong class='color-block'>blocks</strong> caught in <strong class='color-e'>explosions</strong> also <strong class='color-e'>explode</strong>",
|
||||
@@ -4901,9 +4919,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isVacuumBomb && !tech.isExplodeRadio
|
||||
return tech.haveGunCheck("grenades") && !tech.isExplodeRadio && !tech.isNeutronBomb //tech.isVacuumBomb
|
||||
},
|
||||
requires: "grenades, vacuum bomb, not iridium-192",
|
||||
requires: "grenades, not iridium-192, neutron bomb",
|
||||
effect() {
|
||||
tech.isBlockExplode = true; //chain reaction
|
||||
},
|
||||
@@ -4911,6 +4929,44 @@ const tech = {
|
||||
tech.isBlockExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "flame test",
|
||||
description: "when <strong>grenades</strong> detonate they release<br>a colorful <strong>cluster</strong> of small <strong class='color-e'>explosions</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.isNeutronBomb
|
||||
},
|
||||
requires: "grenades, not neutron bomb",
|
||||
effect() {
|
||||
tech.isClusterExplode = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isClusterExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "pyrotechnics",
|
||||
description: "when <strong>grenades</strong> detonate they release<br>a colorful <strong>circle</strong> of <strong class='color-e'>explosions</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.isNeutronBomb && tech.isClusterExplode
|
||||
},
|
||||
requires: "grenades, flame test, not neutron bomb",
|
||||
effect() {
|
||||
tech.isCircleExplode = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isCircleExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "neutron bomb",
|
||||
description: "<strong>grenades</strong> are <strong class='color-p'>irradiated</strong> with <strong class='color-p'>Cf-252</strong><br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>",
|
||||
@@ -4920,9 +4976,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio
|
||||
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio && !tech.isBlockExplode && !tech.isClusterExplode && tech.implosion === -1
|
||||
},
|
||||
requires: "grenades, not fragmentation, vacuum bomb, iridium-192",
|
||||
requires: "grenades, not fragmentation, vacuum bomb, iridium-192, pyrotechnics, implosion",
|
||||
effect() {
|
||||
tech.isNeutronBomb = true;
|
||||
b.setGrenadeMode()
|
||||
@@ -4972,9 +5028,9 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "nuclear transmutation",
|
||||
description: "<strong class='color-p'>radiation</strong> does <strong>70%</strong> more <strong class='color-d'>damage</strong> and <strong class='color-harm'>harm</strong><br><em>nail, drone, neutron bomb, iridium, string, deflect</em>",
|
||||
description: "<strong class='color-p'>radiation</strong> does <strong>47%</strong> more <strong class='color-d'>damage</strong> and <strong class='color-harm'>harm</strong><br><em>nail, drone, neutron bomb, iridium, string, deflect</em>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
@@ -4983,7 +5039,7 @@ const tech = {
|
||||
},
|
||||
requires: "radiation damage source",
|
||||
effect() {
|
||||
tech.radioactiveDamage = 1.7
|
||||
tech.radioactiveDamage += 1.47
|
||||
},
|
||||
remove() {
|
||||
tech.radioactiveDamage = 1
|
||||
@@ -5213,7 +5269,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "annelids",
|
||||
description: "increase <strong class='color-p' style='letter-spacing: -0.8px;'>worm</strong> size and <strong class='color-d'>damage</strong><br>between <strong>10%</strong> and <strong>120%</strong>",
|
||||
description: "increase <strong class='color-p' style='letter-spacing: -0.8px;'>worm</strong> size and <strong class='color-d'>damage</strong><br>by an average of <strong>37%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
@@ -5259,7 +5315,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 || tech.isFoamBall
|
||||
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.isFoamBotUpgrade || tech.isFoamBall
|
||||
},
|
||||
requires: "drones, spores, missiles, foam, matter wave, neutron bomb, ice IX",
|
||||
effect() {
|
||||
@@ -5530,7 +5586,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)
|
||||
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall)
|
||||
},
|
||||
requires: "foam, not uncertainty",
|
||||
effect() {
|
||||
@@ -5549,7 +5605,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
|
||||
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
|
||||
},
|
||||
requires: "foam, matter wave, not electrostatic induction, not phonon",
|
||||
effect() {
|
||||
@@ -5568,7 +5624,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.isFoamBall || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm
|
||||
return tech.haveGunCheck("foam") || tech.isFoamBall || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isSporeWorm
|
||||
},
|
||||
requires: "foam, worms",
|
||||
effect() {
|
||||
@@ -5587,7 +5643,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall
|
||||
return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
@@ -5608,7 +5664,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall
|
||||
return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
@@ -5814,7 +5870,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "alternator",
|
||||
description: "<strong>harpoons</strong> drain no <strong class='color-f'>energy</strong><br><strong>railgun</strong> generates <strong class='color-f'>energy</strong>", //as they <strong>retract</strong><br><strong>crouch</strong> firing <strong>harpoon</strong> generates <strong class='color-f'>energy</strong>",
|
||||
description: "<strong>harpoon</strong>, <strong>railgun</strong>, and <strong>grappling hook</strong><br>drain <strong>60%</strong> less <strong class='color-f'>energy</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -5852,7 +5908,10 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "Bessemer process",
|
||||
description: "increase the <strong>size</strong> of your <strong>harpoon</strong><br>by <strong>10%</strong> of the square root of harpoon <strong class='color-ammo'>ammo</strong>",
|
||||
descriptionFunction() {
|
||||
return `increase <strong>harpoon</strong> size and <strong class='color-d'>damage</strong><br>by 1/10 √ harpoon <strong class='color-ammo'>ammo</strong> <em>(${(10 * Math.sqrt(b.guns[9].ammo)).toFixed(0)}%)</em>`
|
||||
},
|
||||
// description: "increase the <strong>size</strong> of your <strong>harpoon</strong><br>by <strong>10%</strong> of √ of harpoon <strong class='color-ammo'>ammo</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -5878,8 +5937,8 @@ const tech = {
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') >= (tech.isRailGun ? 5 : 3) * (1 + this.count)
|
||||
},
|
||||
@@ -5913,7 +5972,10 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "UHMWPE",
|
||||
description: "increase the <strong>length</strong> of your <strong>harpoon</strong>'s <strong>rope</strong><br>by <strong>1%</strong> per harpoon <strong class='color-ammo'>ammo</strong>",
|
||||
descriptionFunction() {
|
||||
return `increase the <strong>length</strong> of your <strong>harpoon</strong>'s <strong>rope</strong><br>by 1/100 of harpoon <strong class='color-ammo'>ammo</strong> <em>(${(b.guns[9].ammo).toFixed(0)}%)</em>`
|
||||
},
|
||||
// description: "increase the <strong>length</strong> of your <strong>harpoon</strong>'s <strong>rope</strong><br>by <strong>1%</strong> per harpoon <strong class='color-ammo'>ammo</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -6021,7 +6083,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.laserBotCount > 1 || tech.isLaserMine) && tech.laserDamage === 0.17
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.17
|
||||
},
|
||||
requires: "laser, not free-electron",
|
||||
effect() {
|
||||
@@ -6044,7 +6106,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.laserBotCount > 1) && !tech.isPulseLaser && tech.isLaserDiode === 1
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade) && !tech.isPulseLaser && tech.isLaserDiode === 1
|
||||
},
|
||||
requires: "laser, not pulse, diodes",
|
||||
effect() {
|
||||
@@ -6069,7 +6131,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") && !tech.isPulseLaser) || tech.laserBotCount > 1
|
||||
return (tech.haveGunCheck("laser") && !tech.isPulseLaser) || tech.isLaserBotUpgrade
|
||||
},
|
||||
requires: "laser, not pulse",
|
||||
effect() {
|
||||
@@ -6088,7 +6150,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.laserBotCount > 1) && !tech.isWideLaser && !tech.isPulseLaser && !tech.historyLaser
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade) && !tech.isWideLaser && !tech.isPulseLaser && !tech.historyLaser
|
||||
},
|
||||
requires: "laser, not diffuse beam, pulse, or slow light",
|
||||
effect() {
|
||||
@@ -6344,7 +6406,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
|
||||
return m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
|
||||
},
|
||||
requires: "standing wave, perfect diamagnetism",
|
||||
effect() {
|
||||
@@ -6363,7 +6425,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism") && tech.blockDmg
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && tech.blockDmg
|
||||
},
|
||||
requires: "bremsstrahlung",
|
||||
effect() {
|
||||
@@ -6459,9 +6521,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && (build.isExperimentSelection || powerUps.research.count > 3)
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && (build.isExperimentSelection || powerUps.research.count > 3) && !tech.isEnergyHealth
|
||||
},
|
||||
requires: "perfect diamagnetism, negative mass, pilot wave",
|
||||
requires: "perfect diamagnetism, negative mass, pilot wave, not mass energy",
|
||||
effect() {
|
||||
tech.isFieldHarmReduction = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
@@ -6710,7 +6772,7 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport || tech.isDronesTravel)
|
||||
return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport)
|
||||
},
|
||||
requires: "molecular assembler, no other manufacturing, no drone tech",
|
||||
effect() {
|
||||
@@ -7732,7 +7794,7 @@ const tech = {
|
||||
// },
|
||||
{
|
||||
name: "panpsychism",
|
||||
description: "awaken all <strong class='color-block'>blocks</strong><br><strong class='color-block'>blocks</strong> have a chance to spawn random power ups",
|
||||
description: "awaken all <strong class='color-block'>blocks</strong><br><strong class='color-block'>blocks</strong> have a chance to spawn power ups",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
@@ -9592,6 +9654,70 @@ const tech = {
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
// {
|
||||
// name: "rule 90",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 0,
|
||||
// isJunk: true,
|
||||
// allowed() {
|
||||
// return true
|
||||
// },
|
||||
// requires: "",
|
||||
// effect() {},
|
||||
// remove() {},
|
||||
// state: [
|
||||
// [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
// ],
|
||||
// rule(state, a, b, c) {
|
||||
// if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
// if (state[a] && state[b] && !state[c]) return true; // TTF => T
|
||||
// if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
// if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
// if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
// if (!state[a] && state[b] && !state[c]) return false; //FTF => F
|
||||
// if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
// if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
// },
|
||||
// id: 0,
|
||||
// descriptionFunction() {
|
||||
// const loop = () => {
|
||||
// if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
|
||||
// let b = []; //produce next row
|
||||
// b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
|
||||
// for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
|
||||
// b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
|
||||
// }
|
||||
// b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
|
||||
// this.state.push(b)
|
||||
// if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
|
||||
// if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
|
||||
// setTimeout(() => { loop() }, 400);
|
||||
// }
|
||||
// }
|
||||
// setTimeout(() => { loop() }, 400);
|
||||
// // if (this.id === 0) {
|
||||
// // for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
|
||||
// // }
|
||||
// this.id++
|
||||
// return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>`
|
||||
// },
|
||||
// outputText() {
|
||||
// let text = ""
|
||||
// for (let j = 0; j < this.state.length; j++) {
|
||||
// text += "<p style = 'margin-bottom: -11px;'>"
|
||||
// for (let i = 0; i < this.state[j].length; i++) {
|
||||
// if (this.state[j][i]) {
|
||||
// text += "⬛" //"█" //"■"
|
||||
// } else {
|
||||
// text += "⬜" //" " //"□"
|
||||
// }
|
||||
// }
|
||||
// text += "</p>"
|
||||
// }
|
||||
// return text
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: "rule 30",
|
||||
maxCount: 1,
|
||||
@@ -9607,7 +9733,8 @@ const tech = {
|
||||
state: [
|
||||
[false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
],
|
||||
rule30(state, a, b, c) {
|
||||
rule(state, a, b, c) {
|
||||
//30
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return false; // TTF => F
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
@@ -9619,21 +9746,40 @@ const tech = {
|
||||
},
|
||||
id: 0,
|
||||
descriptionFunction() {
|
||||
|
||||
if (this.id === 0 && Math.random() < 0.5) {
|
||||
// for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
|
||||
this.name = "rule 90"
|
||||
this.link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(this.name).replace(/'/g, '%27')}&title=Special:Search' class="link">${this.name}</a>`
|
||||
// console.log(this.name)
|
||||
this.state[0] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
this.rule = function(state, a, b, c) {
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return true; // TTF => T
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
if (!state[a] && state[b] && !state[c]) return false; //FTF => F
|
||||
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
}
|
||||
}
|
||||
|
||||
const loop = () => {
|
||||
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
|
||||
let b = []; //produce next row
|
||||
b.push(this.rule30(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
|
||||
for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
|
||||
b.push(this.rule30(this.state[this.state.length - 1], i - 1, i, i + 1));
|
||||
b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
|
||||
}
|
||||
b.push(this.rule30(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
|
||||
this.state.push(b)
|
||||
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
|
||||
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
|
||||
setTimeout(() => { loop() }, 500);
|
||||
setTimeout(() => { loop() }, 400);
|
||||
}
|
||||
}
|
||||
setTimeout(() => { loop() }, 500);
|
||||
setTimeout(() => { loop() }, 400);
|
||||
this.id++
|
||||
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>`
|
||||
},
|
||||
@@ -10038,5 +10184,8 @@ const tech = {
|
||||
isFoamBall: null,
|
||||
isNoDraftPause: null,
|
||||
isFoamPressure: null,
|
||||
foamDamage: null
|
||||
foamDamage: null,
|
||||
implosion: null,
|
||||
isClusterExplode: null,
|
||||
isCircleExplode: null
|
||||
}
|
||||
46
todo.txt
46
todo.txt
@@ -1,22 +1,51 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
bremsstrahlung does extra damage to shields
|
||||
grenade tech: flame test - grenades release a cluster of smaller explosions
|
||||
grenade tech: pyrotechnics - grenades release a circle of smaller explosions
|
||||
grenade tech: implosion - explosions pull things in, not out, +25% to grenade explosion damage and radius
|
||||
chain reaction no longer requires vacuum bomb
|
||||
bosses and mobs have much less knock back from explosions
|
||||
invulnerable mobs have no knock back
|
||||
|
||||
alternator harpoon/grapple/railgun energy drain reduced by 100->60%
|
||||
bots no longer unlock tech until you upgrade to a bot type
|
||||
JUNK tech rule 30 is now sometimes rule 90 instead
|
||||
disabled testing for why? mode
|
||||
|
||||
wave beam
|
||||
amplitude 50->37% damage
|
||||
propagation 50->37% damage
|
||||
worms
|
||||
annelids 10-120% -> about 37% damage
|
||||
radiation
|
||||
nuclear transmutation stacks 9x
|
||||
gives 70->47% damage per stack
|
||||
explosions
|
||||
ammonium nitrate 27->24% damage and radius
|
||||
|
||||
bug fixes
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
tech: increase damage from all radioactive sources by 66%
|
||||
apply to dots and to drones, neutron bomb, and radioactive explosions
|
||||
buff early matter wave without phonon
|
||||
|
||||
some grenade tech made all the bosses go away and not drop anything
|
||||
check: fireworks, vacuum, stun, chain reaction, implosion
|
||||
|
||||
more fireworks themed grenade tech
|
||||
shotting star - fire a series of explosions higher and higher up, also increase radius with height
|
||||
star burst - 5 explosions in star shape
|
||||
delay - explosion in same place
|
||||
pulse
|
||||
30s of lasers
|
||||
|
||||
merge mines and grenades?
|
||||
tech - neutron bombs deal 100% more damage, but finishes detonating much faster
|
||||
tech - neutron bombs will explode into a small iridum explosion after it expires
|
||||
|
||||
tech: damage mobs in your last 10 seconds of history
|
||||
field tech?
|
||||
time dilation?
|
||||
|
||||
standing wave is weak vs. exploding bullets
|
||||
|
||||
add foam tech that makes foam stronger vs. shields
|
||||
|
||||
tech: eternalism - don't pause time during draft
|
||||
bugs?
|
||||
requirements change after draft is generated
|
||||
@@ -26,6 +55,7 @@ tech expansion: should also make other fields do things
|
||||
how to make the description work
|
||||
change description based on your current field?
|
||||
perfect diamagnetism moves forward when you hold down the shield
|
||||
it's great, but maybe annoying?
|
||||
maybe only with crouch?
|
||||
time dilation drains 1/2 as much energy when paused
|
||||
grow plasma torch as you hold it down
|
||||
|
||||
Reference in New Issue
Block a user