tech: MIRV - now effects grenades and super balls in addition to missiles
  no change for super balls and missiles, but this is a new tech for grenades

undetonated mines are returned at the end of a level
  removed tech: mine reclamation
  mine gun has 30% less ammo
  laser mines do 7% less damage
  booby trap now comes with 53 JUNK (up from 33) but it's mines can be returned for ammo

removed ctx.clip() from metamaterial cloaking field for performance reasons
  the graphics look a bit different now, maybe not as good, maybe it's just different

iceIX bullets last 50% less time, but do 50% more damage and have 25% more thrust
  so it's more of a close range bullet
  ice-shot has 2 fewer bullets
This commit is contained in:
landgreen
2021-08-22 20:35:27 -07:00
parent a1f42479c0
commit 9567a23cf5
9 changed files with 168 additions and 309 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -713,11 +713,11 @@ const b = {
}, },
setGrenadeMode() { setGrenadeMode() {
grenadeDefault = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { grenadeDefault = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
Matter.Body.setDensity(bullet[me], 0.0005); Matter.Body.setDensity(bullet[me], 0.0003);
bullet[me].explodeRad = 300; bullet[me].explodeRad = 300 * size;
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4)
@@ -738,11 +738,11 @@ const b = {
}; };
Composite.add(engine.world, bullet[me]); //add bullet to world Composite.add(engine.world, bullet[me]); //add bullet to world
} }
grenadeRPG = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { grenadeRPG = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
Matter.Body.setDensity(bullet[me], 0.0005); Matter.Body.setDensity(bullet[me], 0.0003);
bullet[me].explodeRad = 305; bullet[me].explodeRad = 305 * size;
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4)
@@ -773,11 +773,11 @@ const b = {
} }
}; };
} }
grenadeRPGVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { grenadeRPGVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
Matter.Body.setDensity(bullet[me], 0.0005); Matter.Body.setDensity(bullet[me], 0.0003);
bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110 bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4)
@@ -849,11 +849,11 @@ const b = {
} }
}; };
} }
grenadeVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { grenadeVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false)); bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false));
Matter.Body.setDensity(bullet[me], 0.0003); Matter.Body.setDensity(bullet[me], 0.0002);
bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100 bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 6) if (tech.fragments) b.targetedNail(this.position, tech.fragments * 6)
@@ -920,10 +920,10 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world Composite.add(engine.world, bullet[me]); //add bullet to world
} }
grenadeNeutron = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { grenadeNeutron = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false)); bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false));
b.fireProps(m.crouch ? 45 : 25, m.crouch ? 35 : 20, angle, me); //cd , speed b.fireProps((m.crouch ? 45 : 25) / Math.pow(0.93, tech.missileCount), m.crouch ? 35 : 20, angle, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.000001); Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = Infinity; bullet[me].endCycle = Infinity;
bullet[me].frictionAir = 0; bullet[me].frictionAir = 0;
@@ -932,7 +932,7 @@ const b = {
bullet[me].restitution = 0; bullet[me].restitution = 0;
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].damageRadius = 100; bullet[me].damageRadius = 100;
bullet[me].maxDamageRadius = 450 + 130 * tech.isNeutronSlow //+ 150 * Math.random() bullet[me].maxDamageRadius = 450 * size + 130 * tech.isNeutronSlow //+ 150 * Math.random()
bullet[me].radiusDecay = (0.81 + 0.15 * tech.isNeutronSlow) / tech.isBulletsLastLonger bullet[me].radiusDecay = (0.81 + 0.15 * tech.isNeutronSlow) / tech.isBulletsLastLonger
bullet[me].stuckTo = null; bullet[me].stuckTo = null;
bullet[me].stuckToRelativePosition = null; bullet[me].stuckToRelativePosition = null;
@@ -1604,7 +1604,7 @@ const b = {
laserMine(position, velocity = { x: 0, y: -8 }) { laserMine(position, velocity = { x: 0, y: -8 }) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, { bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, {
bulletType: "mine", bulletType: "laser mine",
angle: m.angle, angle: m.angle,
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
@@ -1612,8 +1612,8 @@ const b = {
dmg: 0, // 0.14 //damage done in addition to the damage from momentum dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2, minDmgSpeed: 2,
lookFrequency: 67 + Math.floor(7 * Math.random()), lookFrequency: 67 + Math.floor(7 * Math.random()),
drain: 0.5 * tech.isLaserDiode * tech.laserFieldDrain, drain: 0.62 * tech.isLaserDiode * tech.laserFieldDrain,
isArmed: false, isDetonated: false,
torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1),
range: 1500, range: 1500,
endCycle: Infinity, endCycle: Infinity,
@@ -1623,17 +1623,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
}, },
beforeDmg() {}, beforeDmg() {},
onEnd() { onEnd() {},
if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "mine") {
b.guns[i].ammo++
simulation.updateGunHUD();
break;
}
}
}
},
do() { do() {
if (!(simulation.cycle % this.lookFrequency) && m.energy > this.drain) { //find mob targets if (!(simulation.cycle % this.lookFrequency) && m.energy > this.drain) { //find mob targets
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
@@ -1648,7 +1638,7 @@ const b = {
if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin
this.endCycle = simulation.cycle + 360 + 120 this.endCycle = simulation.cycle + 360 + 120
// if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin // if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin
this.isArmed = true this.isDetonated = true
break break
} }
} }
@@ -1669,7 +1659,7 @@ const b = {
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
const where = this.vertices[i] const where = this.vertices[i]
const endPoint = Vector.add(where, Vector.mult(Vector.normalise(Vector.sub(where, this.position)), 2500)) const endPoint = Vector.add(where, Vector.mult(Vector.normalise(Vector.sub(where, this.position)), 2500))
b.laser(where, endPoint, tech.laserDamage * 14, this.reflections, true) b.laser(where, endPoint, tech.laserDamage * 13, this.reflections, true)
} }
ctx.stroke(); ctx.stroke();
// ctx.globalAlpha = 1; // ctx.globalAlpha = 1;
@@ -1704,28 +1694,26 @@ const b = {
lookFrequency: 0, lookFrequency: 0,
range: 700, range: 700,
beforeDmg() {}, beforeDmg() {},
onEnd() {
if (this.isArmed) b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
},
do() { do() {
this.force.y += this.mass * 0.002; //extra gravity this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) { if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) { for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) { if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) {
const angle = Vector.angle(collide[i].normal, { const angle = Vector.angle(collide[i].normal, { x: 1, y: 0 })
x: 1,
y: 0
})
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x)) Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation //move until touching map again after rotation
for (let j = 0; j < 10; j++) { for (let j = 0; j < 10; j++) {
if (Matter.Query.collides(this, map).length > 0) { //touching map if (Matter.Query.collides(this, map).length > 0) { //touching map
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setStatic(this, true) //don't set to static if not touching map Matter.Body.setStatic(this, true) //don't set to static if not touching map
this.collisionFilter.mask = cat.map | cat.bullet this.collisionFilter.mask = cat.map | cat.bullet
} else { } else {
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, { x: 0, y: 0 });
x: 0,
y: 0
});
Matter.Body.setAngularVelocity(this, 0) Matter.Body.setAngularVelocity(this, 0)
} }
this.arm(); this.arm();
@@ -1752,55 +1740,7 @@ const b = {
} }
if (this.stillCount > 25) this.arm(); if (this.stillCount > 25) this.arm();
}, },
// sentry() {
// this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets
// this.lookFrequency = simulation.cycle + 60
// this.do = function() { //overwrite the do method for this bullet
// this.force.y += this.mass * 0.002; //extra gravity
// if (simulation.cycle > this.lookFrequency) {
// const random = 300 * Math.random
// for (let i = 0, len = mob.length; i < len; ++i) {
// if (
// !mob[i].isBadTarget &&
// Vector.magnitude(Vector.sub(this.position, mob[i].position)) < 700 + mob[i].radius + random &&
// Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
// Matter.Query.ray(body, this.position, mob[i].position).length === 0
// ) {
// this.lookFrequency = 8 + Math.floor(3 * Math.random())
// this.endCycle = simulation.cycle + 900
// this.do = function() { //overwrite the do method for this bullet
// this.force.y += this.mass * 0.002; //extra gravity
// if (!(simulation.cycle % this.lookFrequency) && !m.isBodiesAsleep) { //find mob targets
// // this.endCycle -= 8
// b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
// if (!(simulation.cycle % (this.lookFrequency * 6))) {
// simulation.drawList.push({
// x: this.position.x,
// y: this.position.y,
// radius: 8,
// color: "#fe0",
// time: 4
// });
// }
// }
// }
// }
// }
// }
// }
// },
arm() { arm() {
//false alert
// for (let i = 0, len = mob.length; i < len; i++) {
// if (!mob[i].seePlayer.recall && Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 4000000) { //2000 range
// mob[i].seePlayer.recall = 240; //cycles before mob falls a sleep
// mob[i].seePlayer.position.x = this.position.x;
// mob[i].seePlayer.position.y = this.position.y;
// }
// }
this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets
this.lookFrequency = simulation.cycle + 60 this.lookFrequency = simulation.cycle + 60
this.do = function() { //overwrite the do method for this bullet this.do = function() { //overwrite the do method for this bullet
@@ -1848,11 +1788,8 @@ const b = {
break break
} else { } else {
this.endCycle = 0 //end life if mob is near and visible this.endCycle = 0 //end life if mob is near and visible
if (Math.random() < 0.8) isAmmoBack = false; //20% chance to get ammo back after detonation
break break
} }
} }
} }
} }
@@ -1860,29 +1797,6 @@ const b = {
} }
} }
}, },
onEnd() {
if (this.isArmed) {
b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
}
if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "mine") {
b.guns[i].ammo++
simulation.updateGunHUD();
break;
}
}
}
// if (isAmmoBack) { //get ammo back from tech.isMineAmmoBack
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
// if (b.guns[i].name === "mine") {
// b.guns[i].ammo++
// simulation.updateGunHUD();
// break;
// }
// }
// }
}
}); });
bullet[bIndex].torque += bullet[bIndex].inertia * 0.0002 * (0.5 - Math.random()) bullet[bIndex].torque += bullet[bIndex].inertia * 0.0002 * (0.5 - Math.random())
Matter.Body.setVelocity(bullet[bIndex], velocity); Matter.Body.setVelocity(bullet[bIndex], velocity);
@@ -2110,7 +2024,7 @@ const b = {
}, },
iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
const me = bullet.length; const me = bullet.length;
const THRUST = 0.0006 const THRUST = 0.0009
const RADIUS = 18 const RADIUS = 18
const SCALE = 1 - 0.08 / tech.isBulletsLastLonger const SCALE = 1 - 0.08 / tech.isBulletsLastLonger
bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, { bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, {
@@ -2119,9 +2033,9 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.023, frictionAir: 0.023,
restitution: 0.9, restitution: 0.9,
dmg: 0.55, //damage done in addition to the damage from momentum dmg: 1, //damage done in addition to the damage from momentum
lookFrequency: 14 + Math.floor(8 * Math.random()), lookFrequency: 14 + Math.floor(8 * Math.random()),
endCycle: simulation.cycle + 150 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
category: cat.bullet, category: cat.bullet,
@@ -2607,7 +2521,7 @@ const b = {
inertia: Infinity, inertia: Infinity,
frictionAir: 0.003, frictionAir: 0.003,
dmg: 0, //damage on impact dmg: 0, //damage on impact
damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isFoamTeleport ? 1.55 : 1), //damage done over time damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isFoamTeleport ? 1.5 : 1), //damage done over time
scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1), scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -2748,7 +2662,7 @@ const b = {
} }
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport
this.nextPortCycle = simulation.cycle + this.portFrequency this.nextPortCycle = simulation.cycle + this.portFrequency
const range = 10 * Math.sqrt(this.radius) * Math.random() const range = 15 * Math.sqrt(this.radius) * Math.random()
Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random()))) Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
} }
} }
@@ -4043,9 +3957,9 @@ const b = {
} }
} else if (tech.isIceShot) { } else if (tech.isIceShot) {
const spread = (m.crouch ? 0.7 : 1.2) const spread = (m.crouch ? 0.7 : 1.2)
for (let i = 0, len = 18 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) { for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) {
// iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
b.iceIX(25 + 32 * Math.random(), m.angle + spread * (Math.random() - 0.5)) b.iceIX(25 + 20 * Math.random(), m.angle + spread * (Math.random() - 0.5))
} }
} else if (tech.isFoamShot) { } else if (tech.isFoamShot) {
const spread = (m.crouch ? 0.35 : 0.7) const spread = (m.crouch ? 0.35 : 0.7)
@@ -4132,8 +4046,9 @@ const b = {
const SPEED = m.crouch ? 43 : 36 const SPEED = m.crouch ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
const SPREAD = m.crouch ? 0.08 : 0.13 const SPREAD = m.crouch ? 0.08 : 0.13
let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; const num = tech.missileCount + 2
for (let i = 0; i < tech.superBallNumber; i++) { let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
Composite.add(engine.world, bullet[me]); //add bullet to world Composite.add(engine.world, bullet[me]); //add bullet to world
@@ -4163,6 +4078,7 @@ const b = {
const dir = m.angle const dir = m.angle
const x = m.pos.x const x = m.pos.x
const y = m.pos.y const y = m.pos.y
const num = tech.missileCount + 2
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale) const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down m.fireCDcycle = m.cycle + delay; // cool down
@@ -4194,7 +4110,7 @@ const b = {
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else { if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
count++ count++
if (count % 2) fireBall() if (count % 2) fireBall()
if (count < tech.superBallNumber * 2 && m.alive) requestAnimationFrame(cycle); if (count < num * 2 && m.alive) requestAnimationFrame(cycle);
} }
} }
let count = 0 let count = 0
@@ -4640,14 +4556,21 @@ const b = {
have: false, have: false,
do() {}, do() {},
fire() { fire() {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale); // cool down const countReduction = Math.pow(0.93, tech.missileCount)
b.grenade() m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale / countReduction); // cool down
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
const SPREAD = m.crouch ? 0.12 : 0.2
let angle = m.angle - SPREAD * (tech.missileCount - 1) / 2;
for (let i = 0; i < tech.missileCount; i++) {
b.grenade(where, angle, countReduction) //function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1)
angle += SPREAD
}
}, },
}, { }, {
name: "mine", name: "mine",
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>fires <strong>nails</strong> at mobs within range", 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, ammo: 0,
ammoPack: 1.4, ammoPack: 1.1,
have: false, have: false,
do() {}, do() {},
fire() { fire() {
@@ -4657,33 +4580,17 @@ const b = {
const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
b.laserMine(m.pos, velocity) b.laserMine(m.pos, velocity)
} else { } else {
const pos = { const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
let speed = 36 let speed = 36
if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
speed = -2 b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
}
b.mine(pos, {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 0, tech.isMineAmmoBack)
} }
m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down
} else { } else {
const pos = { const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
let speed = 23 let speed = 23
if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
speed = -2 b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
}
b.mine(pos, {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 0, tech.isMineAmmoBack)
m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down
} }
} }

