diff --git a/.DS_Store b/.DS_Store
index d10987f..7554219 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 04a6504..6ae5558 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -2301,17 +2301,32 @@ const b = {
World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], velocity);
},
+ targetedBlock(who, isSpin = false, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
+ let closestMob, dist
+ for (let i = 0, len = mob.length; i < len; i++) {
+ if (who !== mob[i]) {
+ dist = Vector.magnitude(Vector.sub(who.position, mob[i].position));
+ if (dist < range && Matter.Query.ray(map, who.position, mob[i].position).length === 0) { //&& Matter.Query.ray(body, position, mob[i].position).length === 0
+ closestMob = mob[i]
+ range = dist
+ }
+ }
+ }
+ if (closestMob) {
+ const where = Vector.add(closestMob.position, Vector.mult(closestMob.velocity, dist / 60))
+ const velocity = Vector.mult(Vector.normalise(Vector.sub(where, who.position)), speed)
+ velocity.y -= Math.abs(who.position.x - closestMob.position.x) / 150; //gives an arc, but not a good one
+ Matter.Body.setVelocity(who, velocity);
+ if (isSpin) Matter.Body.setAngularVelocity(who, 2 + 2 * Math.random() * (Math.random() < 0.5 ? -1 : 1));
+ }
+ },
targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true) {
const targets = [] //target nearby mobs
for (let i = 0, len = mob.length; i < len; i++) {
- // if (mob[i].isDropPowerUp) {
const dist = Vector.magnitude(Vector.sub(position, mob[i].position));
- if (dist < range &&
- Matter.Query.ray(map, position, mob[i].position).length === 0 &&
- Matter.Query.ray(body, position, mob[i].position).length === 0) {
+ if (dist < range && Matter.Query.ray(map, position, mob[i].position).length === 0 && Matter.Query.ray(body, position, mob[i].position).length === 0) {
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles
}
- // }
}
for (let i = 0; i < num; i++) {
if (targets.length > 0) { // aim near a random target in array
diff --git a/js/engine.js b/js/engine.js
index 87d11d4..0668ee0 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -181,8 +181,8 @@ function collisionChecks(event) {
if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) {
- let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
- if (mob[k].isShielded) dmg *= 0.35
+ let dmg = 0.075 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
+ if (mob[k].isShielded) dmg *= 0.6
mob[k].damage(dmg, true);
if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
@@ -196,7 +196,7 @@ function collisionChecks(event) {
}
const stunTime = dmg / Math.sqrt(obj.mass)
- if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
+ if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
obj.hasFragmented = true;
diff --git a/js/level.js b/js/level.js
index 6eb843d..8d3fad9 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,7 +16,7 @@ const level = {
// simulation.zoomScale = 1000;
// simulation.setZoom();
// m.setField("nano-scale manufacturing")
- // b.giveGuns("shotgun")
+ // b.giveGuns("laser")
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("incendiary ammunition")
@@ -1111,13 +1111,16 @@ const level = {
// spawn.grower(1900, -500)
// spawn.pulsarBoss(1900, -500)
// spawn.shooterBoss(1900, -500)
- spawn.spawns(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
- // spawn.striker(4600, -500)
+ spawn.striker(1600, -500)
+ spawn.striker(1600, -500)
+ spawn.striker(1600, -500)
// spawn.laserTargetingBoss(1700, -120)
// spawn.bomberBoss(1400, -500)
- // spawn.sniper(1800, -120)
+ spawn.sniper(1800, -120)
+ spawn.sniper(1800, -120)
+ spawn.sniper(2800, -120)
// spawn.streamBoss(1600, -500)
// spawn.orbitalBoss(1600, -500)
// spawn.spawnerBossCulture(1600, -500)
diff --git a/js/mob.js b/js/mob.js
index f2bafd9..8eed00d 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1073,10 +1073,7 @@ const mobs = {
}
if (tech.isBotSpawnerReset) {
for (let i = 0, len = bullet.length; i < len; i++) {
- if (bullet[i].botType && bullet[i].endCycle !== Infinity) {
- console.log(bullet[i].endCycle)
- bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun
- }
+ if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun
}
}
if (Math.random() < tech.botSpawner) {
@@ -1199,9 +1196,13 @@ const mobs = {
};
shrink(body[len], 7 + 4 * Math.random())
}
+ Matter.World.remove(engine.world, this);
+ mob.splice(i, 1);
+ if (tech.isMobBlockFling) b.targetedBlock(body[body.length - 1], true)
+ } else {
+ Matter.World.remove(engine.world, this);
+ mob.splice(i, 1);
}
- Matter.World.remove(engine.world, this);
- mob.splice(i, 1);
}
});
mob[i].alertRange2 = Math.pow(mob[i].radius * 3 + 550, 2);
diff --git a/js/player.js b/js/player.js
index bd97ab4..7c2b5bc 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1145,14 +1145,14 @@ const m = {
m.fieldCDcycle = m.cycle + 15;
m.isHolding = false;
//bullet-like collisions
- m.holdingTarget.collisionFilter.category = cat.body; //cat.bullet;
+ m.holdingTarget.collisionFilter.category = cat.bullet; //cat.body;
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
//check every second to see if player is away from thrown body, and make solid
const solid = function(that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
- // that.collisionFilter.category = cat.body; //make solid
+ that.collisionFilter.category = cat.body; //make solid
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {
setTimeout(solid, 25, that);
@@ -1650,14 +1650,14 @@ const m = {
},
{
name: "negative mass field",
- description: "use energy to nullify gravity
reduce harm by 50%
blocks held by the field have a lower mass",
+ description: "use energy to nullify gravity
reduce harm by 55%
blocks held by the field have a lower mass",
fieldDrawRadius: 0,
effect: () => {
m.fieldFire = true;
- m.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
+ m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
m.fieldMeterColor = "#333"
m.eyeFillColor = m.fieldMeterColor
- m.fieldHarmReduction = 0.5;
+ m.fieldHarmReduction = 0.55;
m.fieldDrawRadius = 0;
m.hold = function() {
diff --git a/js/spawn.js b/js/spawn.js
index 56e8c6f..18430ab 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -264,7 +264,6 @@ const spawn = {
});
}
const len = (this.totalCycles / 400 + simulation.difficulty / 2 - 30) / 15
- // console.log(len)
for (let i = 0; i < len; i++) {
spawn.randomLevelBoss(3000 + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5))
}
@@ -2360,7 +2359,7 @@ const spawn = {
};
Matter.Body.setDensity(me, 0.00004); //normal is 0.001
me.timeLeft = 200;
- me.g = 0.001; //required if using 'gravity'
+ me.g = 0.001; //required if using 'gravity'
me.frictionAir = 0;
me.restitution = 0.8;
me.leaveBody = false;
diff --git a/js/tech.js b/js/tech.js
index 564c214..0b3f2c9 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -833,7 +833,7 @@
count: 0,
frequency: 2,
allowed() {
- return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner
+ return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling
},
requires: "an explosive damage source, no other mob death tech",
effect: () => {
@@ -850,7 +850,7 @@
count: 0,
frequency: 2,
allowed() {
- return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner
+ return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
},
requires: "no other mob death tech",
effect: () => {
@@ -867,7 +867,7 @@
count: 0,
frequency: 2,
allowed() {
- return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner
+ return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
},
requires: "no other mob death tech",
effect() {
@@ -887,7 +887,7 @@
count: 0,
frequency: 2,
allowed() {
- return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner
+ return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner || tech.isMobBlockFling
},
requires: "any mob death tech",
effect: () => {
@@ -944,7 +944,7 @@
frequency: 1,
isBotTech: true,
allowed() {
- return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob //b.totalBots() > 0 &&
+ return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob && !tech.isMobBlockFling
},
requires: "no other mob death tech",
effect() {
@@ -1380,16 +1380,16 @@
},
{
name: "mass driver",
- description: "increase block collision damage by 100%
charge throws more quickly for less energy",
+ description: "increase block collision damage by 200%
charge throws more quickly for less energy",
maxCount: 1,
count: 0,
- frequency: 1,
+ frequency: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name !== "wormhole"
},
requires: "not wormhole",
effect() {
- tech.throwChargeRate = 2
+ tech.throwChargeRate = 3
},
remove() {
tech.throwChargeRate = 1
@@ -1413,6 +1413,24 @@
tech.isBlockPowerUps = false
}
},
+ {
+ name: "flywheel",
+ description: "after a mob dies its body is spun and flung
in the general direction of a nearby mob",
+ maxCount: 1,
+ count: 0,
+ frequency: 4,
+ frequencyDefault: 4,
+ allowed() {
+ return tech.throwChargeRate > 1 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner
+ },
+ requires: "mass driver, no other mob death tech",
+ effect() {
+ tech.isMobBlockFling = true
+ },
+ remove() {
+ tech.isMobBlockFling = false
+ }
+ },
{
name: "inelastic collision",
description: "while you are holding a block
reduce harm by 85%",
@@ -6414,5 +6432,6 @@
frequencyResonance: null,
isAlwaysFire: null,
isDroneRespawn: null,
- deathSpawns: null
+ deathSpawns: null,
+ isMobBlockFling: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index c3db8f6..03dbe85 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,14 +1,15 @@
******************************************************** NEXT PATCH ********************************************************
-bots are now nonrefundable, so they don't display as a tech when you select them
- this might introduce some errors, please let me know if you see something
-bot counts can be seen in pause menu
+thrown blocks can damage intangible mobs for a couple seconds after they are thrown
+ they are set to act like bullets for a few seconds after being thrown
+all blocks do 50% more damage to mobs and 50% longer stun
+blocks do more damage vs. shielded mobs (damage penalty is 40%, was 66%))
+mass driver - damage increase set to 200% (up from 100%)
+negative mass field can lift blocks twice as heavy as before with little movement reduction
-the final boss will spawn progressively more mobs if you don't kill it quickly enough
- levelBosses are also more likely to spawn on the final boss
+tech: flywheel - when mobs die their body is spun and flung at nearby mobs
+ requires mass driver, no other mob death tech
-added community map - crossfire
- by iNoobBoi
******************************************************** BUGS ********************************************************
@@ -40,9 +41,12 @@ fix door.isOpen actually meaning isClosed?
******************************************************** TODO ********************************************************
-import the procedural level generation from one of the older versions of the game as one single level
+chance for the block resulting from a slain enemy to be thrown at the nearest mob.
+ tech: flywheel - after a mob dies their body is fired towards a nearby mob
+ requires: block throwing technology?
+ adjust for gravity
-Tech: "Spacial Continuity": 12% chance for the block resulting from a slain enemy to be thrown at the nearest mob.
+import the procedural level generation from one of the older versions of the game as one single level
tech plasma field - plasma field becomes an aoe damage field with the same radius
200% more energy drain, 100% more damage