sound-bot
new community level: dojo by weird_pusheen sound-bot: makes phonon waves updated tech drone repair -> von Neumann probe - if a drones ends near a block it will use that block to repair quantum eraser -> metamaterial absorber: for each mob left alive after you exit a level there is a 17% chance to spawn a power up uncertainty principle: extended to super balls aperture: camera zooms in and out along with the skin animation balanced tech: cordyceps: zombies are much smarter, faster, do more damage, and last longer negative entropy -> self-assembly: 1 heal per 33->25% missing health on each new level renormalization: 44 -> 46% and +3% JUNK tech to pool parasitism: 60 -> 83% damage non-renewables: 67 -> 78% damage ground state: 200 -> 266 max energy dark patterns: 17 -> 22% damage and JUNK eternalism: 30 -> 24% damage stimulated emission 15 -> 17% duplication nitinol 30 -> 22% defense bug fixes
This commit is contained in:
699
js/bullet.js
699
js/bullet.js
@@ -3648,6 +3648,31 @@ const b = {
|
||||
bullet[bullet.length - 1].isMutualismActive = true
|
||||
}
|
||||
},
|
||||
delayDrones(where, droneCount = 1) {
|
||||
let respawnDrones = () => {
|
||||
if (droneCount > 0) {
|
||||
requestAnimationFrame(respawnDrones);
|
||||
if (!simulation.paused && !simulation.isChoosing && m.alive) {
|
||||
droneCount--
|
||||
if (tech.isDroneRadioactive) {
|
||||
b.droneRadioactive({ x: where.x + 50 * (Math.random() - 0.5), y: where.y + 50 * (Math.random() - 0.5) }, 0)
|
||||
} else {
|
||||
b.drone({ x: where.x + 50 * (Math.random() - 0.5), y: where.y + 50 * (Math.random() - 0.5) }, 0)
|
||||
if (tech.isDroneGrab && deliveryCount > 0) {
|
||||
const who = bullet[bullet.length - 1]
|
||||
who.isImproved = true;
|
||||
const SCALE = 2.25
|
||||
Matter.Body.scale(who, SCALE, SCALE);
|
||||
who.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
who.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger
|
||||
deliveryCount--
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(respawnDrones);
|
||||
},
|
||||
drone(where = {
|
||||
x: m.pos.x + 30 * Math.cos(m.angle) + 20 * (Math.random() - 0.5),
|
||||
y: m.pos.y + 30 * Math.sin(m.angle) + 20 * (Math.random() - 0.5)
|
||||
@@ -3693,10 +3718,7 @@ const b = {
|
||||
} else {
|
||||
//move away from target after hitting
|
||||
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20)
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: unit.x,
|
||||
y: unit.y
|
||||
});
|
||||
Matter.Body.setVelocity(this, { x: unit.x, y: unit.y });
|
||||
this.lockedOn = null
|
||||
if (this.endCycle > simulation.cycle + this.deathCycles) {
|
||||
this.endCycle -= 60
|
||||
@@ -3705,68 +3727,164 @@ const b = {
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isDroneRespawn && b.inventory.length && b.activeGun === 7 && b.guns[b.activeGun].ammo > 0 && mob.length) {
|
||||
b.drone({
|
||||
x: this.position.x,
|
||||
y: this.position.y
|
||||
}, 0)
|
||||
if (Math.random() < 0.2) {
|
||||
b.guns[b.activeGun].ammo--;
|
||||
simulation.updateGunHUD();
|
||||
if (tech.isDroneRespawn) {
|
||||
//are there any nearby bodies nearby that aren't blocked by map?
|
||||
const canSee = body.filter(a => Matter.Query.ray(map, this.position, a.position).length === 0 && !a.isNotHoldable && Vector.magnitude(Vector.sub(this.position, a.position)) < 70 + 30 * a.mass)
|
||||
if (canSee.length) {
|
||||
//find the closest body to the drone from the canSee array
|
||||
const found = canSee.reduce((a, b) => {
|
||||
const distA = Vector.magnitude(Vector.sub(this.position, a.position))
|
||||
const distB = Vector.magnitude(Vector.sub(this.position, b.position))
|
||||
return distA < distB ? a : b
|
||||
})
|
||||
if (found && m.energy > 0.05) {
|
||||
m.energy -= 0.05
|
||||
//remove the body and spawn a new drone
|
||||
Composite.remove(engine.world, found)
|
||||
body.splice(body.indexOf(found), 1)
|
||||
b.delayDrones(found.position, 0.7 * Math.sqrt(found.mass))
|
||||
//draw a line from the drone to the body on the canvas
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(found.position.x, found.position.y);
|
||||
ctx.strokeStyle = "#000";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
|
||||
//animate the block fading away
|
||||
simulation.ephemera.push({
|
||||
name: "droneRespawn",
|
||||
count: 60, //cycles before it self removes
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||
ctx.beginPath();
|
||||
let vertices = found.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
}
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = `rgba(0,0,0,${this.count / 60})`
|
||||
ctx.stroke();
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
do() {
|
||||
if (simulation.cycle + this.deathCycles > this.endCycle) { //fall shrink and die
|
||||
this.force.y += this.mass * 0.0012;
|
||||
this.restitution = 0.2;
|
||||
const scale = 0.995;
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
doRespawning() { //fall shrink and die
|
||||
const scale = 0.995;
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
if (this.bodyTarget) {
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.bodyTarget.position)), -this.mass * THRUST)
|
||||
} else {
|
||||
this.force.y += this.mass * 0.0002;
|
||||
if (!(simulation.cycle % this.lookFrequency)) {
|
||||
//find mob targets
|
||||
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 &&
|
||||
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);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = mob[i]
|
||||
}
|
||||
this.force.y += this.mass * 0.0012;
|
||||
}
|
||||
},
|
||||
doDieing() { //fall shrink and die
|
||||
this.force.y += this.mass * 0.0012;
|
||||
const scale = 0.995;
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
},
|
||||
do() {
|
||||
if (simulation.cycle + this.deathCycles > this.endCycle) {
|
||||
this.restitution = 0.2;
|
||||
if (tech.isDroneRespawn) {
|
||||
this.do = this.doRespawning
|
||||
//make a list of all elements of array body that a ray can be drawn to from the drone
|
||||
const canSee = body.filter(a => Matter.Query.ray(map, this.position, a.position).length === 0 && !a.isNotHoldable)
|
||||
if (canSee.length) {
|
||||
//find the closest body to the drone from the canSee array
|
||||
const found = canSee.reduce((a, b) => {
|
||||
const distA = Vector.magnitude(Vector.sub(this.position, a.position))
|
||||
const distB = Vector.magnitude(Vector.sub(this.position, b.position))
|
||||
return distA < distB ? a : b
|
||||
})
|
||||
if (found) this.bodyTarget = found
|
||||
}
|
||||
} else {
|
||||
this.do = this.doDieing
|
||||
}
|
||||
}
|
||||
|
||||
this.force.y += this.mass * 0.0002;
|
||||
if (!(simulation.cycle % this.lookFrequency)) {
|
||||
//find mob targets
|
||||
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 &&
|
||||
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);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = mob[i]
|
||||
}
|
||||
}
|
||||
//blink towards mobs
|
||||
if (tech.isDroneTeleport && this.lockedOn) {
|
||||
const sub = Vector.sub(this.lockedOn.position, this.position);
|
||||
const distMag = Vector.magnitude(sub);
|
||||
const unit = Vector.normalise(sub)
|
||||
Matter.Body.setVelocity(this, Vector.mult(unit, Math.max(20, this.speed * 1.5)));
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
Matter.Body.translate(this, Vector.mult(unit, Math.min(350, distMag - this.lockedOn.radius + 10)));
|
||||
ctx.lineTo(this.position.x, this.position.y);
|
||||
ctx.lineWidth = RADIUS * 2;
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.5)";
|
||||
ctx.stroke();
|
||||
}
|
||||
//power ups
|
||||
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 (
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
}
|
||||
//blink towards mobs
|
||||
if (tech.isDroneTeleport && this.lockedOn) {
|
||||
const sub = Vector.sub(this.lockedOn.position, this.position);
|
||||
const distMag = Vector.magnitude(sub);
|
||||
const unit = Vector.normalise(sub)
|
||||
Matter.Body.setVelocity(this, Vector.mult(unit, Math.max(20, this.speed * 1.5)));
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
Matter.Body.translate(this, Vector.mult(unit, Math.min(350, distMag - this.lockedOn.radius + 10)));
|
||||
ctx.lineTo(this.position.x, this.position.y);
|
||||
ctx.lineWidth = RADIUS * 2;
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.5)";
|
||||
ctx.stroke();
|
||||
}
|
||||
//power ups
|
||||
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 (
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(powerUp[i].position.x, powerUp[i].position.y);
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.lineWidth = 4
|
||||
ctx.stroke();
|
||||
//pick up nearby power ups
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (tech.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2.25
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
this.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//look for power ups to lock onto
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
@@ -3785,71 +3903,38 @@ const b = {
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
this.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger
|
||||
// this.frictionAir = 0
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//look for power ups to lock onto
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
//look for power ups to lock onto
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
|
||||
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(powerUp[i].position.x, powerUp[i].position.y);
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.lineWidth = 4
|
||||
ctx.stroke();
|
||||
//pick up nearby power ups
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (tech.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2.25
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
this.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger
|
||||
// this.frictionAir = 0
|
||||
}
|
||||
break;
|
||||
}
|
||||
//look for power ups to lock onto
|
||||
if (
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = powerUp[i]
|
||||
}
|
||||
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = powerUp[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.lockedOn) { //accelerate towards mobs
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST)
|
||||
} else { //accelerate towards mouse
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, simulation.mouseInGame)), -this.mass * THRUST)
|
||||
}
|
||||
// speed cap instead of friction to give more agility
|
||||
if (this.speed > 6) {
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: this.velocity.x * 0.97,
|
||||
y: this.velocity.y * 0.97
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.lockedOn) { //accelerate towards mobs
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST)
|
||||
} else { //accelerate towards mouse
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, simulation.mouseInGame)), -this.mass * THRUST)
|
||||
}
|
||||
// speed cap instead of friction to give more agility
|
||||
if (this.speed > 6) {
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: this.velocity.x * 0.97,
|
||||
y: this.velocity.y * 0.97
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -3891,14 +3976,50 @@ const b = {
|
||||
maxRadioRadius: 270 + Math.floor(90 * Math.random()),
|
||||
beforeDmg() { },
|
||||
onEnd() {
|
||||
if (tech.isDroneRespawn && b.inventory.length && b.activeGun === 7 && b.guns[b.activeGun].ammo > 0 && mob.length) {
|
||||
b.droneRadioactive({
|
||||
x: this.position.x,
|
||||
y: this.position.y
|
||||
}, 0)
|
||||
if (Math.random() < 0.2) {
|
||||
b.guns[b.activeGun].ammo--;
|
||||
simulation.updateGunHUD();
|
||||
if (tech.isDroneRespawn) {
|
||||
//are there any nearby bodies nearby that aren't blocked by map?
|
||||
const canSee = body.filter(a => Matter.Query.ray(map, this.position, a.position).length === 0 && !a.isNotHoldable && Vector.magnitude(Vector.sub(this.position, a.position)) < 70 + 30 * a.mass)
|
||||
if (canSee.length) {
|
||||
//find the closest body to the drone from the canSee array
|
||||
const found = canSee.reduce((a, b) => {
|
||||
const distA = Vector.magnitude(Vector.sub(this.position, a.position))
|
||||
const distB = Vector.magnitude(Vector.sub(this.position, b.position))
|
||||
return distA < distB ? a : b
|
||||
})
|
||||
if (found && m.energy > 0.05) {
|
||||
m.energy -= 0.1
|
||||
//remove the body and spawn a new drone
|
||||
Composite.remove(engine.world, found)
|
||||
body.splice(body.indexOf(found), 1)
|
||||
b.delayDrones(found.position, 0.35 * Math.sqrt(found.mass))
|
||||
//draw a line from the drone to the body on the canvas
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(found.position.x, found.position.y);
|
||||
ctx.strokeStyle = "#000";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
|
||||
//animate the block fading away
|
||||
simulation.ephemera.push({
|
||||
name: "droneRespawn",
|
||||
count: 60, //cycles before it self removes
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||
ctx.beginPath();
|
||||
let vertices = found.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
}
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = `rgba(0,0,0,${this.count / 60})`
|
||||
ctx.stroke();
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4074,7 +4195,8 @@ const b = {
|
||||
bullet[me] = Bodies.polygon(where.x, where.y, 12, radius, b.fireAttributes(dir, false));
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
Matter.Body.setVelocity(bullet[me], velocity);
|
||||
Matter.Body.setDensity(bullet[me], 0.0007 + 0.00055 * tech.isSuperHarm);
|
||||
bullet[me].calcDensity = () => 0.0007 + 0.00055 * tech.isSuperHarm + 0.0004 * tech.isBulletTeleport
|
||||
Matter.Body.setDensity(bullet[me], bullet[me].calcDensity());
|
||||
bullet[me].endCycle = simulation.cycle + Math.floor(270 + 90 * Math.random());
|
||||
bullet[me].minDmgSpeed = 0;
|
||||
bullet[me].restitution = 1;
|
||||
@@ -4086,18 +4208,7 @@ const b = {
|
||||
this.force.y += this.mass * 0.001;
|
||||
if (Matter.Query.collides(this, [player]).length) {
|
||||
this.endCycle = 0
|
||||
// let dmg = 0.015 * this.mass * tech.isSuperHarm
|
||||
// m.damage(dmg);
|
||||
const drain = m.energy * 0.25
|
||||
m.energy -= drain
|
||||
|
||||
// simulation.drawList.push({ //add dmg to draw queue
|
||||
// x: this.position.x,
|
||||
// y: this.position.y,
|
||||
// radius: radius * 3,
|
||||
// color: "hsla(194, 100%, 43%,0.2)",
|
||||
// time: 7
|
||||
// });
|
||||
m.energy -= m.energy * 0.25
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -4113,6 +4224,18 @@ const b = {
|
||||
if (this.cycle > 2) this.do = this.collidePlayerDo
|
||||
this.force.y += this.mass * 0.001;
|
||||
};
|
||||
} else if (tech.isBulletTeleport) {
|
||||
bullet[me].portFrequency = 25 + Math.floor(10 * Math.random())
|
||||
bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency
|
||||
bullet[me].do = function () {
|
||||
this.force.y += this.mass * 0.001;
|
||||
if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport
|
||||
this.nextPortCycle = simulation.cycle + this.portFrequency
|
||||
const range = 33 * Math.sqrt(radius) * Math.random()
|
||||
Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
|
||||
Matter.Body.setVelocity(this, Vector.rotate(this.velocity, 2 * (Math.random() * Math.random() - 0.25)))
|
||||
}
|
||||
};
|
||||
} else {
|
||||
bullet[me].do = function () {
|
||||
this.force.y += this.mass * 0.001;
|
||||
@@ -4133,7 +4256,7 @@ const b = {
|
||||
this.endCycle = 0
|
||||
} else if (tech.isSuperBounce) {
|
||||
const cycle = () => {
|
||||
Matter.Body.setDensity(this, (0.0008 + 0.0009 * tech.isSuperHarm) * 1.33); //50% more density and damage
|
||||
Matter.Body.setDensity(bullet[me], bullet[me].calcDensity() * 1.33);//33% more density and damage
|
||||
this.endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random()); //reset to full duration of time
|
||||
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(this.velocity), 60)); //reset to high velocity
|
||||
|
||||
@@ -4848,7 +4971,7 @@ const b = {
|
||||
// **************************************************************************************************
|
||||
// **************************************************************************************************
|
||||
totalBots() {
|
||||
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
|
||||
return tech.dynamoBotCount + tech.foamBotCount + tech.soundBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
|
||||
},
|
||||
hasBotUpgrade() {
|
||||
return tech.isNailBotUpgrade + tech.isFoamBotUpgrade + tech.isBoomBotUpgrade + tech.isLaserBotUpgrade + tech.isOrbitBotUpgrade + tech.isDynamoBotUpgrade
|
||||
@@ -4898,6 +5021,10 @@ const b = {
|
||||
tech.foamBotCount--
|
||||
return
|
||||
}
|
||||
if (tech.soundBotCount > 1) {
|
||||
tech.soundBotCount--
|
||||
return
|
||||
}
|
||||
if (tech.boomBotCount > 1) {
|
||||
tech.boomBotCount--
|
||||
return
|
||||
@@ -4924,6 +5051,7 @@ const b = {
|
||||
tech.laserBotCount = 0
|
||||
tech.nailBotCount = 0
|
||||
tech.foamBotCount = 0
|
||||
tech.soundBotCount = 0
|
||||
tech.boomBotCount = 0
|
||||
tech.orbitBotCount = 0
|
||||
tech.missileBotCount = 0
|
||||
@@ -4945,6 +5073,10 @@ const b = {
|
||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||
}, false)
|
||||
for (let i = 0; i < tech.soundBotCount; i++) b.soundBot({
|
||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||
}, false)
|
||||
for (let i = 0; i < tech.boomBotCount; i++) b.boomBot({
|
||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||
@@ -4968,13 +5100,16 @@ const b = {
|
||||
}
|
||||
},
|
||||
randomBot(where = player.position, isKeep = true, isLaser = true) {
|
||||
if (Math.random() < 0.5) { //chance to match scrap bot to your upgrade
|
||||
if (Math.random() < 0.5) { //chance to match bot to your upgrade
|
||||
if (tech.isNailBotUpgrade) { //check for upgrades first
|
||||
b.nailBot(where, isKeep)
|
||||
if (isKeep) tech.nailBotCount++;
|
||||
} else if (tech.isFoamBotUpgrade) {
|
||||
b.foamBot(where, isKeep)
|
||||
if (isKeep) tech.foamBotCount++;
|
||||
} else if (tech.isSoundBotUpgrade) {
|
||||
b.soundBot(where, isKeep)
|
||||
if (isKeep) tech.soundBotCount++;
|
||||
} else if (tech.isBoomBotUpgrade) {
|
||||
b.boomBot(where, isKeep)
|
||||
if (isKeep) tech.boomBotCount++;
|
||||
@@ -4987,7 +5122,10 @@ const b = {
|
||||
} else if (tech.isDynamoBotUpgrade) {
|
||||
b.dynamoBot(where, isKeep)
|
||||
if (isKeep) tech.dynamoBotCount++;
|
||||
} else if (Math.random() < 0.166 && isLaser) { //random
|
||||
} else if (Math.random() < 0.143) { //random
|
||||
b.soundBot(where, isKeep)
|
||||
if (isKeep) tech.soundBotCount++;
|
||||
} else if (Math.random() < 0.166 && isLaser) {
|
||||
b.laserBot(where, isKeep)
|
||||
if (isKeep) tech.laserBotCount++;
|
||||
} else if (Math.random() < 0.2) {
|
||||
@@ -5006,8 +5144,11 @@ const b = {
|
||||
b.boomBot(where, isKeep)
|
||||
if (isKeep) tech.boomBotCount++;
|
||||
}
|
||||
} else { //else don't match scrap bot to upgrade
|
||||
if (Math.random() < 0.166 && isLaser) { //random
|
||||
} else { //else don't match bot to upgrade
|
||||
if (Math.random() < 0.143) { //random
|
||||
b.soundBot(where, isKeep)
|
||||
if (isKeep) tech.soundBotCount++;
|
||||
} else if (Math.random() < 0.166 && isLaser) { //random
|
||||
b.laserBot(where, isKeep)
|
||||
if (isKeep) tech.laserBotCount++;
|
||||
} else if (Math.random() < 0.2) {
|
||||
@@ -5084,7 +5225,7 @@ const b = {
|
||||
if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250 && m.immuneCycle < m.cycle) { //give energy
|
||||
Matter.Body.setAngularVelocity(this, this.spin)
|
||||
if (this.isUpgraded) {
|
||||
m.energy += 0.115
|
||||
m.energy += 0.12
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -5093,7 +5234,7 @@ const b = {
|
||||
time: simulation.drawTime
|
||||
});
|
||||
} else {
|
||||
m.energy += 0.035
|
||||
m.energy += 0.04
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -5148,10 +5289,7 @@ const b = {
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
b.setDynamoBotDelay()
|
||||
},
|
||||
nailBot(position = {
|
||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||
}, isConsole = true) {
|
||||
nailBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
|
||||
const me = bullet.length;
|
||||
const dir = m.angle;
|
||||
@@ -5168,7 +5306,7 @@ const b = {
|
||||
minDmgSpeed: 2,
|
||||
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
|
||||
lastLookCycle: simulation.cycle + 60 * Math.random(),
|
||||
delay: Math.floor((tech.isNailBotUpgrade ? 20 : 100) * b.fireCDscale),
|
||||
delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85) * b.fireCDscale),
|
||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
|
||||
endCycle: Infinity,
|
||||
@@ -5199,13 +5337,13 @@ const b = {
|
||||
) {
|
||||
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) {
|
||||
const SPEED = 55
|
||||
const SPEED = 60
|
||||
b.nail(this.position, Vector.mult(unit, SPEED))
|
||||
this.force = Vector.mult(unit, -0.018 * this.mass)
|
||||
this.force = Vector.mult(unit, -0.02 * this.mass)
|
||||
} else {
|
||||
const SPEED = 40
|
||||
const SPEED = 45
|
||||
b.nail(this.position, Vector.mult(unit, SPEED))
|
||||
this.force = Vector.mult(unit, -0.01 * this.mass)
|
||||
this.force = Vector.mult(unit, -0.012 * this.mass)
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -5354,7 +5492,7 @@ const b = {
|
||||
if (this.cd < simulation.cycle && !m.isCloak && !(simulation.cycle % this.lookFrequency)) {
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
|
||||
if (dist2 < 1700000 && !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
if (dist2 < 1600000 && !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
|
||||
this.fireTarget = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist2) / 60)) //set target to where the mob will be in 1 second
|
||||
this.fire()
|
||||
break;
|
||||
@@ -5414,6 +5552,172 @@ const b = {
|
||||
})
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
soundBot(position = { x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.soundBot()`);
|
||||
const me = bullet.length;
|
||||
const dir = m.angle;
|
||||
bullet[me] = Bodies.rectangle(position.x, position.y, 12, 30, {
|
||||
isUpgraded: tech.isSoundBotUpgrade,
|
||||
botType: "sound",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
frictionAir: 0.05,
|
||||
restitution: 0.6 * (1 + 0.5 * Math.random()),
|
||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||
minDmgSpeed: 2,
|
||||
lookFrequency: 17 + Math.floor(7 * Math.random()) - 10 * tech.isSoundBotUpgrade,
|
||||
cd: 0,
|
||||
fireCount: 0,
|
||||
fireLimit: 5 + 3 * tech.isSoundBotUpgrade,
|
||||
delay: Math.floor((90 + (tech.isSoundBotUpgrade ? 0 : 90)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), //how far from the player the bot will move
|
||||
endCycle: Infinity,
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: b.totalBots() < 50 ? cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield //if over 50 bots, they no longer collide with each other
|
||||
},
|
||||
beforeDmg() { },
|
||||
onEnd() { },
|
||||
fireTarget: { x: 0, y: 0 },
|
||||
waves: [],
|
||||
phononWaveCD: 0,
|
||||
addWave(where, angle) {
|
||||
const halfArc = 0.2 * (tech.isBulletTeleport ? 0.66 + (Math.random() - 0.5) : 1) + 0.05 * tech.isSoundBotUpgrade //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
|
||||
this.waves.push({
|
||||
position: where,
|
||||
angle: angle - halfArc, //used in drawing ctx.arc
|
||||
unit1: { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }, //used for collision
|
||||
unit2: { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }, //used for collision
|
||||
arc: halfArc * 2,
|
||||
radius: 25,
|
||||
resonanceCount: 0,
|
||||
dmg: (tech.isUpgraded ? 3 : 1.5) * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.5 : 1),
|
||||
})
|
||||
},
|
||||
fire() {
|
||||
if (!(simulation.cycle % (6 - 2 * tech.isSoundBotUpgrade))) {
|
||||
this.fireCount++
|
||||
if (this.fireCount > this.fireLimit) {
|
||||
this.fireCount = 0
|
||||
this.cd = simulation.cycle + this.delay;
|
||||
}
|
||||
this.addWave({ x: this.position.x, y: this.position.y }, Math.atan2(this.fireTarget.y - this.position.y, this.fireTarget.x - this.position.x) + tech.isBulletTeleport * 0.3 * (Math.random() - 0.5)) //add wave to waves array
|
||||
//face target
|
||||
Matter.Body.setAngle(this, Vector.angle(this.position, this.fireTarget));
|
||||
}
|
||||
},
|
||||
do() {
|
||||
if (this.fireCount === 0) { //passive mode: look for targets and following player
|
||||
const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, m.pos))
|
||||
if (distanceToPlayer > this.range) { //if far away move towards player
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.acceleration)
|
||||
} else { //close to player
|
||||
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity
|
||||
}
|
||||
if (this.cd < simulation.cycle && !m.isCloak && !(simulation.cycle % this.lookFrequency)) {
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
|
||||
if (dist2 < 1300000 && !mob[i].isBadTarget && (Matter.Query.ray(map, this.position, mob[i].position).length === 0 || dist2 < 300000) && !mob[i].isInvulnerable) {
|
||||
this.fireTarget = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist2) / 60)) //set target to where the mob will be in 1 second
|
||||
this.fire()
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { //fire mode: quickly fire at targets and doesn't follow player
|
||||
this.fire()
|
||||
}
|
||||
if (!m.isBodiesAsleep) { //update current waves
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 1200 * tech.isBulletsLastLonger
|
||||
//this does less damage than the player phonon waves 2.3 -> 2
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
|
||||
const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius))
|
||||
//draw wave
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc);
|
||||
//using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector
|
||||
let hits = Matter.Query.ray(mob, v1, v2, 50)
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
if (!who.isShielded) {
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
Matter.Body.setVelocity(who, { x: who.velocity.x * 0.95, y: who.velocity.y * 0.95 });
|
||||
let vertices = who.vertices;
|
||||
const vibe = 50 + who.radius * 0.15
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
who.locatePlayer();
|
||||
who.damage(this.waves[i].dmg / Math.pow(who.radius, 0.33));
|
||||
|
||||
|
||||
if (tech.isPhononWave && this.phononWaveCD < m.cycle) {
|
||||
this.phononWaveCD = m.cycle + 10 * (1 + this.waves[i].resonanceCount)
|
||||
let closestMob, dist
|
||||
let range = end - 30 * this.waves[i].resonanceCount
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (who !== mob[i] && !mob[i].isBadTarget && !mob[i].isInvulnerable) {
|
||||
dist = Vector.magnitude(Vector.sub(who.position, mob[i].position));
|
||||
if (dist < range) {
|
||||
closestMob = mob[i]
|
||||
range = dist
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closestMob) { //add wave to waves array
|
||||
this.addWave(who.position, Math.atan2(closestMob.position.y - who.position.y, closestMob.position.x - who.position.x) + tech.isBulletTeleport * 0.3 * (Math.random() - 0.5))
|
||||
} else {
|
||||
this.addWave(who.position, Math.random() * Math.PI)
|
||||
}
|
||||
this.waves[this.waves.length - 1].resonanceCount = this.waves[i].resonanceCount + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0, len = Math.min(30, hits.length); j < len; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
|
||||
let vertices = who.vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
|
||||
if (tech.isPhononBlock && !who.isNotHoldable && who.speed < 5 && who.angularSpeed < 0.1) {
|
||||
if (Math.random() < 0.5) b.targetedBlock(who, 50 - Math.min(25, who.mass * 3)) // targetedBlock(who, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
|
||||
// Matter.Body.setAngularVelocity(who, (0.25 + 0.12 * Math.random()) * (Math.random() < 0.5 ? -1 : 1));
|
||||
who.torque += who.inertia * 0.001 * (Math.random() - 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
this.waves[i].radius += tech.waveBeamSpeed * 2
|
||||
if (this.waves[i].radius > end - 30 * this.waves[i].resonanceCount) {
|
||||
this.waves.splice(i, 1) //end
|
||||
}
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
laserBot(position = {
|
||||
x: player.position.x + 50 * (Math.random() - 0.5),
|
||||
y: player.position.y + 50 * (Math.random() - 0.5)
|
||||
@@ -5823,15 +6127,7 @@ const b = {
|
||||
//calculate laser collision
|
||||
let best;
|
||||
let range = tech.isPlasmaRange * (120 + 300 * Math.sqrt(Math.random()))
|
||||
const path = [{
|
||||
x: this.position.x,
|
||||
y: this.position.y
|
||||
},
|
||||
{
|
||||
x: this.position.x + range * unit.x,
|
||||
y: this.position.y + range * unit.y
|
||||
}
|
||||
];
|
||||
const path = [{ x: this.position.x, y: this.position.y }, { x: this.position.x + range * unit.x, y: this.position.y + range * unit.y }];
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
@@ -5890,7 +6186,7 @@ const b = {
|
||||
y: best.y
|
||||
};
|
||||
if (best.who.alive) {
|
||||
const dmg = 0.75 * m.dmgScale; //********** SCALE DAMAGE HERE *********************
|
||||
const dmg = 0.9 * m.dmgScale; //********** SCALE DAMAGE HERE *********************
|
||||
best.who.damage(dmg);
|
||||
best.who.locatePlayer();
|
||||
//push mobs away
|
||||
@@ -6747,7 +7043,6 @@ const b = {
|
||||
have: false,
|
||||
wavePacketCycle: 0,
|
||||
delay: 40,
|
||||
propagationRate: 20,
|
||||
phononWaveCD: 0,
|
||||
waves: [], //used in longitudinal mode
|
||||
chooseFireMethod() { //set in simulation.startGame
|
||||
@@ -6771,7 +7066,7 @@ const b = {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) * Math.pow(0.93, tech.waveReflections) // / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
|
||||
const end = 700 * Math.sqrt(tech.isBulletsLastLonger)
|
||||
const damage = 2.3 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) * (tech.isInfiniteWaveAmmo ? 0.75 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
@@ -6815,8 +7110,6 @@ const b = {
|
||||
this.waves.push({
|
||||
position: mob[j].position,
|
||||
radius: 25,
|
||||
reflection: 1,
|
||||
expanding: true,
|
||||
resonanceCount: this.waves[i].resonanceCount + 1,
|
||||
})
|
||||
}
|
||||
@@ -6848,16 +7141,10 @@ const b = {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.waves[i].radius += 0.9 * tech.waveBeamSpeed * this.waves[i].expanding //expand / move
|
||||
this.waves[i].radius += 0.9 * tech.waveBeamSpeed //expand / move
|
||||
// if (this.waves[i].radius > end) this.waves.splice(i, 1) //end
|
||||
if (this.waves[i].radius > end - 30 * this.waves[i].resonanceCount) { //* Math.pow(0.9, this.waves[i].resonanceCount)
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
this.waves.splice(i, 1) //end
|
||||
}
|
||||
}
|
||||
ctx.stroke();
|
||||
@@ -6866,13 +7153,8 @@ const b = {
|
||||
fire360Longitudinal() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 4 : 8) * b.fireCDscale); // cool down
|
||||
this.waves.push({
|
||||
position: {
|
||||
x: m.pos.x,
|
||||
y: m.pos.y,
|
||||
},
|
||||
position: { x: m.pos.x, y: m.pos.y, },
|
||||
radius: 25,
|
||||
reflection: tech.waveReflections,
|
||||
expanding: true,
|
||||
resonanceCount: 0 //used with tech.isPhononWave
|
||||
})
|
||||
},
|
||||
@@ -6881,8 +7163,7 @@ const b = {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
// const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
|
||||
const end = 1100 * tech.isBulletsLastLonger * Math.pow(0.93, tech.waveReflections) //should equal about 1767
|
||||
const end = 1100 * tech.isBulletsLastLonger
|
||||
const damage = 2.3 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.4 : 1) * (tech.isInfiniteWaveAmmo ? 0.75 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
|
||||
@@ -6897,10 +7178,7 @@ const b = {
|
||||
if (!who.isShielded) {
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
Matter.Body.setVelocity(who, { //friction
|
||||
x: who.velocity.x * 0.95,
|
||||
y: who.velocity.y * 0.95
|
||||
});
|
||||
Matter.Body.setVelocity(who, { x: who.velocity.x * 0.95, y: who.velocity.y * 0.95 });
|
||||
let vertices = who.vertices;
|
||||
const vibe = 50 + who.radius * 0.15
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
@@ -6909,7 +7187,6 @@ const b = {
|
||||
who.locatePlayer();
|
||||
who.damage(damage / Math.sqrt(who.radius));
|
||||
|
||||
// if (tech.isPhononWave && (!who.alive || this.waves.length < 30 + 30 * Math.random()) && m.fireCDcycle < m.cycle) { //
|
||||
if (tech.isPhononWave && this.phononWaveCD < m.cycle) {
|
||||
this.phononWaveCD = m.cycle + 8 * (1 + this.waves[i].resonanceCount)
|
||||
const halfArc = 0.27 //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
|
||||
@@ -6933,18 +7210,10 @@ const b = {
|
||||
this.waves.push({
|
||||
position: who.position,
|
||||
angle: angle - halfArc, //used in drawing ctx.arc
|
||||
unit1: {
|
||||
x: Math.cos(angle - halfArc),
|
||||
y: Math.sin(angle - halfArc)
|
||||
}, //used for collision
|
||||
unit2: {
|
||||
x: Math.cos(angle + halfArc),
|
||||
y: Math.sin(angle + halfArc)
|
||||
}, //used for collision
|
||||
unit1: { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }, //used for collision
|
||||
unit2: { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }, //used for collision
|
||||
arc: halfArc * 2,
|
||||
radius: 25,
|
||||
reflection: 1,
|
||||
expanding: 1,
|
||||
resonanceCount: this.waves[i].resonanceCount + 1
|
||||
})
|
||||
}
|
||||
@@ -6952,13 +7221,11 @@ const b = {
|
||||
}
|
||||
|
||||
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
// for (let j = 0; j < hits.length; j++) {
|
||||
for (let j = 0, len = Math.min(30, hits.length); j < len; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
|
||||
|
||||
let vertices = who.vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
@@ -6973,17 +7240,10 @@ const b = {
|
||||
who.torque += who.inertia * 0.001 * (Math.random() - 0.5)
|
||||
}
|
||||
}
|
||||
// ctx.stroke(); //draw vibes
|
||||
|
||||
this.waves[i].radius += tech.waveBeamSpeed * 1.8 * this.waves[i].expanding //expand / move
|
||||
this.waves[i].radius += tech.waveBeamSpeed * 1.8 //expand / move
|
||||
if (this.waves[i].radius > end - 30 * this.waves[i].resonanceCount) {
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
this.waves.splice(i, 1) //end
|
||||
}
|
||||
}
|
||||
ctx.stroke();
|
||||
@@ -6992,29 +7252,14 @@ const b = {
|
||||
fireLongitudinal() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 4 : 8) * b.fireCDscale); // cool down
|
||||
const halfArc = (m.crouch ? 0.0785 : 0.275) * (tech.isBulletTeleport ? 0.66 + (Math.random() - 0.5) : 1) //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
|
||||
// if (tech.isBulletTeleport && Math.random() < 0.04) {
|
||||
// const scale = 400 * Math.random()
|
||||
// this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
|
||||
// }
|
||||
const angle = m.angle + tech.isBulletTeleport * 0.3 * (Math.random() - 0.5)
|
||||
this.waves.push({
|
||||
position: {
|
||||
x: m.pos.x + 25 * Math.cos(m.angle),
|
||||
y: m.pos.y + 25 * Math.sin(m.angle),
|
||||
},
|
||||
position: { x: m.pos.x + 25 * Math.cos(m.angle), y: m.pos.y + 25 * Math.sin(m.angle), },
|
||||
angle: angle - halfArc, //used in drawing ctx.arc
|
||||
unit1: {
|
||||
x: Math.cos(angle - halfArc),
|
||||
y: Math.sin(angle - halfArc)
|
||||
}, //used for collision
|
||||
unit2: {
|
||||
x: Math.cos(angle + halfArc),
|
||||
y: Math.sin(angle + halfArc)
|
||||
}, //used for collision
|
||||
unit1: { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }, //used for collision
|
||||
unit2: { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }, //used for collision
|
||||
arc: halfArc * 2,
|
||||
radius: 25,
|
||||
reflection: tech.waveReflections,
|
||||
expanding: 1,
|
||||
resonanceCount: 0
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user