From 0d2c673aece2858354352782bec92551cf13a4ec Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 3 Oct 2021 07:08:22 -0700 Subject: [PATCH] mob: slasher new mob: slasher - it's basically a jedi harpoon: +33% damage, +33% delay after firing time dilation reverted 50% -> 0% collision harm reduction time dilation can no longer get tech: symbiosis nano-scale: can access tokamak and discrete optimization cache: 11x -> 13x ammo bug fixes --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 59 +++++++++++++++++---- js/engine.js | 2 +- js/level.js | 8 +-- js/mob.js | 2 +- js/player.js | 11 ++-- js/powerup.js | 80 ++++++++++++++-------------- js/simulation.js | 2 +- js/spawn.js | 132 +++++++++++++++++++++++++++++++++++++++++++---- js/tech.js | 50 +++++++++--------- todo.txt | 30 +++++++---- 11 files changed, 272 insertions(+), 104 deletions(-) diff --git a/.DS_Store b/.DS_Store index babae7abd3072f5715fa7ddcad9223c8f7ddca45..f787002ddd9a5ef85b0d65bd6a54b32e9cf290e1 100644 GIT binary patch delta 22 dcmZoMXffEJ#mp4&b+Qh#FO!VH=4$3n5dcxJ2DktK delta 22 dcmZoMXffEJ#muDtaIy}wFO&3!&DG4EA^=g>2Lb>9 diff --git a/js/bullet.js b/js/bullet.js index 9728ed8..05c5a5e 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1118,7 +1118,7 @@ const b = { turnRate: isReturn ? 0.1 : 0.03, //0.015 drawStringControlMagnitude: 3000 + 5000 * Math.random(), drawStringFlip: (Math.round(Math.random()) ? 1 : -1), - dmg: 6, //damage done in addition to the damage from momentum + dmg: 7, //damage done in addition to the damage from momentum classType: "bullet", endCycle: simulation.cycle + totalCycles * 2.5 + 15, collisionFilter: { @@ -1133,10 +1133,9 @@ const b = { who.isShielded = false requestAnimationFrame(() => { who.isShielded = true }); } + if (tech.fragments) b.targetedNail(this.vertices[2], tech.fragments * 3) if (!who.isBadTarget) { - if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * 4) - } else if (isReturn) { + if (isReturn) { this.do = this.returnToPlayer } else { this.frictionAir = 0.01 @@ -1166,7 +1165,7 @@ const b = { this.caughtPowerUp.effect(); Matter.Composite.remove(engine.world, this.caughtPowerUp); powerUp.splice(index, 1); - if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.006 * 6 //0.006 is normal + if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.008 * 6 //0.006 is normal } else { this.dropCaughtPowerUp() } @@ -1195,7 +1194,7 @@ const b = { returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player this.endCycle = 0; - if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 25 * b.fireCDscale //lower cd to 25 if it is above 25 + if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25 //recoil on catching const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), this.mass * (input.down ? 0.0001 : 0.0002)) player.force.x += momentum.x @@ -1364,6 +1363,48 @@ const b = { this.force.y += this.mass * 0.001; //gravity } } + + /* todo + despawn + when player gets far away? + set time + release mouse? + + */ + // if (true && input.down) { + // Matter.Body.setVelocity(bullet[me], { + // x: m.Vx / 2 + 70 * Math.cos(bullet[me].angle), + // y: m.Vy / 2 + 70 * Math.sin(bullet[me].angle) + // }); + // bullet[me].frictionAir = 0.0011 + // bullet[me].endCycle = simulation.cycle + Infinity + // bullet[me].do = function() { + // if (!m.isBodiesAsleep) { + // this.cycle++ + // if (Matter.Query.collides(this, map).length) { + // // this.collisionFilter.mask = 0; //non collide with everything + // this.collisionFilter.category = cat.map + // this.collisionFilter.mask = cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; + + // Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(Vector.normalise(this.lastVelocity), 30))) //move a bit into the wall + // Matter.Body.setVelocity(this, { x: 0, y: 0 }); + // Matter.Body.setStatic(this, true) //don't set to static if not touching map + + // Matter.Body.setAngularVelocity(this, 0) + // const unit = Vector.normalise(Vector.sub({ x: this.position.x, y: this.position.y - 150 }, player.position)) + // const push = Vector.mult(unit, 1) + // player.force.x += push.x + // player.force.y += push.y + // //pull player back in + // this.do = () => { + + // } + // } + // this.lastVelocity = { x: this.velocity.x, y: this.velocity.y } + // } + // this.drawString() + // } + // } Composite.add(engine.world, bullet[me]); //add bullet to world }, missile(where, angle, speed, size = 1) { @@ -2794,7 +2835,7 @@ const b = { inertia: Infinity, frictionAir: 0.003, dmg: 0, //damage on impact - damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isBulletTeleport ? 1.43 : 1), //damage done over time + damage: (tech.isFastFoam ? 0.033 : 0.011) * (tech.isBulletTeleport ? 1.43 : 1), //damage done over time scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1), classType: "bullet", collisionFilter: { @@ -5102,7 +5143,7 @@ const b = { } } b.harpoon(where, closest.target, m.angle, length, false, 15) - m.fireCDcycle = m.cycle + 40 * b.fireCDscale; // cool down + m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down } else if (tech.extraHarpoons) { const range = 450 * (tech.isFilament ? 1 + Math.min(100, this.ammo) / 100 : 1) let targetCount = 0 @@ -5144,7 +5185,7 @@ const b = { const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035) player.force.x -= recoil.x player.force.y -= recoil.y - tech.harpoonDensity = 0.005 + tech.harpoonDensity = 0.008 } }, { diff --git a/js/engine.js b/js/engine.js index 3d213f3..1a1d97e 100644 --- a/js/engine.js +++ b/js/engine.js @@ -107,7 +107,7 @@ function collisionChecks(event) { !(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned)) ) { let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0 - if (m.isBodiesAsleep || m.isCloak) dmg *= 0.5 + if (m.isCloak) dmg *= 0.5 mob[k].foundPlayer(); if (tech.isRewindAvoidDeath && m.energy > 0.66) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too m.damage(dmg); diff --git a/js/level.js b/js/level.js index a194bae..1e492ec 100644 --- a/js/level.js +++ b/js/level.js @@ -2300,11 +2300,11 @@ const level = { // spawn.laserBombingBoss(1900, -500) // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) - // spawn.grenadier(1900, -500) + spawn.slasher(1900, -500) // spawn.sneaker(1900, -500, 200) // spawn.shield(mob[mob.length - 1], 1900, -500, 1); // mob[mob.length - 1].isShielded = true - // spawn.historyBoss(1200, -500) + // spawn.growBossCulture(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.focuser(1600, -500) // spawn.laserTargetingBoss(1700, -120) @@ -2313,7 +2313,7 @@ const level = { // spawn.laserBombingBoss(1600, -500) // spawn.laserTargetingBoss(1600, -500) // spawn.laserBoss(1600, -500) - spawn.cellBossCulture(1600, -500) + // spawn.cellBossCulture(1600, -500) // spawn.nodeGroup(1200, -500, "grenadier") // spawn.nodeGroup(1800, -500, "grenadier") // spawn.nodeGroup(1200, 0, "grenadier") @@ -4420,7 +4420,7 @@ const level = { spawn.randomSmallMob(-900, 825); if (simulation.difficulty > 1) { - if (Math.random() < 0.33) { + if (Math.random() < 0.70) { spawn.randomLevelBoss(-800, -1300) } else { spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head diff --git a/js/mob.js b/js/mob.js index 0c63e09..ace5981 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1264,7 +1264,7 @@ const mobs = { //if there are too many bodies don't turn into blocks to help performance if (this.leaveBody && body.length < 40 && this.mass < 200 && this.radius > 18) { let v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure - if (v.length > 5 && body.length < 35 && Math.random() < 0.5) { + if (v.length > 5 && body.length < 35 && Math.random() < 0.25) { const cutPoint = 3 + Math.floor((v.length - 6) * Math.random()) //Math.floor(v.length / 2) const v2 = v.slice(0, cutPoint + 1) v = v.slice(cutPoint - 1) diff --git a/js/player.js b/js/player.js index c0977c2..7333ab4 100644 --- a/js/player.js +++ b/js/player.js @@ -1121,12 +1121,12 @@ const m = { m.fieldCDcycle = m.cycle + 15; m.isHolding = false; - if (tech.isTokamak && m.throwCharge > 5) { //remove the block body and pulse in the direction you are facing + if (tech.isTokamak && m.throwCharge > 3) { //remove the block body and pulse in the direction you are facing //m.throwCharge > 5 seems to be when the field full colors in a block you are holding - m.throwCharge = 0; m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds + if (m.immuneCycle < m.cycle) m.energy += 0.25 * Math.sqrt(m.holdingTarget.mass) * Math.min(5, m.throwCharge) + m.throwCharge = 0; m.definePlayerMass() //return to normal player mass - if (m.immuneCycle < m.cycle) m.energy += 2.5 * Math.sqrt(m.holdingTarget.mass) //remove block before pulse, so it doesn't get in the way for (let i = 0; i < body.length; i++) { if (body[i] === m.holdingTarget) { @@ -1134,7 +1134,7 @@ const m = { body.splice(i, 1); } } - b.pulse(50 * Math.pow(m.holdingTarget.mass, 0.25), m.angle) + b.pulse(60 * Math.pow(m.holdingTarget.mass, 0.25), m.angle) } else { //normal throw //bullet-like collisions m.holdingTarget.collisionFilter.category = cat.bullet @@ -2027,7 +2027,8 @@ const m = { }, { name: "time dilation", - description: "use energy to stop time
while time is stopped you can move and fire
and collisions do 50% less harm", + // description: "use energy to stop time
while time is stopped you can move and fire
and collisions do 50% less harm", + description: "use energy to stop time
move and fire while time is stopped
but, collisions still do harm", effect: () => { // m.fieldMeterColor = "#000" m.fieldFire = true; diff --git a/js/powerup.js b/js/powerup.js index 40887f0..1b2ff89 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -463,54 +463,56 @@ const powerUps = { return 17; }, effect() { - if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { //give extra ammo to one gun only with tech logistics - const target = b.guns[b.activeGun] - if (target.ammo !== Infinity) { - if (tech.ammoCap) { - const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap) //0.7 is average - target.ammo = ammoAdded - simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) - } else { - const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack) - target.ammo += ammoAdded - simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) - } - } - } else { //give ammo to all guns in inventory - let textLog = "" - for (let i = 0, len = b.inventory.length; i < len; i++) { - const target = b.guns[b.inventory[i]] + if (b.inventory.length > 0) { + if (tech.isAmmoForGun && b.activeGun) { //give extra ammo to one gun only with tech logistics + const target = b.guns[b.activeGun] if (target.ammo !== Infinity) { if (tech.ammoCap) { - const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average + const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap) //0.7 is average target.ammo = ammoAdded - textLog += `${target.name}.ammo = ${ammoAdded}
` + simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) } else { - const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) + const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack) target.ammo += ammoAdded - textLog += `${target.name}.ammo += ${ammoAdded}
` + simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } } + } else { //give ammo to all guns in inventory + let textLog = "" + for (let i = 0, len = b.inventory.length; i < len; i++) { + const target = b.guns[b.inventory[i]] + if (target.ammo !== Infinity) { + if (tech.ammoCap) { + const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average + target.ammo = ammoAdded + textLog += `${target.name}.ammo = ${ammoAdded}
` + } else { + const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) + target.ammo += ammoAdded + textLog += `${target.name}.ammo += ${ammoAdded}
` + } + } + } + simulation.makeTextLog(textLog) } - simulation.makeTextLog(textLog) + // } else { //give ammo to all guns in inventory + // for (let i = 0, len = b.inventory.length; i < len; i++) { + // const target = b.guns[b.inventory[i]] + // if (target.ammo !== Infinity) { + // if (tech.ammoCap) { + // const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average + // target.ammo = ammoAdded + // simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) + // } else { + // const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) + // target.ammo += ammoAdded + // simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + // } + // } + // } + // } + simulation.updateGunHUD(); } - // } else { //give ammo to all guns in inventory - // for (let i = 0, len = b.inventory.length; i < len; i++) { - // const target = b.guns[b.inventory[i]] - // if (target.ammo !== Infinity) { - // if (tech.ammoCap) { - // const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average - // target.ammo = ammoAdded - // simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) - // } else { - // const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) - // target.ammo += ammoAdded - // simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) - // } - // } - // } - // } - simulation.updateGunHUD(); } }, field: { diff --git a/js/simulation.js b/js/simulation.js index 0679ecd..9b3269d 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -261,7 +261,7 @@ const simulation = { const bolts = [] colors = [powerUps.research.color, powerUps.ammo.color, powerUps.heal.color, powerUps.tech.color, powerUps.field.color, powerUps.gun.color] for (let i = 0; i < boltNum; ++i) { - const mag = 4 + 20 * Math.random() + const mag = 6 + 20 * Math.random() const angle = 2 * Math.PI * Math.random() bolts.push({ x: m.pos.x, diff --git a/js/spawn.js b/js/spawn.js index 3b53316..74bce3b 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -8,6 +8,7 @@ const spawn = { pickList: ["starter", "starter"], fullPickList: [ "hopper", "hopper", "hopper", + "slasher", "slasher", "shooter", "shooter", "grenadier", "grenadier", "striker", "striker", @@ -27,7 +28,7 @@ const spawn = { "spawner", "ghoster", ], - allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper", "pulsar", "grenadier"], + allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper", "pulsar", "grenadier", "slasher"], setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level //each level has 2 mobs: one new mob and one from the last level spawn.pickList.splice(0, 1); @@ -1079,7 +1080,7 @@ const spawn = { me.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)" me.buffCount = 0 - me.accelMag = 0.00006 //* simulation.accelScale; + me.accelMag = 0.00005 //* simulation.accelScale; me.setBuffed = function() { this.buffCount++ this.accelMag += 0.000035 //* Math.sqrt(simulation.accelScale) @@ -1104,10 +1105,11 @@ const spawn = { powerUps.spawnBossPowerUp(this.position.x, this.position.y) } else { this.leaveBody = false; - if (!count % 2) powerUps.spawnRandomPowerUp(this.position.x, this.position.y) // higher then normal chance to drop heals and ammo + this.isDropPowerUp = false; + powerUps.spawnRandomPowerUp(this.position.x, this.position.y) // manual power up spawn to avoid spawning too many tech with "symbiosis" } } - me.damageReduction = 0.22 + me.damageReduction = 0.18 me.do = function() { // this.armor(); this.alwaysSeePlayer(); @@ -2910,6 +2912,117 @@ const spawn = { } }; }, + slasher(x, y, radius = 36 + Math.ceil(Math.random() * 25)) { + mobs.spawn(x, y, 5, radius, "rgb(201,202,225)"); + let me = mob[mob.length - 1]; + Matter.Body.rotate(me, 2 * Math.PI * Math.random()); + me.accelMag = 0.00085 * simulation.accelScale; + me.torqueMagnitude = 0.00002 * me.inertia * (Math.random() > 0.5 ? -1 : 1); + me.frictionStatic = 0; + me.friction = 0; + me.frictionAir = 0.035; + me.delay = 120 * simulation.CDScale; + me.cd = 0; + me.swordRadius = 0; + me.swordRadiusMax = 350 + 5 * simulation.difficulty; + me.swordRadiusGrowRate = me.swordRadiusMax * (0.02 + 0.0008 * simulation.difficulty) + me.isSlashing = false; + me.swordDamage = 0.07 * simulation.dmgScale + const laserAngle = 3 * Math.PI / 5 + const seeDistance2 = 200000 + spawn.shield(me, x, y); + me.onDamage = function() {}; + me.do = function() { + this.checkStatus(); + this.seePlayerByHistory(15); + this.attraction(); + if (!m.isBodiesAsleep) this.sword() //does various things depending on what stage of the sword swing + }; + + me.swordWaiting = function() { + if ( + this.seePlayer.recall && + this.cd < simulation.cycle && + this.distanceToPlayer2() < seeDistance2 && + Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && + Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0 + ) { + this.sword = this.swordGrow + // Matter.Body.setVelocity(this, { x: 0, y: 0 }); + this.accelMag = 0 + } + } + me.sword = me.swordWaiting //base function that changes during different aspects of the sword swing + me.swordGrow = function() { + this.laserSword(this.vertices[1], this.angle + laserAngle); + this.swordRadius += this.swordRadiusGrowRate + if (this.swordRadius > this.swordRadiusMax) { + this.sword = this.swordSlash + this.spinCount = 0 + } + } + me.swordSlash = function() { + this.laserSword(this.vertices[1], this.angle + laserAngle); + this.torque += this.torqueMagnitude; + this.spinCount++ + if (this.spinCount > 60) { + this.sword = this.swordWaiting + this.swordRadius = 0 + this.accelMag = 0.001 * simulation.accelScale; + this.cd = simulation.cycle + this.delay; + } + } + me.laserSword = function(where, angle) { + const vertexCollision = function(v1, v1End, domain) { + for (let i = 0; i < domain.length; ++i) { + let vertices = domain[i].vertices; + const len = vertices.length - 1; + for (let j = 0; j < len; j++) { + results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: vertices[j], v2: vertices[j + 1] }; + } + } + results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: vertices[0], v2: vertices[len] }; + } + } + }; + best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null }; + const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) }; + vertexCollision(where, look, body); // vertexCollision(where, look, mob); + vertexCollision(where, look, map); + if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); + if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { + m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to damage for an extra second + m.damage(this.swordDamage); + simulation.drawList.push({ //add dmg to draw queue + x: best.x, + y: best.y, + radius: this.swordDamage * 1500, + color: "rgba(80,0,255,0.5)", + time: 20 + }); + } + if (best.dist2 === Infinity) best = look; + ctx.beginPath(); //draw beam + ctx.moveTo(where.x, where.y); + ctx.lineTo(best.x, best.y); + ctx.strokeStyle = "rgba(100,100,255,0.1)"; // Purple path + ctx.lineWidth = 15; + ctx.stroke(); + ctx.strokeStyle = "rgba(100,100,255,0.5)"; // Purple path + ctx.lineWidth = 4; + ctx.stroke(); + } + }, sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 10)) { mobs.spawn(x, y, 5, radius, "transparent"); let me = mob[mob.length - 1]; @@ -2961,11 +3074,11 @@ const spawn = { } }; }, - ghoster(x, y, radius = 40 + Math.ceil(Math.random() * 100)) { + ghoster(x, y, radius = 50 + Math.ceil(Math.random() * 90)) { mobs.spawn(x, y, 7, radius, "transparent"); let me = mob[mob.length - 1]; me.seeAtDistance2 = 300000; - me.accelMag = 0.00012 * simulation.accelScale; + me.accelMag = 0.00013 * simulation.accelScale; if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search // Matter.Body.setDensity(me, 0.001); //normal is 0.001 //makes effective life much lower me.stroke = "transparent"; //used for drawGhost @@ -2989,10 +3102,10 @@ const spawn = { this.search(); //draw if (!m.isBodiesAsleep) { - if (this.distanceToPlayer2() - this.seeAtDistance2 < 0) { - if (this.alpha < 1) this.alpha += 0.002 * simulation.CDScale; + if (this.distanceToPlayer2() < this.seeAtDistance2) { + if (this.alpha < 1) this.alpha += 0.003 * simulation.CDScale; //near player go solid } else { - if (this.alpha > 0) this.alpha -= 0.03; + if (this.alpha > 0) this.alpha -= 0.03; ///away from player, hide } } if (this.alpha > 0) { @@ -4146,6 +4259,7 @@ const spawn = { me.accelMag = 0.0004 * simulation.accelScale; me.leaveBody = false; me.showHealthBar = false; + me.isDropPowerUp = false; // Matter.Body.setDensity(me, 0.00004); //normal is 0.001 me.frictionAir = 0.02; me.isSnakeTail = true; diff --git a/js/tech.js b/js/tech.js index 0358128..2e54e1b 100644 --- a/js/tech.js +++ b/js/tech.js @@ -443,7 +443,7 @@ }, { name: "cache", - description: `${powerUps.orb.ammo()} give 11x more ammo, but
you can't store any more ammo than that`, + description: `${powerUps.orb.ammo()} give 13x more ammo, but
you can't store any more ammo than that`, maxCount: 1, count: 0, frequency: 1, @@ -453,7 +453,7 @@ }, requires: "not exciton-lattice", effect() { - tech.ammoCap = 11; + tech.ammoCap = 13; powerUps.ammo.effect() }, remove() { @@ -4932,7 +4932,7 @@ }, { name: "aerogel", - description: "foam bubbles float and dissipate 50% faster
increase foam damage per second by 260%", + description: "foam bubbles float and dissipate 50% faster
increase foam damage per second by 200%", isGunTech: true, maxCount: 1, count: 0, @@ -5044,7 +5044,7 @@ }, remove() { tech.isHarpoonPowerUp = false - tech.harpoonDensity = 0.006 + tech.harpoonDensity = 0.008 } }, { @@ -5876,6 +5876,25 @@ // tech.isPlasmaRange = 1; // } // }, + { + name: "tokamak", + description: "throwing a block converts it into energy
and a pulsed fusion explosion", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" + }, + requires: "plasma torch", + effect() { + tech.isTokamak = true; + }, + remove() { + tech.isTokamak = false; + } + }, { name: "plasma-bot", description: "remove your field to build a bot
that uses energy to emit plasma", @@ -5936,25 +5955,6 @@ if (this.count > 0) powerUps.research.changeRerolls(this.count) } }, - { - name: "tokamak", - description: "throwing a block converts it into energy
and a pulsed fusion explosion", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "plasma torch" - }, - requires: "plasma torch", - effect() { - tech.isTokamak = true; - }, - remove() { - tech.isTokamak = false; - } - }, { name: "micro-extruder", description: "plasma torch extrudes a thin hot wire
increases damage, energy drain, and lag", @@ -6074,7 +6074,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking") + return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" }, requires: "metamaterial cloaking", effect() { @@ -6221,7 +6221,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" + return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" }, requires: "metamaterial cloaking or pilot wave", effect() { diff --git a/todo.txt b/todo.txt index e7eeb9b..471d34b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,14 +1,30 @@ ******************************************************** NEXT PATCH ************************************************** -blackhole mobs can no longer see past stealth -adding dup chance has graphics now +new mob: slasher - it's basically a jedi + +harpoon: +33% damage, +33% delay after firing +time dilation reverted 50% -> 0% collision harm reduction +time dilation can no longer get tech: symbiosis +nano-scale: can access tokamak and discrete optimization +cache: 11x -> 13x ammo bug fixes ******************************************************** TODO ******************************************************** -how to make only killing mobs more viable: - reduce damage from mobs that are asleep or unaware of the player when you touch them? +slasher compute fastest direction to rotate towards player + cross product + +death animation ideas: + redraw game in strange ways, to show that it's a simulation (for example the testing mode is a strange redraw of map) + stroke only, but connect all vertices together, no moveTo + draw dots at all the vertices + +be nice if block throwing had a projected path + +slasher mob: extends a thin radial line, then spins around and damages player if in circle around mob + do short length laser damage + doesn't have to be a full spin JUNK tech: planetesimals game inside n-gon https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 @@ -63,10 +79,6 @@ Pilot wave tech Grouping blocks will merge them into a massive ball Size, density is determined by total mass -make another boss with a tail - but the tail is made of interesting mobs - stabbers maybe - suckers maybe make experiment and understand vibe more obvious mostly in early game or first time players @@ -76,8 +88,6 @@ 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 - mob: spawning seekers on death drones can combine with other drones to get bigger?