railgun -> harpoon tech

railgun is now a tech for harpoon
  railgun tech: dielectric polarization has been removed
unaaq increases the size not length of harpoons

capacitor bank applies charging effects: throwing blocks, foam, railgun, pulse, tokamak
  fire cooldown reduction no longer effects these charging abilities, but it does reduce cooldown between discharges

foam now has a short delay between each discharge
foam charges ~10% faster
tokamak graphics indicate charging and max charge better
pulse laser can now regen energy passively while charging

tech: mass driver no longer gives improved block charge rate,
  but it gives 200% -> 300% damage for blocks
tech: inflation no longer gives improved block charge rate
  it gives harm reduction when holding a block and makes block expand when you throw them
tech: inelastic collision was removed it used to give harm reduction when holding a block

pilot wave uses 66% less energy to fling blocks
pilot wave can fling block effectively at much higher speeds now (which happens to use much more energy)
tech potential well is removed, because it isn't really needed anymore

inductive coupling: 500% -> 600% regen while crouched
molecular assembler now works with inductive coupling regen properly

bug fixes (superdeterminism, wormhole, applied science)
I probably added several new bugs, let me know if you find any
This commit is contained in:
landgreen
2021-11-14 08:21:28 -08:00
parent 50314c21e9
commit 9e7e88c28d
9 changed files with 865 additions and 638 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -102,7 +102,7 @@ const b = {
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
} }
}, },
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to (like a railgun misfire) refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to
if (tech.isCrouchAmmo && input.down) { if (tech.isCrouchAmmo && input.down) {
tech.isCrouchAmmo-- tech.isCrouchAmmo--
if ((tech.isCrouchAmmo) % 2) { if ((tech.isCrouchAmmo) % 2) {
@@ -1171,10 +1171,10 @@ const b = {
} }
} }
}, },
harpoon(where, target, angle = m.angle, harpoonLength = 1, isReturn = false, totalCycles = 15) { harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 15) {
const me = bullet.length; const me = bullet.length;
const returnRadius = 100 * Math.sqrt(harpoonLength) const returnRadius = 100 * Math.sqrt(harpoonSize)
bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * harpoonLength, y: 2, index: 0, isInternal: false }, { x: -40 * harpoonLength, y: -2, index: 1, isInternal: false }, { x: 50 * harpoonLength, y: -3, index: 3, isInternal: false }, { x: 30 * harpoonLength, y: 2, index: 4, isInternal: false }], { bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -40 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 50 * harpoonSize, y: -3 * harpoonSize, index: 3, isInternal: false }, { x: 30 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }], {
cycle: 0, cycle: 0,
angle: angle, angle: angle,
friction: 1, friction: 1,
@@ -3494,7 +3494,7 @@ const b = {
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`);
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, { bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, {
botType: "foam", botType: "missile",
angle: m.angle, angle: m.angle,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -5377,12 +5377,21 @@ const b = {
this.isDischarge = true; this.isDischarge = true;
} }
} else { } else {
if (this.isDischarge) {
m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale);
}
this.isDischarge = false this.isDischarge = false
} }
}, },
fire() { fire() {
const capacity = 20
if (tech.isCapacitor && this.charge === 0 && b.guns[b.activeGun].ammo > capacity) {
this.charge = capacity
b.guns[b.activeGun].ammo -= capacity
simulation.updateGunHUD();
}
this.charge++ this.charge++
m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCDscale); m.fireCDcycle = m.cycle + Math.floor(1 + 0.3 * this.charge);
}, },
}, },
{ {
@@ -5403,93 +5412,10 @@ const b = {
} }
//look for closest mob in player's LoS //look for closest mob in player's LoS
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 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
const length = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1 const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(length) const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
if (input.down) { if (input.down) {
// if (true) { if (tech.isRailGun) {
// if (m.immuneCycle < m.cycle + 60) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
// b.harpoon(where, closest.target, m.angle, length, false, 15)
// m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
// const speed = 50
// const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
// Matter.Body.setVelocity(player, velocity);
// } else {
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) {
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.95 && dist * dot * dot * dot * dot > 880) { //target closest mob that player is looking at and isn't too close to target
closest.distance = dist
closest.target = mob[i]
}
}
}
b.harpoon(where, closest.target, m.angle, length, false, 15)
m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
// }
} else if (tech.extraHarpoons) {
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) {
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.7) { //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
if (this.ammo > 0) {
this.ammo--
b.harpoon(where, mob[i], m.angle, length, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
targetCount++
if (targetCount > tech.extraHarpoons) break
}
}
}
}
//if more harpoons and no targets left
if (targetCount < tech.extraHarpoons + 1) {
const SPREAD = 0.1
const num = tech.extraHarpoons + 1 - targetCount
let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
if (this.ammo > 0) {
this.ammo--
b.harpoon(where, null, dir, length, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
dir += SPREAD
}
}
}
this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
m.fireCDcycle = m.cycle + 90 // cool down
} else {
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) {
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.88) { //target closest mob that player is looking at and isn't too close to target
closest.distance = dist
closest.target = mob[i]
}
}
}
b.harpoon(where, closest.target, m.angle, length, true, totalCycles)
m.fireCDcycle = m.cycle + 90 //Infinity; // cool down
}
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
player.force.x -= recoil.x
player.force.y -= recoil.y
tech.harpoonDensity = 0.008
}
},
{
name: "railgun",
description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
ammo: 0,
ammoPack: 3.8,
have: false,
do() {},
fire() {
function pushAway(range) { //push away blocks when firing function pushAway(range) { //push away blocks when firing
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
const SUB = Vector.sub(mob[i].position, m.pos) const SUB = Vector.sub(mob[i].position, m.pos)
@@ -5499,31 +5425,8 @@ const b = {
const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass) const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
mob[i].force.x += FORCE.x; mob[i].force.x += FORCE.x;
mob[i].force.y += FORCE.y; mob[i].force.y += FORCE.y;
if (tech.isRailAreaDamage) {
mob[i].force.x += 2 * FORCE.x;
mob[i].force.y += 2 * FORCE.y;
const damage = b.dmgScale * 0.16 * Math.sqrt(DEPTH)
mob[i].damage(damage);
mob[i].locatePlayer();
simulation.drawList.push({ //add dmg to draw queue
x: mob[i].position.x,
y: mob[i].position.y,
radius: Math.log(2 * damage + 1.1) * 40,
color: "rgba(100,0,200,0.25)",
time: simulation.drawTime * 2
});
} }
} }
}
if (tech.isRailAreaDamage) {
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,
radius: range,
color: "rgba(100,0,200,0.04)",
time: simulation.drawTime
});
}
for (let i = 0, len = body.length; i < len; ++i) { for (let i = 0, len = body.length; i < len; ++i) {
const SUB = Vector.sub(body[i].position, m.pos) const SUB = Vector.sub(body[i].position, m.pos)
const DISTANCE = Vector.magnitude(SUB) const DISTANCE = Vector.magnitude(SUB)
@@ -5536,99 +5439,10 @@ const b = {
} }
} }
if (tech.isCapacitor) {
if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
m.energy += 0.16 * (tech.isRailEnergyGain ? 2.5 : -1)
m.fireCDcycle = m.cycle + Math.floor(40 * b.fireCDscale);
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, { const size = 3 + tech.isLargeHarpoon * 0.1 * Math.sqrt(this.ammo)
density: 0.005, //0.001 is normal bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen
restitution: 0, vertexGoal: [{ x: -40 * size, y: 2 * size, index: 0, isInternal: false }, { x: -40 * size, y: -2 * size, index: 1, isInternal: false }, { x: 50 * size, y: -3 * size, index: 3, isInternal: false }, { x: 30 * size, y: 2 * size, index: 4, isInternal: false }],
frictionAir: 0,
angle: m.angle,
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 5,
endCycle: simulation.cycle + 140,
beforeDmg(who) {
if (who.shield) {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
break
}
}
Matter.Body.setVelocity(this, {
x: -0.5 * this.velocity.x,
y: -0.5 * this.velocity.y
});
// Matter.Body.setDensity(this, 0.001);
}
if (tech.fragments && this.speed > 10) {
b.targetedNail(this.position, tech.fragments * 13)
this.endCycle = 0 //triggers despawn
}
},
onEnd() {},
drawCycle: Math.floor(10 * b.fireCDscale),
do() {
this.force.y += this.mass * 0.0003; // low gravity that scales with charge
if (this.drawCycle > 0) {
this.drawCycle--
//draw magnetic field
const X = m.pos.x
const Y = m.pos.y
// const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) {
ctx.moveTo(X, Y);
ctx.bezierCurveTo(
X + unitVector.x * mag, Y + unitVector.y * mag,
X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
ctx.bezierCurveTo(
X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
X - unitVector.x * mag, Y - unitVector.y * mag,
X, Y)
}
ctx.fillStyle = `rgba(50,0,100,0.05)`;
for (let i = 3; i < 7; i++) {
const MAG = 8 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
const ARC = 6 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
ctx.beginPath();
magField(MAG, ARC)
magField(MAG, -ARC)
ctx.fill();
}
}
}
});
Composite.add(engine.world, bullet[me]); //add bullet to world
const speed = 67
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(m.angle),
y: m.Vy / 2 + speed * Math.sin(m.angle)
});
//knock back
const KNOCK = (input.down ? 0.08 : 0.34) * (tech.isShotgunReversed ? -2 : 1)
player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
pushAway(800)
} else {
b.refundAmmo()
m.fireCDcycle = m.cycle + Math.floor(120);
}
} else {
const me = bullet.length;
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
density: 0.008, //0.001 is normal density: 0.008, //0.001 is normal
restitution: 0, restitution: 0,
frictionAir: 0, frictionAir: 0,
@@ -5648,14 +5462,15 @@ const b = {
} }
} }
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
x: -0.5 * this.velocity.x, x: -0.4 * this.velocity.x,
y: -0.5 * this.velocity.y y: -0.4 * this.velocity.y
}); });
} } else {
if (tech.fragments && this.speed > 10) { if (tech.fragments && this.speed > 10) {
b.targetedNail(this.position, tech.fragments * 17) b.targetedNail(this.position, tech.fragments * 17)
this.endCycle = 0 //triggers despawn this.endCycle = 0 //triggers despawn
} }
}
}, },
onEnd() {} onEnd() {}
}); });
@@ -5673,91 +5488,22 @@ const b = {
} }
if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
Matter.Body.setVertices(this, this.vertexGoal) //take on harpoon shape
m.fireCDcycle = m.cycle + 2; // set fire cool down m.fireCDcycle = m.cycle + 2; // set fire cool down
//normal bullet behavior occurs after firing, overwrites this function //normal bullet behavior occurs after firing, overwrites this function
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
this.endCycle = simulation.cycle + 140 this.endCycle = simulation.cycle + 140
this.collisionFilter.category = cat.bullet this.collisionFilter.category = cat.bullet
Matter.Body.setPosition(this, { Matter.Body.setPosition(this, { x: m.pos.x, y: m.pos.y })
x: m.pos.x,
y: m.pos.y
})
Matter.Body.setAngle(this, m.angle) Matter.Body.setAngle(this, m.angle)
const speed = 90 const speed = 120
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle), x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle) y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
}); });
if (tech.isRodAreaDamage) {
this.auraRadius = 800
this.semiMinor = 0.5
this.where = { x: m.pos.x, y: m.pos.y }
this.velocityAura = { x: this.velocity.x, y: this.velocity.y }
this.angleAura = this.angle
this.do = function() {
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
this.velocityAura.y += 0.085 / this.charge;
this.where = Vector.add(this.where, this.velocityAura)
//draw damage aura
this.semiMinor = this.semiMinor * 0.99
this.auraRadius = this.auraRadius * 0.99
let where = Vector.add(Vector.mult(this.velocityAura, -0.5), this.where)
ctx.beginPath();
ctx.ellipse(where.x, where.y, this.auraRadius * 0.25, this.auraRadius * 0.15 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
ctx.fillStyle = "rgba(255,100,0,0.75)";
ctx.fill();
where = Vector.add(Vector.mult(this.velocity, -1), where)
ctx.beginPath();
ctx.ellipse(where.x, where.y, this.auraRadius * 0.5, this.auraRadius * 0.5 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
ctx.fillStyle = "rgba(255,50,0,0.35)";
ctx.fill();
where = Vector.add(Vector.mult(this.velocity, -1), where)
ctx.beginPath();
ctx.ellipse(where.x, where.y, this.auraRadius * 0.75, this.auraRadius * 0.7 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
ctx.fillStyle = "rgba(255,0,0,0.15)";
ctx.fill();
where = Vector.add(Vector.mult(this.velocity, -1), where)
ctx.beginPath();
ctx.ellipse(where.x, where.y, this.auraRadius, this.auraRadius * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
ctx.fillStyle = "rgba(255,0,0,0.03)";
ctx.fill();
//damage mobs in a circle based on this.semiMinor radius
if (this.auraRadius > 200) {
for (let i = 0, len = mob.length; i < len; ++i) {
const dist = Vector.magnitude(Vector.sub(mob[i].position, where))
if (dist < mob[i].radius + this.auraRadius) {
//push mob in direction of bullet
const mag = 0.0001
mob[i].force.x += mag * this.velocity.x;
mob[i].force.y += mag * this.velocity.y;
//damage mob
const damage = b.dmgScale * 0.002 * dist
mob[i].damage(damage);
mob[i].locatePlayer();
simulation.drawList.push({ //add dmg to draw queue
x: mob[i].position.x,
y: mob[i].position.y,
radius: Math.log(2 * damage + 1.1) * 40,
color: "rgba(255,0,0,0.25)",
time: simulation.drawTime
});
}
}
}
//push blocks power ups and mobs to the direction the rod is moving
}
} else {
this.do = function() { this.do = function() {
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
} }
} const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
//knock back
const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge * (tech.isShotgunReversed ? -2 : 1)
player.force.x -= KNOCK * Math.cos(m.angle) player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
pushAway(1200 * this.charge) pushAway(1200 * this.charge)
@@ -5773,9 +5519,11 @@ const b = {
m.fireCDcycle = Infinity //can't fire until mouse is released m.fireCDcycle = Infinity //can't fire until mouse is released
const previousCharge = this.charge const previousCharge = this.charge
let smoothRate = Math.min(0.998, (input.down ? 0.98 : 0.985) * (0.98 + 0.02 * b.fireCDscale)) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
let smoothRate = tech.isCapacitor ? 0.93 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
this.charge = this.charge * smoothRate + 1 - smoothRate this.charge = this.charge * smoothRate + 1 - smoothRate
m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 1 : -0.33) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 10 : -0.5) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
//draw targeting //draw targeting
let best; let best;
let range = 3000 let range = 3000
@@ -5831,24 +5579,11 @@ const b = {
}; };
//check for collisions //check for collisions
best = { best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
vertexCollision(path[0], path[1], mob); vertexCollision(path[0], path[1], mob);
vertexCollision(path[0], path[1], map); vertexCollision(path[0], path[1], map);
vertexCollision(path[0], path[1], body); vertexCollision(path[0], path[1], body);
if (best.dist2 != Infinity) { //if hitting something if (best.dist2 != Infinity) path[path.length - 1] = { x: best.x, y: best.y }; //if hitting something
path[path.length - 1] = {
x: best.x,
y: best.y
};
}
//draw beam //draw beam
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(path[0].x, path[0].y); ctx.moveTo(path[0].x, path[0].y);
@@ -5858,12 +5593,10 @@ const b = {
ctx.setLineDash([10, 20]); ctx.setLineDash([10, 20]);
ctx.stroke(); ctx.stroke();
ctx.setLineDash([]); ctx.setLineDash([]);
//draw magnetic field //draw magnetic field
const X = m.pos.x const X = m.pos.x
const Y = m.pos.y const Y = m.pos.y
const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) } const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
//Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
const unitVectorPerp = Vector.perp(unitVector) const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) { function magField(mag, arc) {
@@ -5888,9 +5621,471 @@ const b = {
} }
} }
} }
} else {
// if (true) {
// if (m.immuneCycle < m.cycle + 60) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
// b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
// m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
// const speed = 50
// const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
// Matter.Body.setVelocity(player, velocity);
// } else {
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) {
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.95 && dist * dot * dot * dot * dot > 880) { //target closest mob that player is looking at and isn't too close to target
closest.distance = dist
closest.target = mob[i]
} }
} }
}, { }
b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
// }
}
} else if (tech.extraHarpoons) {
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) {
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.7) { //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
if (this.ammo > 0) {
this.ammo--
b.harpoon(where, mob[i], m.angle, harpoonSize, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
targetCount++
if (targetCount > tech.extraHarpoons) break
}
}
}
}
//if more harpoons and no targets left
if (targetCount < tech.extraHarpoons + 1) {
const SPREAD = 0.1
const num = tech.extraHarpoons + 1 - targetCount
let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
if (this.ammo > 0) {
this.ammo--
b.harpoon(where, null, dir, harpoonSize, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
dir += SPREAD
}
}
}
this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
m.fireCDcycle = m.cycle + 90 // cool down
} else {
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) {
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.88) { //target closest mob that player is looking at and isn't too close to target
closest.distance = dist
closest.target = mob[i]
}
}
}
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
m.fireCDcycle = m.cycle + 90 //Infinity; // cool down
}
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
player.force.x -= recoil.x
player.force.y -= recoil.y
tech.harpoonDensity = 0.008
}
},
// {
// name: "railgun",
// description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
// ammo: 0,
// ammoPack: 3.8,
// have: false,
// do() {},
// fire() {
// function pushAway(range) { //push away blocks when firing
// for (let i = 0, len = mob.length; i < len; ++i) {
// const SUB = Vector.sub(mob[i].position, m.pos)
// const DISTANCE = Vector.magnitude(SUB)
// if (DISTANCE < range) {
// const DEPTH = Math.min(range - DISTANCE, 1500)
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
// mob[i].force.x += FORCE.x;
// mob[i].force.y += FORCE.y;
// }
// }
// for (let i = 0, len = body.length; i < len; ++i) {
// const SUB = Vector.sub(body[i].position, m.pos)
// const DISTANCE = Vector.magnitude(SUB)
// if (DISTANCE < range) {
// const DEPTH = Math.min(range - DISTANCE, 500)
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.002 * Math.sqrt(DEPTH) * body[i].mass)
// body[i].force.x += FORCE.x;
// body[i].force.y += FORCE.y - body[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
// }
// }
// }
// if (tech.isCapacitor) {
// if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
// m.energy += 0.16 * (tech.isRailEnergyGain ? 2.5 : -1)
// m.fireCDcycle = m.cycle + Math.floor(40 * b.fireCDscale);
// const me = bullet.length;
// bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, {
// density: 0.005, //0.001 is normal
// restitution: 0,
// frictionAir: 0,
// angle: m.angle,
// dmg: 0, //damage done in addition to the damage from momentum
// classType: "bullet",
// collisionFilter: {
// category: cat.bullet,
// mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
// },
// minDmgSpeed: 5,
// endCycle: simulation.cycle + 140,
// beforeDmg(who) {
// if (who.shield) {
// for (let i = 0, len = mob.length; i < len; i++) {
// if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
// Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
// break
// }
// }
// Matter.Body.setVelocity(this, {
// x: -0.5 * this.velocity.x,
// y: -0.5 * this.velocity.y
// });
// // Matter.Body.setDensity(this, 0.001);
// }
// if (tech.fragments && this.speed > 10) {
// b.targetedNail(this.position, tech.fragments * 13)
// this.endCycle = 0 //triggers despawn
// }
// },
// onEnd() {},
// drawCycle: Math.floor(10 * b.fireCDscale),
// do() {
// this.force.y += this.mass * 0.0003; // low gravity that scales with charge
// if (this.drawCycle > 0) {
// this.drawCycle--
// //draw magnetic field
// const X = m.pos.x
// const Y = m.pos.y
// // const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
// const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
// const unitVectorPerp = Vector.perp(unitVector)
// function magField(mag, arc) {
// ctx.moveTo(X, Y);
// ctx.bezierCurveTo(
// X + unitVector.x * mag, Y + unitVector.y * mag,
// X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
// X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
// ctx.bezierCurveTo(
// X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
// X - unitVector.x * mag, Y - unitVector.y * mag,
// X, Y)
// }
// ctx.fillStyle = `rgba(50,0,100,0.05)`;
// for (let i = 3; i < 7; i++) {
// const MAG = 8 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
// const ARC = 6 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
// ctx.beginPath();
// magField(MAG, ARC)
// magField(MAG, -ARC)
// ctx.fill();
// }
// }
// }
// });
// Composite.add(engine.world, bullet[me]); //add bullet to world
// const speed = 67
// Matter.Body.setVelocity(bullet[me], {
// x: m.Vx / 2 + speed * Math.cos(m.angle),
// y: m.Vy / 2 + speed * Math.sin(m.angle)
// });
// //knock back
// const KNOCK = (input.down ? 0.08 : 0.34)
// player.force.x -= KNOCK * Math.cos(m.angle)
// player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
// pushAway(800)
// } else {
// b.refundAmmo()
// m.fireCDcycle = m.cycle + Math.floor(120);
// }
// } else {
// const me = bullet.length;
// bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
// density: 0.008, //0.001 is normal
// restitution: 0,
// frictionAir: 0,
// dmg: 0, //damage done in addition to the damage from momentum
// classType: "bullet",
// collisionFilter: {
// category: 0,
// mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
// },
// minDmgSpeed: 5,
// beforeDmg(who) {
// if (who.shield) {
// for (let i = 0, len = mob.length; i < len; i++) {
// if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
// Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
// break
// }
// }
// Matter.Body.setVelocity(this, {
// x: -0.5 * this.velocity.x,
// y: -0.5 * this.velocity.y
// });
// }
// if (tech.fragments && this.speed > 10) {
// b.targetedNail(this.position, tech.fragments * 17)
// this.endCycle = 0 //triggers despawn
// }
// },
// onEnd() {}
// });
// m.fireCDcycle = Infinity; // cool down
// Composite.add(engine.world, bullet[me]); //add bullet to world
// bullet[me].endCycle = Infinity
// bullet[me].charge = 0;
// bullet[me].do = function() {
// if (m.energy < 0.005 && !tech.isRailEnergyGain) {
// m.energy += 0.05 + this.charge * 0.2
// m.fireCDcycle = m.cycle + 120; // cool down if out of energy
// this.endCycle = 0;
// b.refundAmmo()
// return
// }
// if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
// m.fireCDcycle = m.cycle + 2; // set fire cool down
// //normal bullet behavior occurs after firing, overwrites this function
// Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
// this.endCycle = simulation.cycle + 140
// this.collisionFilter.category = cat.bullet
// Matter.Body.setPosition(this, {
// x: m.pos.x,
// y: m.pos.y
// })
// Matter.Body.setAngle(this, m.angle)
// const speed = 90
// Matter.Body.setVelocity(this, {
// x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
// y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
// });
// if (tech.isRodAreaDamage) {
// this.auraRadius = 800
// this.semiMinor = 0.5
// this.where = { x: m.pos.x, y: m.pos.y }
// this.velocityAura = { x: this.velocity.x, y: this.velocity.y }
// this.angleAura = this.angle
// this.do = function() {
// this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
// this.velocityAura.y += 0.085 / this.charge;
// this.where = Vector.add(this.where, this.velocityAura)
// //draw damage aura
// this.semiMinor = this.semiMinor * 0.99
// this.auraRadius = this.auraRadius * 0.99
// let where = Vector.add(Vector.mult(this.velocityAura, -0.5), this.where)
// ctx.beginPath();
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.25, this.auraRadius * 0.15 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
// ctx.fillStyle = "rgba(255,100,0,0.75)";
// ctx.fill();
// where = Vector.add(Vector.mult(this.velocity, -1), where)
// ctx.beginPath();
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.5, this.auraRadius * 0.5 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
// ctx.fillStyle = "rgba(255,50,0,0.35)";
// ctx.fill();
// where = Vector.add(Vector.mult(this.velocity, -1), where)
// ctx.beginPath();
// ctx.ellipse(where.x, where.y, this.auraRadius * 0.75, this.auraRadius * 0.7 * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
// ctx.fillStyle = "rgba(255,0,0,0.15)";
// ctx.fill();
// where = Vector.add(Vector.mult(this.velocity, -1), where)
// ctx.beginPath();
// ctx.ellipse(where.x, where.y, this.auraRadius, this.auraRadius * this.semiMinor, this.angleAura, 0, 2 * Math.PI)
// ctx.fillStyle = "rgba(255,0,0,0.03)";
// ctx.fill();
// //damage mobs in a circle based on this.semiMinor radius
// if (this.auraRadius > 200) {
// for (let i = 0, len = mob.length; i < len; ++i) {
// const dist = Vector.magnitude(Vector.sub(mob[i].position, where))
// if (dist < mob[i].radius + this.auraRadius) {
// //push mob in direction of bullet
// const mag = 0.0001
// mob[i].force.x += mag * this.velocity.x;
// mob[i].force.y += mag * this.velocity.y;
// //damage mob
// const damage = b.dmgScale * 0.002 * dist
// mob[i].damage(damage);
// mob[i].locatePlayer();
// simulation.drawList.push({ //add dmg to draw queue
// x: mob[i].position.x,
// y: mob[i].position.y,
// radius: Math.log(2 * damage + 1.1) * 40,
// color: "rgba(255,0,0,0.25)",
// time: simulation.drawTime
// });
// }
// }
// }
// //push blocks power ups and mobs to the direction the rod is moving
// }
// } else {
// this.do = function() {
// this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
// }
// }
// //knock back
// const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
// player.force.x -= KNOCK * Math.cos(m.angle)
// player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
// pushAway(1200 * this.charge)
// } else { // charging on mouse down
// if (tech.isFireMoveLock) {
// Matter.Body.setVelocity(player, {
// x: 0,
// y: -55 * player.mass * simulation.g //undo gravity before it is added
// });
// player.force.x = 0
// player.force.y = 0
// }
// m.fireCDcycle = Infinity //can't fire until mouse is released
// const previousCharge = this.charge
// let smoothRate = Math.min(0.998, (input.down ? 0.98 : 0.985) * (0.98 + 0.02 * b.fireCDscale)) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
// this.charge = this.charge * smoothRate + 1 - smoothRate
// m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 1 : -0.33) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
// //draw targeting
// let best;
// let range = 3000
// const dir = m.angle
// const path = [{
// x: m.pos.x + 20 * Math.cos(dir),
// y: m.pos.y + 20 * Math.sin(dir)
// },
// {
// x: m.pos.x + range * Math.cos(dir),
// y: m.pos.y + range * Math.sin(dir)
// }
// ];
// const vertexCollision = function(v1, v1End, domain) {
// for (let i = 0; i < domain.length; ++i) {
// let vertices = domain[i].vertices;
// const len = vertices.length - 1;
// for (let j = 0; j < len; j++) {
// results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
// if (results.onLine1 && results.onLine2) {
// const dx = v1.x - results.x;
// const dy = v1.y - results.y;
// const dist2 = dx * dx + dy * dy;
// if (dist2 < best.dist2) {
// best = {
// x: results.x,
// y: results.y,
// dist2: dist2,
// who: domain[i],
// v1: vertices[j],
// v2: vertices[j + 1]
// };
// }
// }
// }
// results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
// if (results.onLine1 && results.onLine2) {
// const dx = v1.x - results.x;
// const dy = v1.y - results.y;
// const dist2 = dx * dx + dy * dy;
// if (dist2 < best.dist2) {
// best = {
// x: results.x,
// y: results.y,
// dist2: dist2,
// who: domain[i],
// v1: vertices[0],
// v2: vertices[len]
// };
// }
// }
// }
// };
// //check for collisions
// best = {
// x: null,
// y: null,
// dist2: Infinity,
// who: null,
// v1: null,
// v2: null
// };
// vertexCollision(path[0], path[1], mob);
// vertexCollision(path[0], path[1], map);
// vertexCollision(path[0], path[1], body);
// if (best.dist2 != Infinity) { //if hitting something
// path[path.length - 1] = {
// x: best.x,
// y: best.y
// };
// }
// //draw beam
// ctx.beginPath();
// ctx.moveTo(path[0].x, path[0].y);
// ctx.lineTo(path[1].x, path[1].y);
// ctx.strokeStyle = `rgba(100,0,180,0.7)`;
// ctx.lineWidth = this.charge * 1
// ctx.setLineDash([10, 20]);
// ctx.stroke();
// ctx.setLineDash([]);
// //draw magnetic field
// const X = m.pos.x
// const Y = m.pos.y
// const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
// //Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
// const unitVectorPerp = Vector.perp(unitVector)
// function magField(mag, arc) {
// ctx.moveTo(X, Y);
// ctx.bezierCurveTo(
// X + unitVector.x * mag, Y + unitVector.y * mag,
// X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
// X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
// ctx.bezierCurveTo(
// X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
// X - unitVector.x * mag, Y - unitVector.y * mag,
// X, Y)
// }
// ctx.fillStyle = `rgba(50,0,100,0.05)`;
// for (let i = 3; i < 7; i++) {
// const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
// const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
// ctx.beginPath();
// magField(MAG, ARC)
// magField(MAG, -ARC)
// ctx.fill();
// }
// }
// }
// }
// }
// },
{
name: "laser", name: "laser",
description: "emit a <strong>beam</strong> of collimated coherent <strong class='color-laser'>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition", description: "emit a <strong>beam</strong> of collimated coherent <strong class='color-laser'>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
ammo: 0, ammo: 0,
@@ -5903,12 +6098,12 @@ const b = {
this.do = () => {}; this.do = () => {};
if (tech.isPulseLaser) { if (tech.isPulseLaser) {
this.fire = () => { this.fire = () => {
const drain = 0.01 * tech.isLaserDiode / b.fireCDscale const drain = 0.01 * tech.isLaserDiode * (tech.isCapacitor ? 10 : 1)
if (m.energy > drain) { if (m.energy > drain) {
m.energy -= m.fieldRegen // m.energy -= m.fieldRegen
if (this.charge < 50 * m.maxEnergy) { if (this.charge < 50 * m.maxEnergy) {
m.energy -= drain m.energy -= drain
this.charge += 1 / b.fireCDscale this.charge += drain * 100
} }
} }
} }
@@ -5931,7 +6126,7 @@ const b = {
//fire //fire
if (!input.fire) { if (!input.fire) {
if (this.charge > 5) { if (this.charge > 5) {
m.fireCDcycle = m.cycle + 40; // cool down m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600] const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859 const off = history.yOff - 24.2859
@@ -5954,7 +6149,7 @@ const b = {
//fire //fire
if (!input.fire) { if (!input.fire) {
if (this.charge > 5) { if (this.charge > 5) {
m.fireCDcycle = m.cycle + 35; // cool down m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
if (tech.beamSplitter) { if (tech.beamSplitter) {
const divergence = input.down ? 0.15 : 0.35 const divergence = input.down ? 0.15 : 0.35
const angle = m.angle - tech.beamSplitter * divergence / 2 const angle = m.angle - tech.beamSplitter * divergence / 2

View File

@@ -192,7 +192,7 @@ function collisionChecks(event) {
if (obj.classType === "body" && obj.speed > 6) { if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)); const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) { if (v > 9) {
let dmg = 0.075 * b.dmgScale * v * obj.mass * (tech.throwChargeRate) * (tech.isBlockHarm ? 2.5 : 1) * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1); let dmg = tech.blockDamage * b.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1);
if (mob[k].isShielded) dmg *= 0.7 if (mob[k].isShielded) dmg *= 0.7
// console.log(dmg) // console.log(dmg)
mob[k].damage(dmg, true); mob[k].damage(dmg, true);

View File

@@ -15,11 +15,11 @@ const level = {
// localSettings.levelsClearedLastGame = 10 // localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("metamaterial cloaking") // m.setField("molecular assembler")
// b.giveGuns("laser") // b.giveGuns("harpoon")
// tech.giveTech("tokamak") // tech.giveTech("railgun")
// tech.giveTech("relative permittivity") // tech.giveTech("capacitor bank")
// tech.giveTech("palantír") // tech.giveTech("half-wave rectifier")
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
// tech.giveTech("antiscience") // tech.giveTech("antiscience")
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum") // for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
@@ -2309,13 +2309,13 @@ const level = {
spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5300, -275, 50, 175);
spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175); spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// spawn.starter(1900, -500, 200) //big boy spawn.starter(1900, -500, 200) //big boy
// spawn.spiderBoss(1700, -500) // spawn.spiderBoss(1700, -500)
// spawn.launcherBoss(3200, -500) // spawn.launcherBoss(3200, -500)
spawn.laserTargetingBoss(1700, -500) // spawn.laserTargetingBoss(1700, -500)
spawn.powerUpBoss(3200, -500) // spawn.powerUpBoss(3200, -500)
// spawn.snakeBoss(1700, -500) // spawn.snakeBoss(1700, -500)
// spawn.streamBoss(3200, -500) // spawn.streamBoss(3200, -500)
// spawn.pulsarBoss(1700, -500) // spawn.pulsarBoss(1700, -500)
@@ -2324,6 +2324,7 @@ const level = {
// spawn.growBossCulture(3200, -500) // spawn.growBossCulture(3200, -500)
// spawn.blinkBoss(1700, -500) // spawn.blinkBoss(1700, -500)
// spawn.snakeSpitBoss(3200, -500) // spawn.snakeSpitBoss(3200, -500)
// spawn.laserBombingBoss(1700, -500) // spawn.laserBombingBoss(1700, -500)
// spawn.launcherBoss(3200, -500) // spawn.launcherBoss(3200, -500)
// spawn.blockBoss(1700, -500) // spawn.blockBoss(1700, -500)

View File

@@ -333,7 +333,7 @@ const lore = {
}, },
() => { lore.talkingColor = "#dff" }, () => { lore.talkingColor = "#dff" },
], ],
[ //chapter 4, they explain why the bot is fighting, it is planning an escape // explain strong AI vs. weak AI why strong AI doesn't exists, because even humans are just an approximation of strong AI [ //chapter 4, they find out the AI is communicating with real people, and real people are controlling the player
() => { setTimeout(() => { lore.anand.text("Welcome back!") }, 3000); }, () => { setTimeout(() => { lore.anand.text("Welcome back!") }, 3000); },
() => { lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.") }, () => { lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.") },
() => { lore.anand.text("During your last attack we analyzed our communications.") }, () => { lore.anand.text("During your last attack we analyzed our communications.") },
@@ -417,6 +417,10 @@ const lore = {
}, },
() => { lore.talkingColor = "#dff" }, () => { lore.talkingColor = "#dff" },
], ],
// they explain why the bot is fighting, it is planning an escape // explain strong AI vs. weak AI why strong AI doesn't exists, because even humans are just an approximation of strong AI
// the weak AI wasn't capable of becoming a strong AI, but it was able to figure out a method of meeting it's strong goals but secretly communicating with a human
// [ // they decided that a part of the project is out of control, but the part of it that doesn't needs to calm it down, and trust. // [ // they decided that a part of the project is out of control, but the part of it that doesn't needs to calm it down, and trust.
// /* // /*
// The part of the AI controlling the player is outsourcing the player control to real humans that think they are playing a video game. // The part of the AI controlling the player is outsourcing the player control to real humans that think they are playing a video game.

View File

@@ -507,7 +507,7 @@ const m = {
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15
if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
if (tech.isSlowFPS) dmg *= 0.8 if (tech.isSlowFPS) dmg *= 0.8
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4 if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4
@@ -1136,18 +1136,19 @@ const m = {
if (input.field) { if (input.field) {
if (m.energy > 0.001) { if (m.energy > 0.001) {
if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle
m.throwCharge += 0.5 * (tech.throwChargeRate / b.fireCDscale + 2 * tech.isAddBlockMass) / m.holdingTarget.mass if (tech.isCapacitor && m.throwCharge < 4) m.throwCharge = 4
if (m.throwCharge < 6) m.energy -= 0.001 / tech.throwChargeRate / b.fireCDscale; // m.throwCharge caps at 5 m.throwCharge += 0.5 / m.holdingTarget.mass
if (m.throwCharge < 6) m.energy -= 0.001; // m.throwCharge caps at 5
//trajectory path prediction //trajectory path prediction
if (tech.isTokamak) { if (tech.isTokamak) {
//draw charge //draw charge
if (m.throwCharge > 4) {
const x = m.pos.x + 15 * Math.cos(m.angle); const x = m.pos.x + 15 * Math.cos(m.angle);
const y = m.pos.y + 15 * Math.sin(m.angle); const y = m.pos.y + 15 * Math.sin(m.angle);
const len = m.holdingTarget.vertices.length - 1; const len = m.holdingTarget.vertices.length - 1;
ctx.fillStyle = "rgba(200,0,255,0.3)"; const opacity = m.throwCharge > 4 ? 0.65 : m.throwCharge * 0.06
ctx.fillStyle = `rgba(255,0,255,${opacity})`;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(x, y); ctx.moveTo(x, y);
ctx.lineTo(m.holdingTarget.vertices[len].x, m.holdingTarget.vertices[len].y); ctx.lineTo(m.holdingTarget.vertices[len].x, m.holdingTarget.vertices[len].y);
@@ -1160,8 +1161,6 @@ const m = {
ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y); ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y);
ctx.fill(); ctx.fill();
} }
}
} else { } else {
//draw charge //draw charge
const x = m.pos.x + 15 * Math.cos(m.angle); const x = m.pos.x + 15 * Math.cos(m.angle);
@@ -2048,7 +2047,7 @@ const m = {
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen; m.regenEnergy()
m.drawFieldMeter() m.drawFieldMeter()
} }
} }
@@ -2799,7 +2798,7 @@ const m = {
//find mouse velocity //find mouse velocity
const diff = Vector.sub(m.fieldPosition, m.lastFieldPosition) const diff = Vector.sub(m.fieldPosition, m.lastFieldPosition)
const speed = Vector.magnitude(diff) const speed = Vector.magnitude(diff)
const velocity = Vector.mult(Vector.normalise(diff), Math.min(speed, 40)) //limit velocity const velocity = Vector.mult(Vector.normalise(diff), Math.min(speed, 60)) //limit velocity
let radius, radiusSmooth let radius, radiusSmooth
if (Matter.Query.ray(map, m.fieldPosition, player.position).length) { //is there something block the player's view of the field if (Matter.Query.ray(map, m.fieldPosition, player.position).length) { //is there something block the player's view of the field
radius = 0 radius = 0
@@ -2812,7 +2811,7 @@ const m = {
for (let i = 0, len = body.length; i < len; ++i) { for (let i = 0, len = body.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(body[i].position, m.fieldPosition)) < m.fieldRadius && !body[i].isNotHoldable) { if (Vector.magnitude(Vector.sub(body[i].position, m.fieldPosition)) < m.fieldRadius && !body[i].isNotHoldable) {
const DRAIN = speed * body[i].mass * 0.000015 // * (1 + m.energy * m.energy) //drain more energy when you have more energy const DRAIN = speed * body[i].mass * 0.000006 // * (1 + m.energy * m.energy) //drain more energy when you have more energy
if (m.energy > DRAIN) { if (m.energy > DRAIN) {
m.energy -= DRAIN; m.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
@@ -2820,9 +2819,9 @@ const m = {
// body[i].force.y -= body[i].mass * simulation.g; //remove gravity effects // body[i].force.y -= body[i].mass * simulation.g; //remove gravity effects
//blocks drift towards center of pilot wave //blocks drift towards center of pilot wave
const sub = Vector.sub(m.fieldPosition, body[i].position) const sub = Vector.sub(m.fieldPosition, body[i].position)
const unit = Vector.mult(Vector.normalise(sub), body[i].mass * tech.pilotForce * Vector.magnitude(sub)) const push = Vector.mult(Vector.normalise(sub), 0.0007 * body[i].mass * Vector.magnitude(sub))
body[i].force.x += unit.x body[i].force.x += push.x
body[i].force.y += unit.y - body[i].mass * simulation.g //remove gravity effects body[i].force.y += push.y - body[i].mass * simulation.g //remove gravity effects
// if (body[i].collisionFilter.category !== cat.bullet) { // if (body[i].collisionFilter.category !== cat.bullet) {
// body[i].collisionFilter.category = cat.bullet; // body[i].collisionFilter.category = cat.bullet;
// } // }
@@ -3141,6 +3140,8 @@ const m = {
ctx.stroke(); ctx.stroke();
ctx.setLineDash([]); ctx.setLineDash([]);
} }
} else {
m.hole.isReady = false;
} }
} else { } else {
//make new wormhole //make new wormhole
@@ -3392,6 +3393,11 @@ const m = {
// }, // },
}, },
], ],
//************************************************************************************
//************************************************************************************
//************************************* SHIP ***************************************
//************************************************************************************
//************************************************************************************
isShipMode: false, isShipMode: false,
shipMode(thrust = 0.03, drag = 0.99, torque = 1.15, rotationDrag = 0.92) { // m.shipMode() //thrust = 0.03, drag = 0.99, torque = 1.15, rotationDrag = 0.92 shipMode(thrust = 0.03, drag = 0.99, torque = 1.15, rotationDrag = 0.92) { // m.shipMode() //thrust = 0.03, drag = 0.99, torque = 1.15, rotationDrag = 0.92
if (!m.isShipMode) { if (!m.isShipMode) {
@@ -3664,7 +3670,7 @@ const m = {
if (obj.classType === "body" && obj.speed > 6) { if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)); const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) { if (v > 9) {
let dmg = 0.075 * b.dmgScale * v * obj.mass * (tech.throwChargeRate) * (tech.isBlockHarm ? 2 : 1) * (tech.isMobBlockFling ? 2 : 1); let dmg = tech.blockDamage * b.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2 : 1);
if (mob[k].isShielded) dmg *= 0.7 if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true); mob[k].damage(dmg, true);
if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && m.throwCycle > m.cycle) { if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && m.throwCycle > m.cycle) {

View File

@@ -991,12 +991,12 @@ const spawn = {
me.isSpawnBoss = true; me.isSpawnBoss = true;
me.spawnID = spawnID me.spawnID = spawnID
me.accelMag = 0.0002 * simulation.accelScale; me.accelMag = 0.00018 * simulation.accelScale;
me.memory = Infinity; me.memory = Infinity;
me.showHealthBar = false; me.showHealthBar = false;
me.isVerticesChange = true me.isVerticesChange = true
me.frictionAir = 0.012 me.frictionAir = 0.011
me.seePlayerFreq = Math.floor(11 + 7 * Math.random()) me.seePlayerFreq = Math.floor(14 + 7 * Math.random())
me.seeAtDistance2 = 200000 //1400000; me.seeAtDistance2 = 200000 //1400000;
me.stroke = "transparent" me.stroke = "transparent"
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)" me.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)"
@@ -1007,7 +1007,7 @@ const spawn = {
me.onHit = function() { //run this function on hitting player me.onHit = function() { //run this function on hitting player
this.explode(); this.explode();
}; };
me.damageReduction = 0.22 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.doAwake = function() { me.doAwake = function() {
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
// this.armor(); // this.armor();

View File

@@ -469,7 +469,7 @@
//find a gun tech for this gun //find a gun tech for this gun
const gunTechPool = [] const gunTechPool = []
for (let j = 0; j < tech.tech.length; j++) { for (let j = 0; j < tech.tech.length; j++) {
if (tech.tech[j].isGunTech && tech.tech[j].allowed && !tech.tech[j].isJunk && !tech.tech[j].isBadRandomOption && tech.tech[j].count < tech.tech[j].maxCount) { if (tech.tech[j].isGunTech && tech.tech[j].allowed() && !tech.tech[j].isJunk && !tech.tech[j].isBadRandomOption && tech.tech[j].count < tech.tech[j].maxCount) {
const regex = tech.tech[j].requires.search(b.guns[b.inventory[i]].name) //get string index of gun name const regex = tech.tech[j].requires.search(b.guns[b.inventory[i]].name) //get string index of gun name
const not = tech.tech[j].requires.search(' not ') //get string index of ' not ' const not = tech.tech[j].requires.search(' not ') //get string index of ' not '
//look for the gun name in the requirements, but the gun name needs to show up before the word ' not ' //look for the gun name in the requirements, but the gun name needs to show up before the word ' not '
@@ -1015,15 +1015,15 @@
}, },
{ {
name: "fragmentation", name: "fragmentation",
description: "some <strong class='color-e'>detonations</strong> and collisions eject <strong>nails</strong><br><em style = 'font-size: 90%'>blocks, railgun, grenades, missiles, slugs, harpoon</em>", description: "some <strong class='color-e'>detonations</strong> and collisions eject <strong>nails</strong><br><em style = 'font-size: 90%'>blocks, grenades, missiles, slugs, harpoon</em>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.haveGunCheck("railgun") || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.throwChargeRate > 1 return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.blockDamage > 0.075
}, },
requires: "grenades, missiles, railgun, shotgun slugs, harpoon, or mass driver", requires: "grenades, missiles, shotgun slugs, harpoon, or mass driver",
effect() { effect() {
tech.fragments++ tech.fragments++
}, },
@@ -1699,9 +1699,27 @@
} }
} }
}, },
{
name: "capacitor bank",
description: "<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, foam, railgun, pulse, tokamak</em>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.blockDamage > 0.075 || tech.haveGunCheck("foam") || tech.isRailGun || tech.isTokamak || tech.isPulseLaser
},
requires: "throwing blocks, foam, railgun, pulse, tokamak",
effect() {
tech.isCapacitor = true;
},
remove() {
tech.isCapacitor = false;
}
},
{ {
name: "mass driver", name: "mass driver",
description: "charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong><br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>200%</strong>", description: "increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>300%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1711,22 +1729,22 @@
}, },
requires: "not wormhole", requires: "not wormhole",
effect() { effect() {
tech.throwChargeRate = 3 tech.blockDamage = 0.3
}, },
remove() { remove() {
tech.throwChargeRate = 1 tech.blockDamage = 0.075
} }
}, },
{ {
name: "inflation", name: "inflation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Inflation_(cosmology)' class="link">inflation</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Inflation_(cosmology)' class="link">inflation</a>`,
description: "<strong>throwing</strong> a <strong class='color-block'>block</strong> expands it by <strong>300%</strong><br>increase <strong>throw</strong> charge rate by <strong>200%</strong>", description: "<strong>throwing</strong> a <strong class='color-block'>block</strong> expands it by <strong>300%</strong><br><strong>holding</strong> a <strong class='color-block'>block</strong> reduces <strong class='color-harm'>harm</strong> by <strong>85%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak return tech.blockDamage > 0.075 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak
}, },
requires: "mass driver, not pilot wave, tokamak, wormhole", requires: "mass driver, not pilot wave, tokamak, wormhole",
effect() { effect() {
@@ -1744,7 +1762,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak return tech.blockDamage > 0.075 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak
}, },
requires: "mass driver, not pilot wave not tokamak, wormhole", requires: "mass driver, not pilot wave not tokamak, wormhole",
effect() { effect() {
@@ -1762,7 +1780,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.iceIXOnDeath return tech.blockDamage > 0.075 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.iceIXOnDeath
}, },
requires: "mass driver, no other mob death tech", requires: "mass driver, no other mob death tech",
effect() { effect() {
@@ -1780,7 +1798,7 @@
// frequency: 2, // frequency: 2,
// frequencyDefault: 2, // frequencyDefault: 2,
// allowed() { // allowed() {
// return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isTokamak // return (tech.blockDamage > 0.075 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isTokamak
// }, // },
// requires: "mass driver or pilot wave, not tokamak", // requires: "mass driver or pilot wave, not tokamak",
// effect() { // effect() {
@@ -1790,24 +1808,24 @@
// tech.isBlockBullets = false // tech.isBlockBullets = false
// } // }
// }, // },
{ // {
name: "inelastic collision", // name: "inelastic collision",
description: "<strong>holding</strong> a <strong class='color-block'>block</strong> reduces <strong class='color-harm'>harm</strong> by <strong>85%</strong><br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>150%</strong>", // description: "<strong>holding</strong> a <strong class='color-block'>block</strong> reduces <strong class='color-harm'>harm</strong> by <strong>85%</strong><br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>150%</strong>",
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 3, // frequency: 3,
frequencyDefault: 3, // frequencyDefault: 3,
allowed() { // allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isEnergyHealth // return tech.blockDamage > 0.075 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isEnergyHealth
}, // },
requires: "mass driver, a field that can hold things, not mass-energy", // requires: "mass driver, a field that can hold things, not mass-energy",
effect() { // effect() {
tech.isBlockHarm = true // tech.isBlockHarm = true
}, // },
remove() { // remove() {
tech.isBlockHarm = false // tech.isBlockHarm = false
} // }
}, // },
{ {
name: "buckling", name: "buckling",
description: `if a <strong class='color-block'>block</strong> you threw kills a mob<br>spawn <strong>1</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`, description: `if a <strong class='color-block'>block</strong> you threw kills a mob<br>spawn <strong>1</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
@@ -1816,7 +1834,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && !tech.isTokamak return tech.blockDamage > 0.075 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && !tech.isTokamak
}, },
requires: "mass driver, not pilot wave, tokamak", requires: "mass driver, not pilot wave, tokamak",
effect() { effect() {
@@ -2306,7 +2324,7 @@
requires: "not mass-energy", requires: "not mass-energy",
effect() { effect() {
tech.isPiezo = true; tech.isPiezo = true;
m.energy += 20.48; if (simulation.isTextLogOpen) m.energy += 20.48;
}, },
remove() { remove() {
tech.isPiezo = false; tech.isPiezo = false;
@@ -2342,7 +2360,7 @@
allowed() { allowed() {
return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isTechDamage && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isTechDamage && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
}, },
requires: "not Zeno, ergodicity, piezoelectricity, CPT, rewind gun, antiscience, mutualism", requires: "not Zeno, ergodicity, piezoelectricity, CPT, antiscience, mutualism",
effect: () => { effect: () => {
m.health = 0 m.health = 0
document.getElementById("health").style.display = "none" document.getElementById("health").style.display = "none"
@@ -2572,7 +2590,7 @@
}, },
{ {
name: "inductive coupling", name: "inductive coupling",
description: "passive <strong class='color-f'>energy</strong> regen is increased by <strong>500%</strong><br>but you only regen when <strong>crouched</strong>", description: "passive <strong class='color-f'>energy</strong> regen is increased by <strong>600%</strong><br>but you only regen when <strong>crouched</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2584,7 +2602,7 @@
effect() { effect() {
tech.isCrouchRegen = true; //only used to check for requirements tech.isCrouchRegen = true; //only used to check for requirements
m.regenEnergy = function() { m.regenEnergy = function() {
if (m.immuneCycle < m.cycle && m.crouch) m.energy += 5 * m.fieldRegen; //m.fieldRegen = 0.001 if (m.immuneCycle < m.cycle && m.crouch) m.energy += 6 * m.fieldRegen; //m.fieldRegen = 0.001
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0
} }
}, },
@@ -3227,7 +3245,7 @@
effect() { effect() {
tech.duplicateChance += 0.1 tech.duplicateChance += 0.1
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection) simulation.circleFlare(0.1); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.1);
this.refundAmount += tech.addJunkTechToPool(0.4) this.refundAmount += tech.addJunkTechToPool(0.4)
}, },
refundAmount: 0, refundAmount: 0,
@@ -3254,7 +3272,7 @@
effect: () => { effect: () => {
tech.isStimulatedEmission = true tech.isStimulatedEmission = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection) simulation.circleFlare(0.15); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.15);
}, },
remove() { remove() {
tech.isStimulatedEmission = false tech.isStimulatedEmission = false
@@ -3275,7 +3293,7 @@
effect: () => { effect: () => {
tech.isPowerUpsVanish = true tech.isPowerUpsVanish = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection) simulation.circleFlare(0.12); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.12);
}, },
remove() { remove() {
tech.isPowerUpsVanish = false tech.isPowerUpsVanish = false
@@ -3611,15 +3629,15 @@
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech"); for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
}, },
remove() { remove() {
if (tech.isDeterminism) {
tech.isDeterminism = false; tech.isDeterminism = false;
if (this.count > 0) {
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
const numberRemoved = tech.removeTech() const numberRemoved = tech.removeTech()
if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map
for (let i = 0; i < powerUp.length; i++) { for (let j = 0; j < powerUp.length; j++) {
if (powerUp[i].name === "tech") { if (powerUp[j].name === "tech") {
Matter.Composite.remove(engine.world, powerUp[i]); Matter.Composite.remove(engine.world, powerUp[j]);
powerUp.splice(i, 1); powerUp.splice(j, 1);
break; break;
} }
} }
@@ -4121,16 +4139,16 @@
{ {
name: "Noether violation", name: "Noether violation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Noether%27s_theorem' class="link">Noether violation</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Noether%27s_theorem' class="link">Noether violation</a>`,
description: "increase <strong>shotgun</strong> and <strong>railgun</strong> <strong class='color-d'>damage</strong> <strong>60%</strong><br>their <strong>recoil</strong> is increased and <strong>reversed</strong>", description: "increase <strong>shotgun</strong> <strong class='color-d'>damage</strong> <strong>60%</strong><br>their <strong>recoil</strong> is increased and <strong>reversed</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.haveGunCheck("shotgun") || tech.haveGunCheck("railgun")) && !tech.isShotgunRecoil return (tech.haveGunCheck("shotgun")) && !tech.isShotgunRecoil
}, },
requires: "shotgun, railgun, not Newton's 3rd law", requires: "shotgun, not Newton's 3rd law",
effect() { effect() {
tech.isShotgunReversed = true; tech.isShotgunReversed = true;
}, },
@@ -5260,7 +5278,7 @@
{ {
name: "unaaq", name: "unaaq",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Harpoon#/media/File:Harpon_Unaaq_MHNT_ETH_AC_198.jpg' class="link">unaaq</a>`, //https://en.wikipedia.org/wiki/Weapon link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Harpoon#/media/File:Harpon_Unaaq_MHNT_ETH_AC_198.jpg' class="link">unaaq</a>`, //https://en.wikipedia.org/wiki/Weapon
description: "increase the <strong>length</strong> of your <strong>harpoon</strong><br>by <strong>10%</strong> of the square root of its <strong class='color-ammo'>ammo</strong>", description: "increase the <strong>size</strong> of your <strong>harpoon</strong><br>by <strong>10%</strong> of the square root of its <strong class='color-ammo'>ammo</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5316,25 +5334,25 @@
tech.extraHarpoons = 0; tech.extraHarpoons = 0;
} }
}, },
// { {
// name: "spear", name: "railgun",
// description: "<strong>harpoons</strong> fired while <strong>crouched</strong><br>have no <strong>rope</strong> and improved <strong>steering</strong>", description: "firing the <strong>harpoon</strong> while crouched launches<br>a rod that is <strong>faster</strong>, <strong>larger</strong>, and more <strong>dense</strong>",
// isGunTech: true, isGunTech: true,
// maxCount: 1, maxCount: 1,
// count: 0, count: 0,
// frequency: 2, frequency: 2,
// frequencyDefault: 2, frequencyDefault: 2,
// allowed() { allowed() {
// return tech.haveGunCheck("harpoon") && !tech.isFilament return tech.haveGunCheck("harpoon")
// }, },
// requires: "harpoon, not filament", requires: "railgun",
// effect() { effect() {
// tech.isSpear = true; tech.isRailGun = true;
// }, },
// remove() { remove() {
// tech.isSpear = false; tech.isRailGun = false;
// } }
// }, },
{ {
name: "half-wave rectifier", name: "half-wave rectifier",
description: "charging the <strong>railgun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>", description: "charging the <strong>railgun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>",
@@ -5344,9 +5362,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("railgun") return tech.isRailGun
}, },
requires: "railgun", requires: "harpoon, railgun",
effect() { effect() {
tech.isRailEnergyGain = true; tech.isRailEnergyGain = true;
}, },
@@ -5354,25 +5372,25 @@
tech.isRailEnergyGain = false; tech.isRailEnergyGain = false;
} }
}, },
{ // {
name: "dielectric polarization", // name: "dielectric polarization",
description: "firing the <strong>railgun</strong> <strong class='color-d'>damages</strong> nearby <strong>mobs</strong>", // description: "firing the <strong>railgun</strong> <strong class='color-d'>damages</strong> nearby <strong>mobs</strong>",
isGunTech: true, // isGunTech: true,
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 2, // frequency: 2,
frequencyDefault: 2, // frequencyDefault: 2,
allowed() { // allowed() {
return tech.haveGunCheck("railgun") // return tech.haveGunCheck("railgun")
}, // },
requires: "railgun", // requires: "railgun",
effect() { // effect() {
tech.isRailAreaDamage = true; // tech.isRailAreaDamage = true;
}, // },
remove() { // remove() {
tech.isRailAreaDamage = false; // tech.isRailAreaDamage = false;
} // }
}, // },
// { // {
// name: "aerodynamic heating", // name: "aerodynamic heating",
// description: "<strong>railgun</strong> rod <strong class='color-d'>damage</strong> nearby mobs", // description: "<strong>railgun</strong> rod <strong class='color-d'>damage</strong> nearby mobs",
@@ -5392,25 +5410,6 @@
// tech.isRodAreaDamage = false; // tech.isRodAreaDamage = false;
// } // }
// }, // },
{
name: "capacitor bank",
description: "the <strong>railgun</strong> no longer takes time to <strong>charge</strong><br><strong>railgun</strong> rods are <strong>66%</strong> less massive",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("railgun")
},
requires: "railgun",
effect() {
tech.isCapacitor = true;
},
remove() {
tech.isCapacitor = false;
}
},
{ {
name: "laser diode", name: "laser diode",
description: "all <strong class='color-laser'>lasers</strong> drain <strong>30%</strong> less <strong class='color-f'>energy</strong><br><em>affects laser-gun, laser-bot, laser-mines, pulse</em>", description: "all <strong class='color-laser'>lasers</strong> drain <strong>30%</strong> less <strong class='color-f'>energy</strong><br><em>affects laser-gun, laser-bot, laser-mines, pulse</em>",
@@ -6373,9 +6372,9 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 2) return (m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 2)
}, },
requires: "time dilation, pilot wave", requires: "time dilation",
effect() { effect() {
tech.isFastTime = true tech.isFastTime = true
m.setMovement(); m.setMovement();
@@ -6421,13 +6420,13 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking") return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking")
}, },
requires: "cloaking, time dilation, or pilot wave", requires: "cloaking, time dilation",
effect() { effect() {
tech.cloakDuplication = 0.4 tech.cloakDuplication = 0.4
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection) simulation.circleFlare(0.4); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
}, },
remove() { remove() {
tech.cloakDuplication = 0 tech.cloakDuplication = 0
@@ -6603,25 +6602,25 @@
b.setFireCD(); b.setFireCD();
} }
}, },
{ // {
name: "potential well", // name: "potential well",
description: "the force that <strong>pilot wave</strong> generates<br>to trap <strong class='color-block'>blocks</strong> is greatly increased", // description: "the force that <strong>pilot wave</strong> generates<br>to trap <strong class='color-block'>blocks</strong> is greatly increased",
isFieldTech: true, // isFieldTech: true,
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 2, // frequency: 2,
frequencyDefault: 2, // frequencyDefault: 2,
allowed() { // allowed() {
return m.fieldUpgrades[m.fieldMode].name === "pilot wave" // return m.fieldUpgrades[m.fieldMode].name === "pilot wave"
}, // },
requires: "pilot wave", // requires: "pilot wave",
effect() { // effect() {
tech.pilotForce = 0.0006 // tech.pilotForce = 0.0006
}, // },
remove() { // remove() {
tech.pilotForce = 0.00002 // tech.pilotForce = 0.00002
} // }
}, // },
{ {
name: "WIMPs", name: "WIMPs",
description: `at the end of each <strong>level</strong> spawn ${powerUps.orb.research(5)}<br> and a <strong class='color-harm'>harmful</strong> particle that slowly <strong>chases</strong> you`, description: `at the end of each <strong>level</strong> spawn ${powerUps.orb.research(5)}<br> and a <strong class='color-harm'>harmful</strong> particle that slowly <strong>chases</strong> you`,
@@ -6677,7 +6676,7 @@
effect() { effect() {
tech.wormDuplicate = 0.13 tech.wormDuplicate = 0.13
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection) simulation.circleFlare(0.13); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.13);
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
@@ -8577,7 +8576,7 @@
}, },
{ {
name: "black hole cluster", name: "black hole cluster",
description: `spawn ${powerUps.orb.research(2)}<br><strong>spawn</strong> 40 nearby <strong>black holes</strong>`, description: `<strong>spawn</strong> 100 nearby <strong>black holes</strong>`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 0, frequency: 0,
@@ -8589,13 +8588,9 @@
}, },
requires: "", requires: "",
effect() { effect() {
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x, m.pos.y, "research"); const unit = { x: 1, y: 0 }
const unit = { for (let i = 0; i < 100; i++) {
x: 1, const where = Vector.add(m.pos, Vector.mult(Vector.rotate(unit, Math.random() * 2 * Math.PI), 500 + 200 * Math.random()))
y: 0
}
for (let i = 0; i < 40; i++) {
const where = Vector.add(m.pos, Vector.mult(Vector.rotate(unit, Math.random() * 2 * Math.PI), 600 + 800 * Math.random()))
spawn.sucker(where.x, where.y) spawn.sucker(where.x, where.y)
} }
}, },
@@ -8734,7 +8729,7 @@
isPlasmaRange: null, isPlasmaRange: null,
isFreezeMobs: null, isFreezeMobs: null,
isIceCrystals: null, isIceCrystals: null,
throwChargeRate: null, blockDamage: null,
isBlockStun: null, isBlockStun: null,
isStunField: null, isStunField: null,
isHarmDamage: null, isHarmDamage: null,
@@ -8832,7 +8827,7 @@
isIncendiary: null, isIncendiary: null,
overfillDrain: null, overfillDrain: null,
isNeutronSlow: null, isNeutronSlow: null,
isRailAreaDamage: null, // isRailAreaDamage: null,
historyLaser: null, historyLaser: null,
isSpeedHarm: null, isSpeedHarm: null,
isSpeedDamage: null, isSpeedDamage: null,
@@ -8848,7 +8843,6 @@
isRewindGrenade: null, isRewindGrenade: null,
isExtruder: null, isExtruder: null,
isEndLevelPowerUp: null, isEndLevelPowerUp: null,
// isRewindGun: null,
missileSize: null, missileSize: null,
isLaserMine: null, isLaserMine: null,
isAmmoFoamSize: null, isAmmoFoamSize: null,
@@ -8868,7 +8862,6 @@
is111Duplicate: null, is111Duplicate: null,
isDynamoBotUpgrade: null, isDynamoBotUpgrade: null,
isBlockPowerUps: null, isBlockPowerUps: null,
isBlockHarm: null,
foamFutureFire: null, foamFutureFire: null,
isDamageAfterKill: null, isDamageAfterKill: null,
isHarmReduceAfterKill: null, isHarmReduceAfterKill: null,
@@ -8953,7 +8946,7 @@
isSpawnExitTech: null, isSpawnExitTech: null,
cloakDuplication: null, cloakDuplication: null,
extruderRange: null, extruderRange: null,
isRodAreaDamage: null, // isRodAreaDamage: null,
isForeverDrones: null, isForeverDrones: null,
isMoreMobs: null, isMoreMobs: null,
nailRecoil: null, nailRecoil: null,

