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:
59
js/bullet.js
59
js/bullet.js
@@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
11
js/player.js
11
js/player.js
@@ -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;
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
132
js/spawn.js
132
js/spawn.js
@@ -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;
|
||||||
|
|||||||
50
js/tech.js
50
js/tech.js
@@ -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() {
|
||||||
|
|||||||
30
todo.txt
30
todo.txt
@@ -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?
|
||||||
|
|||||||
Reference in New Issue
Block a user