path intergral
boss orbitals and mineBoss mines are destroyed when you deflect them with your field drones, spores and other bullets that target mobs, will not target invulnerable mobs timeSKipBoss is a bit slower with a bit less time skipping fixed color to better match level background colors JUNK tech: path integral - your next tech choice has almost all possible choices bug fixes
This commit is contained in:
330
js/bullet.js
330
js/bullet.js
@@ -595,7 +595,8 @@ const b = {
|
||||
newDist < dist &&
|
||||
!mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, path[0], mob[i].position).length === 0
|
||||
Matter.Query.ray(body, path[0], mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
dist = newDist
|
||||
best.who = mob[i]
|
||||
@@ -1271,148 +1272,148 @@ const b = {
|
||||
}
|
||||
}
|
||||
},
|
||||
dart(where, angle = m.angle, size = 0.8) {
|
||||
//find a target
|
||||
const closest = {
|
||||
score: 10000,
|
||||
position: null
|
||||
}
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, where, mob[i].position).length === 0) {
|
||||
const dot = Vector.dot({ x: Math.cos(angle), y: Math.sin(angle) }, Vector.normalise(Vector.sub(mob[i].position, where))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||
// if (dist < closest.score && ((dist > 500 && dot > 0) || (dot > 0.9))) { //target closest mob that player is looking at and isn't too close to target
|
||||
if (dist < closest.score && dot > 0.9 - 0.0004 * dist) { //target closest mob that player is looking at and isn't too close to target
|
||||
closest.score = dist
|
||||
closest.position = mob[i].position
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!closest.position) {
|
||||
// const unit = Vector.mult(sub(simulation.mouseInGame, where), 10000)
|
||||
closest.position = Vector.mult(Vector.sub(simulation.mouseInGame, where), 10000)
|
||||
}
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -20 * size, y: 2 * size, index: 0, isInternal: false }, { x: -20 * size, y: -2 * size, index: 1, isInternal: false }, { x: 5 * size, y: -2 * size, index: 4, isInternal: false }, { x: 20 * size, y: 0, index: 3, isInternal: false }, { x: 5 * size, y: 2 * size, index: 4, isInternal: false }], {
|
||||
cycle: 0,
|
||||
angle: angle,
|
||||
friction: 1,
|
||||
frictionAir: 0.15,
|
||||
thrustMag: 0.03,
|
||||
turnRate: 0.15, //0.015
|
||||
drawStringControlMagnitude: 3000 + 5000 * Math.random(),
|
||||
drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
|
||||
dmg: 7, //damage done in addition to the damage from momentum
|
||||
classType: "bullet",
|
||||
endCycle: simulation.cycle + 120,
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
|
||||
},
|
||||
minDmgSpeed: 0,
|
||||
lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||
density: 0.001, //0.001 is normal for blocks, 0.008 is normal for harpoon, 0.008*6 when buffed
|
||||
beforeDmg(who) {
|
||||
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||
who.isShielded = false
|
||||
requestAnimationFrame(() => { who.isShielded = true });
|
||||
}
|
||||
if (tech.fragments) {
|
||||
b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
this.endCycle = 0;
|
||||
}
|
||||
if (!who.isBadTarget) {
|
||||
this.frictionAir = 0.01
|
||||
this.do = this.doNoTargeting
|
||||
}
|
||||
},
|
||||
onEnd() {},
|
||||
doNoTargeting: function() {
|
||||
// this.force.y += this.mass * 0.001;
|
||||
if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
this.collisionFilter.mask = 0;
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
this.do = () => {
|
||||
// if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
|
||||
}
|
||||
}
|
||||
},
|
||||
do() {
|
||||
this.cycle++
|
||||
// if (this.cycle > 40) {
|
||||
// this.frictionAir = 0.003
|
||||
// this.do = this.doNoTargeting
|
||||
// }
|
||||
// if (closest.target) { //rotate towards the target
|
||||
const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) };
|
||||
const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position));
|
||||
const cross = Vector.cross(vectorGoal, face)
|
||||
if (cross > 0.01) {
|
||||
Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross));
|
||||
} else if (cross < 0.01) {
|
||||
Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross)));
|
||||
}
|
||||
this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
|
||||
this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
|
||||
// }
|
||||
if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
this.collisionFilter.mask = 0;
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
this.do = this.doNoTargeting
|
||||
}
|
||||
// else if (!(this.cycle % 2)) { //look for a target if you don't have one
|
||||
// simulation.drawList.push({ //add dmg to draw queue
|
||||
// x: this.position.x,
|
||||
// y: this.position.y,
|
||||
// radius: 10,
|
||||
// color: simulation.mobDmgColor,
|
||||
// time: simulation.drawTime
|
||||
// });
|
||||
// let closest = {
|
||||
// distance: 2000,
|
||||
// target: null
|
||||
// }
|
||||
// const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1
|
||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
// if (
|
||||
// mob[i].alive && !mob[i].isBadTarget &&
|
||||
// Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight
|
||||
// Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors
|
||||
// ) {
|
||||
// const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position))
|
||||
// if (dist < closest.distance) {
|
||||
// closest.distance = dist
|
||||
// closest.target = mob[i]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (closest.target) {
|
||||
// target = closest.target
|
||||
// this.turnRate = 0.05
|
||||
// this.frictionAir = 0.8
|
||||
// }
|
||||
// }
|
||||
},
|
||||
});
|
||||
Matter.Body.setVelocity(bullet[me], {
|
||||
x: m.Vx / 2 + 40 * Math.cos(bullet[me].angle),
|
||||
y: m.Vy / 2 + 40 * Math.sin(bullet[me].angle)
|
||||
});
|
||||
// if (!closest.target) {
|
||||
// bullet[me].frictionAir = 0.002
|
||||
// bullet[me].do = bullet[me].doNoTargeting
|
||||
// }
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
// dart(where, angle = m.angle, size = 0.8) {
|
||||
// //find a target
|
||||
// const closest = {
|
||||
// score: 10000,
|
||||
// position: null
|
||||
// }
|
||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
// if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, where, mob[i].position).length === 0) {
|
||||
// const dot = Vector.dot({ x: Math.cos(angle), y: Math.sin(angle) }, Vector.normalise(Vector.sub(mob[i].position, where))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||
// const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||
// // if (dist < closest.score && ((dist > 500 && dot > 0) || (dot > 0.9))) { //target closest mob that player is looking at and isn't too close to target
|
||||
// if (dist < closest.score && dot > 0.9 - 0.0004 * dist) { //target closest mob that player is looking at and isn't too close to target
|
||||
// closest.score = dist
|
||||
// closest.position = mob[i].position
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (!closest.position) {
|
||||
// // const unit = Vector.mult(sub(simulation.mouseInGame, where), 10000)
|
||||
// closest.position = Vector.mult(Vector.sub(simulation.mouseInGame, where), 10000)
|
||||
// }
|
||||
// const me = bullet.length;
|
||||
// bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -20 * size, y: 2 * size, index: 0, isInternal: false }, { x: -20 * size, y: -2 * size, index: 1, isInternal: false }, { x: 5 * size, y: -2 * size, index: 4, isInternal: false }, { x: 20 * size, y: 0, index: 3, isInternal: false }, { x: 5 * size, y: 2 * size, index: 4, isInternal: false }], {
|
||||
// cycle: 0,
|
||||
// angle: angle,
|
||||
// friction: 1,
|
||||
// frictionAir: 0.15,
|
||||
// thrustMag: 0.03,
|
||||
// turnRate: 0.15, //0.015
|
||||
// drawStringControlMagnitude: 3000 + 5000 * Math.random(),
|
||||
// drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
|
||||
// dmg: 7, //damage done in addition to the damage from momentum
|
||||
// classType: "bullet",
|
||||
// endCycle: simulation.cycle + 120,
|
||||
// collisionFilter: {
|
||||
// category: cat.bullet,
|
||||
// mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
|
||||
// },
|
||||
// minDmgSpeed: 0,
|
||||
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||
// density: 0.001, //0.001 is normal for blocks, 0.008 is normal for harpoon, 0.008*6 when buffed
|
||||
// beforeDmg(who) {
|
||||
// if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||
// who.isShielded = false
|
||||
// requestAnimationFrame(() => { who.isShielded = true });
|
||||
// }
|
||||
// if (tech.fragments) {
|
||||
// b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random()))
|
||||
// this.endCycle = 0;
|
||||
// }
|
||||
// if (!who.isBadTarget) {
|
||||
// this.frictionAir = 0.01
|
||||
// this.do = this.doNoTargeting
|
||||
// }
|
||||
// },
|
||||
// onEnd() {},
|
||||
// doNoTargeting: function() {
|
||||
// // this.force.y += this.mass * 0.001;
|
||||
// if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
// this.collisionFilter.mask = 0;
|
||||
// Matter.Body.setAngularVelocity(this, 0)
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: 0,
|
||||
// y: 0
|
||||
// });
|
||||
// this.do = () => {
|
||||
// // if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// do() {
|
||||
// this.cycle++
|
||||
// // if (this.cycle > 40) {
|
||||
// // this.frictionAir = 0.003
|
||||
// // this.do = this.doNoTargeting
|
||||
// // }
|
||||
// // if (closest.target) { //rotate towards the target
|
||||
// const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) };
|
||||
// const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position));
|
||||
// const cross = Vector.cross(vectorGoal, face)
|
||||
// if (cross > 0.01) {
|
||||
// Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross));
|
||||
// } else if (cross < 0.01) {
|
||||
// Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross)));
|
||||
// }
|
||||
// this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
|
||||
// this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
|
||||
// // }
|
||||
// if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
// this.collisionFilter.mask = 0;
|
||||
// Matter.Body.setAngularVelocity(this, 0)
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: 0,
|
||||
// y: 0
|
||||
// });
|
||||
// this.do = this.doNoTargeting
|
||||
// }
|
||||
// // else if (!(this.cycle % 2)) { //look for a target if you don't have one
|
||||
// // simulation.drawList.push({ //add dmg to draw queue
|
||||
// // x: this.position.x,
|
||||
// // y: this.position.y,
|
||||
// // radius: 10,
|
||||
// // color: simulation.mobDmgColor,
|
||||
// // time: simulation.drawTime
|
||||
// // });
|
||||
// // let closest = {
|
||||
// // distance: 2000,
|
||||
// // target: null
|
||||
// // }
|
||||
// // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1
|
||||
// // for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
// // if (
|
||||
// // mob[i].alive && !mob[i].isBadTarget &&
|
||||
// // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight
|
||||
// // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors
|
||||
// // ) {
|
||||
// // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position))
|
||||
// // if (dist < closest.distance) {
|
||||
// // closest.distance = dist
|
||||
// // closest.target = mob[i]
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // if (closest.target) {
|
||||
// // target = closest.target
|
||||
// // this.turnRate = 0.05
|
||||
// // this.frictionAir = 0.8
|
||||
// // }
|
||||
// // }
|
||||
// },
|
||||
// });
|
||||
// Matter.Body.setVelocity(bullet[me], {
|
||||
// x: m.Vx / 2 + 40 * Math.cos(bullet[me].angle),
|
||||
// y: m.Vy / 2 + 40 * Math.sin(bullet[me].angle)
|
||||
// });
|
||||
// // if (!closest.target) {
|
||||
// // bullet[me].frictionAir = 0.002
|
||||
// // bullet[me].do = bullet[me].doNoTargeting
|
||||
// // }
|
||||
// Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
|
||||
},
|
||||
// },
|
||||
grapple(where, angle = m.angle, harpoonSize = 1) {
|
||||
const me = bullet.length;
|
||||
const returnRadius = 100 * Math.sqrt(harpoonSize)
|
||||
@@ -2012,7 +2013,8 @@ const b = {
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (
|
||||
mob[i].alive && !mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
// && Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
) {
|
||||
const futureDist = Vector.magnitude(Vector.sub(futurePos, mob[i].position));
|
||||
@@ -2639,7 +2641,8 @@ const b = {
|
||||
!mob[i].isBadTarget &&
|
||||
Vector.magnitude(Vector.sub(this.position, mob[i].position)) < 700 + mob[i].radius + random &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
if (tech.isExplosionStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random);
|
||||
if (tech.isMineSentry) {
|
||||
@@ -2753,7 +2756,7 @@ const b = {
|
||||
this.lockedOn = null;
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
|
||||
if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
const targetVector = Vector.sub(this.position, mob[i].position)
|
||||
const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5);
|
||||
if (dist < closeDist) {
|
||||
@@ -2841,7 +2844,7 @@ const b = {
|
||||
this.lockedOn = null;
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
|
||||
if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
const targetVector = Vector.sub(this.position, mob[i].position)
|
||||
const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5);
|
||||
if (dist < closeDist) {
|
||||
@@ -2957,7 +2960,8 @@ const b = {
|
||||
if (
|
||||
!mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
@@ -3059,7 +3063,6 @@ const b = {
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
} else {
|
||||
this.force.y += this.mass * 0.0002;
|
||||
|
||||
if (!(simulation.cycle % this.lookFrequency)) {
|
||||
//find mob targets
|
||||
this.lockedOn = null;
|
||||
@@ -3068,7 +3071,8 @@ const b = {
|
||||
if (
|
||||
!mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
@@ -3297,7 +3301,8 @@ const b = {
|
||||
if (
|
||||
!mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
@@ -3785,9 +3790,10 @@ const b = {
|
||||
const dist = Vector.magnitude(Vector.sub(position, mob[i].position));
|
||||
if (
|
||||
dist < range + mob[i].radius &&
|
||||
(!mob[i].isBadTarget) && //|| mob[i].isMobBullet
|
||||
!mob[i].isBadTarget && //|| mob[i].isMobBullet
|
||||
Matter.Query.ray(map, position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, position, mob[i].position).length === 0
|
||||
Matter.Query.ray(body, position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles
|
||||
}
|
||||
@@ -4280,7 +4286,8 @@ const b = {
|
||||
dist < 3000000 &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isShielded
|
||||
!mob[i].isShielded &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position))
|
||||
if (this.isUpgraded) {
|
||||
@@ -4338,7 +4345,8 @@ const b = {
|
||||
mob[i].alive &&
|
||||
!mob[i].isBadTarget &&
|
||||
dist2 > 40000 &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
this.cd = simulation.cycle + this.delay;
|
||||
const angle = Vector.angle(this.position, mob[i].position)
|
||||
@@ -4670,10 +4678,12 @@ const b = {
|
||||
let closeDist = tech.isPlasmaRange * 1000;
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
const DIST = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius;
|
||||
if (DIST < closeDist &&
|
||||
(!mob[i].isBadTarget || mob[i].isMobBullet) &&
|
||||
if (
|
||||
DIST < closeDist && (!mob[i].isBadTarget || mob[i].isMobBullet) &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!mob[i].isInvulnerable
|
||||
) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = mob[i]
|
||||
}
|
||||
@@ -6376,7 +6386,7 @@ const b = {
|
||||
const dir = { x: Math.cos(angle), y: Math.sin(angle) }; //make a vector for the player's direction of length 1; used in dot product
|
||||
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||
// console.log(dot, 0.95 - Math.min(dist * 0.00015, 0.3))
|
||||
@@ -6521,7 +6531,7 @@ const b = {
|
||||
const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1)
|
||||
let targetCount = 0
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||
if (dist < range && dot > 0.9) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target
|
||||
@@ -6553,7 +6563,7 @@ const b = {
|
||||
//single harpoon
|
||||
const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
|
||||
if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||
if (dist < closest.distance && dot > 0.98 - Math.min(dist * 0.00014, 0.3)) { //target closest mob that player is looking at and isn't too close to target
|
||||
|
||||
@@ -52,7 +52,7 @@ const cat = {
|
||||
}
|
||||
|
||||
const color = { //light
|
||||
background: "#ddd",
|
||||
// background: "#ddd", // used instead: document.body.style.backgroundColor
|
||||
block: "rgba(140,140,140,0.85)",
|
||||
blockS: "#222",
|
||||
map: "#444",
|
||||
|
||||
68
js/level.js
68
js/level.js
@@ -18,14 +18,16 @@ const level = {
|
||||
// // simulation.isHorizontalFlipped = true
|
||||
// m.addHealth(Infinity)
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("nail gun")
|
||||
// b.giveGuns("spores")
|
||||
// tech.giveTech("closed timelike curve")
|
||||
// tech.giveTech("retrocausality")
|
||||
// tech.giveTech("pneumatic actuator")
|
||||
// tech.giveTech("clock gating")
|
||||
// tech.giveTech("6s half-life")
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
||||
// tech.giveTech("eternalism")
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("ammonium nitrate")
|
||||
// m.maxHealth = 100
|
||||
// m.health = m.maxHealth
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
|
||||
// for (let i = 0; i < 15; i++) tech.giveTech()
|
||||
@@ -33,11 +35,15 @@ const level = {
|
||||
// powerUps.research.changeRerolls(100000)
|
||||
// tech.tech[297].frequency = 100
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.testing();
|
||||
// spawn.snakeSpitBoss(1900, -500)
|
||||
// level.reservoir(); //not in rotation, used for testing
|
||||
// simulation.fpsCap = 30 //new fps
|
||||
// simulation.fpsInterval = 1000 / simulation.fpsCap;
|
||||
//how long to wait to return to normal fps
|
||||
// m.defaultFPSCycle = m.cycle + 20 + Math.min(90, Math.floor(200 * dmg))
|
||||
// spawn.timeSkipBoss(1900, -500)
|
||||
// level.reactor(); //not in rotation, used for testing
|
||||
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||
// powerUps.research.changeRerolls(3000)
|
||||
@@ -2619,7 +2625,7 @@ const level = {
|
||||
// level.difficultyIncrease(14); //hard mode level 7
|
||||
level.defaultZoom = 1500
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = color.background //"#ddd";
|
||||
document.body.style.backgroundColor = "#ddd";
|
||||
spawn.mapRect(-950, 0, 8200, 800); //ground
|
||||
spawn.mapRect(-950, -1200, 800, 1400); //left wall
|
||||
spawn.mapRect(-950, -1800, 8200, 800); //roof
|
||||
@@ -2761,22 +2767,23 @@ const level = {
|
||||
for (let i = 0; i < 9; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo")
|
||||
for (let i = 0; i < 3; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "heal");
|
||||
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
|
||||
if (Math.random() < 0.07 && simulation.difficulty > 24) {
|
||||
for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
|
||||
for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
|
||||
for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
|
||||
} else {
|
||||
if (Math.random() < 0.25) {
|
||||
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.33) {
|
||||
for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.5) {
|
||||
for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
} else {
|
||||
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
}
|
||||
}
|
||||
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
// if (Math.random() < 0.07 && simulation.difficulty > 24) {
|
||||
// for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
// for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
|
||||
// for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
|
||||
// for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
|
||||
// } else {
|
||||
// if (Math.random() < 0.25) {
|
||||
// for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
// } else if (Math.random() < 0.33) {
|
||||
// for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
// } else if (Math.random() < 0.5) {
|
||||
// for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
// } else {
|
||||
// for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
// }
|
||||
// }
|
||||
spawn.secondaryBossChance(2200, -800)
|
||||
}
|
||||
} else {
|
||||
@@ -4740,19 +4747,15 @@ const level = {
|
||||
skyscrapers() {
|
||||
const boost1 = level.boost(475, 0, 1300)
|
||||
const boost2 = level.boost(4450, 0, 1300);
|
||||
|
||||
level.custom = () => {
|
||||
boost1.query();
|
||||
boost2.query();
|
||||
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
ctx.fillRect(1350, -2100, 400, 250)
|
||||
ctx.fillStyle = "#d4d4d7"
|
||||
ctx.fillRect(3350, -1300, 50, 1325)
|
||||
ctx.fillRect(1300, -1800, 750, 1800)
|
||||
|
||||
level.exit.drawAndCheck();
|
||||
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
@@ -4766,20 +4769,16 @@ const level = {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.15)"
|
||||
ctx.fillRect(-250, -300, 450, 300)
|
||||
};
|
||||
|
||||
level.setPosToSpawn(-50, -60); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 1500;
|
||||
level.exit.y = -1875;
|
||||
|
||||
level.defaultZoom = 2000
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
powerUps.spawnStartingPowerUps(1475, -1175);
|
||||
spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||
document.body.style.backgroundColor = "#dcdcde";
|
||||
// simulation.draw.mapFill = "#444"
|
||||
// simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
|
||||
// simulation.draw.bodyStroke = "#222"
|
||||
|
||||
spawn.mapRect(-300, 0, 5100, 300); //***********ground
|
||||
spawn.mapRect(-300, -350, 50, 400); //far left starting left wall
|
||||
spawn.mapRect(-300, -10, 500, 50); //far left starting ground
|
||||
@@ -4844,13 +4843,12 @@ const level = {
|
||||
spawn.randomMob(-100, -1700, -0.2);
|
||||
spawn.randomGroup(3700, -1500, 0.4);
|
||||
spawn.randomGroup(1700, -900, 0.4);
|
||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(2600, -2300);
|
||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(2800 + 200 * Math.random(), -2200 + 200 * Math.random());
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
spawn.secondaryBossChance(3075, -2050)
|
||||
spawn.secondaryBossChance(4000, -1825)
|
||||
|
||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||
|
||||
boost1.boostBounds.min.x = -boost1.boostBounds.min.x - 100
|
||||
boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100
|
||||
boost2.boostBounds.min.x = -boost2.boostBounds.min.x - 100
|
||||
|
||||
10
js/player.js
10
js/player.js
@@ -1379,7 +1379,10 @@ const m = {
|
||||
x: player.velocity.x - (15 * unit.x) / massRoot,
|
||||
y: player.velocity.y - (15 * unit.y) / massRoot
|
||||
});
|
||||
if (who.isOrbital) Matter.Body.setVelocity(who, { x: 0, y: 0 });
|
||||
if (who.isUnstable) {
|
||||
if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
|
||||
who.death();
|
||||
}
|
||||
|
||||
if (m.crouch) {
|
||||
Matter.Body.setVelocity(player, {
|
||||
@@ -1762,7 +1765,10 @@ const m = {
|
||||
x: player.velocity.x - (30 * unit.x) / massRoot,
|
||||
y: player.velocity.y - (30 * unit.y) / massRoot
|
||||
});
|
||||
if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 });
|
||||
if (mob[i].isUnstable) {
|
||||
if (m.fieldCDcycle < m.cycle + 10) m.fieldCDcycle = m.cycle + 10
|
||||
mob[i].death();
|
||||
}
|
||||
if (!isFree) { //player knock backs
|
||||
if (mob[i].isDropPowerUp && player.speed < 12) {
|
||||
const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass)));
|
||||
|
||||
@@ -758,6 +758,10 @@ const powerUps = {
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choiceField})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choiceField].name}</div> ${m.fieldUpgrades[choiceField].description}</div>`
|
||||
}
|
||||
}
|
||||
if (tech.tooManyTechChoices) {
|
||||
tech.tooManyTechChoices--
|
||||
for (let i = 0; i < powerUps.tech.lastTotalChoices; i++) pick()
|
||||
}
|
||||
|
||||
if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
|
||||
tech.isBrainstormActive = true
|
||||
|
||||
16
js/spawn.js
16
js/spawn.js
@@ -2398,6 +2398,7 @@ const spawn = {
|
||||
me.memory = Infinity
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
ctx.setLineDash([]);
|
||||
};
|
||||
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReductionGoal
|
||||
me.awake = function() {
|
||||
@@ -3784,6 +3785,7 @@ const spawn = {
|
||||
me.isDropPowerUp = false;
|
||||
me.isBadTarget = true;
|
||||
me.isMobBullet = true;
|
||||
me.isUnstable = true; //dies when blocked
|
||||
me.showHealthBar = false;
|
||||
me.explodeRange = 200 + 150 * Math.random()
|
||||
me.isExploding = false
|
||||
@@ -5179,16 +5181,16 @@ const spawn = {
|
||||
};
|
||||
},
|
||||
timeSkipBoss(x, y, radius = 50) {
|
||||
mobs.spawn(x, y, 15, radius, "rgb(150, 150, 255)");
|
||||
mobs.spawn(x, y, 15, radius, "transparent");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.eventHorizon = 0; //set in mob loop
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.004;
|
||||
me.accelMag = 0.0001 + 0.00003 * simulation.accelScale
|
||||
me.accelMag = 0.00008 + 0.00002 * simulation.accelScale
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random(), true)
|
||||
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random())
|
||||
|
||||
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
@@ -5208,14 +5210,14 @@ const spawn = {
|
||||
this.seePlayerByHistory();
|
||||
this.attraction();
|
||||
this.checkStatus();
|
||||
this.eventHorizon = 950 + 170 * Math.sin(simulation.cycle * 0.005)
|
||||
this.eventHorizon = 900 + 200 * Math.sin(simulation.cycle * 0.005)
|
||||
if (!simulation.isTimeSkipping) {
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < this.eventHorizon) {
|
||||
this.attraction();
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
this.isInvulnerable = false
|
||||
if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
|
||||
simulation.timePlayerSkip(8)
|
||||
simulation.timePlayerSkip(5)
|
||||
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
|
||||
}); //wrapping in animation frame prevents errors, probably
|
||||
|
||||
@@ -5237,7 +5239,7 @@ const spawn = {
|
||||
simulation.camera();
|
||||
ctx.beginPath(); //gets rid of already draw shapes
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI, false); //part you can't see
|
||||
ctx.fillStyle = color.background;
|
||||
ctx.fillStyle = document.body.style.backgroundColor;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
})
|
||||
@@ -5854,7 +5856,7 @@ const spawn = {
|
||||
me.leaveBody = false;
|
||||
me.isDropPowerUp = false;
|
||||
me.isBadTarget = true;
|
||||
me.isUnblockable = true;
|
||||
me.isUnstable = true; //dies when blocked
|
||||
me.showHealthBar = false;
|
||||
me.isOrbital = true;
|
||||
// me.isShielded = true
|
||||
|
||||
284
js/tech.js
284
js/tech.js
@@ -223,22 +223,21 @@ const tech = {
|
||||
let dmg = 1 //m.fieldDamage
|
||||
if (tech.isDeathSkipTime) dmg *= 1.67
|
||||
if (tech.isNoDraftPause) dmg *= 1.4
|
||||
if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount)
|
||||
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
|
||||
if (tech.OccamDamage) dmg *= tech.OccamDamage
|
||||
if (tech.isCloakingDamage) dmg *= 1.35
|
||||
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
||||
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
|
||||
if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg
|
||||
if (tech.isTechDamage) dmg *= 1.9
|
||||
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
|
||||
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
|
||||
if (tech.isMaxEnergyTech) dmg *= 1.5
|
||||
if (tech.isEnergyNoAmmo) dmg *= 1.88
|
||||
if (tech.isEnergyLoss) dmg *= 1.55
|
||||
if (tech.OccamDamage) dmg *= tech.OccamDamage
|
||||
if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount)
|
||||
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
|
||||
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
||||
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
|
||||
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
|
||||
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
|
||||
if (tech.isDamageForGuns) dmg *= 1 + 0.13 * b.inventory.length
|
||||
if (tech.isLowHealthDmg) dmg *= 1 + Math.max(0, 1 - m.health) * 0.5
|
||||
if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3;
|
||||
if (tech.isEnergyLoss) dmg *= 1.55;
|
||||
if (tech.isAcidDmg && m.health > 1) dmg *= 1.35;
|
||||
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
|
||||
if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.125;
|
||||
@@ -249,6 +248,7 @@ const tech = {
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
|
||||
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
|
||||
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.5
|
||||
if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg
|
||||
return dmg * tech.slowFire * tech.aimDamage
|
||||
},
|
||||
duplicationChance() {
|
||||
@@ -7932,51 +7932,51 @@ const tech = {
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "translate",
|
||||
description: "translate n-gon into a random language",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
isNonRefundable: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
// generate a container
|
||||
const gtElem = document.createElement('div')
|
||||
gtElem.id = "gtElem"
|
||||
gtElem.style.visibility = 'hidden' // make it invisible
|
||||
document.body.append(gtElem)
|
||||
// {
|
||||
// name: "translate",
|
||||
// description: "translate n-gon into a random language",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 0,
|
||||
// isJunk: true,
|
||||
// isNonRefundable: true,
|
||||
// allowed() {
|
||||
// return true
|
||||
// },
|
||||
// requires: "",
|
||||
// effect() {
|
||||
// // generate a container
|
||||
// const gtElem = document.createElement('div')
|
||||
// gtElem.id = "gtElem"
|
||||
// gtElem.style.visibility = 'hidden' // make it invisible
|
||||
// document.body.append(gtElem)
|
||||
|
||||
// generate a script to run after creation
|
||||
function initGT() {
|
||||
// create a new translate element
|
||||
new google.translate.TranslateElement({ pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL }, 'gtElem')
|
||||
// ok now since it's loaded perform a funny hack to make it work
|
||||
const langSelect = document.getElementsByClassName("goog-te-combo")[0]
|
||||
// select a random language. It takes a second for all langauges to load, so wait a second.
|
||||
setTimeout(() => {
|
||||
langSelect.selectedIndex = Math.round(langSelect.options.length * Math.random())
|
||||
// simulate a click
|
||||
langSelect.dispatchEvent(new Event('change'))
|
||||
// now make it go away
|
||||
const bar = document.getElementById(':1.container')
|
||||
bar.style.display = 'none'
|
||||
bar.style.visibility = 'hidden'
|
||||
}, 1000)
|
||||
// // generate a script to run after creation
|
||||
// function initGT() {
|
||||
// // create a new translate element
|
||||
// new google.translate.TranslateElement({ pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL }, 'gtElem')
|
||||
// // ok now since it's loaded perform a funny hack to make it work
|
||||
// const langSelect = document.getElementsByClassName("goog-te-combo")[0]
|
||||
// // select a random language. It takes a second for all langauges to load, so wait a second.
|
||||
// setTimeout(() => {
|
||||
// langSelect.selectedIndex = Math.round(langSelect.options.length * Math.random())
|
||||
// // simulate a click
|
||||
// langSelect.dispatchEvent(new Event('change'))
|
||||
// // now make it go away
|
||||
// const bar = document.getElementById(':1.container')
|
||||
// bar.style.display = 'none'
|
||||
// bar.style.visibility = 'hidden'
|
||||
// }, 1000)
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// add the google translate script
|
||||
const translateScript = document.createElement('script')
|
||||
translateScript.src = '//translate.google.com/translate_a/element.js?cb=initGT'
|
||||
document.body.append(translateScript)
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
// // add the google translate script
|
||||
// const translateScript = document.createElement('script')
|
||||
// translateScript.src = '//translate.google.com/translate_a/element.js?cb=initGT'
|
||||
// document.body.append(translateScript)
|
||||
// },
|
||||
// remove() {}
|
||||
// },
|
||||
{
|
||||
name: "discount",
|
||||
description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!",
|
||||
@@ -9674,6 +9674,108 @@ const tech = {
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "path integral",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Path_integral_formulation' class="link">path integral</a>`,
|
||||
// description: "your next <strong>3</strong> <strong class='color-m'>tech</strong> choices<br>present almost every possible <strong>option</strong>",
|
||||
description: "your next <strong class='color-m'>tech</strong> choice<br>presents almost every possible <strong>option</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
isNonRefundable: true,
|
||||
isJunk: true,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.tooManyTechChoices = 1
|
||||
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
},
|
||||
remove() {
|
||||
tech.tooManyTechChoices = 0
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "rule 30",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {},
|
||||
remove() {},
|
||||
state: [
|
||||
[false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
],
|
||||
rule(state, a, b, c) {
|
||||
//30
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return false; // TTF => F
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
if (!state[a] && state[b] && !state[c]) return true; //FTF => T
|
||||
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
},
|
||||
id: 0,
|
||||
descriptionFunction() {
|
||||
|
||||
if (this.id === 0 && Math.random() < 0.5) {
|
||||
// for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
|
||||
this.name = "rule 90"
|
||||
this.link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(this.name).replace(/'/g, '%27')}&title=Special:Search' class="link">${this.name}</a>`
|
||||
// console.log(this.name)
|
||||
this.state[0] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
this.rule = function(state, a, b, c) {
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return true; // TTF => T
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
if (!state[a] && state[b] && !state[c]) return false; //FTF => F
|
||||
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
}
|
||||
}
|
||||
|
||||
const loop = () => {
|
||||
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
|
||||
let b = []; //produce next row
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
|
||||
for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
|
||||
b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
|
||||
}
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
|
||||
this.state.push(b)
|
||||
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
|
||||
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
|
||||
setTimeout(() => { loop() }, 400);
|
||||
}
|
||||
}
|
||||
setTimeout(() => { loop() }, 400);
|
||||
this.id++
|
||||
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>`
|
||||
},
|
||||
outputText() {
|
||||
let text = ""
|
||||
for (let j = 0; j < this.state.length; j++) {
|
||||
text += "<p style = 'margin-bottom: -11px;'>"
|
||||
for (let i = 0; i < this.state[j].length; i++) {
|
||||
if (this.state[j][i]) {
|
||||
text += "⬛" //"█" //"■"
|
||||
} else {
|
||||
text += "⬜" //" " //"□"
|
||||
}
|
||||
}
|
||||
text += "</p>"
|
||||
}
|
||||
return text
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cosmogonic myth",
|
||||
description: `<span style = "opacity: 9%;">open a portal to a primordial version of reality<br>in 5 minutes close the portal, spawn 1 of each power up</span>`,
|
||||
@@ -9835,87 +9937,7 @@ const tech = {
|
||||
// return text
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: "rule 30",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {},
|
||||
remove() {},
|
||||
state: [
|
||||
[false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
],
|
||||
rule(state, a, b, c) {
|
||||
//30
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return false; // TTF => F
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
if (!state[a] && state[b] && !state[c]) return true; //FTF => T
|
||||
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
},
|
||||
id: 0,
|
||||
descriptionFunction() {
|
||||
|
||||
if (this.id === 0 && Math.random() < 0.5) {
|
||||
// for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
|
||||
this.name = "rule 90"
|
||||
this.link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(this.name).replace(/'/g, '%27')}&title=Special:Search' class="link">${this.name}</a>`
|
||||
// console.log(this.name)
|
||||
this.state[0] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
this.rule = function(state, a, b, c) {
|
||||
if (state[a] && state[b] && state[c]) return false; // TTT => F
|
||||
if (state[a] && state[b] && !state[c]) return true; // TTF => T
|
||||
if (state[a] && !state[b] && state[c]) return false; //TFT => F
|
||||
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
|
||||
if (!state[a] && state[b] && state[c]) return true; //FTT => T
|
||||
if (!state[a] && state[b] && !state[c]) return false; //FTF => F
|
||||
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
|
||||
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
|
||||
}
|
||||
}
|
||||
|
||||
const loop = () => {
|
||||
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
|
||||
let b = []; //produce next row
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
|
||||
for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
|
||||
b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
|
||||
}
|
||||
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
|
||||
this.state.push(b)
|
||||
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
|
||||
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
|
||||
setTimeout(() => { loop() }, 400);
|
||||
}
|
||||
}
|
||||
setTimeout(() => { loop() }, 400);
|
||||
this.id++
|
||||
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>`
|
||||
},
|
||||
outputText() {
|
||||
let text = ""
|
||||
for (let j = 0; j < this.state.length; j++) {
|
||||
text += "<p style = 'margin-bottom: -11px;'>"
|
||||
for (let i = 0; i < this.state[j].length; i++) {
|
||||
if (this.state[j][i]) {
|
||||
text += "⬛" //"█" //"■"
|
||||
} else {
|
||||
text += "⬜" //" " //"□"
|
||||
}
|
||||
}
|
||||
text += "</p>"
|
||||
}
|
||||
return text
|
||||
},
|
||||
},
|
||||
//**************************************************
|
||||
//************************************************** undefined / lore
|
||||
//************************************************** tech
|
||||
|
||||
Reference in New Issue
Block a user