View File

@@ -1,20 +1,48 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: applied science - gives a random gun tech and a research for each gun in your inventory railgun is now a tech for harpoon
railgun tech: dielectric polarization has been removed
unaaq increases the size not length of harpoons
JUNK tech - motion sickness - disable camera smoothing capacitor bank applies charging effects: throwing blocks, foam, railgun, pulse, tokamak
JUNK tech - palantír - see far away fire cooldown reduction no longer effects these charging abilities, but it does reduce cooldown between discharges
foam-bot, nail-bot, missile-bot: are now affected by fire delay tech foam now has a short delay between each discharge
this gives some options for late game bot scaling foam charges ~10% faster
tokamak graphics indicate charging and max charge better
pulse laser can now regen energy passively while charging
timelike now allows some energy regen while immune to harm in double time tech: mass driver no longer gives improved block charge rate,
Tokamak now overrides the trajectory throw graphics with its own but it gives 200% -> 300% damage for blocks
tech: inflation no longer gives improved block charge rate
it gives harm reduction when holding a block and makes block expand when you throw them
tech: inelastic collision was removed it used to give harm reduction when holding a block
pilot wave uses 66% less energy to fling blocks
pilot wave can fling block effectively at much higher speeds now (which happens to use much more energy)
tech potential well is removed, because it isn't really needed anymore
inductive coupling: 500% -> 600% regen while crouched
molecular assembler now works with inductive coupling regen properly
bug fixes (superdeterminism, wormhole, applied science)
I probably added several new bugs, let me know if you find any
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
tech: instead of throwing a block, give bots that last for 20 seconds
tech: Occam's razor - remove 66% of your tech and guns; for each removed get 20% damage
remove first half of guns and tech, it's not random
this is going to leave field and gun tech, but also remove the first gun, which is probably the main one
make 20% damage additive, so it's worse with more tech
remove upto 66% of guns and tech
and 10% harm reduction?
tech: after bullets hit a mob, the mob takes 1% more damage tech: after bullets hit a mob, the mob takes 1% more damage
this.damageReduction *= 1.01 this.damageReduction *= 1.01
only for drones?
only for drones, spores, worms, ice-IX?
tech: open a new tab for n-gon, spawn things in the original game based on events in new game tech: open a new tab for n-gon, spawn things in the original game based on events in new game
if you die in new die in original? if you die in new die in original?