card adjustments

card font is 10% smaller with a bit more padding on the edges
background is darker on power up selection
css border added to research and cancel buttons
JUNK images now timeout if you don't download the image in under 1 sec
  and it will not even try to download an image above 500KB
  and it will try a different random image if it's first attempt is too big
    (gotta protect our friends with slow internet)

finalBoss
  mine mode comes in waves
  orbiters mode comes in waves, and they spawn at a radius that intersects the player

several on new level tech effects now also run on each new final Boss phase
  gun stuff, many worlds, negative entropy heal spawns

perfect diamagnetism slow fall is much strong, but works better when angled like a parachute
This commit is contained in:
landgreen
2022-12-19 10:54:09 -08:00
parent 16834e95be
commit 8b9511f975
16 changed files with 489 additions and 570 deletions

View File

@@ -547,7 +547,7 @@ const b = {
y: where.y + range * Math.sin(angle)
}
];
const vertexCollision = function (v1, v1End, domain) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -883,7 +883,7 @@ const b = {
},
setGrenadeMode() {
grenadeDefault = function (where = {
grenadeDefault = function(where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, angle = m.angle, size = 1) {
@@ -893,7 +893,7 @@ const b = {
bullet[me].explodeRad = 300 * size + 100 * tech.isBlockExplode;
bullet[me].onEnd = b.grenadeEnd
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 43 : 32
@@ -903,12 +903,12 @@ const b = {
});
bullet[me].endCycle = simulation.cycle + Math.floor(input.down ? 120 : 80) * tech.isBulletsLastLonger;
bullet[me].restitution = 0.4;
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
};
Composite.add(engine.world, bullet[me]); //add bullet to world
}
grenadeRPG = function (where = {
grenadeRPG = function(where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, angle = m.angle, size = 1) {
@@ -918,7 +918,7 @@ const b = {
bullet[me].explodeRad = 300 * size + 100 * tech.isBlockExplode;
bullet[me].onEnd = b.grenadeEnd
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 46 : 32
@@ -935,7 +935,7 @@ const b = {
x: bullet[me].mass * MAG * Math.cos(angle),
y: bullet[me].mass * MAG * Math.sin(angle)
}
bullet[me].do = function () {
bullet[me].do = function() {
this.force.x += this.thrust.x;
this.force.y += this.thrust.y;
if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
@@ -943,7 +943,7 @@ const b = {
}
};
}
grenadeRPGVacuum = function (where = {
grenadeRPGVacuum = function(where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, angle = m.angle, size = 1) {
@@ -953,7 +953,7 @@ const b = {
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
bullet[me].onEnd = b.grenadeEnd
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 46 : 32
@@ -970,7 +970,7 @@ const b = {
x: bullet[me].mass * MAG * Math.cos(angle),
y: bullet[me].mass * MAG * Math.sin(angle)
}
bullet[me].suck = function () {
bullet[me].suck = function() {
const suck = (who, radius = this.explodeRad * 3.2) => {
for (i = 0, len = who.length; i < len; i++) {
const sub = Vector.sub(this.position, who[i].position);
@@ -1010,7 +1010,7 @@ const b = {
ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI);
ctx.fill();
}
bullet[me].do = function () {
bullet[me].do = function() {
if (simulation.cycle > this.endCycle - this.suckCycles) { //suck
this.do = this.suck
} else if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
@@ -1022,7 +1022,7 @@ const b = {
}
};
}
grenadeVacuum = function (where = {
grenadeVacuum = function(where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, angle = m.angle, size = 1) {
@@ -1031,11 +1031,11 @@ const b = {
Matter.Body.setDensity(bullet[me], 0.0002);
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
bullet[me].onEnd = b.grenadeEnd
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
bullet[me].restitution = 0.4;
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
const suckCycles = 40
@@ -1097,7 +1097,7 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
}
grenadeNeutron = function (where = {
grenadeNeutron = function(where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, angle = m.angle, size = 1) {
@@ -1132,9 +1132,9 @@ const b = {
}
}
bullet[me].beforeDmg = function () {};
bullet[me].stuck = function () {};
bullet[me].do = function () {
bullet[me].beforeDmg = function() {};
bullet[me].stuck = function() {};
bullet[me].do = function() {
const onCollide = () => {
this.collisionFilter.mask = 0; //non collide with everything
Matter.Body.setVelocity(this, {
@@ -1161,14 +1161,14 @@ const b = {
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
}
this.stuck = function () {
this.stuck = function() {
if (this.stuckTo && this.stuckTo.alive) {
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
} else {
this.collisionFilter.mask = cat.map | cat.body | cat.player | cat.mob; //non collide with everything but map
this.stuck = function () {
this.stuck = function() {
this.force.y += this.mass * 0.001;
}
}
@@ -1184,7 +1184,7 @@ const b = {
} else {
this.do = this.radiationMode;
}
this.stuck = function () {
this.stuck = function() {
if (this.stuckTo) {
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
@@ -1205,7 +1205,7 @@ const b = {
}
}
}
bullet[me].radiationMode = function () { //the do code after the bullet is stuck on something, projects a damaging radiation field
bullet[me].radiationMode = function() { //the do code after the bullet is stuck on something, projects a damaging radiation field
this.stuck(); //runs different code based on what the bullet is stuck to
this.damageRadius = this.damageRadius * 0.85 + 0.15 * this.maxDamageRadius //smooth radius towards max
this.maxDamageRadius -= this.radiusDecay
@@ -1267,9 +1267,9 @@ const b = {
if (tech.isNeutronBomb) {
b.grenade = grenadeNeutron
if (tech.isRPG) {
b.guns[5].do = function () {}
b.guns[5].do = function() {}
} else {
b.guns[5].do = function () {
b.guns[5].do = function() {
if (!input.field && input.down) {
const cycles = 80
const speed = input.down ? 35 : 20 //input.down ? 43 : 32
@@ -1290,7 +1290,7 @@ const b = {
}
}
} else if (tech.isRPG) {
b.guns[5].do = function () {}
b.guns[5].do = function() {}
if (tech.isVacuumBomb) {
b.grenade = grenadeRPGVacuum
} else {
@@ -1298,7 +1298,7 @@ const b = {
}
} else if (tech.isVacuumBomb) {
b.grenade = grenadeVacuum
b.guns[5].do = function () {
b.guns[5].do = function() {
if (!input.field && input.down) {
const cycles = Math.floor(input.down ? 50 : 30) //30
const speed = input.down ? 44 : 35
@@ -1318,7 +1318,7 @@ const b = {
}
} else {
b.grenade = grenadeDefault
b.guns[5].do = function () {
b.guns[5].do = function() {
if (!input.field && input.down) {
const cycles = Math.floor(input.down ? 120 : 80) //30
const speed = input.down ? 43 : 32
@@ -2043,24 +2043,24 @@ const b = {
y: m.Vy / 2 + 600 * thrust * Math.sin(bullet[me].angle)
});
bullet[me].frictionAir = 0.002
bullet[me].do = function () {
bullet[me].do = function() {
if (this.speed < 20) this.force.y += 0.0005 * this.mass;
this.draw();
}
}
if (tech.isHarpoonPowerUp && bullet[me].density > 0.01) {
if (isReturn) {
bullet[me].draw = function () {
bullet[me].draw = function() {
this.drawToggleHarpoon()
this.drawString()
}
} else {
bullet[me].draw = function () {
bullet[me].draw = function() {
this.drawToggleHarpoon()
}
}
} else if (isReturn) {
bullet[me].draw = function () {
bullet[me].draw = function() {
this.drawString()
}
}
@@ -2250,7 +2250,7 @@ const b = {
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
if (180 - Math.abs(Math.abs(b.lastAngle - m.angle) - 180) > 0.13 || !b.wasExtruderOn) {
bullet[me].isBranch = true; //don't draw stroke for this bullet
bullet[me].do = function () {
bullet[me].do = function() {
if (this.endCycle < simulation.cycle + 1) this.isWave = false
}
}
@@ -2281,7 +2281,7 @@ const b = {
y: m.pos.y + range * Math.sin(m.angle)
}
];
const vertexCollision = function (v1, v1End, domain) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -2420,7 +2420,7 @@ const b = {
x: whereEnd.x,
y: whereEnd.y
}];
const vertexCollision = function (v1, v1End, domain) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -2461,7 +2461,7 @@ const b = {
}
};
const checkForCollisions = function () {
const checkForCollisions = function() {
best = {
x: 1,
y: 1,
@@ -2474,7 +2474,7 @@ const b = {
vertexCollision(path[path.length - 2], path[path.length - 1], map);
vertexCollision(path[path.length - 2], path[path.length - 1], body);
};
const laserHitMob = function () {
const laserHitMob = function() {
if (best.who.alive) {
best.who.locatePlayer();
if (best.who.damageReduction) {
@@ -2520,7 +2520,7 @@ const b = {
Matter.Body.applyForce(best.who, path[index], force)
}
};
const reflection = function () { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const reflection = function() { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
@@ -2828,7 +2828,7 @@ const b = {
arm() {
this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets
this.lookFrequency = simulation.cycle + 60
this.do = function () { //overwrite the do method for this bullet
this.do = function() { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity
if (simulation.cycle > this.lookFrequency) {
this.isArmed = true
@@ -2840,7 +2840,7 @@ const b = {
color: "#f00",
time: 4
});
this.do = function () { //overwrite the do method for this bullet
this.do = function() { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
const random = 300 * Math.random()
@@ -2855,7 +2855,7 @@ const b = {
if (tech.isMineSentry) {
this.lookFrequency = 6
this.endCycle = simulation.cycle + 1020
this.do = function () { //overwrite the do method for this bullet
this.do = function() { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
this.endCycle -= 5
@@ -3455,7 +3455,7 @@ const b = {
ctx.stroke();
}
//power ups
if (!this.isImproved && !simulation.isChoosing && !tech.isExtraMaxEnergy) {
if (!this.isImproved && !simulation.isChoosing) {
if (this.lockedOn) {
for (let i = 0, len = powerUp.length; i < len; ++i) { //grab, but don't lock onto nearby power up
if (
@@ -3665,7 +3665,7 @@ const b = {
}
}
//power ups
if (!this.isImproved && !simulation.isChoosing && !tech.isExtraMaxEnergy) {
if (!this.isImproved && !simulation.isChoosing) {
if (this.lockedOn) {
//grab, but don't lock onto nearby power up
for (let i = 0, len = powerUp.length; i < len; ++i) {
@@ -4200,7 +4200,7 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world
bullet[me].endCycle = simulation.cycle + 60 + 18 * Math.random();
bullet[me].dmg = tech.isNailRadiation ? 0 : dmg
bullet[me].beforeDmg = function (who) { //beforeDmg is rewritten with ice crystal tech
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech
if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 1 / who.radius) {
@@ -4209,7 +4209,7 @@ const b = {
}
this.ricochet(who)
};
bullet[me].ricochet = function (who) { //use for normal nails, and ice crystal nails
bullet[me].ricochet = function(who) { //use for normal nails, and ice crystal nails
if (tech.isRicochet) {
const targets = [] //target nearby mobs
for (let i = 0, len = mob.length; i < len; i++) {
@@ -4234,7 +4234,7 @@ const b = {
this.dmg += 2
}
}
bullet[me].do = function () {};
bullet[me].do = function() {};
},
needle(angle = m.angle) {
const me = bullet.length;
@@ -4248,7 +4248,7 @@ const b = {
bullet[me].collisionFilter.mask = tech.isShieldPierce ? 0 : cat.mobShield
// bullet[me].turnRate = 0.005 * (Math.random() - 0.5)
bullet[me].isInMap = false
bullet[me].do = function () {
bullet[me].do = function() {
const whom = Matter.Query.collides(this, mob)
if (whom.length && this.speed > 20) { //if touching a mob
for (let i = 0, len = whom.length; i < len; i++) {
@@ -4306,7 +4306,7 @@ const b = {
} else {
bullet[me].endCycle = simulation.cycle + 100;
bullet[me].collisionFilter.mask = tech.isShieldPierce ? cat.body : cat.body | cat.mobShield
bullet[me].do = function () {
bullet[me].do = function() {
const whom = Matter.Query.collides(this, mob)
if (whom.length && this.speed > 20) { //if touching a mob
for (let i = 0, len = whom.length; i < len; i++) {
@@ -4354,7 +4354,7 @@ const b = {
x: 0,
y: 0
});
this.do = function () {
this.do = function() {
if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
}
if (tech.isNeedleIce) {
@@ -4989,7 +4989,7 @@ const b = {
y: this.lockedOn.position.y
}];
const vertexCollision = function (v1, v1End, domain) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -5030,7 +5030,7 @@ const b = {
}
};
const checkForCollisions = function () {
const checkForCollisions = function() {
best = {
x: 1,
y: 1,
@@ -5043,7 +5043,7 @@ const b = {
vertexCollision(path[path.length - 2], path[path.length - 1], map);
vertexCollision(path[path.length - 2], path[path.length - 1], body);
};
const laserHitMob = function () {
const laserHitMob = function() {
if (best.who.alive) {
best.who.locatePlayer();
if (best.who.damageReduction) {
@@ -5089,7 +5089,7 @@ const b = {
Matter.Body.applyForce(best.who, path[index], force)
}
};
const reflection = function () { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const reflection = function() { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
@@ -5316,7 +5316,7 @@ const b = {
y: this.position.y + range * unit.y
}
];
const vertexCollision = function (v1, v1End, domain) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -5665,7 +5665,7 @@ const b = {
});
bullet[me].endCycle = simulation.cycle + 180
bullet[me].beforeDmg = function (who) { //beforeDmg is rewritten with ice crystal tech
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech
if (tech.isIncendiary) {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
@@ -5684,7 +5684,7 @@ const b = {
bullet[me].minDmgSpeed = 10
bullet[me].frictionAir = 0.006;
bullet[me].rotateToVelocity = function () { //rotates bullet to face current velocity?
bullet[me].rotateToVelocity = function() { //rotates bullet to face current velocity?
if (this.speed > 7) {
const facing = {
x: Math.cos(this.angle),
@@ -5699,7 +5699,7 @@ const b = {
}
};
if (tech.isIncendiary) {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
//collide with map
@@ -5709,7 +5709,7 @@ const b = {
}
};
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
};
@@ -5751,7 +5751,7 @@ const b = {
y: SPEED * Math.sin(m.angle)
});
bullet[me].endCycle = simulation.cycle + 180
bullet[me].beforeDmg = function (who) { //beforeDmg is rewritten with ice crystal tech
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech
if (tech.isIncendiary) {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
@@ -5770,7 +5770,7 @@ const b = {
bullet[me].minDmgSpeed = 10
bullet[me].frictionAir = 0.006;
bullet[me].rotateToVelocity = function () { //rotates bullet to face current velocity?
bullet[me].rotateToVelocity = function() { //rotates bullet to face current velocity?
if (this.speed > 7) {
const facing = {
x: Math.cos(this.angle),
@@ -5785,7 +5785,7 @@ const b = {
}
};
if (tech.isIncendiary) {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
//collide with map
@@ -5795,7 +5795,7 @@ const b = {
}
};
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
};
@@ -5841,7 +5841,7 @@ const b = {
y: m.Vy / 2 + speed * Math.sin(angle)
}) //position, velocity, damage
if (tech.isIceCrystals) {
bullet[bullet.length - 1].beforeDmg = function (who) {
bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 60)
if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit) {
@@ -5910,7 +5910,7 @@ const b = {
if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0015)
// bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.034;
bullet[me].do = function () {
bullet[me].do = function() {
const scale = 1 - 0.034 / tech.isBulletsLastLonger
Matter.Body.scale(this, scale, scale);
};
@@ -5933,10 +5933,10 @@ const b = {
});
if (tech.isIncendiary) {
bullet[me].endCycle = simulation.cycle + 60
bullet[me].onEnd = function () {
bullet[me].onEnd = function() {
b.explosion(this.position, 360 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
};
} else {
@@ -5946,7 +5946,7 @@ const b = {
// bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.004;
bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75)
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.002
if (this.speed > 6) { //rotates bullet to face current velocity?
const facing = {
@@ -5963,7 +5963,7 @@ const b = {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
}
};
bullet[me].beforeDmg = function (who) {
bullet[me].beforeDmg = function(who) {
if (this.speed > 4) {
if (tech.fragments) {
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
@@ -5992,13 +5992,13 @@ const b = {
x: speed * Math.cos(dirOff),
y: speed * Math.sin(dirOff)
});
bullet[me].onEnd = function () {
bullet[me].onEnd = function() {
b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.4 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
};
bullet[me].do = function () {
bullet[me].do = function() {
if (Matter.Query.collides(this, map).length) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
}
Composite.add(engine.world, bullet[me]); //add bullet to world
@@ -6127,11 +6127,11 @@ const b = {
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 1;
bullet[me].friction = 0;
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
if (tech.isIncendiary) {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
@@ -6139,11 +6139,11 @@ const b = {
}
};
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function (who) {
bullet[me].beforeDmg = function(who) {
mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
@@ -6184,7 +6184,7 @@ const b = {
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
if (tech.isIncendiary) {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
@@ -6192,11 +6192,11 @@ const b = {
}
};
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
@@ -6239,7 +6239,7 @@ const b = {
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
if (tech.isIncendiary) {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
@@ -6247,11 +6247,11 @@ const b = {
}
};
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
@@ -6645,7 +6645,7 @@ const b = {
}
});
if (tech.isBulletTeleport) {
bullet[me].wiggle = function () {
bullet[me].wiggle = function() {
this.cycle++
const where = Vector.mult(transverse, this.amplitude * Math.cos(this.cycle * tech.waveFrequency))
if (Math.random() < 0.005) {
@@ -6674,7 +6674,7 @@ const b = {
}
if (tech.waveReflections) {
bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange
bullet[me].do = function () {
bullet[me].do = function() {
this.query()
if (this.cycle > this.reflectCycle) {
this.reflectCycle += totalCycles / tech.waveReflections
@@ -6684,7 +6684,7 @@ const b = {
this.wiggle()
}
} else {
bullet[me].do = function () {
bullet[me].do = function() {
this.query()
this.wiggle();
}
@@ -6860,9 +6860,9 @@ const b = {
bullet[me].restitution = 0.3;
bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * tech.isSporeFreeze + 4 * tech.isSporeColony
bullet[me].stuck = function () {};
bullet[me].beforeDmg = function () {};
bullet[me].do = function () {
bullet[me].stuck = function() {};
bullet[me].beforeDmg = function() {};
bullet[me].do = function() {
function onCollide(that) {
that.collisionFilter.mask = 0; //non collide with everything
Matter.Body.setVelocity(that, {
@@ -6886,14 +6886,14 @@ const b = {
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
}
this.stuck = function () {
this.stuck = function() {
if (this.stuckTo && this.stuckTo.alive) {
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
} else {
this.collisionFilter.mask = cat.map; //non collide with everything but map
this.stuck = function () {
this.stuck = function() {
this.force.y += this.mass * 0.0006;
}
}
@@ -6909,7 +6909,7 @@ const b = {
} else {
this.do = this.grow;
}
this.stuck = function () {
this.stuck = function() {
if (this.stuckTo) {
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
@@ -6932,7 +6932,7 @@ const b = {
ctx.arc(this.position.x, this.position.y, this.maxRadius, 0, 2 * Math.PI);
ctx.fill();
}
bullet[me].grow = function () {
bullet[me].grow = function() {
this.stuck(); //runs different code based on what the bullet is stuck to
let scale = 1.01
if (tech.isSporeGrowth && !(simulation.cycle % 40)) { //release a spore
@@ -6967,7 +6967,7 @@ const b = {
ctx.fill();
};
//spawn bullets on end
bullet[me].onEnd = function () {
bullet[me].onEnd = function() {
let count = 0 //used in for loop below
const things = [

View File

@@ -14,7 +14,7 @@ Math.hash = s => {
document.getElementById("seed").placeholder = Math.initialSeed = String(Math.floor(Date.now() % 100000))
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it
Math.seededRandom = function (min = 0, max = 1) { // in order to work 'Math.seed' must NOT be undefined
Math.seededRandom = function(min = 0, max = 1) { // in order to work 'Math.seed' must NOT be undefined
Math.seed = (Math.seed * 9301 + 49297) % 233280;
return min + Math.seed / 233280 * (max - min);
}
@@ -100,7 +100,7 @@ const color = { //light
//difficulty is 0 easy, 1 normal, 2 hard, 4 why
function getUrlVars() {
let vars = {};
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, k, v) {
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, k, v) {
vars[k] = v;
});
return vars;
@@ -202,7 +202,7 @@ const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#fff";
//disable pop up menu on right click
document.oncontextmenu = function () {
document.oncontextmenu = function() {
return false;
}
@@ -412,7 +412,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
// } else {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// }
const style = localSettings.isHideImages ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"`
const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"`
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isNonRefundable) {
text += `<div class="pause-grid-module" id ="${i}-pause-tech" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
@@ -542,10 +542,10 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
}, 50);
}
}
//update tech text //disable not allowed tech
//update tech text
for (let i = 0, len = tech.tech.length; i < len; i++) {
const techID = document.getElementById("tech-" + i)
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //!tech.tech[i].isNonRefundable && //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! does removing this cause problems????
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment) && !tech.tech[i].isLore) {
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
if (tech.tech[i].isFieldTech) {
techID.classList.remove('experiment-grid-hide');
@@ -559,28 +559,20 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
} else {
techID.innerHTML = build.techText(i)
}
//deselect selected tech options if you don't have the tech any more // for example: when bot techs are converted after a bot upgrade tech is taken
if (tech.tech[i].count === 0 && techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected");
if (techID.classList.contains("experiment-grid-disabled")) {
techID.classList.remove("experiment-grid-disabled");
techID.setAttribute("onClick", `javascript: build.choosePowerUp(${i},'tech')`);
}
// } else if (tech.tech[i].isGunTech || tech.tech[i].isFieldTech) {
// techID.classList.add('experiment-grid-hide');
} else { //disabled color
// techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
// techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
} else { //disabled color for disabled tech
techID.innerHTML = `<div class="grid-title">${tech.tech[i].name}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
// console.log(techID)
if (!techID.classList.contains("experiment-grid-disabled")) {
techID.classList.add("experiment-grid-disabled");
techID.onclick = null
}
if (tech.tech[i].count > 0) tech.removeTech(i)
if (techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected");
if (tech.tech[i].isFieldTech) {
techID.innerHTML = build.fieldTechText(i)
} else if (tech.tech[i].isGunTech) {
@@ -652,9 +644,8 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
// text += `<div id = "gun-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div> ${b.guns[i].description}</div>`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isJunk || localSettings.isJunkExperiment) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/${tech.tech[i].name}.webp');"`
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment) && !tech.tech[i].isLore) {
const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? hideStyle : `style="background-image: url('img/${tech.tech[i].name}.webp');"`
if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
text += `<div id="tech-${i}" class="experiment-grid-module card-background" onclick="build.choosePowerUp(${i},'tech')" ${style}>`
} else { //disabled
@@ -749,17 +740,17 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
}
console.log('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
console.log(url)
navigator.clipboard.writeText(url).then(function () {
navigator.clipboard.writeText(url).then(function() {
/* clipboard successfully set */
if (isCustom) {
setTimeout(function () {
setTimeout(function() {
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
}, 300);
}
}, function () {
}, function() {
/* clipboard write failed */
if (isCustom) {
setTimeout(function () {
setTimeout(function() {
alert('copy failed')
}, 300);
}
@@ -984,14 +975,14 @@ document.getElementById("control-table").addEventListener('click', (event) => {
window.addEventListener("keydown", input.setKeys);
}
});
document.getElementById("control-details").addEventListener("toggle", function () {
document.getElementById("control-details").addEventListener("toggle", function() {
input.controlTextUpdate()
input.endKeySensing();
})
document.getElementById("control-reset").addEventListener('click', input.setDefault);
window.addEventListener("keyup", function (event) {
window.addEventListener("keyup", function(event) {
switch (event.code) {
case input.key.right:
case "ArrowRight":
@@ -1018,7 +1009,7 @@ window.addEventListener("keyup", function (event) {
}
});
window.addEventListener("keydown", function (event) {
window.addEventListener("keydown", function(event) {
// console.log(event.code)
switch (event.code) {
case input.key.right:
@@ -1055,7 +1046,7 @@ window.addEventListener("keydown", function (event) {
case input.key.pause:
if (!simulation.isChoosing && input.isPauseKeyReady && m.alive) {
input.isPauseKeyReady = false
setTimeout(function () {
setTimeout(function() {
input.isPauseKeyReady = true
}, 300);
if (simulation.paused) {
@@ -1499,10 +1490,10 @@ document.getElementById("difficulty-select").addEventListener("input", () => {
});
document.getElementById("updates").addEventListener("toggle", function () {
document.getElementById("updates").addEventListener("toggle", function() {
function loadJSON(path, success, error) { //generic function to get JSON
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
if (success)
@@ -1521,7 +1512,7 @@ document.getElementById("updates").addEventListener("toggle", function () {
/// https://api.github.com/repos/landgreen/n-gon/stats/commit_activity
loadJSON('https://api.github.com/repos/landgreen/n-gon/commits',
function (data) {
function(data) {
// console.log(data)
for (let i = 0, len = 20; i < len; i++) {
text += "<strong>" + data[i].commit.author.date.substr(0, 10) + "</strong> - "; //+ "<br>"
@@ -1530,7 +1521,7 @@ document.getElementById("updates").addEventListener("toggle", function () {
}
document.getElementById("updates-div").innerHTML = text.replace(/\n/g, "<br />")
},
function (xhr) {
function(xhr) {
console.error(xhr);
}
);

View File

@@ -21,15 +21,15 @@ const level = {
// level.difficultyIncrease(30 * 4) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(5)
// powerUps.research.changeRerolls(20)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
// m.setField("time dilation") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch
// m.setField("perfect diamagnetism") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("spores") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 10000
// tech.giveTech("alternator")
// tech.giveTech("posture")
@@ -100,19 +100,6 @@ const level = {
m.resetHistory();
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
//used for generalist and pigeonhole principle
tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle) {
b.inventoryGun = tech.buffedGun;
simulation.switchGun();
}
if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) {
var gun = b.guns[b.inventory[tech.buffedGun]].name
simulation.makeTextLog(`pigeonhole principle: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`, 600);
}
if (tech.isForeverDrones) {
if (tech.isDroneRadioactive) {
for (let i = 0; i < tech.isForeverDrones * 0.25; i++) {
@@ -132,29 +119,7 @@ const level = {
}
}
}
if (tech.isExtraMaxEnergy) {
tech.healMaxEnergyBonus += 0.1 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51)
m.setMaxEnergy();
}
if (tech.isSwitchReality) {
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
m.switchWorlds()
simulation.trails()
powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
}
if (tech.isHealLowHealth) {
// if (tech.isEnergyHealth) {
// var len = Math.ceil((m.maxEnergy - m.energy) / 0.33)
// } else {
// var len = Math.ceil((m.maxHealth - m.health) / 0.33)
// }
if (tech.isEnergyHealth) {
var len = 3 * (1 - m.energy / m.maxEnergy) //as a percent
} else {
var len = 3 * (1 - m.health / m.maxHealth) //as a percent
}
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
}
if (tech.isMACHO) spawn.MACHO()
for (let i = 0; i < tech.wimpCount; i++) {
spawn.WIMP()
@@ -175,15 +140,40 @@ const level = {
m.eyeFillColor = m.fieldMeterColor
simulation.makeTextLog(`tech.isFlipFlopOn <span class='color-symbol'>=</span> true`);
}
if (tech.isSpawnExitTech) {
for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit
}
// if (m.plasmaBall) m.plasmaBall.reset()
if (m.plasmaBall) m.plasmaBall.fire()
if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) {
const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
powerUps.directSpawn(flip * localSettings.entanglement.position.x, localSettings.entanglement.position.y, "entanglement", false);
}
level.newLevelOrPhase()
},
newLevelOrPhase() { //runs on each new level but also on final boss phases
//used for generalist and pigeonhole principle
tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle) {
b.inventoryGun = tech.buffedGun;
simulation.switchGun();
}
if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) {
var gun = b.guns[b.inventory[tech.buffedGun]].name
simulation.makeTextLog(`pigeonhole principle: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`, 600);
}
if (tech.isSwitchReality) {
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
m.switchWorlds()
simulation.trails()
powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
}
if (tech.isHealLowHealth) {
if (tech.isEnergyHealth) {
var len = 3 * (1 - m.energy / m.maxEnergy) //as a percent
} else {
var len = 3 * (1 - m.health / m.maxHealth) //as a percent
}
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
}
},
trainingText(say) {
simulation.lastLogTime = 0; //clear previous messages
@@ -267,7 +257,7 @@ const level = {
document.getElementById("health-bg").style.display = "none"
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
document.getElementById("fade-out").style.opacity = 1; //slowly fades out
setTimeout(function () {
setTimeout(function() {
simulation.paused = true;
level.disableExit = false;
engine.world.bodies.forEach((body) => {
@@ -557,7 +547,7 @@ const level = {
x: who.position.x,
y: who.position.y
}
who.rotate = function () {
who.rotate = function() {
if (!m.isBodiesAsleep) {
Matter.Body.applyForce(this, {
x: this.position.x + 100,
@@ -1279,7 +1269,7 @@ const level = {
y: 0
}, angleB)
draw = function () {
draw = function() {
ctx.beginPath(); //portal
let v = this.vertices;
ctx.moveTo(v[0].x, v[0].y);
@@ -1289,7 +1279,7 @@ const level = {
ctx.fillStyle = this.color
ctx.fill();
}
query = function (isRemoveBlocks = false) {
query = function(isRemoveBlocks = false) {
if (Matter.Query.collides(this, [player]).length === 0) { //not touching player
if (player.isInPortal === this) player.isInPortal = null
} else if (player.isInPortal !== this) { //touching player
@@ -1943,7 +1933,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
fireBlock = function (xPos, yPos) {
fireBlock = function(xPos, yPos) {
const index = body.length
spawn.bodyRect(xPos, yPos, 35 + 50 * Math.random(), 35 + 50 * Math.random());
const bodyBullet = body[body.length - 1]
@@ -2000,7 +1990,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
fireBlock = function (xPos, yPos) {
fireBlock = function(xPos, yPos) {
const index = body.length
spawn.bodyRect(xPos, yPos, 35 + 50 * Math.random(), 35 + 50 * Math.random());
const bodyBullet = body[body.length - 1]
@@ -3009,7 +2999,7 @@ const level = {
// spawn.starter(1900, -500, 200) //big boy
// for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500)
spawn.suckerBoss(1900, -500)
// spawn.suckerBoss(1900, -500)
// spawn.launcherBoss(3200, -500)
// spawn.laserTargetingBoss(1700, -500)
// spawn.powerUpBoss(1900, -500)
@@ -7436,11 +7426,11 @@ const level = {
body[body.length] = part4;
body[body.length] = part5;
body[body.length] = part6;
setTimeout(function () {
setTimeout(function() {
chair.collisionFilter.category = cat.body;
chair.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
setTimeout(function () {
setTimeout(function() {
chair2.collisionFilter.category = cat.body;
chair2.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
@@ -7495,7 +7485,7 @@ const level = {
body[body.length] = rightUpperLeg
body[body.length] = rightLowerArm
body[body.length] = rightUpperArm
setTimeout(function () {
setTimeout(function() {
person.collisionFilter.category = cat.body;
person.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
@@ -8960,7 +8950,7 @@ const level = {
body[body.length] = part1;
body[body.length] = part2;
body[body.length] = part3;
setTimeout(function () {
setTimeout(function() {
compoundParts.collisionFilter.category = cat.body;
compoundParts.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
@@ -10225,19 +10215,19 @@ const level = {
simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
const V = Vector;
const Equation = (function () {
const Equation = (function() {
function Equation(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
}
Equation.prototype.getXfromY = function (y) {
Equation.prototype.getXfromY = function(y) {
return (-this.b * y - this.c) / this.a;
}
Equation.prototype.getYfromX = function (x) {
Equation.prototype.getYfromX = function(x) {
return (-this.a * x - this.c) / this.b;
}
Equation.fromPoints = function (v1, v2) {
Equation.fromPoints = function(v1, v2) {
if (v1.x === v2.x) return new Equation(1, 0, -v1.x);
if (v1.y === v2.y) return new Equation(0, 1, -v1.y);
const d = (v2.y - v1.y) / (v2.x - v1.x);
@@ -10245,7 +10235,7 @@ const level = {
};
return Equation;
})();
const Rect = (function () {
const Rect = (function() {
function Rect(x, y, w, h) {
this.pos = {
x,
@@ -10254,14 +10244,14 @@ const level = {
this.width = w;
this.height = h;
}
Rect.prototype.has = function ({
Rect.prototype.has = function({
x,
y
}) {
return x >= this.pos.x && x <= this.pos.x + this.width &&
y >= this.pos.y && y <= this.pos.y + this.height;
}
Rect.prototype.hasLine = function (eq) {
Rect.prototype.hasLine = function(eq) {
const leftInter = eq.getYfromX(this.pos.x);
const rightInter = eq.getYfromX(this.pos.x + this.width);
const topInter = eq.getXfromY(this.pos.y);
@@ -10269,7 +10259,7 @@ const level = {
(rightInter >= this.pos.y && rightInter <= this.pos.y + this.height) ||
(topInter >= this.pos.x && topInter <= this.pos.x + this.width);
}
Rect.prototype.addToMap = function () {
Rect.prototype.addToMap = function() {
spawn.mapRect(this.pos.x, this.pos.y, this.width, this.height);
}
Object.defineProperty(Rect.prototype, "midPos", {
@@ -10280,10 +10270,10 @@ const level = {
});
}
});
Rect.fromBounds = function (min, max) {
Rect.fromBounds = function(min, max) {
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}
Rect.prototype.isCollidingWith = function (other) {
Rect.prototype.isCollidingWith = function(other) {
const tc = {
p1: [this.pos.x, this.pos.y],
p2: [this.pos.x + this.width, this.pos.y + this.height]
@@ -10344,14 +10334,14 @@ const level = {
me.attackCycle = 0;
me.lastAttackCycle = 0;
Matter.Body.setDensity(me, 0.012); // extra dense, normal is 0.001 // makes effective life much larger
me.onDeath = function () {
me.onDeath = function() {
// applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawn(this.position.x + 20, this.position.y, "ammo");
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.do = function () {
me.do = function() {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) {
Matter.Body.setVelocity(this, {
@@ -10448,13 +10438,13 @@ const level = {
me.attackCycle = 0;
me.maxAttackCycle = isDark ? 90 : 240;
Matter.Body.setDensity(me, 0.006); // extra dense, normal is 0.001 // makes effective life much larger
me.onDeath = function () {
me.onDeath = function() {
powerUps.spawn(this.position.x + 20, this.position.y, "ammo");
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.do = function () {
me.do = function() {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 2) {
Matter.Body.setVelocity(this, {
@@ -10506,12 +10496,12 @@ const level = {
me.maxAttackCycle = 10;
me.inertia = Infinity;
}
me.do = isDark ? function () {
me.do = isDark ? function() {
Matter.Body.setVelocity(this, {
x: this.velocity.x * 0.95,
y: this.velocity.y * 0.95
});
} : function () {
} : function() {
Matter.Body.setVelocity(this, {
x: this.velocity.x * 0.95,
y: this.velocity.y * 0.95
@@ -10551,7 +10541,7 @@ const level = {
let me = mob[mob.length - 1];
me.fill = "#ace";
me.damageReduction = 0;
me.onDeath = function () {
me.onDeath = function() {
//damage player if in range
if (distance(player.position, this.position) < pulseRadius && m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage
@@ -10565,7 +10555,7 @@ const level = {
time: simulation.drawTime
});
};
me.do = function () {
me.do = function() {
this.timeLimit();
ctx.beginPath(); //draw explosion outline
ctx.arc(this.position.x, this.position.y, pulseRadius * (1.01 - this.timeLeft / this.lifeSpan), 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
@@ -10599,7 +10589,7 @@ const level = {
me.lastAttackCycle = 0;
me.spawnCycle = 0;
Matter.Body.setDensity(me, 0.08); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () {
me.onDeath = function() {
for (let j = 0; j < 8; j++) { //in case some mobs leave things after they die
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i] !== this) {
@@ -10618,7 +10608,7 @@ const level = {
};
me.nextHealthThreshold = 0.75;
me.trapCycle = 0;
me.onDamage = function () {
me.onDamage = function() {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
@@ -10641,7 +10631,7 @@ const level = {
radius: 500,
id: 2
}];
me.ring = function () {
me.ring = function() {
if (this.isInvulnerable) return;
ctx.lineWidth = 10;
for (const ring of this.rings) {
@@ -10653,7 +10643,7 @@ const level = {
DrawTools.arcOut(this.position.x, this.position.y, radius, 0, Math.PI * 2);
}
}
me.horizon = function () {
me.horizon = function() {
if (this.isInvulnerable) return this.fill = "#f00";
// eventHorizon waves in and out
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008));
@@ -10708,7 +10698,7 @@ const level = {
DrawTools.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
}
}
me.periodicSpawns = function () {
me.periodicSpawns = function() {
if (this.isInvulnerable) return;
this.spawnCycle++;
// Spawn annoying purple thing(s) that chases the player
@@ -10748,7 +10738,7 @@ const level = {
spawn.allowShields = true;
}
}
me.invulnerableTrap = function () {
me.invulnerableTrap = function() {
if (this.trapCycle < 1) return;
this.trapCycle++;
// 24 is just an arbitrarily large number
@@ -10800,7 +10790,7 @@ const level = {
ctx.fillText("!", 2700, -14350);
ctx.shadowBlur = 0;
}
me.do = function () {
me.do = function() {
this.checkStatus();
this.horizon();
this.ring();
@@ -10821,7 +10811,7 @@ const level = {
let bounds = [];
let mobPositionsQueue = Array.from(Array(10), () => []);
m.oldDeath = m.death;
m.death = function () {
m.death = function() {
if (!tech.isImmortal) {
requestAnimationFrame(() => color.map = "#444");
m.death = m.oldDeath;
@@ -10932,7 +10922,7 @@ const level = {
spawn.mapRect(-500, -8250, 800, 20);
for (let i = 0; i < 2; i++) spawn.mapRect(-250, -8400 + 150 * i, 500, 60);
const room2SlimePit = level.hazard(-400, -8410, 800, 1090);
room2SlimePit.logic = function () {
room2SlimePit.logic = function() {
if (this.height > 0 && Matter.Query.region([player], this).length) {
if (m.immuneCycle < m.cycle) {
// Trolled
@@ -10972,7 +10962,7 @@ const level = {
});
}
}
room2SlimePit.draw = function () {
room2SlimePit.draw = function() {
if (this.isOn) {
ctx.fillStyle = "hsla(160, 100%, 35%, 0.75)";
ctx.fillRect(this.min.x, this.min.y, this.width, this.height);
@@ -11174,7 +11164,7 @@ const level = {
}
},
room2GeneratedPath: {
rects: (function () {
rects: (function() {
const rects = [];
for (let i = 0; i < 4; i++) {
rects.push(new Rect(-1405 + (i & 1) * 200, -9700 + i * 300, 205, 30));
@@ -11205,16 +11195,16 @@ const level = {
}
},
room3Rotors: {
rotor1: (function () {
rotor1: (function() {
const rotor = level.spinner(900, -13700, 200, 30);
rotor.rotate = function () {
rotor.rotate = function() {
Matter.Body.setAngularVelocity(this.bodyB, (this.bodyB.angularVelocity + 0.01) * 0.9)
}
return rotor;
})(),
rotor2: (function () {
rotor2: (function() {
const rotor = level.spinner(2700, -13700, 200, 30);
rotor.rotate = function () {
rotor.rotate = function() {
Matter.Body.setAngularVelocity(this.bodyB, (this.bodyB.angularVelocity - 0.01) * 0.9)
}
return rotor;
@@ -12170,7 +12160,7 @@ const level = {
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob | cat.bullet
me.g = simulation.g
me.leaveBody = me.isDropPowerUp = false
me.do = function () {
me.do = function() {
this.gravity()
// apply shock damage when touching the map, if it's fast
if (this.speed > 5) {
@@ -12185,7 +12175,7 @@ const level = {
this.fill = `rgb(${232 * this.health}, 191, 40)`
}
me.onDeath = function () {
me.onDeath = function() {
const END = Math.floor(input.down ? 10 : 7)
const totalBullets = 10
const angleStep = (input.down ? 0.4 : 1.3) / totalBullets
@@ -12209,16 +12199,16 @@ const level = {
x: speed * Math.cos(dirOff),
y: speed * Math.sin(dirOff)
})
bullet[me].onEnd = function () {
bullet[me].onEnd = function() {
b.explosion(
this.position,
150 + (Math.random() - 0.5) * 40
) //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function () {
bullet[me].beforeDmg = function() {
this.endCycle = 0 //bullet ends cycle after hitting a mob and triggers explosion
}
bullet[me].do = function () {}
bullet[me].do = function() {}
Composite.add(engine.world, bullet[me]) //add bullet to world
}
// barrels drop a ton of ammo and some heals, scales up with difficulty because I have mercy
@@ -12326,7 +12316,7 @@ const level = {
mobs.spawn(x, y + chainLength + radius * 2, 4, trappedMob.radius + 50, 'rgba(150, 255, 150, 0.3)')
const cage = mob[mob.length - 1]
cage.g = simulation.g
cage.do = function () {
cage.do = function() {
this.gravity()
}
// label it
@@ -12624,7 +12614,7 @@ const level = {
const color = `rgba(${150 + 105 * charge}, 81, 50, 0.6)`
mobs.spawn(origin.x, origin.y, 12, 20 + 20 * charge, color)
const me = mob[mob.length - 1]
me.end = function () {
me.end = function() {
simulation.drawList.push({
// some nice graphics
x: this.position.x,
@@ -12647,7 +12637,7 @@ const level = {
me.life = 0
me.isDropPowerUp = false
me.leaveBody = false
me.do = function () {
me.do = function() {
// die on collision with the map
if (Matter.Query.collides(this, map).length > 0) {
this.end()
@@ -12710,7 +12700,7 @@ const level = {
me.bossPos = null // the position that the mob remembers when charging
me.density = me.density * 2
Matter.Body.setDensity(me, 0.0022 * 3 + 0.0002 * Math.sqrt(simulation.difficulty)) //extra dense
me.do = function () {
me.do = function() {
// if the boss is dead, die
if (!parentBoss.alive) {
this.death()
@@ -12778,7 +12768,7 @@ const level = {
// draw energy bar
drawEnergyBar(this)
}
me.onDeath = function () {
me.onDeath = function() {
// remove itself from the list
const beacons = parentBoss.energyBeacons
beacons.splice(beacons.indexOf(this), 1)
@@ -12823,7 +12813,7 @@ const level = {
me.showHealthBar = false
me.collisionFilter.category = cat.mobBullet
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet
me.do = function () {
me.do = function() {
this.alwaysSeePlayer()
this.attraction()
this.timeLimit()
@@ -12854,7 +12844,7 @@ const level = {
// ctx.fillStyle = 'rgba(252, 0, 143, 1)'
// ctx.fillText(~~this.score, this.position.x - this.radius, this.position.y - this.radius)
}
me.onHit = function () {
me.onHit = function() {
// hitting the player gives a 50 points score bonus
this.score += 50
this.score += this.mass * 2 // bigger mass = bigger damage, add that too
@@ -12862,7 +12852,7 @@ const level = {
this.hitPlayer = true
this.explode(this.mass)
}
me.onDeath = function () {
me.onDeath = function() {
if (!this.hitPlayer) {
// if it didn't hit the player, give it a score based on its distance
this.score += 10000 / this.distanceToPlayer()
@@ -12916,7 +12906,7 @@ const level = {
me.laserRange = radius * 4
Matter.Body.setDensity(me, 0.0022 * 4 + 0.0002 * Math.sqrt(simulation.difficulty)) //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () {
me.onDeath = function() {
if (spawnBossPowerUp) {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
const amount = ~~(5 * Math.random() * simulation.difficulty / 10) * 2
@@ -12935,8 +12925,8 @@ const level = {
// stop spawning barrels
bossInit = false
}
me.onDamage = function () {}
me.spawnBeacon = function () {
me.onDamage = function() {}
me.spawnBeacon = function() {
// the vertex to spawn the beacon from
const vert = this.vertices[~~(Math.random() * this.vertices.length)]
// the position should be a little to the side to prevent crashing into the boss
@@ -12952,7 +12942,7 @@ const level = {
y: this.velocity.y + velocity.y
})
}
me.spawnOrbs = function () {
me.spawnOrbs = function() {
Matter.Body.setAngularVelocity(this, 0.11)
// sort the vertices by the distance to the player
const sorted = [...this.vertices].sort(dist2)
@@ -13009,7 +12999,7 @@ const level = {
})
}
}
me.do = function () {
me.do = function() {
this.seePlayerCheck()
this.checkStatus()
this.attraction()

View File

@@ -423,7 +423,7 @@ const m = {
m.health = 1;
// m.addHealth(1)
simulation.wipe = function () { //set wipe to have trails
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
@@ -433,8 +433,8 @@ const m = {
m.switchWorlds()
const swapPeriod = 1000
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function () {
simulation.wipe = function () { //set wipe to have trails
setTimeout(function() {
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
@@ -444,14 +444,14 @@ const m = {
simulation.isTextLogOpen = true;
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len - i - 1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function () { //set wipe to have trails
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i + 1) * (i + 1) * 0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}, (i + 1) * swapPeriod);
}
setTimeout(function () {
simulation.wipe = function () { //set wipe to normal
setTimeout(function() {
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
simulation.isTextLogOpen = true;
@@ -467,7 +467,7 @@ const m = {
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
document.getElementById("fade-out").style.opacity = 0.9; //slowly fade to 90% white on top of canvas
// build.shareURL(false)
setTimeout(function () {
setTimeout(function() {
Composite.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
@@ -642,7 +642,7 @@ const m = {
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
let isDrawPlayer = true
const shortPause = function () {
const shortPause = function() {
if (m.defaultFPSCycle < m.cycle) { //back to default values
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
@@ -716,13 +716,13 @@ const m = {
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
m.energy = m.maxEnergy
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function () { //set wipe to have trails
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
setTimeout(function() {
tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -745,13 +745,13 @@ const m = {
<br>${powerUps.research.count}`)
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function () { //set wipe to have trails
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
setTimeout(function() {
tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -771,7 +771,7 @@ const m = {
if (dmg > 0.06 / m.holdingMassScale) m.drop(); //drop block if holding // m.holdingMassScale = 0.5 for most fields
if (m.isCloak) m.fireCDcycle = m.cycle //forced exit cloak
}
const normalFPS = function () {
const normalFPS = function() {
if (m.defaultFPSCycle < m.cycle) { //back to default values
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
@@ -1058,7 +1058,7 @@ const m = {
ctx.fillRect(xOff, yOff, range * m.energy, 10);
}
},
drawRegenEnergyCloaking: function () {
drawRegenEnergyCloaking: function() {
if (m.energy < m.maxEnergy) { // replaces m.drawRegenEnergy() with custom code
m.regenEnergy();
const xOff = m.pos.x - m.radius * m.maxEnergy
@@ -1090,11 +1090,11 @@ const m = {
m.fieldRegen *= 0.6
}
},
regenEnergy: function () { //used in drawRegenEnergy // rewritten by some tech
regenEnergy: function() { //used in drawRegenEnergy // rewritten by some tech
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0
},
regenEnergyDefault: function () {
regenEnergyDefault: function() {
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0
},
@@ -1279,7 +1279,7 @@ const m = {
m.holdingTarget.friction = m.holdingTarget.frictionStatic = m.holdingTarget.frictionAir = 0.001
}
//check every second to see if player is away from thrown body, and make solid
const solid = function (that) {
const solid = function(that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
@@ -1311,7 +1311,7 @@ const m = {
m.definePlayerMass() //return to normal player mass
if (tech.isAddBlockMass) {
const expand = function (that, massLimit) {
const expand = function(that, massLimit) {
if (that.mass < massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
@@ -1698,7 +1698,7 @@ const m = {
description: `use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs
<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
effect: () => {
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -1796,7 +1796,7 @@ const m = {
} else {
m.harmonicShield = m.harmonicAtomic
}
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -1976,7 +1976,7 @@ const m = {
}
}
}
m.hold = function () {
m.hold = function() {
const wave = Math.sin(m.cycle * 0.022);
m.fieldRange = 180 + 12 * wave + 100 * tech.isBigField
m.fieldArc = 0.35 + 0.045 * wave + 0.065 * tech.isBigField //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
@@ -1987,8 +1987,12 @@ const m = {
m.throwBlock();
} else if (input.field) { //not hold but field button is pressed
//float while field is on
// console.log(m.angle, Math.abs(m.angle + Math.PI / 2))
//
const angleReduction = 0.1 + (Math.PI / 2 - Math.min(Math.PI / 2, Math.abs(m.angle + Math.PI / 2)))
if (player.velocity.y > 1) {
player.force.y -= (tech.isBigField ? 0.87 : 0.7) * player.mass * simulation.g;
player.force.y -= angleReduction * (tech.isBigField ? 0.87 : 0.7) * player.mass * simulation.g;
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: 0.98 * player.velocity.y
@@ -2084,7 +2088,7 @@ const m = {
m.fieldHarmReduction = 0.45; //55% reduction
m.fieldDrawRadius = 0;
m.hold = function () {
m.hold = function() {
m.airSpeedLimit = 125 //5 * player.mass * player.mass
m.FxAir = 0.016
if (m.isHolding) {
@@ -2234,7 +2238,7 @@ const m = {
effect: () => {
m.fieldMeterColor = "#ff0"
m.eyeFillColor = m.fieldMeterColor
m.hold = function () {
m.hold = function() {
if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 300 && (m.cycle % 2)) {
if (simulation.molecularMode === 0) {
if (tech.isSporeFlea) {
@@ -2621,7 +2625,7 @@ const m = {
Composite.add(engine.world, m.plasmaBall);
// m.plasmaBall.startingVertices = m.plasmaBall.vertices.slice();
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2712,7 +2716,7 @@ const m = {
m.plasmaBall.do()
}
} else if (tech.isExtruder) {
m.hold = function () {
m.hold = function() {
b.isExtruderOn = false
if (m.isHolding) {
m.drawHold(m.holdingTarget);
@@ -2754,7 +2758,7 @@ const m = {
ctx.stroke();
}
} else {
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2818,7 +2822,7 @@ const m = {
if (tech.isRewindField) {
this.rewindCount = 0
m.grabPowerUpRange2 = 300000
m.hold = function () {
m.hold = function() {
// console.log(m.fieldCDcycle)
m.grabPowerUp();
// //grab power ups
@@ -2914,7 +2918,7 @@ const m = {
} else {
m.fieldFire = true;
m.isBodiesAsleep = false;
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.wakeCheck();
m.drawHold(m.holdingTarget);
@@ -2981,7 +2985,7 @@ const m = {
m.isSneakAttack = true;
m.sneakAttackCycle = 0;
m.enterCloakCycle = 0;
m.drawCloak = function () {
m.drawCloak = function() {
m.fieldPhase += 0.007
const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5)
ctx.beginPath();
@@ -2995,7 +2999,7 @@ const m = {
ctx.globalCompositeOperation = "source-over";
ctx.clip();
}
m.hold = function () {
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -3275,7 +3279,7 @@ const m = {
m.fieldOn = false;
m.fieldRadius = 0;
m.drop();
m.hold = function () {
m.hold = function() {
if (input.field) {
if (m.fieldCDcycle < m.cycle) {
const scale = 25
@@ -3459,7 +3463,7 @@ const m = {
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+3%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
drain: 0,
effect: function () {
effect: function() {
m.fieldMeterColor = "#bbf" //"#0c5"
m.eyeFillColor = m.fieldMeterColor
@@ -3467,7 +3471,7 @@ const m = {
m.fieldRange = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
m.hold = function () {
m.hold = function() {
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference
// isOn: false,
// isReady: true,

View File

@@ -322,7 +322,7 @@ const powerUps = {
document.getElementById("choose-grid").style.visibility = "visible"
requestAnimationFrame(() => {
ctx.fillStyle = `rgba(221,221,221,0.6)`;
ctx.fillStyle = `rgba(150,150,150,0.6)`; //`rgba(221,221,221,0.6)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
// document.getElementById("pause-grid-right").style.opacity = "0.7"
@@ -378,9 +378,6 @@ const powerUps = {
// document.getElementById("choose-grid").style.display = "none"
document.getElementById("choose-grid").style.visibility = "hidden"
document.getElementById("choose-grid").style.opacity = "0"
// document.getElementById("choose-background").style.display = "none"
document.getElementById("choose-background").style.visibility = "hidden"
document.getElementById("choose-background").style.opacity = "0"
document.body.style.cursor = "none";
// document.body.style.overflow = "hidden"
@@ -623,21 +620,21 @@ const powerUps = {
if (tech.isSuperDeterminism) {
return `<div></div>`
} else if (tech.isCancelTech) {
return `<div class='choose-grid-module' onclick='powerUps.endDraft("${type}",true)' style="width: 115px; text-align: center;font-size: 1.1em;font-weight: 100;justify-self: end;">randomize</div>`
return `<div class='choose-grid-module' onclick='powerUps.endDraft("${type}",true)' style="width: 115px; text-align: center;font-size: 1.1em;font-weight: 100;justify-self: end;border: 1px solid #444;">randomize</div>`
} else {
return `<div class='choose-grid-module' onclick='powerUps.endDraft("${type}",true)' style="width: 82px; text-align: center;font-size: 1.1em;font-weight: 100;justify-self: end;">cancel</div>`
return `<div class='choose-grid-module' onclick='powerUps.endDraft("${type}",true)' style="width: 82px; text-align: center;font-size: 1.1em;font-weight: 100;justify-self: end;border: 1px solid #444;">cancel</div>`
}
},
researchText(type) {
let text = ""
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module' style="font-size: 1.1em;font-weight: 100;">` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module' style="font-size: 1.1em;font-weight: 100;border: 1px solid #444;">` // style = "margin-left: 192px; margin-right: -192px;"
tech.junkResearchNumber = Math.ceil(4 * Math.random())
text += `<div><div> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div></div>`
} else if (powerUps.research.count > 0) {
text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module' style="font-size: 1.1em;font-weight: 100;">` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module' style="font-size: 1.1em;font-weight: 100;border: 1px solid #444;">` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div><div><span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.21)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div></div>`
@@ -649,7 +646,6 @@ const powerUps = {
hideStyle: `style="height:auto; border: none; background-color: transparent;"`,
gunText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choose].name}</div>
@@ -657,16 +653,14 @@ const powerUps = {
},
fieldText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[choose].name}${choose === 0 ? Math.floor(Math.random()*10) : ""}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choose].name}</div>
${m.fieldUpgrades[choose].description}</div></div>`
},
techText(choose, click) {
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
@@ -674,9 +668,8 @@ const powerUps = {
},
fieldTechText(choose, click) {
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title">
@@ -688,9 +681,8 @@ const powerUps = {
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
},
gunTechText(choose, click) {
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title">
@@ -702,28 +694,33 @@ const powerUps = {
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
},
junkTechText(choose, click) {
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;"`
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
if (!localSettings.isHideImages) {
setTimeout(() => { //pull image from web search if no url
if (tech.tech[choose].url === undefined) {
setTimeout(() => { //delay so that the html element exists
if (tech.tech[choose].url === undefined) { //if on url has been set yet
const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
fetch(url)
fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
.then((response) => response.text())
.then((html) => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const elements = doc.getElementsByClassName("ld");
// console.log(JSON.parse(elements[i].getAttribute("data")).iurl)
tech.tech[choose].url = JSON.parse(elements[i].getAttribute("data")).iurl
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
} else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
}
});
} else {
document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
}
}, 100);
}, 1);
}
return `<div id = "junk-${choose}" class="choose-grid-module card-background" onclick="${click}" ${style}>
<div class="card-text">
<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
@@ -731,7 +728,6 @@ const powerUps = {
},
incoherentTechText(choose, click) {
// text += `<div class="choose-grid-module" style = "background-color: #efeff5; border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[choose].name} <span style = "color: #aaa;font-weight: normal;font-size:80%;">- incoherent</span></div></div>`
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" ${style}>
<div class="card-text" style = "background-color: #efeff5;">
@@ -801,7 +797,7 @@ const powerUps = {
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
text += `<div class="choose-grid-module card-background" onclick="powerUps.choose('tech',${choose})" ${style}>
<div class="card-text">
@@ -880,7 +876,7 @@ const powerUps = {
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
text += `<div class="choose-grid-module card-background" onclick="powerUps.choose('tech',${choose})" ${style}>
<div class="card-text">
@@ -1001,7 +997,7 @@ const powerUps = {
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div> ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const techCountText = tech.tech[choose].count > 1 ? `(${tech.tech[choose].count}x)` : "";
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
text += `<div class="choose-grid-module card-background" onclick="powerUps.choose('tech',${choose})" ${style}>
<div class="card-text">

View File

@@ -546,16 +546,16 @@ const simulation = {
const swapPeriod = 150
const len = 30
for (let i = 0; i < len; i++) {
setTimeout(function () {
simulation.wipe = function () { //set wipe to have trails
setTimeout(function() {
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(221,221,221,${i*i*0.0005 +0.0025})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}, (i) * swapPeriod);
}
setTimeout(function () {
simulation.wipe = function () { //set wipe to normal
setTimeout(function() {
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, len * swapPeriod);
@@ -616,14 +616,11 @@ const simulation = {
simulation.clearTimeouts();
simulation.onTitlePage = true;
document.getElementById("splash").onclick = function () {
document.getElementById("splash").onclick = function() {
simulation.startGame();
};
// document.getElementById("choose-grid").style.display = "none"
document.getElementById("choose-grid").style.visibility = "hidden"
document.getElementById("choose-grid").style.opacity = "0"
document.getElementById("choose-background").style.visibility = "hidden"
document.getElementById("choose-background").style.opacity = "0"
document.getElementById("info").style.display = "inline";
document.getElementById("info").style.opacity = "0";
document.getElementById("experiment-button").style.display = "inline"
@@ -782,7 +779,7 @@ const simulation = {
// m.maxEnergy = 1
// m.energy = 1
input.isPauseKeyReady = true
simulation.wipe = function () { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
m.hole.isOn = false
@@ -863,7 +860,7 @@ const simulation = {
requestAnimationFrame(cycle); //starts game loop
},
clearTimeouts() {
let id = window.setTimeout(function () {}, 0);
let id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
@@ -1200,7 +1197,7 @@ const simulation = {
}
if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to damage for 60 cycles
fallCheck = function (who, save = false) {
fallCheck = function(who, save = false) {
let i = who.length;
while (i--) {
if (who[i].position.y > simulation.fallHeight) {
@@ -1584,9 +1581,9 @@ const simulation = {
outHTML += "<div>" + simulation.constructMapString[i] + "</div>"
}
console.log(out)
navigator.clipboard.writeText(out).then(function () {
navigator.clipboard.writeText(out).then(function() {
/* clipboard successfully set */
}, function () {
}, function() {
/* clipboard write failed */
console.log('copy failed')
});

View File

@@ -397,6 +397,8 @@ const spawn = {
//spawn 6 mobs
me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; //fire a bullet from each vertex
for (let i = 0; i < 6; i++) me.spawnMobs(i)
level.newLevelOrPhase() //run some new level tech effects
}
ctx.beginPath(); //draw invulnerable
let vertices = this.vertices;
@@ -499,36 +501,32 @@ const spawn = {
{
name: "mines",
bombCycle: 0,
bombInterval: 55 - 2 * simulation.difficultyMode,
bombInterval: 10 - simulation.difficultyMode,
do() {
const yOff = 120
this.bombCycle++
if (!(this.bombCycle % this.bombInterval) && (this.bombCycle & 60) > 30) { //mines above player
if (!(this.bombCycle % this.bombInterval) && (this.bombCycle % 660) > 330) { //mines above player
if (simulation.isHorizontalFlipped) {
if (this.bombCycle > 120) { //wait 2 seconds before targeted mines drop
const x = m.pos.x + 200 * (Math.random() - 0.5)
if (x > -750) { //mines above player IN tunnel
spawn.mine(Math.min(Math.max(-730, x), 100), -450 - yOff * Math.random()) //player in main room
mob[mob.length - 1].fallHeight = -209
} else { //mines above player NOT in tunnel
spawn.mine(Math.min(Math.max(-5375, x), -765), -1500 - yOff * Math.random()) //player in tunnel
mob[mob.length - 1].fallHeight = -9
}
const x = m.pos.x + 200 * (Math.random() - 0.5)
if (x > -750) { //mines above player IN tunnel
spawn.mine(Math.min(Math.max(-730, x), 100), -450 - yOff * Math.random()) //player in main room
mob[mob.length - 1].fallHeight = -209
} else { //mines above player NOT in tunnel
spawn.mine(Math.min(Math.max(-5375, x), -765), -1500 - yOff * Math.random()) //player in tunnel
mob[mob.length - 1].fallHeight = -9
}
if (Math.random() < 0.5) {
spawn.mine(-5350 + 4550 * Math.random(), -1500 - yOff * Math.random()) //random mines
mob[mob.length - 1].fallHeight = -9
}
} else {
if (this.bombCycle > 120) { //wait 2 seconds before targeted mines drop
const x = m.pos.x + 200 * (Math.random() - 0.5)
if (x < 750) { //mines above player IN tunnel
spawn.mine(Math.min(Math.max(-100, x), 735), -450 - yOff * Math.random()) //player in main room
mob[mob.length - 1].fallHeight = -209
} else { //mines above player NOT in tunnel
spawn.mine(Math.min(Math.max(760, x), 5375), -1500 - yOff * Math.random()) //player in tunnel
mob[mob.length - 1].fallHeight = -9
}
const x = m.pos.x + 200 * (Math.random() - 0.5)
if (x < 750) { //mines above player IN tunnel
spawn.mine(Math.min(Math.max(-100, x), 735), -450 - yOff * Math.random()) //player in main room
mob[mob.length - 1].fallHeight = -209
} else { //mines above player NOT in tunnel
spawn.mine(Math.min(Math.max(760, x), 5375), -1500 - yOff * Math.random()) //player in tunnel
mob[mob.length - 1].fallHeight = -9
}
if (Math.random() < 0.5) { //random mines, but not in tunnel
spawn.mine(800 + 4550 * Math.random(), -1500 - yOff * Math.random()) //random mines
@@ -561,12 +559,17 @@ const spawn = {
},
{
name: "orbiters",
spawnRate: 42 - 2 * simulation.difficultyMode,
spawnRate: Math.ceil(4 - 0.25 * simulation.difficultyMode),
orbitersCycle: 0,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
this.orbitersCycle++
if (!(this.orbitersCycle % this.spawnRate) && (this.orbitersCycle % 660) > 600 && mob.length < me.maxMobs) {
const speed = (0.01 + 0.0005 * simulation.difficultyMode) * ((Math.random() < 0.5) ? 0.85 : -1.15)
const phase = 0 //Math.floor(2 * Math.random()) * Math.PI
me.orbitalNoVelocity(me, 360 + 2150 * Math.random(), 0.1 * Math.random() + phase, speed) // orbital(who, radius, phase, speed)
//find distance to play and set orbs at that range
const dist = me.distanceToPlayer()
//360 + 2150 * Math.random()
me.orbitalNoVelocity(me, dist + 900 * (Math.random() - 0.5), 0.1 * Math.random() + phase, speed) // orbital(who, radius, phase, speed)
}
},
enter() {},
@@ -706,6 +709,7 @@ const spawn = {
this.damageReductionDecay();
for (let i = 0; i < this.totalModes; i++) this.mode[i].do()
}
// this.mode[5].do() //deelete this
// this.cycle++;
// this.mode[4].do()
// this.mode[7].do()
@@ -1537,16 +1541,18 @@ const spawn = {
zombie(x, y, radius, sides, color) { //mob that attacks other mobs
mobs.spawn(x, y, sides, radius, color);
let me = mob[mob.length - 1];
me.damageReduction = 0.5 //take less damage
// Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
me.isZombie = true
me.isBadTarget = true;
me.isDropPowerUp = false;
me.showHealthBar = false;
me.stroke = "#83a"
me.accelMag = 0.0015
me.frictionAir = 0.01
// me.repulsionRange = 400000 + radius * radius; //squared
// me.collisionFilter.mask = cat.player | cat.map | cat.body
// me.memory = 120;
me.seeAtDistance2 = 1000000 //1000 vision range
// Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
me.do = function() {
this.zombieHealthBar();
this.lookForMobTargets();
@@ -1556,15 +1562,31 @@ const spawn = {
me.mobSearchIndex = 0;
me.target = null
me.lookForMobTargets = function() {
if (this.target && !this.target.alive) this.target = null
if (this.target === null && !(simulation.cycle % 10) && mob.length > 1) { //if you have no target
this.mobSearchIndex++ //look for a different mob index every time
if (this.mobSearchIndex > mob.length - 1) this.mobSearchIndex = 0
if (!(simulation.cycle % 10)) {
if (this.target === null) { //if you have no target
this.mobSearchIndex++ //look for a different mob index every time
if (this.mobSearchIndex > mob.length - 1) this.mobSearchIndex = 0
if (
mob.length > 1 &&
!mob[this.mobSearchIndex].isZombie &&
(Vector.magnitudeSquared(Vector.sub(this.position, mob[this.mobSearchIndex].position)) < this.seeAtDistance2 && Matter.Query.ray(map, this.position, mob[this.mobSearchIndex].position).length === 0)
) {
this.target = mob[this.mobSearchIndex]
} else if (Math.random() < 0.05 && (Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < this.seeAtDistance2 || Matter.Query.ray(map, this.position, player.position).length === 0)) {
this.target = player
this.isBadTarget = false;
}
}
}
//chance to forget target
if (!(simulation.cycle % this.memory) && this.target) {
if (
!mob[this.mobSearchIndex].isZombie &&
(Vector.magnitudeSquared(Vector.sub(this.position, mob[this.mobSearchIndex].position)) < this.seeAtDistance2 || Matter.Query.ray(map, this.position, mob[this.mobSearchIndex].position).length === 0)
(this.target && this.target !== player && !this.target.alive) ||
Vector.magnitudeSquared(Vector.sub(this.position, this.target.position)) > this.seeAtDistance2 ||
Matter.Query.ray(map, this.position, this.target.position).length !== 0
) {
this.target = mob[this.mobSearchIndex]
if (this.target === player) this.isBadTarget = true
this.target = null
}
}
}
@@ -1600,13 +1622,11 @@ const spawn = {
const force = Vector.mult(Vector.normalise(Vector.sub(who.position, this.position)), 0.03 * this.mass)
this.force.x -= force.x;
this.force.y -= force.y;
this.target = null //look for a new target
const dmg = 0.3 * m.dmgScale
who.damage(dmg);
who.locatePlayer();
simulation.drawList.push({
x: this.position.x,
y: this.position.y,

View File

@@ -1854,7 +1854,7 @@ const tech = {
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after a <strong>collision</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
nameInfo: "<span id = 'tech-flip-flop'></span>",
addNameInfo() {
setTimeout(function () {
setTimeout(function() {
if (document.getElementById("tech-flip-flop")) {
if (tech.isFlipFlopOn) {
document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
@@ -2005,7 +2005,7 @@ const tech = {
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after picking up a <strong>power up</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
nameInfo: "<span id = 'tech-switch'></span>",
addNameInfo() {
setTimeout(function () {
setTimeout(function() {
if (document.getElementById("tech-switch")) {
if (tech.isFlipFlopOn) {
document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
@@ -2408,42 +2408,6 @@ const tech = {
}
}
},
// {
// name: "weak interaction",
// description: "for each unused <strong>power up</strong> at the end of a <strong>level</strong><br><strong>+10</strong> maximum <strong class='color-f'>energy</strong>", // <em>(up to 51 health per level)</em>",
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// allowed() {
// return !tech.isDroneGrab
// },
// requires: "not delivery drone",
// effect() {
// tech.isExtraMaxEnergy = true; //tracked by tech.extraMaxHealth
// },
// remove() {
// tech.isExtraMaxEnergy = false;
// }
// },
// {
// name: "electroweak interaction",
// description: "unused <strong>power ups</strong> at the end of a <strong>level</strong><br>are still activated <em>(selections are random)</em>",
// maxCount: 1,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return tech.isExtraMaxEnergy
// },
// requires: "weak interaction",
// effect() {
// tech.isEndLevelPowerUp = true;
// },
// remove() {
// tech.isEndLevelPowerUp = false;
// }
// },
{
name: "electronegativity",
descriptionFunction() {
@@ -2609,7 +2573,7 @@ const tech = {
requires: "not parasitism",
effect() {
tech.isCrouchRegen = true; //only used to check for requirements
m.regenEnergy = function () {
m.regenEnergy = function() {
if (m.immuneCycle < m.cycle && m.crouch) m.energy += 7 * m.fieldRegen;
if (m.energy < 0) m.energy = 0
}
@@ -2650,7 +2614,7 @@ const tech = {
requires: "not inductive charging",
effect() {
tech.isDamageAfterKillNoRegen = true;
m.regenEnergy = function () {
m.regenEnergy = function() {
if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle)) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0
}
@@ -3011,7 +2975,7 @@ const tech = {
name: "anthropic principle",
nameInfo: "<span id = 'tech-anthropic'></span>",
addNameInfo() {
setTimeout(function () {
setTimeout(function() {
powerUps.research.changeRerolls(0)
}, 1000);
},
@@ -3030,7 +2994,7 @@ const tech = {
effect() {
tech.isDeathAvoid = true;
tech.isDeathAvoidedThisLevel = false;
setTimeout(function () {
setTimeout(function() {
powerUps.research.changeRerolls(0)
}, 1000);
},
@@ -8421,7 +8385,7 @@ const tech = {
const loop = () => {
if ((simulation.isChoosing) && m.alive && !build.isExperimentSelection) {
const dmg = Math.floor(33 * Math.random()) * 0.01
this.text = `<strong style = "font-family: 'Courier New', monospace;">+${(dmg*100).toFixed(0).padStart(2, '0')}%</strong> <strong class='color-d'>damage</strong>`
this.text = `<strong style = "font-family: 'Courier New', monospace;">+${(dmg*100).toFixed(0).padStart(2, '0')}%</strong> <strong class='color-d'>damage</strong><br>&nbsp;`
this.damage = 1 + dmg
if (document.getElementById(`damage-JUNK-id${this.id}`)) document.getElementById(`damage-JUNK-id${this.id}`).innerHTML = this.text
setTimeout(() => {
@@ -8548,7 +8512,7 @@ const tech = {
},
{
name: "meteor shower",
description: "take a shower, but meteors instead of water",
description: "take a shower, but meteors instead of water<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -8559,7 +8523,7 @@ const tech = {
effect() {
setInterval(() => {
fireBlock = function (xPos, yPos) {
fireBlock = function(xPos, yPos) {
const index = body.length
spawn.bodyRect(xPos, yPos, 20 + 50 * Math.random(), 20 + 50 * Math.random());
const bodyBullet = body[index]
@@ -8694,7 +8658,7 @@ const tech = {
// },
{
name: "discount",
description: "get 3 random <strong class='color-j'>JUNK</strong><strong class='color-m'>tech</strong> for the price of 1!",
description: "get 3 random <strong class='color-j'>JUNK</strong><strong class='color-m'>tech</strong> for the price of 1!<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -8763,7 +8727,7 @@ const tech = {
},
{
name: "harvest",
description: "convert all the mobs on this level into <strong class='color-ammo'>ammo</strong>",
description: "convert all the mobs on this level into <strong class='color-ammo'>ammo</strong><br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -8788,19 +8752,6 @@ const tech = {
},
remove() {}
},
{
name: "&nbsp;",
description: "",
maxCount: 1,
count: 0,
frequency: 0,
frequencyDefault: 0,
isJunk: true,
allowed: () => true,
requires: "",
effect() {},
remove() {}
},
{
name: "brainstorm",
description: "the <strong class='color-m'>tech</strong> choice menu <strong>randomizes</strong><br>every <strong>0.5</strong> seconds for <strong>10</strong> seconds",
@@ -8843,7 +8794,7 @@ const tech = {
},
{
name: "palantír",
description: `see far away lands`,
description: `see far away lands<br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -8874,7 +8825,7 @@ const tech = {
},
{
name: "motion sickness",
description: `disable camera smoothing`,
description: `disable camera smoothing<br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -8907,7 +8858,7 @@ const tech = {
},
{
name: "facsimile",
description: `inserts a copy of your current level into the level list`,
description: `inserts a copy of your current level into the level list<br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -8943,7 +8894,7 @@ const tech = {
},
{
name: "bounce",
description: "you bounce off things. It's annoying, but not that bad.",
description: "you bounce off things. It's annoying, but not that bad.<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -8961,7 +8912,7 @@ const tech = {
},
{
name: "mouth",
description: "mobs have a non functional mouth",
description: "mobs have a non functional mouth<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9007,7 +8958,7 @@ const tech = {
},
{
name: "all-stars",
description: "make all mobs look like stars",
description: "make all mobs look like stars<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9068,7 +9019,7 @@ const tech = {
// },
{
name: "true colors",
description: `set all power ups to their real world colors`,
description: `set all power ups to their real world colors<br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -9283,7 +9234,7 @@ const tech = {
},
{
name: "not a bug",
description: "initiate a totally safe game crash for 10 seconds",
description: "initiate a totally safe game crash for 10 seconds<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9310,7 +9261,7 @@ const tech = {
},
{
name: "spinor",
description: "the direction you aim is determined by your position",
description: "the direction you aim is determined by your position<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9321,7 +9272,7 @@ const tech = {
},
requires: "",
effect() {
m.look = function () {
m.look = function() {
//always on mouse look
m.angle = (((m.pos.x + m.pos.y) / 100 + Math.PI) % Math.PI * 2) - Math.PI
//smoothed mouse look translations
@@ -9339,7 +9290,7 @@ const tech = {
},
{
name: "decomposers",
description: "after they die <strong>mobs</strong> leave behind <strong>spawns</strong>",
description: "after they die <strong>mobs</strong> leave behind <strong>spawns</strong><br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9358,7 +9309,7 @@ const tech = {
},
{
name: "panopticon",
description: "<strong>mobs</strong> can always see you",
description: "<strong>mobs</strong> can always see you<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9482,7 +9433,7 @@ const tech = {
},
{
name: "encryption",
description: "secure <strong class='color-m'>tech</strong> information",
description: "secure <strong class='color-m'>tech</strong> information<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9493,7 +9444,7 @@ const tech = {
},
requires: "",
effect() {
String.prototype.shuffle = function () {
String.prototype.shuffle = function() {
var a = this.split(""),
n = a.length;
@@ -9532,7 +9483,7 @@ const tech = {
},
{
name: "score",
description: "Add a score to n-gon!",
description: "Add a score to n-gon!<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9571,7 +9522,7 @@ const tech = {
},
{
name: "music",
description: "add music to n-gon",
description: "add music to n-gon<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9588,7 +9539,7 @@ const tech = {
},
{
name: "performance",
description: "display performance stats to n-gon",
description: "display performance stats to n-gon<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9599,9 +9550,9 @@ const tech = {
},
requires: "",
effect() {
(function () {
(function() {
var script = document.createElement('script');
script.onload = function () {
script.onload = function() {
var stats = new Stats();
document.body.appendChild(stats.dom);
requestAnimationFrame(function loop() {
@@ -9644,7 +9595,7 @@ const tech = {
},
{
name: "defragment",
description: "set the <strong class='flicker'>frequency</strong> of finding <strong class='color-j'>JUNK</strong><strong class='color-m'>tech</strong> to zero",
description: "set the <strong class='flicker'>frequency</strong> of finding <strong class='color-j'>JUNK</strong><strong class='color-m'>tech</strong> to zero<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9684,7 +9635,7 @@ const tech = {
// },
{
name: "pitch",
description: "oscillate the pitch of your world",
description: "oscillate the pitch of your world<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9721,7 +9672,7 @@ const tech = {
},
{
name: "lighter",
description: `ctx.globalCompositeOperation = "lighter"`,
description: `ctx.globalCompositeOperation = "lighter"<br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -9738,7 +9689,7 @@ const tech = {
},
{
name: "rewind",
description: "every 10 seconds <strong class='color-rewind'>rewind</strong> <strong>2</strong> seconds",
description: "every 10 seconds <strong class='color-rewind'>rewind</strong> <strong>2</strong> seconds<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9761,7 +9712,7 @@ const tech = {
},
{
name: "undo",
description: "every 4 seconds <strong class='color-rewind'>rewind</strong> <strong>1/2</strong> a second",
description: "every 4 seconds <strong class='color-rewind'>rewind</strong> <strong>1/2</strong> a second<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9781,7 +9732,7 @@ const tech = {
},
{
name: "energy to mass conversion",
description: "convert your <strong class='color-f'>energy</strong> into <strong class='color-block'>blocks</strong>",
description: "convert your <strong class='color-f'>energy</strong> into <strong class='color-block'>blocks</strong><br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9813,7 +9764,7 @@ const tech = {
},
{
name: "level.nextLevel()",
description: "advance to the next level",
description: "advance to the next level<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9899,7 +9850,7 @@ const tech = {
},
{
name: "missile launching system",
description: "fire missiles for the next 120 seconds",
description: "fire missiles for the next 120 seconds<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9924,7 +9875,7 @@ const tech = {
},
{
name: "grenade production",
description: "drop a grenade every 2 seconds",
description: "drop a grenade every 2 seconds<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -9977,7 +9928,7 @@ const tech = {
// },
{
name: "Sleipnir",
description: "grow more legs",
description: "grow more legs<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9989,7 +9940,7 @@ const tech = {
},
requires: "",
effect() {
m.draw = function () {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -10035,7 +9986,7 @@ const tech = {
},
requires: "",
effect() {
m.draw = function () {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -10064,7 +10015,7 @@ const tech = {
},
{
name: "🐱",
description: "🐈",
description: "🐈<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10076,7 +10027,7 @@ const tech = {
},
requires: "",
effect() {
m.draw = function () {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -10164,7 +10115,7 @@ const tech = {
},
{
name: "posture",
description: "stand a bit taller",
description: "stand a bit taller<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10183,7 +10134,7 @@ const tech = {
},
{
name: "rhythm",
description: "you oscillate up and down",
description: "you oscillate up and down<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10204,7 +10155,7 @@ const tech = {
},
{
name: "pareidolia",
description: "don't",
description: "don't<br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10216,7 +10167,7 @@ const tech = {
},
requires: "",
effect() {
m.draw = function () {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -10273,7 +10224,7 @@ const tech = {
},
{
name: "prism",
description: "you cycle through different <strong>colors</strong>",
description: "you cycle through different <strong>colors</strong><br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10290,7 +10241,7 @@ const tech = {
sat: 100,
light: 50
}
setInterval(function () {
setInterval(function() {
m.color.hue++
m.setFillColors()
}, 10);
@@ -10427,7 +10378,7 @@ const tech = {
},
{
name: "growth hacking",
description: "increase combat <strong>difficulty</strong> by <strong>1 level</strong>",
description: "increase combat <strong>difficulty</strong> by <strong>1 level</strong><br>&nbsp;",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10444,7 +10395,7 @@ const tech = {
},
{
name: "stun",
description: "<strong>stun</strong> all mobs for up to <strong>8</strong> seconds",
description: "<strong>stun</strong> all mobs for up to <strong>8</strong> seconds<br>&nbsp;",
maxCount: 9,
count: 0,
frequency: 0,
@@ -10489,7 +10440,7 @@ const tech = {
},
{
name: "re-research",
description: `<strong>eject</strong> all your ${powerUps.orb.research(1)}`,
description: `<strong>eject</strong> all your ${powerUps.orb.research(1)}<br>&nbsp;`,
maxCount: 9,
count: 0,
frequency: 0,
@@ -10527,7 +10478,7 @@ const tech = {
},
{
name: "black hole cluster",
description: `spawn <strong>30</strong> nearby <strong>black holes</strong>`,
description: `spawn <strong>30</strong> nearby <strong>black holes</strong><br>&nbsp;`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -10755,7 +10706,7 @@ const tech = {
const bc = new BroadcastChannel('planetesimals');
bc.activated = false
bc.onmessage = function (ev) {
bc.onmessage = function(ev) {
if (ev.data === 'tech') powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') {
m.death()
@@ -11056,7 +11007,6 @@ const tech = {
fastTime: null,
squirrelJump: null,
isFastRadiation: null,
isExtraMaxEnergy: null,
isAmmoForGun: null,
isRapidPulse: null,
isSporeFreeze: null,
@@ -11239,7 +11189,6 @@ const tech = {
isHarpoonPowerUp: null,
harpoonDensity: null,
isAddRemoveMaxHealth: null,
isSpawnExitTech: null,
cloakDuplication: null,
extruderRange: null,
isForeverDrones: null,
@@ -11250,11 +11199,9 @@ const tech = {
isFreeWormHole: null,
isRewindField: null,
isCrouchRegen: null,
// OccamDamage: null,
isAxion: null,
isWormholeMapIgnore: null,
isLessDamageReduction: null,
// bulletSize: null,
needleTunnel: null,
isBrainstorm: null,
isBrainstormActive: null,