diff --git a/.DS_Store b/.DS_Store
index 9ebb094..ed82f45 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index beded82..ee19419 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -713,11 +713,11 @@ const b = {
},
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;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
- Matter.Body.setDensity(bullet[me], 0.0005);
- bullet[me].explodeRad = 300;
+ Matter.Body.setDensity(bullet[me], 0.0003);
+ bullet[me].explodeRad = 300 * size;
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
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
}
- 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;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
- Matter.Body.setDensity(bullet[me], 0.0005);
- bullet[me].explodeRad = 305;
+ Matter.Body.setDensity(bullet[me], 0.0003);
+ bullet[me].explodeRad = 305 * size;
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
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;
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
- Matter.Body.setDensity(bullet[me], 0.0005);
- bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110
+ Matter.Body.setDensity(bullet[me], 0.0003);
+ bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
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;
bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false));
- Matter.Body.setDensity(bullet[me], 0.0003);
- bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
+ Matter.Body.setDensity(bullet[me], 0.0002);
+ bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
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
}
- 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;
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);
bullet[me].endCycle = Infinity;
bullet[me].frictionAir = 0;
@@ -932,7 +932,7 @@ const b = {
bullet[me].restitution = 0;
bullet[me].minDmgSpeed = 0;
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].stuckTo = null;
bullet[me].stuckToRelativePosition = null;
@@ -1604,7 +1604,7 @@ const b = {
laserMine(position, velocity = { x: 0, y: -8 }) {
const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, {
- bulletType: "mine",
+ bulletType: "laser mine",
angle: m.angle,
friction: 0,
frictionAir: 0.025,
@@ -1612,8 +1612,8 @@ const b = {
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 67 + Math.floor(7 * Math.random()),
- drain: 0.5 * tech.isLaserDiode * tech.laserFieldDrain,
- isArmed: false,
+ drain: 0.62 * tech.isLaserDiode * tech.laserFieldDrain,
+ isDetonated: false,
torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1),
range: 1500,
endCycle: Infinity,
@@ -1623,17 +1623,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
beforeDmg() {},
- 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;
- }
- }
- }
- },
+ onEnd() {},
do() {
if (!(simulation.cycle % this.lookFrequency) && m.energy > this.drain) { //find mob targets
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
this.endCycle = simulation.cycle + 360 + 120
// if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin
- this.isArmed = true
+ this.isDetonated = true
break
}
}
@@ -1669,7 +1659,7 @@ const b = {
for (let i = 0; i < 3; i++) {
const where = this.vertices[i]
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.globalAlpha = 1;
@@ -1704,28 +1694,26 @@ const b = {
lookFrequency: 0,
range: 700,
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() {
this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) {
- const angle = Vector.angle(collide[i].normal, {
- x: 1,
- y: 0
- })
+ const angle = Vector.angle(collide[i].normal, { x: 1, y: 0 })
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation
for (let j = 0; j < 10; j++) {
if (Matter.Query.collides(this, map).length > 0) { //touching map
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
this.collisionFilter.mask = cat.map | cat.bullet
} else {
- Matter.Body.setVelocity(this, {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(this, 0)
}
this.arm();
@@ -1752,55 +1740,7 @@ const b = {
}
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() {
- //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.lookFrequency = simulation.cycle + 60
this.do = function() { //overwrite the do method for this bullet
@@ -1848,11 +1788,8 @@ const b = {
break
} else {
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
}
-
-
}
}
}
@@ -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())
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) }) {
const me = bullet.length;
- const THRUST = 0.0006
+ const THRUST = 0.0009
const RADIUS = 18
const SCALE = 1 - 0.08 / tech.isBulletsLastLonger
bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, {
@@ -2119,9 +2033,9 @@ const b = {
friction: 0,
frictionAir: 0.023,
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()),
- endCycle: simulation.cycle + 150 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
+ endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
classType: "bullet",
collisionFilter: {
category: cat.bullet,
@@ -2607,7 +2521,7 @@ const b = {
inertia: Infinity,
frictionAir: 0.003,
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),
classType: "bullet",
collisionFilter: {
@@ -2748,7 +2662,7 @@ const b = {
}
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport
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())))
}
}
@@ -4043,9 +3957,9 @@ const b = {
}
} else if (tech.isIceShot) {
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) }) {
- 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) {
const spread = (m.crouch ? 0.35 : 0.7)
@@ -4132,8 +4046,9 @@ const b = {
const SPEED = m.crouch ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
const SPREAD = m.crouch ? 0.08 : 0.13
- let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2;
- for (let i = 0; i < tech.superBallNumber; i++) {
+ const num = tech.missileCount + 2
+ let dir = m.angle - SPREAD * (num - 1) / 2;
+ for (let i = 0; i < num; i++) {
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));
Composite.add(engine.world, bullet[me]); //add bullet to world
@@ -4163,6 +4078,7 @@ const b = {
const dir = m.angle
const x = m.pos.x
const y = m.pos.y
+ const num = tech.missileCount + 2
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down
@@ -4194,7 +4110,7 @@ const b = {
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
count++
if (count % 2) fireBall()
- if (count < tech.superBallNumber * 2 && m.alive) requestAnimationFrame(cycle);
+ if (count < num * 2 && m.alive) requestAnimationFrame(cycle);
}
}
let count = 0
@@ -4640,14 +4556,21 @@ const b = {
have: false,
do() {},
fire() {
- m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale); // cool down
- b.grenade()
+ const countReduction = Math.pow(0.93, tech.missileCount)
+ 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",
- description: "toss a proximity mine that sticks to walls
fires nails at mobs within range",
+ description: "toss a proximity mine that sticks to walls
refund undetonated mines on exiting a level", //fires nails at mobs within range
ammo: 0,
- ammoPack: 1.4,
+ ammoPack: 1.1,
have: false,
do() {},
fire() {
@@ -4657,33 +4580,17 @@ const b = {
const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
b.laserMine(m.pos, velocity)
} else {
- const pos = {
- x: m.pos.x + 30 * Math.cos(m.angle),
- y: m.pos.y + 30 * Math.sin(m.angle)
- }
+ const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
let speed = 36
- if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map
- speed = -2
- }
- b.mine(pos, {
- x: speed * Math.cos(m.angle),
- y: speed * Math.sin(m.angle)
- }, 0, tech.isMineAmmoBack)
+ if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
+ b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
}
m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down
} else {
- const pos = {
- x: m.pos.x + 30 * Math.cos(m.angle),
- y: m.pos.y + 30 * Math.sin(m.angle)
- }
+ const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
let speed = 23
- if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map
- speed = -2
- }
- b.mine(pos, {
- x: speed * Math.cos(m.angle),
- y: speed * Math.sin(m.angle)
- }, 0, tech.isMineAmmoBack)
+ if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
+ b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down
}
}
diff --git a/js/engine.js b/js/engine.js
index fdfa9d1..9cb3e8d 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -175,8 +175,8 @@ function collisionChecks(event) {
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
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
+ // console.log(dmg)
mob[k].damage(dmg);
if (mob[k].alive) mob[k].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue
diff --git a/js/level.js b/js/level.js
index ec482df..6987d65 100644
--- a/js/level.js
+++ b/js/level.js
@@ -11,13 +11,14 @@ const level = {
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
+ // simulation.enableConstructMode() //used to build maps in testing mode
// localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
- // b.giveGuns("mine")
- // b.giveGuns("nail gun")
- // m.setField("wormhole")
+ // b.giveGuns("grenades")
// tech.giveTech("laser-mines")
+ // m.setField("metamaterial cloaking")
+ // for (let i = 0; i < 3; i++) tech.giveTech("super sized")
// tech.giveTech("irradiated nails")
// 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 < 7; i++) tech.giveTech("undefined")
// lore.techCount = 6
- // simulation.enableConstructMode() //used to build maps in testing mode
// simulation.isCheating = false //true;
// 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);
}
// 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
blockDoor(2585, -210)
@@ -4027,8 +4027,8 @@ const level = {
// spawn.mapRect(-2600, -1975, 250, 25);
spawn.mapRect(-2515, -2000, 180, 50);
- spawn.bodyRect(-3410, -1425, 100, 100);
- spawn.bodyRect(-3390, -1525, 100, 100);
+ spawn.bodyRect(-3410, -1425, 50, 50);
+ spawn.bodyRect(-3390, -1525, 40, 60);
// spawn.bodyRect(-3245, -1425, 100, 100);
//building 3
spawn.mapRect(-4450, -1750, 800, 1050);
@@ -4171,16 +4171,6 @@ const level = {
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
lightingPath.moveTo(-1800, -500)
lightingPath.lineTo(-910, -500) //3rd floor light
diff --git a/js/player.js b/js/player.js
index fad4a75..895f481 100644
--- a/js/player.js
+++ b/js/player.js
@@ -642,7 +642,7 @@ const m = {
tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`m.research--
${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
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails
@@ -673,7 +673,7 @@ const m = {
powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`m.research--
${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
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)";
@@ -2125,9 +2125,10 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0
m.isSneakAttack = true;
- const drawRadius = 1100
+ const drawRadius = 900
m.hold = function() {
+ // console.log(m.holdingTarget)
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2194,29 +2195,27 @@ const m = {
const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5)
ctx.beginPath();
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)) {
- ctx.lineWidth = 5;
- ctx.strokeStyle = `rgba(0, 204, 255,1)`
- ctx.stroke()
- }
- ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
- ctx.globalCompositeOperation = "destination-in"; //in or atop
+ // if (m.fireCDcycle > m.cycle && (input.field)) {}
+ ctx.fillStyle = "#fff"
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = "#000"
+ ctx.stroke()
+ // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
+ ctx.globalCompositeOperation = "destination-in";
ctx.fill();
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))
if (m.isCloak) {
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()
- } 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 (m.isCloak) {
@@ -2478,7 +2477,8 @@ const m = {
if (
dist2 < 5000 &&
!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)
) { //use power up if it is close enough
powerUps.onPickUp(powerUp[i]);
diff --git a/js/powerup.js b/js/powerup.js
index e862a0f..853a1d6 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -697,7 +697,7 @@ const powerUps = {
if (tech.isLaserMine && m.crouch) {
b.laserMine(who.position)
} else {
- b.mine(who.position, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
+ b.mine(who.position, { x: 0, y: 0 }, 0)
}
}
if (tech.isRelay) {
diff --git a/js/simulation.js b/js/simulation.js
index 5589463..0904b6b 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -737,20 +737,20 @@ const simulation = {
}
}
}
- if (tech.isMineAmmoBack) {
- let count = 0;
- for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
- if (bullet[i].bulletType === "mine") count++
- }
- for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
- if (b.guns[i].name === "mine") {
- if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
- b.guns[i].ammo += count
- simulation.updateGunHUD();
- break;
- }
+
+ let count = 0;
+ for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
+ 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
+ if (b.guns[i].name === "mine") {
+ if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
+ b.guns[i].ammo += count
+ simulation.updateGunHUD();
+ break;
}
}
+
if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) {
diff --git a/js/tech.js b/js/tech.js
index 500a3fe..a5210ed 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -344,7 +344,7 @@
frequency: 2,
frequencyDefault: 2,
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",
effect() {
@@ -470,7 +470,7 @@
},
{
name: "desublimated ammunition",
- description: "use 50% less ammo when crouching<
strong>+6 JUNK to the potential tech pool",
+ description: "use 50% less ammo when crouching
+6 JUNK to the potential tech pool",
maxCount: 1,
count: 0,
frequency: 2,
@@ -2695,7 +2695,7 @@
powerUps.research.changeRerolls(0)
}, 1000);
},
- description: "once per level, instead of dying
consume 1 research and spawn 6 heals",
+ description: "once per level, instead of dying
consume 1 research and spawn 5 heals",
maxCount: 1,
count: 0,
frequency: 2,
@@ -4042,7 +4042,7 @@
},
{
name: "ice-shot",
- description: "shotgun grows 18 freezing ice IX crystals",
+ description: "shotgun grows 15 freezing ice IX crystals",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4059,25 +4059,6 @@
tech.isIceShot = false;
}
},
- {
- name: "super duper",
- description: "fire 1 additional super ball",
- 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",
description: "fire super ball from the same point in space
but separated by 0.1 seconds in time",
@@ -4114,7 +4095,7 @@
frequency: 2,
frequencyDefault: 2,
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",
effect() {
@@ -4134,7 +4115,7 @@
},
{
name: "super sized",
- description: `super balls are 20% larger
increases mass and physical damage`,
+ description: `increase super ball radius by 17%
increases damage by about 35%`,
isGunTech: true,
maxCount: 9,
count: 0,
@@ -4145,7 +4126,7 @@
},
requires: "super balls",
effect() {
- tech.bulletSize += 0.15
+ tech.bulletSize += 0.17
},
remove() {
tech.bulletSize = 1;
@@ -4321,25 +4302,6 @@
tech.missileSize = false
}
},
- {
- name: "MIRV",
- description: "missile gun and bot launch +1 missile
decrease size and fire rate by 10%",
- 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",
description: "remove your missile gun
gain a bot that fires missiles at mobs",
@@ -4368,6 +4330,25 @@
}
}
},
+ {
+ name: "MIRV",
+ description: "fire +1 missile, grenade, and super ball
decrease explosion radius up to 10%",
+ 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",
description: "grenades rapidly accelerate forward
map collisions trigger an explosion",
@@ -4421,7 +4402,7 @@
allowed() {
return tech.isVacuumBomb && !tech.isExplodeRadio
},
- requires: "vacuum bomb && not iridium-192",
+ requires: "vacuum bomb, not iridium-192",
effect() {
tech.isBlockExplode = true; //chain reaction
},
@@ -4469,6 +4450,28 @@
tech.isNeutronSlow = false
}
},
+ {
+ name: "booby trap",
+ description: "drop a mine after picking up a power up
+53 JUNK to the potential tech 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",
description: "mines laid while you are crouched
use energy to emit 3 unaimed lasers",
@@ -4488,25 +4491,6 @@
tech.isLaserMine = false;
}
},
- {
- name: "mine reclamation",
- description: "retrieve ammo from all undetonated mines
and 20% of mines 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",
description: "instead of detonating, mines target mobs
with a stream of nails for about 17 seconds",
@@ -4545,28 +4529,6 @@
tech.isMineStun = false;
}
},
- {
- name: "booby trap",
- description: "drop a mine after picking up a power up
+30 JUNK to the potential tech 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",
description: "sporangium release 6 extra spores
during their growth phase",
@@ -4901,7 +4863,7 @@
},
{
name: "uncertainty principle",
- description: "foam bubbles randomly change position
increase foam damage per second by 55%",
+ description: "foam bubbles randomly change position
increase foam damage per second by 50%",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5964,7 +5926,10 @@
tech.isIntangible = true;
},
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,
isFastDrones: null,
isFastSpores: null,
- superBallNumber: null,
oneSuperBall: null,
laserReflections: null,
laserDamage: null,
@@ -7745,7 +7709,6 @@
isSporeField: null,
isMissileField: null,
isIceField: null,
- isMineAmmoBack: null,
isPlasmaRange: null,
isFreezeMobs: null,
isIceCrystals: null,
diff --git a/todo.txt b/todo.txt
index 851b087..66d8c12 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,18 +1,26 @@
******************************************************** NEXT PATCH **************************************************
-20% damage for all mine modes
-laser mines spin super fast when it first finds a target, and a bit faster overall
-mine sentry lasts 17 seconds (2 more seconds)
+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
-desublimated ammunition comes with 7 JUNK tech
-several foam tech do 5% less damage
-shotgun has 1/9 less ammo
-apomixis now requires 11 research
-historyBoss takes 25% longer to reach it's minimum follow distance
+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
-bug fixes
******************************************************** TODO ********************************************************
+tech MIRV applies to grenades
+ maybe also merge with tech: super balls?, laser refraction...
+
work on necroBoss from TheShwarma
make spawned blocks in the direction of 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
lag if too many particles?
-wormhole show where you would go on mouse down
- trigger teleport on release
-
look into 360 wave beam lag
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
@@ -114,8 +120,6 @@ add back in gamepad support?
but does anyone care?
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
position, velocity, and health
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
disable the in custom setting flag
-super balls start at 3, not 4
- have to balance damage
-
make different move methods
tech crouch charge 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 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
named boost?
enabled by a tech