View File

@@ -175,8 +175,8 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
// console.log(obj.dmg, 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
if (tech.isCrit && mob[k].isStunned) dmg *= 4 if (tech.isCrit && mob[k].isStunned) dmg *= 4
// console.log(dmg)
mob[k].damage(dmg); mob[k].damage(dmg);
if (mob[k].alive) mob[k].foundPlayer(); if (mob[k].alive) mob[k].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue

View File

@@ -11,13 +11,14 @@ const level = {
levels: [], levels: [],
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
// localSettings.levelsClearedLastGame = 10 // localSettings.levelsClearedLastGame = 10
// 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
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// b.giveGuns("mine") // b.giveGuns("grenades")
// b.giveGuns("nail gun")
// m.setField("wormhole")
// tech.giveTech("laser-mines") // tech.giveTech("laser-mines")
// m.setField("metamaterial cloaking")
// for (let i = 0; i < 3; i++) tech.giveTech("super sized")
// tech.giveTech("irradiated nails") // tech.giveTech("irradiated nails")
// for (let i = 0; i < 9; i++) tech.giveTech("MIRV") // for (let i = 0; i < 9; i++) tech.giveTech("MIRV")
@@ -51,7 +52,6 @@ const level = {
// for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); // for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
// for (let i = 0; i < 7; i++) tech.giveTech("undefined") // for (let i = 0; i < 7; i++) tech.giveTech("undefined")
// lore.techCount = 6 // lore.techCount = 6
// simulation.enableConstructMode() //used to build maps in testing mode
// simulation.isCheating = false //true; // simulation.isCheating = false //true;
// localSettings.loreCount = 3; //this sets what conversation is heard // localSettings.loreCount = 3; //this sets what conversation is heard
@@ -2246,7 +2246,7 @@ const level = {
for (let i = 0; i < 4; ++i) spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize); for (let i = 0; i < 4; ++i) spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
} }
// blockDoor(710, -710); // blockDoor(710, -710);
// for (let i = 0; i < 30; i++) powerUps.directSpawn(710, -710, "tech"); // for (let i = 0; i < 200; i++) powerUps.directSpawn(710 + 1000 * Math.random(), -710 + 1000 * Math.random(), "tech");
spawn.mapRect(2500, -1200, 200, 750); //right wall spawn.mapRect(2500, -1200, 200, 750); //right wall
blockDoor(2585, -210) blockDoor(2585, -210)
@@ -4027,8 +4027,8 @@ const level = {
// spawn.mapRect(-2600, -1975, 250, 25); // spawn.mapRect(-2600, -1975, 250, 25);
spawn.mapRect(-2515, -2000, 180, 50); spawn.mapRect(-2515, -2000, 180, 50);
spawn.bodyRect(-3410, -1425, 100, 100); spawn.bodyRect(-3410, -1425, 50, 50);
spawn.bodyRect(-3390, -1525, 100, 100); spawn.bodyRect(-3390, -1525, 40, 60);
// spawn.bodyRect(-3245, -1425, 100, 100); // spawn.bodyRect(-3245, -1425, 100, 100);
//building 3 //building 3
spawn.mapRect(-4450, -1750, 800, 1050); spawn.mapRect(-4450, -1750, 800, 1050);
@@ -4171,16 +4171,6 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
// simulation.draw.mapPath = new Path2D();
// for (let i = 0, len = map.length; i < len; ++i) {
// let vertices = map[i].vertices;
// simulation.draw.mapPath.moveTo(vertices[0].x, vertices[0].y);
// for (let j = 1; j < vertices.length; j += 1) {
// simulation.draw.mapPath.lineTo(vertices[j].x, vertices[j].y);
// }
// simulation.draw.mapPath.lineTo(vertices[0].x, vertices[0].y);
// }
const lightingPath = new Path2D() //pre-draw the complex lighting path to save processing const lightingPath = new Path2D() //pre-draw the complex lighting path to save processing
lightingPath.moveTo(-1800, -500) lightingPath.moveTo(-1800, -500)
lightingPath.lineTo(-910, -500) //3rd floor light lightingPath.lineTo(-910, -500) //3rd floor light

View File

@@ -642,7 +642,7 @@ const m = {
tech.isDeathAvoidedThisLevel = true tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.count}`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.count}`)
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
m.energy = m.maxEnergy m.energy = m.maxEnergy
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
@@ -673,7 +673,7 @@ const m = {
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span> simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
<br>${powerUps.research.count}`) <br>${powerUps.research.count}`)
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)"; ctx.fillStyle = "rgba(255,255,255,0.03)";
@@ -2125,9 +2125,10 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100 // m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0 m.fieldDrawRadius = 0
m.isSneakAttack = true; m.isSneakAttack = true;
const drawRadius = 1100 const drawRadius = 900
m.hold = function() { m.hold = function() {
// console.log(m.holdingTarget)
if (m.isHolding) { if (m.isHolding) {
m.drawHold(m.holdingTarget); m.drawHold(m.holdingTarget);
m.holding(); m.holding();
@@ -2194,29 +2195,27 @@ const m = {
const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5) const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5)
ctx.beginPath(); ctx.beginPath();
ctx.ellipse(m.pos.x, m.pos.y, m.fieldDrawRadius * (1 - wiggle), m.fieldDrawRadius * (1 + wiggle), m.fieldPhase, 0, 2 * Math.PI); ctx.ellipse(m.pos.x, m.pos.y, m.fieldDrawRadius * (1 - wiggle), m.fieldDrawRadius * (1 + wiggle), m.fieldPhase, 0, 2 * Math.PI);
if (m.fireCDcycle > m.cycle && (input.field)) { // if (m.fireCDcycle > m.cycle && (input.field)) {}
ctx.lineWidth = 5; ctx.fillStyle = "#fff"
ctx.strokeStyle = `rgba(0, 204, 255,1)` ctx.lineWidth = 2;
ctx.stroke() ctx.strokeStyle = "#000"
} ctx.stroke()
ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`; // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
ctx.globalCompositeOperation = "destination-in"; //in or atop ctx.globalCompositeOperation = "destination-in";
ctx.fill(); ctx.fill();
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
ctx.clip(); // ctx.clip(); //seems to have a high performance cost
} }
// const energy = Math.max(0.01, Math.min(m.energy, 1)) // const energy = Math.max(0.01, Math.min(m.energy, 1))
if (m.isCloak) { if (m.isCloak) {
this.fieldRange = this.fieldRange * 0.9 + 0.1 * drawRadius this.fieldRange = this.fieldRange * 0.9 + 0.1 * drawRadius
m.fieldDrawRadius = this.fieldRange * 0.9 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); m.fieldDrawRadius = this.fieldRange * 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
drawField()
} else if (this.fieldRange < 3000) {
this.fieldRange += 50
m.fieldDrawRadius = this.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
drawField() drawField()
} else {
if (this.fieldRange < 3000) {
this.fieldRange += 200
m.fieldDrawRadius = this.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
drawField()
}
} }
if (tech.isIntangible) { if (tech.isIntangible) {
if (m.isCloak) { if (m.isCloak) {
@@ -2478,7 +2477,8 @@ const m = {
if ( if (
dist2 < 5000 && dist2 < 5000 &&
!simulation.isChoosing && !simulation.isChoosing &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth) (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
// (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth)
// (powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity) // (powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity)
) { //use power up if it is close enough ) { //use power up if it is close enough
powerUps.onPickUp(powerUp[i]); powerUps.onPickUp(powerUp[i]);

View File

@@ -697,7 +697,7 @@ const powerUps = {
if (tech.isLaserMine && m.crouch) { if (tech.isLaserMine && m.crouch) {
b.laserMine(who.position) b.laserMine(who.position)
} else { } else {
b.mine(who.position, { x: 0, y: 0 }, 0, tech.isMineAmmoBack) b.mine(who.position, { x: 0, y: 0 }, 0)
} }
} }
if (tech.isRelay) { if (tech.isRelay) {

View File

@@ -737,20 +737,20 @@ const simulation = {
} }
} }
} }
if (tech.isMineAmmoBack) {
let count = 0; let count = 0;
for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
if (bullet[i].bulletType === "mine") count++ if (bullet[i].bulletType === "mine" || bullet[i].bulletType === "laser mine") count++
} }
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
if (b.guns[i].name === "mine") { if (b.guns[i].name === "mine") {
if (tech.isCrouchAmmo) count = Math.ceil(count / 2) if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
b.guns[i].ammo += count b.guns[i].ammo += count
simulation.updateGunHUD(); simulation.updateGunHUD();
break; break;
}
} }
} }
if (tech.isMutualism && !tech.isEnergyHealth) { if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) { if (bullet[i].isMutualismActive) {

View File

@@ -344,7 +344,7 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.isDamageForGuns || tech.isFireRateForGuns) && b.inventory.length + 5 < b.guns.length return (tech.isDamageForGuns || tech.isFireRateForGuns) && b.inventory.length < b.guns.length - 5 //12-5 guns total
}, },
requires: "arsenal or active cooling and less than 7 guns", requires: "arsenal or active cooling and less than 7 guns",
effect() { effect() {
@@ -470,7 +470,7 @@
}, },
{ {
name: "desublimated ammunition", name: "desublimated ammunition",
description: "use <strong>50%</strong> less <strong class='color-g'>ammo</strong> when <strong>crouching</strong><<br>strong>+6</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool", description: "use <strong>50%</strong> less <strong class='color-g'>ammo</strong> when <strong>crouching</strong><br><strong>+6</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -2695,7 +2695,7 @@
powerUps.research.changeRerolls(0) powerUps.research.changeRerolls(0)
}, 1000); }, 1000);
}, },
description: "once per level, instead of <strong>dying</strong><br>consume <strong>1</strong> <strong class='color-r'>research</strong> and spawn <strong>6</strong> <strong class='color-h'>heals</strong>", description: "once per level, instead of <strong>dying</strong><br>consume <strong>1</strong> <strong class='color-r'>research</strong> and spawn <strong>5</strong> <strong class='color-h'>heals</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -4042,7 +4042,7 @@
}, },
{ {
name: "ice-shot", name: "ice-shot",
description: "<strong>shotgun</strong> grows <strong>18</strong> freezing <strong class='color-s'>ice IX</strong> crystals", description: "<strong>shotgun</strong> grows <strong>15</strong> freezing <strong class='color-s'>ice IX</strong> crystals",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4059,25 +4059,6 @@
tech.isIceShot = false; tech.isIceShot = false;
} }
}, },
{
name: "super duper",
description: "fire <strong>1</strong> additional <strong>super ball</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("super balls") && !tech.oneSuperBall
},
requires: "super balls, but not the tech super ball",
effect() {
tech.superBallNumber++
},
remove() {
tech.superBallNumber = 3;
}
},
{ {
name: "supertemporal", name: "supertemporal",
description: "fire <strong>super ball</strong> from the same point in <strong>space</strong><br> but separated by <strong>0.1</strong> seconds in <strong>time</strong>", description: "fire <strong>super ball</strong> from the same point in <strong>space</strong><br> but separated by <strong>0.1</strong> seconds in <strong>time</strong>",
@@ -4114,7 +4095,7 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("super balls") && tech.superBallNumber === 3 && !tech.superBallDelay return tech.haveGunCheck("super balls") && tech.missileCount === 1 && !tech.superBallDelay
}, },
requires: "super balls, but not super duper or supertemporal", requires: "super balls, but not super duper or supertemporal",
effect() { effect() {
@@ -4134,7 +4115,7 @@
}, },
{ {
name: "super sized", name: "super sized",
description: `<strong>super balls</strong> are <strong>20%</strong> larger<br>increases mass and physical <strong class='color-d'>damage</strong>`, description: `increase <strong>super ball</strong> radius by <strong>17%</strong><br>increases <strong class='color-d'>damage</strong> by about <strong>35%</strong>`,
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -4145,7 +4126,7 @@
}, },
requires: "super balls", requires: "super balls",
effect() { effect() {
tech.bulletSize += 0.15 tech.bulletSize += 0.17
}, },
remove() { remove() {
tech.bulletSize = 1; tech.bulletSize = 1;
@@ -4321,25 +4302,6 @@
tech.missileSize = false tech.missileSize = false
} }
}, },
{
name: "MIRV",
description: "missile <strong class='color-g'>gun</strong> and <strong>bot</strong> launch <strong>+1</strong> <strong>missile</strong><br>decrease <strong>size</strong> and <strong>fire rate</strong> by <strong>10%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("missiles") || tech.missileBotCount
},
requires: "missiles",
effect() {
tech.missileCount++;
},
remove() {
tech.missileCount = 1;
}
},
{ {
name: "missile-bot", name: "missile-bot",
description: "remove your <strong>missile gun</strong><br>gain a <strong class='color-bot'>bot</strong> that fires <strong>missiles</strong> at mobs", description: "remove your <strong>missile gun</strong><br>gain a <strong class='color-bot'>bot</strong> that fires <strong>missiles</strong> at mobs",
@@ -4368,6 +4330,25 @@
} }
} }
}, },
{
name: "MIRV",
description: "fire <strong>+1</strong> <strong>missile</strong>, <strong>grenade</strong>, and <strong>super ball</strong><br>decrease <strong class='color-e'>explosion</strong> <strong>radius</strong> up to <strong>10%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("missiles") || tech.missileBotCount || tech.haveGunCheck("grenades") || (tech.haveGunCheck("super balls") && !tech.oneSuperBall)
},
requires: "missiles, grenades, super balls, not super ball",
effect() {
tech.missileCount++;
},
remove() {
tech.missileCount = 1;
}
},
{ {
name: "rocket-propelled grenade", name: "rocket-propelled grenade",
description: "<strong>grenades</strong> rapidly <strong>accelerate</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>", description: "<strong>grenades</strong> rapidly <strong>accelerate</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>",
@@ -4421,7 +4402,7 @@
allowed() { allowed() {
return tech.isVacuumBomb && !tech.isExplodeRadio return tech.isVacuumBomb && !tech.isExplodeRadio
}, },
requires: "vacuum bomb && not iridium-192", requires: "vacuum bomb, not iridium-192",
effect() { effect() {
tech.isBlockExplode = true; //chain reaction tech.isBlockExplode = true; //chain reaction
}, },
@@ -4469,6 +4450,28 @@
tech.isNeutronSlow = false tech.isNeutronSlow = false
} }
}, },
{
name: "booby trap",
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br><strong>+53</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("mine")
},
requires: "mines, not mine reclamation",
effect() {
tech.isMineDrop = true;
if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0)
tech.addJunkTechToPool(53)
},
remove() {
tech.isMineDrop = false;
if (this.count > 0) tech.removeJunkTechFromPool(53)
}
},
{ {
name: "laser-mines", name: "laser-mines",
description: "<strong>mines</strong> laid while you are <strong>crouched</strong><br>use <strong class='color-f'>energy</strong> to emit <strong>3</strong> unaimed <strong class='color-laser'>lasers</strong>", description: "<strong>mines</strong> laid while you are <strong>crouched</strong><br>use <strong class='color-f'>energy</strong> to emit <strong>3</strong> unaimed <strong class='color-laser'>lasers</strong>",
@@ -4488,25 +4491,6 @@
tech.isLaserMine = false; tech.isLaserMine = false;
} }
}, },
{
name: "mine reclamation",
description: "retrieve <strong class='color-g'>ammo</strong> from all undetonated <strong>mines</strong><br>and <strong>20%</strong> of <strong>mines</strong> after detonation",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("mine") && !tech.isMineDrop
},
requires: "mine, not bobby trap",
effect() {
tech.isMineAmmoBack = true;
},
remove() {
tech.isMineAmmoBack = false;
}
},
{ {
name: "sentry", name: "sentry",
description: "instead of detonating, <strong>mines</strong> <strong>target</strong> mobs<br>with a stream of nails for about <strong>17</strong> seconds", description: "instead of detonating, <strong>mines</strong> <strong>target</strong> mobs<br>with a stream of nails for about <strong>17</strong> seconds",
@@ -4545,28 +4529,6 @@
tech.isMineStun = false; tech.isMineStun = false;
} }
}, },
{
name: "booby trap",
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br><strong>+30</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("mine") && !tech.isMineAmmoBack
},
requires: "mines, not mine reclamation",
effect() {
tech.isMineDrop = true;
if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
tech.addJunkTechToPool(30)
},
remove() {
tech.isMineDrop = false;
if (this.count > 0) tech.removeJunkTechFromPool(30)
}
},
{ {
name: "mycelial fragmentation", name: "mycelial fragmentation",
description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>6</strong> extra <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br>during their <strong>growth</strong> phase", description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>6</strong> extra <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br>during their <strong>growth</strong> phase",
@@ -4901,7 +4863,7 @@
}, },
{ {
name: "uncertainty principle", name: "uncertainty principle",
description: "<strong>foam</strong> bubbles randomly change <strong>position</strong><br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>55%</strong>", description: "<strong>foam</strong> bubbles randomly change <strong>position</strong><br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>50%</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5964,7 +5926,10 @@
tech.isIntangible = true; tech.isIntangible = true;
}, },
remove() { remove() {
tech.isIntangible = false; if (tech.isIntangible) {
tech.isIntangible = false;
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
}
} }
}, },
{ {
@@ -7730,7 +7695,6 @@
isPiezo: null, isPiezo: null,
isFastDrones: null, isFastDrones: null,
isFastSpores: null, isFastSpores: null,
superBallNumber: null,
oneSuperBall: null, oneSuperBall: null,
laserReflections: null, laserReflections: null,
laserDamage: null, laserDamage: null,
@@ -7745,7 +7709,6 @@
isSporeField: null, isSporeField: null,
isMissileField: null, isMissileField: null,
isIceField: null, isIceField: null,
isMineAmmoBack: null,
isPlasmaRange: null, isPlasmaRange: null,
isFreezeMobs: null, isFreezeMobs: null,
isIceCrystals: null, isIceCrystals: null,

View File

@@ -1,18 +1,26 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
20% damage for all mine modes tech: MIRV - now effects grenades and super balls in addition to missiles
laser mines spin super fast when it first finds a target, and a bit faster overall no change for super balls and missiles, but this is a new tech for grenades
mine sentry lasts 17 seconds (2 more seconds)
desublimated ammunition comes with 7 JUNK tech undetonated mines are returned at the end of a level
several foam tech do 5% less damage removed tech: mine reclamation
shotgun has 1/9 less ammo mine gun has 30% less ammo
apomixis now requires 11 research laser mines do 7% less damage
historyBoss takes 25% longer to reach it's minimum follow distance booby trap now comes with 53 JUNK (up from 33) but it's mines can be returned for ammo
removed ctx.clip() from metamaterial cloaking field for performance reasons
the graphics look a bit different now, maybe not as good, maybe it's just different
iceIX bullets last 50% less time, but do 50% more damage and have 25% more thrust
so it's more of a close range bullet
ice-shot has 2 fewer bullets
bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
tech MIRV applies to grenades
maybe also merge with tech: super balls?, laser refraction...
work on necroBoss from TheShwarma work on necroBoss from TheShwarma
make spawned blocks in the direction of the player make spawned blocks in the direction of the player
make it search the level for blocks, but also kinda avoid the player make it search the level for blocks, but also kinda avoid the player
@@ -28,12 +36,10 @@ falling particle rain
basically spores with no guidance basically spores with no guidance
lag if too many particles? lag if too many particles?
wormhole show where you would go on mouse down
trigger teleport on release
look into 360 wave beam lag look into 360 wave beam lag
aoe effect pushes mobs away, then rapidly pulls them in aoe effect pushes mobs away, then rapidly pulls them in
for mines?
tech: shrapnel - nails have an larger randomized 3 point shape triangle shape and they do more damage tech: shrapnel - nails have an larger randomized 3 point shape triangle shape and they do more damage
@@ -114,8 +120,6 @@ add back in gamepad support?
but does anyone care? but does anyone care?
https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected
RPG default or tech: grenades detonate on your cursor / where your cursor was when they were fired
tech: time dilation - when you exit time dilation rewind to the state you entered tech: time dilation - when you exit time dilation rewind to the state you entered
position, velocity, and health position, velocity, and health
no energy cost no energy cost
@@ -126,9 +130,6 @@ be able to open up custom mode in the normal game
have a way to make limited changes as allowed by tech you pick up in game have a way to make limited changes as allowed by tech you pick up in game
disable the in custom setting flag disable the in custom setting flag
super balls start at 3, not 4
have to balance damage
make different move methods make different move methods
tech crouch charge jump tech crouch charge jump
tech double jump tech double jump
@@ -146,8 +147,6 @@ tech pilot wave: antigravity - blocks have no gravity for a few seconds after ex
maybe they bounce too? maybe they bounce too?
maybe they explode? maybe they explode?
wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks
new power up - increase damage and fire speed, for 15 seconds new power up - increase damage and fire speed, for 15 seconds
named boost? named boost?
enabled by a tech enabled by a tech