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