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
This commit is contained in:
landgreen
2021-10-03 07:08:22 -07:00
parent 62b9d974b4
commit 0d2c673aec
11 changed files with 272 additions and 104 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1118,7 +1118,7 @@ const b = {
turnRate: isReturn ? 0.1 : 0.03, //0.015 turnRate: isReturn ? 0.1 : 0.03, //0.015
drawStringControlMagnitude: 3000 + 5000 * Math.random(), drawStringControlMagnitude: 3000 + 5000 * Math.random(),
drawStringFlip: (Math.round(Math.random()) ? 1 : -1), 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", classType: "bullet",
endCycle: simulation.cycle + totalCycles * 2.5 + 15, endCycle: simulation.cycle + totalCycles * 2.5 + 15,
collisionFilter: { collisionFilter: {
@@ -1133,10 +1133,9 @@ const b = {
who.isShielded = false who.isShielded = false
requestAnimationFrame(() => { who.isShielded = true }); requestAnimationFrame(() => { who.isShielded = true });
} }
if (tech.fragments) b.targetedNail(this.vertices[2], tech.fragments * 3)
if (!who.isBadTarget) { if (!who.isBadTarget) {
if (tech.fragments) { if (isReturn) {
b.targetedNail(this.vertices[2], tech.fragments * 4)
} else if (isReturn) {
this.do = this.returnToPlayer this.do = this.returnToPlayer
} else { } else {
this.frictionAir = 0.01 this.frictionAir = 0.01
@@ -1166,7 +1165,7 @@ const b = {
this.caughtPowerUp.effect(); this.caughtPowerUp.effect();
Matter.Composite.remove(engine.world, this.caughtPowerUp); Matter.Composite.remove(engine.world, this.caughtPowerUp);
powerUp.splice(index, 1); 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 { } else {
this.dropCaughtPowerUp() this.dropCaughtPowerUp()
} }
@@ -1195,7 +1194,7 @@ const b = {
returnToPlayer() { returnToPlayer() {
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
this.endCycle = 0; 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 //recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), this.mass * (input.down ? 0.0001 : 0.0002)) const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), this.mass * (input.down ? 0.0001 : 0.0002))
player.force.x += momentum.x player.force.x += momentum.x
@@ -1364,6 +1363,48 @@ const b = {
this.force.y += this.mass * 0.001; //gravity 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 Composite.add(engine.world, bullet[me]); //add bullet to world
}, },
missile(where, angle, speed, size = 1) { missile(where, angle, speed, size = 1) {
@@ -2794,7 +2835,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.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), scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -5102,7 +5143,7 @@ const b = {
} }
} }
b.harpoon(where, closest.target, m.angle, length, false, 15) 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) { } else if (tech.extraHarpoons) {
const range = 450 * (tech.isFilament ? 1 + Math.min(100, this.ammo) / 100 : 1) const range = 450 * (tech.isFilament ? 1 + Math.min(100, this.ammo) / 100 : 1)
let targetCount = 0 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) const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
player.force.x -= recoil.x player.force.x -= recoil.x
player.force.y -= recoil.y player.force.y -= recoil.y
tech.harpoonDensity = 0.005 tech.harpoonDensity = 0.008
} }
}, },
{ {

View File

@@ -107,7 +107,7 @@ function collisionChecks(event) {
!(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned)) !(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 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(); 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 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); m.damage(dmg);

View File

@@ -2300,11 +2300,11 @@ const level = {
// spawn.laserBombingBoss(1900, -500) // spawn.laserBombingBoss(1900, -500)
// for (let i = 0; i < 5; i++) spawn.focuser(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.sneaker(1900, -500, 200)
// spawn.shield(mob[mob.length - 1], 1900, -500, 1); // spawn.shield(mob[mob.length - 1], 1900, -500, 1);
// mob[mob.length - 1].isShielded = true // mob[mob.length - 1].isShielded = true
// spawn.historyBoss(1200, -500) // spawn.growBossCulture(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.focuser(1600, -500) // spawn.focuser(1600, -500)
// spawn.laserTargetingBoss(1700, -120) // spawn.laserTargetingBoss(1700, -120)
@@ -2313,7 +2313,7 @@ const level = {
// spawn.laserBombingBoss(1600, -500) // spawn.laserBombingBoss(1600, -500)
// spawn.laserTargetingBoss(1600, -500) // spawn.laserTargetingBoss(1600, -500)
// spawn.laserBoss(1600, -500) // spawn.laserBoss(1600, -500)
spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
// spawn.nodeGroup(1200, -500, "grenadier") // spawn.nodeGroup(1200, -500, "grenadier")
// spawn.nodeGroup(1800, -500, "grenadier") // spawn.nodeGroup(1800, -500, "grenadier")
// spawn.nodeGroup(1200, 0, "grenadier") // spawn.nodeGroup(1200, 0, "grenadier")
@@ -4420,7 +4420,7 @@ const level = {
spawn.randomSmallMob(-900, 825); spawn.randomSmallMob(-900, 825);
if (simulation.difficulty > 1) { if (simulation.difficulty > 1) {
if (Math.random() < 0.33) { if (Math.random() < 0.70) {
spawn.randomLevelBoss(-800, -1300) spawn.randomLevelBoss(-800, -1300)
} else { } else {
spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head

View File

@@ -1264,7 +1264,7 @@ const mobs = {
//if there are too many bodies don't turn into blocks to help performance //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) { 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 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 cutPoint = 3 + Math.floor((v.length - 6) * Math.random()) //Math.floor(v.length / 2)
const v2 = v.slice(0, cutPoint + 1) const v2 = v.slice(0, cutPoint + 1)
v = v.slice(cutPoint - 1) v = v.slice(cutPoint - 1)

View File

@@ -1121,12 +1121,12 @@ const m = {
m.fieldCDcycle = m.cycle + 15; m.fieldCDcycle = m.cycle + 15;
m.isHolding = false; 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 > 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 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 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 //remove block before pulse, so it doesn't get in the way
for (let i = 0; i < body.length; i++) { for (let i = 0; i < body.length; i++) {
if (body[i] === m.holdingTarget) { if (body[i] === m.holdingTarget) {
@@ -1134,7 +1134,7 @@ const m = {
body.splice(i, 1); 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 } else { //normal throw
//bullet-like collisions //bullet-like collisions
m.holdingTarget.collisionFilter.category = cat.bullet m.holdingTarget.collisionFilter.category = cat.bullet
@@ -2027,7 +2027,8 @@ const m = {
}, },
{ {
name: "time dilation", name: "time dilation",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>", // description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><strong>move</strong> and <strong>fire</strong> while time is stopped<br>but, <strong>collisions</strong> still do <strong class='color-harm'>harm</strong>",
effect: () => { effect: () => {
// m.fieldMeterColor = "#000" // m.fieldMeterColor = "#000"
m.fieldFire = true; m.fieldFire = true;

View File

@@ -463,7 +463,8 @@ const powerUps = {
return 17; return 17;
}, },
effect() { effect() {
if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { //give extra ammo to one gun only with tech logistics 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] const target = b.guns[b.activeGun]
if (target.ammo !== Infinity) { if (target.ammo !== Infinity) {
if (tech.ammoCap) { if (tech.ammoCap) {
@@ -512,6 +513,7 @@ const powerUps = {
// } // }
simulation.updateGunHUD(); simulation.updateGunHUD();
} }
}
}, },
field: { field: {
name: "field", name: "field",

View File

@@ -261,7 +261,7 @@ const simulation = {
const bolts = [] const bolts = []
colors = [powerUps.research.color, powerUps.ammo.color, powerUps.heal.color, powerUps.tech.color, powerUps.field.color, powerUps.gun.color] 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) { 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() const angle = 2 * Math.PI * Math.random()
bolts.push({ bolts.push({
x: m.pos.x, x: m.pos.x,

View File

@@ -8,6 +8,7 @@ const spawn = {
pickList: ["starter", "starter"], pickList: ["starter", "starter"],
fullPickList: [ fullPickList: [
"hopper", "hopper", "hopper", "hopper", "hopper", "hopper",
"slasher", "slasher",
"shooter", "shooter", "shooter", "shooter",
"grenadier", "grenadier", "grenadier", "grenadier",
"striker", "striker", "striker", "striker",
@@ -27,7 +28,7 @@ const spawn = {
"spawner", "spawner",
"ghoster", "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 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 //each level has 2 mobs: one new mob and one from the last level
spawn.pickList.splice(0, 1); 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.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)"
me.buffCount = 0 me.buffCount = 0
me.accelMag = 0.00006 //* simulation.accelScale; me.accelMag = 0.00005 //* simulation.accelScale;
me.setBuffed = function() { me.setBuffed = function() {
this.buffCount++ this.buffCount++
this.accelMag += 0.000035 //* Math.sqrt(simulation.accelScale) this.accelMag += 0.000035 //* Math.sqrt(simulation.accelScale)
@@ -1104,10 +1105,11 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
} else { } else {
this.leaveBody = false; 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() { me.do = function() {
// this.armor(); // this.armor();
this.alwaysSeePlayer(); 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)) { sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 10)) {
mobs.spawn(x, y, 5, radius, "transparent"); mobs.spawn(x, y, 5, radius, "transparent");
let me = mob[mob.length - 1]; 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"); mobs.spawn(x, y, 7, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.seeAtDistance2 = 300000; 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 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 // Matter.Body.setDensity(me, 0.001); //normal is 0.001 //makes effective life much lower
me.stroke = "transparent"; //used for drawGhost me.stroke = "transparent"; //used for drawGhost
@@ -2989,10 +3102,10 @@ const spawn = {
this.search(); this.search();
//draw //draw
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
if (this.distanceToPlayer2() - this.seeAtDistance2 < 0) { if (this.distanceToPlayer2() < this.seeAtDistance2) {
if (this.alpha < 1) this.alpha += 0.002 * simulation.CDScale; if (this.alpha < 1) this.alpha += 0.003 * simulation.CDScale; //near player go solid
} else { } 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) { if (this.alpha > 0) {
@@ -4146,6 +4259,7 @@ const spawn = {
me.accelMag = 0.0004 * simulation.accelScale; me.accelMag = 0.0004 * simulation.accelScale;
me.leaveBody = false; me.leaveBody = false;
me.showHealthBar = false; me.showHealthBar = false;
me.isDropPowerUp = false;
// Matter.Body.setDensity(me, 0.00004); //normal is 0.001 // Matter.Body.setDensity(me, 0.00004); //normal is 0.001
me.frictionAir = 0.02; me.frictionAir = 0.02;
me.isSnakeTail = true; me.isSnakeTail = true;

View File

@@ -443,7 +443,7 @@
}, },
{ {
name: "cache", name: "cache",
description: `${powerUps.orb.ammo()} give <strong>11x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`, description: `${powerUps.orb.ammo()} give <strong>13x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -453,7 +453,7 @@
}, },
requires: "not exciton-lattice", requires: "not exciton-lattice",
effect() { effect() {
tech.ammoCap = 11; tech.ammoCap = 13;
powerUps.ammo.effect() powerUps.ammo.effect()
}, },
remove() { remove() {
@@ -4932,7 +4932,7 @@
}, },
{ {
name: "aerogel", name: "aerogel",
description: "<strong>foam</strong> bubbles <strong>float</strong> and dissipate <strong>50%</strong> faster<br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>260%</strong>", description: "<strong>foam</strong> bubbles <strong>float</strong> and dissipate <strong>50%</strong> faster<br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>200%</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5044,7 +5044,7 @@
}, },
remove() { remove() {
tech.isHarpoonPowerUp = false tech.isHarpoonPowerUp = false
tech.harpoonDensity = 0.006 tech.harpoonDensity = 0.008
} }
}, },
{ {
@@ -5876,6 +5876,25 @@
// tech.isPlasmaRange = 1; // tech.isPlasmaRange = 1;
// } // }
// }, // },
{
name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>",
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", name: "plasma-bot",
description: "remove your <strong>field</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>", description: "remove your <strong>field</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>",
@@ -5936,25 +5955,6 @@
if (this.count > 0) powerUps.research.changeRerolls(this.count) if (this.count > 0) powerUps.research.changeRerolls(this.count)
} }
}, },
{
name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>",
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", name: "micro-extruder",
description: "<strong class='color-plasma'>plasma</strong> <strong>torch</strong> extrudes a thin <strong class='color-plasma'>hot</strong> wire<br>increases <strong class='color-d'>damage</strong>, <strong class='color-f'>energy</strong> drain, and <strong>lag</strong>", description: "<strong class='color-plasma'>plasma</strong> <strong>torch</strong> extrudes a thin <strong class='color-plasma'>hot</strong> wire<br>increases <strong class='color-d'>damage</strong>, <strong class='color-f'>energy</strong> drain, and <strong>lag</strong>",
@@ -6074,7 +6074,7 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { 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", requires: "metamaterial cloaking",
effect() { effect() {
@@ -6221,7 +6221,7 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { 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", requires: "metamaterial cloaking or pilot wave",
effect() { effect() {

View File

@@ -1,14 +1,30 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
blackhole mobs can no longer see past stealth new mob: slasher - it's basically a jedi
adding dup chance has graphics now
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 bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
how to make only killing mobs more viable: slasher compute fastest direction to rotate towards player
reduce damage from mobs that are asleep or unaware of the player when you touch them? 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 JUNK tech: planetesimals game inside n-gon
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010
@@ -63,10 +79,6 @@ Pilot wave tech
Grouping blocks will merge them into a massive ball Grouping blocks will merge them into a massive ball
Size, density is determined by total mass 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 make experiment and understand vibe more obvious
mostly in early game or first time players 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 aoe effect pushes mobs away, then rapidly pulls them in
for mines? for mines?
tech: shrapnel - nails have an larger randomized 3 point shape triangle shape and they do more damage
mob: spawning seekers on death mob: spawning seekers on death
drones can combine with other drones to get bigger? drones can combine with other drones to get bigger?