diff --git a/js/bullet.js b/js/bullet.js
index cceb11c..ce339fb 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -198,7 +198,7 @@ const b = {
}
if (gunTechPool.length) {
const index = Math.floor(Math.random() * gunTechPool.length)
- simulation.makeTextLog(`tech.giveTech("${tech.tech[gunTechPool[index]].name}")`)
+ simulation.makeTextLog(`tech.giveTech("${tech.tech[gunTechPool[index]].name}")`)
tech.giveTech(gunTechPool[index]) // choose from the gun pool
} else {
tech.giveTech() //get normal tech if you can't find any gun tech
@@ -370,7 +370,7 @@ const b = {
}
},
explosionRange() {
- return tech.explosiveRadius * (tech.isExplosionHarm ? 1.7 : 1) * (tech.isSmallExplosion ? 0.66 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
+ return tech.explosiveRadius * (tech.isExplosionHarm ? 1.7 : 1) * (tech.isSmallExplosion ? 0.7 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
},
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius
@@ -380,8 +380,8 @@ const b = {
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) {
// color = "rgba(255,0,30,0.7)"
- radius *= 0.66
- dmg *= 1.66
+ radius *= 0.7
+ dmg *= 1.7
}
if (tech.isExplodeRadio) { //radiation explosion
@@ -2374,22 +2374,8 @@ const b = {
}, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) {
const reflectivity = 1 - 1 / (reflections * 3)
let damage = m.dmgScale * dmg
-
- let best = {
- x: 1,
- y: 1,
- dist2: Infinity,
- who: null,
- v1: 1,
- v2: 1
- };
- const path = [{
- x: where.x,
- y: where.y
- }, {
- x: whereEnd.x,
- y: whereEnd.y
- }];
+ let best = { x: 1, y: 1, dist2: Infinity, who: null, v1: 1, v2: 1 };
+ const path = [{ x: where.x, y: where.y }, { x: whereEnd.x, y: whereEnd.y }];
const checkForCollisions = function () {
best = vertexCollision(path[path.length - 2], path[path.length - 1], [mob, map, body]);
@@ -4760,7 +4746,6 @@ const b = {
}
},
dynamoBot(position = player.position, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.dynamoBot()`);
const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 5, 10, {
isUpgraded: tech.isDynamoBotUpgrade,
@@ -4862,7 +4847,6 @@ const b = {
b.setDynamoBotDelay()
},
nailBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.nailBot()`);
const me = bullet.length;
const dir = m.angle;
const RADIUS = (12 + 4 * Math.random())
@@ -4878,7 +4862,7 @@ const b = {
minDmgSpeed: 2,
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
lastLookCycle: simulation.cycle + 60 * Math.random(),
- delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85)),
+ delay: Math.floor((tech.isNailBotUpgrade ? 22 : 85)),
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100,
endCycle: Infinity,
@@ -4927,7 +4911,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
missileBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.missileBot()`);
const me = bullet.length;
bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, {
botType: "missile",
@@ -4998,7 +4981,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
foamBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.foamBot()`);
const me = bullet.length;
const dir = m.angle;
const RADIUS = (10 + 5 * Math.random())
@@ -5016,7 +4998,7 @@ const b = {
cd: 0,
fireCount: 0,
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
- delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
+ delay: Math.floor((200 + (tech.isFoamBotUpgrade ? 0 : 200))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
endCycle: Infinity,
@@ -5038,7 +5020,7 @@ const b = {
const radius = 5 + 3 * Math.random()
const SPEED = Math.max(5, 25 - radius * 0.4); //(m.crouch ? 32 : 20) - radius * 0.7;
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.fireTarget, this.position)), SPEED)
- b.foam(this.position, Vector.rotate(velocity, 0.07 * (Math.random() - 0.5)), radius + 6 * this.isUpgraded)
+ b.foam(this.position, Vector.rotate(velocity, 0.07 * (Math.random() - 0.5)), radius + 5 * this.isUpgraded)
//recoil
// const force = Vector.mult(Vector.normalise(velocity), 0.005 * this.mass * (tech.isFoamCavitation ? 2 : 1))
@@ -5068,58 +5050,11 @@ const b = {
} else { //fire mode: quickly fire at targets and doesn't follow player
this.fire()
}
-
-
-
-
-
-
-
-
-
- // const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, m.pos))
- // if (distanceToPlayer > this.range) { //if far away move towards player
- // this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.acceleration)
- // } else { //close to player
- // Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity
-
- // //&& !(simulation.cycle % this.lookFrequency)
- // if (this.cd < simulation.cycle && !m.isCloak) {
- // let target
- // for (let i = 0, len = mob.length; i < len; i++) {
- // const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
- // if (dist2 < 2000000 && !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
-
- // this.fireCount++
- // if (this.fireCount > 5) {
- // this.fireCount = 0
- // this.cd = simulation.cycle + this.delay;
- // } else {
- // // this.cd = simulation.cycle + 1;
- // }
-
- // target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist2) / 60))
- // const radius = 6 + 7 * Math.random()
- // const SPEED = Math.max(5, 25 - radius * 0.4); //(m.crouch ? 32 : 20) - radius * 0.7;
- // const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED)
- // b.foam(this.position, velocity, radius + 7.5 * this.isUpgraded)
-
- // //recoil
- // // const force = Vector.mult(Vector.normalise(velocity), 0.005 * this.mass * (tech.isFoamCavitation ? 2 : 1))
- // const force = Vector.mult(velocity, 0.0003 * this.mass * (tech.isFoamCavitation ? 2 : 1))
- // this.force.x -= force.x
- // this.force.y -= force.y
- // break;
- // }
- // }
- // }
- // }
}
})
Composite.add(engine.world, bullet[me]); //add bullet to world
},
soundBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.soundBot()`);
const me = bullet.length;
const dir = m.angle;
bullet[me] = Bodies.rectangle(position.x, position.y, 12, 30, {
@@ -5132,11 +5067,11 @@ const b = {
restitution: 0.6 * (1 + 0.5 * Math.random()),
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
- lookFrequency: 17 + Math.floor(7 * Math.random()) - 5 * tech.isSoundBotUpgrade,
+ lookFrequency: 17 + Math.floor(7 * Math.random()) - 3 * tech.isSoundBotUpgrade,
cd: 0,
fireCount: 0,
- fireLimit: 5 + 2 * tech.isSoundBotUpgrade,
- delay: Math.floor((120 + (tech.isSoundBotUpgrade ? 0 : 70))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
+ fireLimit: 5 + 3 * tech.isSoundBotUpgrade,
+ delay: Math.floor((140 + (tech.isSoundBotUpgrade ? 0 : 50))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
endCycle: Infinity,
@@ -5151,7 +5086,7 @@ const b = {
waves: [],
phononWaveCD: 0,
addWave(where, angle) {
- const halfArc = 0.2 * (tech.isBulletTeleport ? 0.66 + (Math.random() - 0.5) : 1) + 0.05 * tech.isSoundBotUpgrade //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
+ const halfArc = 0.2 * (tech.isBulletTeleport ? 0.66 + (Math.random() - 0.5) : 1) + 0.04 * tech.isSoundBotUpgrade //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
this.waves.push({
position: where,
angle: angle - halfArc, //used in drawing ctx.arc
@@ -5160,7 +5095,7 @@ const b = {
arc: halfArc * 2,
radius: 25,
resonanceCount: 0,
- dmg: (tech.isUpgraded ? 4 : 1.5) * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.5 : 1),
+ dmg: (tech.isUpgraded ? 3.5 : 1.5) * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.5 : 1),
})
},
fire() {
@@ -5285,7 +5220,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
laserBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.laserBot()`);
const me = bullet.length;
const dir = m.angle;
const RADIUS = (14 + 6 * Math.random())
@@ -5468,7 +5402,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
boomBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.boomBot()`);
const me = bullet.length;
const dir = m.angle;
const RADIUS = (7 + 2 * Math.random())
@@ -5484,8 +5417,8 @@ const b = {
minDmgSpeed: 0,
lookFrequency: 43 + Math.floor(7 * Math.random()) - 13 * tech.isBoomBotUpgrade,
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
- attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade,
- range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade + !isKeep * 100,
+ attackAcceleration: 0.012 + 0.005 * tech.isBoomBotUpgrade,
+ range: 500 * (1 + 0.1 * Math.random()) + 250 * tech.isBoomBotUpgrade + !isKeep * 100,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
@@ -5556,7 +5489,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
plasmaBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.plasmaBot()`);
const me = bullet.length;
const dir = m.angle;
const RADIUS = 21
@@ -5694,7 +5626,6 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
},
orbitBot(position = player.position, isKeep = true) {
- // if (isKeep) simulation.makeTextLog(`b.orbitBot()`);
const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 9, 12, {
isUpgraded: tech.isOrbitBotUpgrade,
@@ -5729,7 +5660,7 @@ const b = {
}
}
},
- range: 190 + 130 * tech.isOrbitBotUpgrade + !isKeep * 60 * (0.5 - Math.random()), //range is set in bot upgrade too!
+ range: 190 + 170 * tech.isOrbitBotUpgrade + !isKeep * 60 * (0.5 - Math.random()), //range is set in bot upgrade too!
orbitalSpeed: 0,
phase: 2 * Math.PI * Math.random(),
do() {
@@ -6125,7 +6056,7 @@ const b = {
name: "shotgun", //1
// description: `fire a wide burst of short range bullets
with a low fire rate
3-4 nails per ${powerUps.orb.ammo()}`,
descriptionFunction() {
- return `fire a wide burst of short range bullets
has a slow fire rate
${this.ammoPack.toFixed(1)} shots per ${powerUps.orb.ammo()}`
+ return `fire a wide burst of short range pellets
has a slow fire rate
${this.ammoPack.toFixed(1)} shots per ${powerUps.orb.ammo()}`
},
ammo: 0,
ammoPack: 1.6,
@@ -6414,9 +6345,8 @@ const b = {
}
}, {
name: "super balls", //2
- // description: `fire 3 balls in a wide arc
balls bounce with no momentum loss
9 balls per ${powerUps.orb.ammo()}`,
descriptionFunction() {
- return `fire 3 balls in a wide arc
balls bounce with no momentum loss
${this.ammoPack.toFixed(0)} balls per ${powerUps.orb.ammo()}`
+ return `fire 3 balls that retain
momentum and kinetic energy after collisions
${this.ammoPack.toFixed(0)} balls per ${powerUps.orb.ammo()}`
},
ammo: 0,
ammoPack: 4.05,
@@ -6974,7 +6904,7 @@ const b = {
name: "grenades", //5
// description: `lob a single bouncy projectile
explodes on contact or after one second
7 grenades per ${powerUps.orb.ammo()}`,
descriptionFunction() {
- return `lob a single bouncy projectile
explodes on contact or after one second
${this.ammoPack.toFixed(0)} grenades per ${powerUps.orb.ammo()}`
+ return `lob a single bouncy projectile
explodes on contact or after 1.5 seconds
${this.ammoPack.toFixed(0)} grenades per ${powerUps.orb.ammo()}`
},
ammo: 0,
ammoPack: 3.2,
@@ -7357,7 +7287,7 @@ const b = {
name: "harpoon", //9
// description: `throw a self-steering harpoon that uses energy
to retract and refund its ammo cost
1-2 harpoons per ${powerUps.orb.ammo()}`,
descriptionFunction() {
- return `throw a self-steering harpoon that uses energy
to retract and refund its ammo cost
${this.ammoPack.toFixed(1)} harpoons per ${powerUps.orb.ammo()}`
+ return `throw a harpoon that uses energy to retract
harpoons refund ammo
${this.ammoPack.toFixed(1)} harpoons per ${powerUps.orb.ammo()}`
},
ammo: 0,
ammoPack: 0.77, //update this in railgun tech
@@ -7767,7 +7697,7 @@ const b = {
{
name: "laser", //11
descriptionFunction() {
- return `emit a beam of collimated coherent light
costs ${(tech.laserDrain * 6000).toFixed(1)} energy per second
doesn't use ammo`
+ return `emit a beam of collimated coherent light
reflects off map, blocks, and mobs ${(tech.isWideLaser || tech.isPulseLaser) ? 0 : tech.laserReflections} times
costs ${(tech.laserDrain * 6000).toFixed(1)} energy per second and 0 ammo`
},
ammo: 0,
ammoPack: Infinity,
@@ -7902,79 +7832,6 @@ const b = {
}
// this.fire = this.firePhoton
},
- // fireLaser() {
- // // console.log('hi')
- // const drain = tech.laserDrain / b.fireCDscale
- // if (m.energy < drain) {
- // m.fireCDcycle = m.cycle + 100; // cool down if out of energy
- // } else {
- // m.fireCDcycle = m.cycle
- // m.energy -= drain
- // const range = {
- // x: 5000 * Math.cos(m.angle),
- // y: 5000 * Math.sin(m.angle)
- // }
- // const laserSeparation = 3
- // const rangeOffPlus = {
- // x: laserSeparation * Math.cos(m.angle + Math.PI / 2),
- // y: laserSeparation * Math.sin(m.angle + Math.PI / 2)
- // }
- // const rangeOffMinus = {
- // x: laserSeparation * Math.cos(m.angle - Math.PI / 2),
- // y: laserSeparation * Math.sin(m.angle - Math.PI / 2)
- // }
- // const dmg = 0.70 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage
- // const where = {
- // x: m.pos.x + 30 * Math.cos(m.angle),
- // y: m.pos.y + 30 * Math.sin(m.angle)
- // }
- // const eye = {
- // x: m.pos.x + 15 * Math.cos(m.angle),
- // y: m.pos.y + 15 * Math.sin(m.angle)
- // }
- // // ctx.strokeStyle = tech.laserColor;
- // // ctx.lineWidth = 8
- // // ctx.beginPath();
- // if (Matter.Query.ray(map, eye, where).length === 0 && Matter.Query.ray(body, eye, where).length === 0) {
- // b.laser(eye, {
- // x: eye.x + range.x,
- // y: eye.y + range.y
- // }, dmg)
- // }
- // for (let i = 1; i < 2; i++) {
- // let whereOff = Vector.add(where, {
- // x: i * rangeOffPlus.x,
- // y: i * rangeOffPlus.y
- // })
- // if (Matter.Query.ray(map, eye, whereOff).length === 0 && Matter.Query.ray(body, eye, whereOff).length === 0) {
- // ctx.moveTo(eye.x, eye.y)
- // ctx.lineTo(whereOff.x, whereOff.y)
- // b.laser(whereOff, {
- // x: whereOff.x + range.x,
- // y: whereOff.y + range.y
- // }, dmg)
- // }
- // whereOff = Vector.add(where, {
- // x: i * rangeOffMinus.x,
- // y: i * rangeOffMinus.y
- // })
- // if (Matter.Query.ray(map, eye, whereOff).length === 0 && Matter.Query.ray(body, eye, whereOff).length === 0) {
- // ctx.moveTo(eye.x, eye.y)
- // ctx.lineTo(whereOff.x, whereOff.y)
- // b.laser(whereOff, {
- // x: whereOff.x + range.x,
- // y: whereOff.y + range.y
- // }, dmg)
- // }
- // }
- // // ctx.stroke();
- // // if (tech.isLaserLens && b.guns[11].lensDamage !== 1) {
- // // ctx.lineWidth = 20 + 3 * b.guns[11].lensDamageOn
- // // ctx.globalAlpha = 0.3
- // // ctx.stroke();
- // // }
- // }
- // },
fireLaser() {
const drain = tech.laserDrain / b.fireCDscale
if (m.energy < drain) {
@@ -8004,10 +7861,7 @@ const b = {
// const scale = Math.pow(0.9, tech.beamSplitter)
// const pushScale = scale * scale
let dmg = tech.laserDamage / b.fireCDscale * this.lensDamage // * scale //Math.pow(0.9, tech.laserDamage)
- const where = {
- x: m.pos.x + 20 * Math.cos(m.angle),
- y: m.pos.y + 20 * Math.sin(m.angle)
- }
+ const where = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) }
const divergence = m.crouch ? 0.15 : 0.35
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) {
@@ -8098,8 +7952,8 @@ const b = {
} else {
m.fireCDcycle = m.cycle
m.energy -= drain
- const dmg = 0.5 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage
- const spacing = Math.ceil(10 - 0.4 * tech.historyLaser)
+ const dmg = tech.laserDamage / b.fireCDscale * this.lensDamage
+ const spacing = Math.ceil(23 - tech.historyLaser)
ctx.beginPath();
b.laser({
x: m.pos.x + 20 * Math.cos(m.angle),
@@ -8107,18 +7961,21 @@ const b = {
}, {
x: m.pos.x + 3000 * Math.cos(m.angle),
y: m.pos.y + 3000 * Math.sin(m.angle)
- }, dmg, 0, true, 0.2);
- for (let i = 1, len = 3 + tech.historyLaser * 3; i < len; i++) {
+ }, dmg);
+
+ for (let i = 1, len = 1 + tech.historyLaser; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
- const off = history.yOff - 24.2859
+ const off = history.yOff - 24.2859 + 2 * i
+ // ctx.globalAlpha = 0.13
b.laser({
x: history.position.x + 20 * Math.cos(history.angle),
y: history.position.y + 20 * Math.sin(history.angle) - off
}, {
x: history.position.x + 3000 * Math.cos(history.angle),
y: history.position.y + 3000 * Math.sin(history.angle) - off
- }, dmg, 0, true, 0.2);
+ }, 0.7 * dmg, tech.laserReflections, true);
}
+ // ctx.globalAlpha = 1
ctx.strokeStyle = tech.laserColor;
ctx.lineWidth = 1
ctx.stroke();
diff --git a/js/engine.js b/js/engine.js
index fb7c481..1090afb 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -117,7 +117,7 @@ function collisionChecks(event) {
if (tech.isCollisionRealitySwitch && m.alive) {
m.switchWorlds()
- simulation.trails()
+ simulation.trails(90)
simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
}
if (tech.isPiezo) m.energy += 20.48;
diff --git a/js/index.js b/js/index.js
index fa71cdc..8b3213d 100644
--- a/js/index.js
+++ b/js/index.js
@@ -464,12 +464,12 @@ const build = {
let text = `
`);
@@ -32583,6 +33718,386 @@ const level = {
let hardBody = body[body.length - 1];
hardBody.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.powerUp
},
+ flappyGon() { //community map by digin
+ level.announceMobTypes();
+ simulation.makeTextLog(`flappy n-gon by Digin`);
+ setTimeout(() => { simulation.makeTextLog("gravity is a choice"); }, 1000);
+ setTimeout(() => { simulation.makeTextLog("everyone will fly"); }, 2000);
+ setTimeout(() => { simulation.makeTextLog("jump from the post and find out"); }, 3000);
+ level.setPosToSpawn(0, -50); //normal spawn
+ level.exit.x = 8600;
+ level.exit.y = -1100;
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#55FF55";
+
+ var slimey = level.hazard(-200, -10, 9000, 10);
+
+ // allow "flight"
+
+ const old_playerOffGroundCheck = playerOffGroundCheck;
+
+ playerOffGroundCheck = (event) => {
+ old_playerOffGroundCheck(event);
+ if (player.position.y < -300) {
+ m.onGround = true;
+ }
+ };
+
+ const oldNextLevel = level.nextLevel;
+ level.nextLevel = () => { // clear the flappy effects, because apparently there's no established api for this
+ playerOffGroundCheck = old_playerOffGroundCheck;
+
+ level.nextLevel = oldNextLevel;
+ oldNextLevel();
+ };
+
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); // standard bumps
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
+ spawn.mapRect(level.exit.x - 100, level.exit.y + 40, 200, 100);
+
+ // room basis
+ spawn.mapRect(-200, 0, 9000, 100);
+ spawn.mapRect(-200, -1500, 9000, 100);
+ spawn.mapRect(-200, -1500, 100, 1500);
+ spawn.mapRect(8700, -1500, 100, 1500);
+
+ // somewhat randomized flappy pylons
+ const pylon = 1500; // height of the entire pylon assembly
+ for (var i = 0; i < 10; i++) {
+ var xbasis = 700 + i * 750;
+ var window = 300 + (10 - i) * 50;
+ var toph = pylon - window - 400 + (Math.random() - 0.5) * 400 - i * 50;
+ if (i == 0) { // on the first one, the lower pile will always have a height of 300
+ toph = pylon - window - 300;
+ }
+ spawn.mapRect(xbasis, -1500, 100, toph);
+ spawn.mapRect(xbasis, toph + window - pylon, 100, pylon - toph - window);
+ if (i < 9) {
+ spawn.randomMob(xbasis + 300, Math.random() * -1400);
+ }
+ else {
+ spawn.randomLevelBoss(xbasis + 300, Math.random() * -1400);
+ }
+ if (i == 5) {
+ spawn.secondaryBossChance(xbasis + 300, Math.random() * -1400);
+ }
+ }
+
+ level.custom = () => {
+ level.exit.drawAndCheck();
+ player.onGround = true;
+ level.enter.draw();
+ };
+ const slimeRise = 0.15;
+ level.customTopLayer = () => {
+ slimey.height += slimeRise;
+ slimey.min.y -= slimeRise;
+ slimey.query();
+ };
+ powerUps.addResearchToLevel();
+ },
+ rings() {
+ level.announceMobTypes();
+ simulation.makeTextLog(`rings by ThatLittleFrog`);
+ setTimeout(() => {
+ simulation.makeTextLog("go up");
+ }, 2000);
+ level.setPosToSpawn(0, -2000); // spawn high up so you can go to the bottom of the lowest ring without tripping the too-low reset
+ level.exit.x = 0;
+ level.exit.y = -6400;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#d8dadf";
+
+ function mkrect(x, y, w, h) {
+ let who = body[body.length] = Bodies.rectangle(x, y, w, h, {
+ collisionFilter: {
+ category: cat.map,
+ mask: cat.body | cat.player | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ },
+ inertia: Infinity, //prevents rotation
+ isNotHoldable: true,
+ friction: 1,
+ frictionStatic: 1,
+ restitution: 0,
+ frictionAir: 1,
+ isStatic: true
+ });
+ Composite.add(engine.world, who);
+ who.classType = "body";
+ return body[body.length - 1];
+ }
+
+ function makeRing(x, y, linegth, thicc = 200) { // I don't feel like doing trigonometry, so linegth is slightly different from the radius
+ var _shape = [undefined, undefined, undefined, undefined];
+ _shape[0] = mkrect(x - linegth / 2 - thicc, y - linegth / 2 - thicc, linegth, thicc);
+ _shape[1] = mkrect(x - linegth / 2 - thicc, y - linegth / 2, thicc, linegth);
+ _shape[2] = mkrect(x - linegth / 2, y + linegth / 2 - thicc, linegth, thicc);
+ _shape[3] = mkrect(x + linegth / 2 - thicc, y - linegth / 2 - thicc, thicc, linegth - thicc * 2);
+ let ret = {
+ shape: _shape,
+ x: x,
+ y: y,
+ r: 0,
+ rot(ang) {
+ this.r = ang;
+ let offs = 0;
+ for (let shape of this.shape) {
+ offs += Math.PI / 2;
+ Matter.Body.setAngle(shape, ang);
+ if (shape == this.shape[3]) {
+ Matter.Body.setPosition(shape, {
+ x: this.x + Math.cos(ang + offs) * (linegth / 2 - thicc / 2) - Math.cos(ang + offs + Math.PI / 2) * thicc,
+ y: this.y + Math.sin(ang + offs) * (linegth / 2 - thicc / 2) - Math.sin(ang + offs + Math.PI / 2) * thicc
+ });
+ }
+ else {
+ Matter.Body.setPosition(shape, {
+ x: this.x + Math.cos(ang + offs) * (linegth / 2 - thicc / 2),
+ y: this.y + Math.sin(ang + offs) * (linegth / 2 - thicc / 2)
+ });
+ }
+ }
+ },
+ rotBy(ang) {
+ this.rot(this.r + ang);
+ }
+ };
+ ret.rot(0);
+ return ret;
+ }
+
+ var inner = makeRing(level.enter.x, level.enter.y, 1000);
+ var mid = makeRing(level.enter.x, level.enter.y, 2500);
+ var mid2 = makeRing(level.enter.x, level.enter.y, 4000);
+ var out = makeRing(level.enter.x, level.enter.y, 6000);
+
+ spawn.randomMob(level.enter.x + 250, level.enter.y);
+
+ spawn.randomMob(level.enter.x + 1250, level.enter.y);
+ spawn.randomMob(level.enter.x - 1250, level.enter.y);
+ spawn.randomMob(level.enter.x, level.enter.y + 1250);
+ spawn.randomMob(level.enter.x, level.enter.y - 1250);
+ spawn.randomMob(level.enter.x + 1250, level.enter.y + 500);
+ spawn.randomMob(level.enter.x - 1250, level.enter.y + 500);
+ spawn.randomMob(level.enter.x + 500, level.enter.y + 1250);
+ spawn.randomMob(level.enter.x + 500, level.enter.y - 1250);
+
+ spawn.randomMob(level.enter.x + 2750, level.enter.y);
+ spawn.randomMob(level.enter.x - 2750, level.enter.y);
+ spawn.randomMob(level.enter.x, level.enter.y + 2750);
+ spawn.randomMob(level.enter.x, level.enter.y - 2750);
+ spawn.randomMob(level.enter.x + 2750, level.enter.y + 500);
+ spawn.randomMob(level.enter.x - 2750, level.enter.y + 500);
+ spawn.randomMob(level.enter.x + 500, level.enter.y + 2750);
+ spawn.randomMob(level.enter.x + 500, level.enter.y - 2750);
+
+ spawn.randomLevelBoss(level.enter.x, level.enter.y - 4250);
+ spawn.secondaryBossChance(level.enter.x, level.enter.y + 4250);
+
+ level.custom = () => {
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ inner.rotBy(0.01);
+ mid.rotBy(-0.005);
+ mid2.rotBy(0.003);
+ out.rotBy(-0.002);
+ };
+
+ powerUps.addResearchToLevel();
+ },
+ trial() { // trial, collab between Cirryn and Tarantula Hawk
+ simulation.makeTextLog(`trial by Cirryn and Tarantula Hawk`);
+ level.setPosToSpawn(0, -50);
+ level.exit.x = 4150;
+ level.exit.y = -30;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#d8dadf";
+ const button = level.button(2000, 0);
+ const door = level.door(3930, -300, 40, 300, 300, 10);
+ door.isClosing = false;
+ var didTrialBegin = false;
+
+ const customMob = {
+ assassin(x, y) { // modified slasher
+ mobs.spawn(x, y, 3, 30, "black");
+ let me = mob[mob.length - 1];
+ Matter.Body.rotate(me, 2 * Math.PI * Math.random());
+ me.accelMag = 0.0008 * simulation.accelScale;
+ me.torqueMagnitude = 0.00002 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
+ me.frictionStatic = 0;
+ me.frictionAir = 0.08;
+ me.delay = 120 * simulation.CDScale;
+ me.cd = 0;
+ spawn.shield(me, x, y);
+ me.damageReduction = 0;
+ const start = window.performance.now(); // they only last ~ten seconds
+ const lifespan = 15000 + 700 * (Math.random() - 0.5);
+ me.onDamage = function () {
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
+ };
+ me.do = function () {
+ this.checkStatus();
+ this.alwaysSeePlayer();
+ this.attraction();
+ this.health = 1 - (window.performance.now() - start) / lifespan;
+ if (this.health < 0) {
+ this.death();
+ }
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 0.05);
+ };
+ },
+ mercenary(x, y) { // fast boi
+ mobs.spawn(x, y, 3, 60, "white");
+ let me = mob[mob.length - 1];
+ Matter.Body.rotate(me, 2 * Math.PI * Math.random());
+ me.accelMag = 0.001 * simulation.accelScale;
+ me.torqueMagnitude = 0.00001 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
+ me.frictionStatic = 0;
+ me.frictionAir = 0.03;
+ me.delay = 120 * simulation.CDScale;
+ me.cd = 0;
+ spawn.shield(me, x, y);
+ me.damageReduction = 0;
+ const start = window.performance.now(); // they only last ~ten seconds
+ const lifespan = 25000 + 700 * (Math.random() - 0.5);
+ me.onDamage = function () {
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
+ };
+ me.do = function () {
+ this.checkStatus();
+ this.attraction();
+ this.health = 1 - (window.performance.now() - start) / lifespan;
+ if (this.health < 0) {
+ this.death();
+ }
+ this.alwaysSeePlayer();
+ };
+ }
+ // eventually maybe add more custom mob types
+ };
+
+ function randomWave(count, source) { // generates a wave list from a source
+ // checks in spawn first, then customMob, for the sources
+ var ret = [];
+ for (var i = 0; i < count; i++) {
+ var pick = source[Math.floor(Math.random() * source.length)];
+ if (spawn[pick]) {
+ ret.push(spawn[pick]);
+ }
+ else if (customMob[pick]) {
+ ret.push(customMob[pick]);
+ }
+ }
+ return ret;
+ }
+
+ function wave(mobs) { // takes a list of functions that accept x,y coordinates to spawn a mob and spawns them in the ceiling
+ for (var i = 0; i < mobs.length; i++) {
+ var x = 1000 + 2400 * i / mobs.length + 200 * (Math.random() - 0.5);
+ var y = -950 - 100 * Math.random();
+ mobs[i](x, y);
+ }
+ const ammoCount = Math.random() * (10 - simulation.difficulty / 4);
+ for (var i = 0; i < ammoCount; i++) {
+ powerUps.spawn(3300, -1000, "ammo");
+ }
+ }
+
+ level.custom = () => {
+ door.openClose();
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ button.query();
+ button.draw();
+ door.draw();
+ if (!button.isUp && !didTrialBegin) {
+ didTrialBegin = true;
+ simulation.makeTextLog('The Trial has begun.');
+
+ setTimeout(() => {
+ simulation.makeTextLog('first wave (domitable)');
+ wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
+ }, 3000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('second wave (domitable)');
+ wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
+ }, 13000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('third wave (indomitable)');
+ wave(randomWave(4, ["assassin"]));
+ }, 23000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('fourth wave (domitable)');
+ wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
+ }, 39000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('fifth wave (domitable)');
+ wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
+ }, 49000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('sixth wave (indomitable)');
+ wave(randomWave(7, ["mercenary"]));
+ }, 59000);
+
+ setTimeout(() => {
+ simulation.makeTextLog('seventh wave (boss)');
+ spawn.randomLevelBoss(700, -1000);
+ var mainBoss = mob[mob.length - 1];
+ mainBoss.oldOnDeath = mainBoss.onDeath;
+ mainBoss.onDeath = () => {
+ door.isClosing = false;
+ powerUps.spawn(4150, -30, "tech");
+ powerUps.spawn(4150, -30, "tech");
+ mainBoss.oldOnDeath();
+ }
+ spawn.secondaryBossChance(3500, -1000);
+ }, 86000);
+
+ door.isClosing = true;
+ }
+ };
+
+ spawn.mapRect(-100, 0, 10000, 10000); // the left half of the room
+ spawn.mapRect(-10000, -300, 9900, 10000);
+ spawn.mapRect(-100, -300, 400, 100);
+ spawn.mapRect(200, -800, 100, 500);
+ spawn.mapRect(200, -800, 500, 100);
+ spawn.mapRect(600, -1000, 100, 200);
+
+ spawn.mapRect(600, -1100, 3000, 100); // the ceiling
+
+ spawn.mapRect(3500, -1000, 100, 200); // the right half of the room
+ spawn.mapRect(3500, -800, 500, 100);
+ spawn.mapRect(3900, -800, 100, 500);
+ spawn.mapRect(3900, -300, 400, 100);
+ spawn.mapRect(4300, -300, 10000, 10000);
+
+ for (var i = 0; i < 4; i++) { // "door" at the entrance
+ spawn.bodyRect(200, -200 + i * 50, 20, 50);
+ }
+
+ for (var i = 0; i < 5; i++) { // some random rubble in the first half of the room
+ spawn.bodyRect(400 + Math.random() * 1000, -200, 40 + Math.random() * 40, 40 + Math.random() * 40);
+ }
+
+ powerUps.addResearchToLevel(); //needs to run after mobs are spawneds
+ },
// ********************************************************************************************************
// ********************************************************************************************************
// ***************************************** training levels **********************************************
diff --git a/js/player.js b/js/player.js
index 6e83d3a..2df51df 100644
--- a/js/player.js
+++ b/js/player.js
@@ -553,17 +553,18 @@ const m = {
if (tech.isHarmMACHO) dmg *= tech.isMoveMACHO ? 0.3 : 0.4
if (tech.isImmortal) dmg *= 0.7
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
- if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
if (tech.isSpeedHarm && (tech.speedAdded + player.speed) > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8) //capped at speed of 55
if (tech.isHarmReduce && input.field) dmg *= 0.1
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
- if (tech.isBotArmor) dmg *= 0.95 ** b.totalBots()
+ if (tech.isBotArmor) dmg *= 0.96 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
if (tech.isTurret && m.crouch) dmg *= 0.3;
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
+ // if (tech.isLowHealthDefense) dmg *= Math.pow(0.3, Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health)))
+ if (tech.isLowHealthDefense) dmg *= Math.pow(0.2, Math.max(0, 1 - (tech.isEnergyHealth ? m.energy / m.maxEnergy : m.health / m.maxHealth)))
// return tech.isEnergyHealth ? Math.pow(dmg, 0.7) : dmg //defense has less effect
// dmg *= m.fieldHarmReduction
return dmg * m.fieldHarmReduction
@@ -2115,7 +2116,7 @@ const m = {
isFieldActive: false,
fieldRange: 155,
fieldShieldingScale: 1,
- // fieldDamage: 1,
+ fieldDamage: 1,
isSneakAttack: false,
lastHit: 0, //stores value of last damage player took above a threshold, in m.damage
sneakAttackCycle: 0,
@@ -2152,6 +2153,7 @@ const m = {
m.eyeFillColor = m.fieldMeterColor
m.fieldShieldingScale = 1;
m.fieldBlockCD = 10;
+ m.fieldDamage = 1
m.fieldHarmReduction = 1;
m.lastHit = 0
m.isSneakAttack = false
@@ -2241,7 +2243,7 @@ const m = {
} else {
m.fieldRegen = 0.001 //6 energy per second
}
- if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling
+ if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.0001 * m.coupling
if (tech.isTimeCrystals) {
m.fieldRegen *= 2.5
} else if (tech.isGroundState) {
@@ -2867,7 +2869,7 @@ const m = {
case 3: //negative mass
return `${(0.973 ** couple).toFixed(2)}x damage taken`
case 4: //assembler
- return `+${(0.8 * couple).toFixed(1)} energy per second`
+ return `+${(0.6 * couple).toFixed(1)} energy per second`
case 5: //plasma
return `${(1 + 0.015 * couple).toFixed(3)}x damage`
case 6: //time dilation
@@ -2883,7 +2885,7 @@ const m = {
}
},
couplingChange(change = 0) {
- if (change > 0 && level.onLevel !== -1) simulation.makeTextLog(`m.coupling += ${change}`, 60); //level.onLevel !== -1 means not on lore level
+ if (change > 0 && level.onLevel !== -1) simulation.makeTextLog(` m.coupling += ${change}`, 60); //level.onLevel !== -1 means not on lore level
m.coupling += change
if (m.coupling < 0) {
//look for coupling power ups on this level and remove them to prevent exploiting tech ejections
@@ -2921,7 +2923,7 @@ const m = {
document.getElementById("field").innerHTML = m.fieldUpgrades[index].name
m.setHoldDefaults();
m.fieldUpgrades[index].effect();
- simulation.makeTextLog(`m.setField("${m.fieldUpgrades[m.fieldMode].name}")`);
+ simulation.makeTextLog(` m.setField("${m.fieldUpgrades[m.fieldMode].name}")