tech: rebound - super balls speed up and reset duration after they hit a mob
Zectron does 100->66% damage and it drains 25% of current energy instead of health
mantisBoss is back
level element: mover - rectangular map element that pushes horizontally
  it's in a possible room for labs

new community level - staircase by ryanbear
This commit is contained in:
landgreen
2023-02-19 15:25:21 -08:00
parent f8b4b6fde5
commit 82c0ea832b
8 changed files with 523 additions and 202 deletions

View File

@@ -82,7 +82,7 @@ const b = {
},
fireWithAmmo() { //triggers after firing when you have ammo
b.guns[b.activeGun].fire();
if (tech.crouchAmmoCount && input.down) {
if (tech.crouchAmmoCount && m.crouch) {
if (tech.crouchAmmoCount % 2) {
b.guns[b.activeGun].ammo--;
simulation.updateGunHUD();
@@ -114,7 +114,7 @@ const b = {
}
},
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to
if (tech.crouchAmmoCount && input.down && b.activeGun !== null) {
if (tech.crouchAmmoCount && m.crouch && b.activeGun !== null) {
tech.crouchAmmoCount--
if ((tech.crouchAmmoCount) % 2) {
b.guns[b.activeGun].ammo++;
@@ -608,7 +608,7 @@ const b = {
v1: null,
v2: null
};
// if (tech.isPulseAim && !input.down) { //find mobs in line of sight
// if (tech.isPulseAim && !m.crouch) { //find mobs in line of sight
// let dist = 2200
// for (let i = 0, len = mob.length; i < len; i++) {
// const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
@@ -908,12 +908,12 @@ const b = {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 43 : 32
speed = m.crouch ? 43 : 32
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle)
});
bullet[me].endCycle = simulation.cycle + Math.floor(input.down ? 120 : 80) * tech.isBulletsLastLonger;
bullet[me].endCycle = simulation.cycle + Math.floor(m.crouch ? 120 : 80) * tech.isBulletsLastLonger;
bullet[me].restitution = 0.4;
bullet[me].do = function() {
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
@@ -933,7 +933,7 @@ const b = {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 46 : 32
speed = m.crouch ? 46 : 32
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle)
@@ -968,7 +968,7 @@ const b = {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
speed = input.down ? 46 : 32
speed = m.crouch ? 46 : 32
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle)
@@ -1095,10 +1095,10 @@ const b = {
}
};
speed = 35
// speed = input.down ? 43 : 32
// speed = m.crouch ? 43 : 32
bullet[me].endCycle = simulation.cycle + 70 * tech.isBulletsLastLonger;
if (input.down) {
if (m.crouch) {
speed += 9
bullet[me].endCycle += 20;
}
@@ -1115,7 +1115,7 @@ const b = {
}, angle = m.angle, size = 1) {
const me = bullet.length;
bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false));
b.fireProps((input.down ? 45 : 25) / Math.pow(0.92, tech.missileCount), input.down ? 35 : 20, angle, me); //cd , speed
b.fireProps((m.crouch ? 45 : 25) / Math.pow(0.92, tech.missileCount), m.crouch ? 35 : 20, angle, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = 500 + simulation.cycle;
bullet[me].frictionAir = 0;
@@ -1131,8 +1131,8 @@ const b = {
if (tech.isRPG) {
const SCALE = 2
Matter.Body.scale(bullet[me], SCALE, SCALE);
speed = input.down ? 25 : 15
// speed = input.down ? 43 : 32
speed = m.crouch ? 25 : 15
// speed = m.crouch ? 43 : 32
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle)
@@ -1282,10 +1282,10 @@ const b = {
b.guns[5].do = function() {}
} else {
b.guns[5].do = function() {
if (!input.field && input.down) {
if (!input.field && m.crouch) {
const cycles = 80
const speed = input.down ? 35 : 20 //input.down ? 43 : 32
const g = input.down ? 0.137 : 0.135
const speed = m.crouch ? 35 : 20 //m.crouch ? 43 : 32
const g = m.crouch ? 0.137 : 0.135
const v = {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
@@ -1311,9 +1311,9 @@ const b = {
} else if (tech.isVacuumBomb) {
b.grenade = grenadeVacuum
b.guns[5].do = function() {
if (!input.field && input.down) {
const cycles = Math.floor(input.down ? 50 : 30) //30
const speed = input.down ? 44 : 35
if (!input.field && m.crouch) {
const cycles = Math.floor(m.crouch ? 50 : 30) //30
const speed = m.crouch ? 44 : 35
const v = {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
@@ -1331,9 +1331,9 @@ const b = {
} else {
b.grenade = grenadeDefault
b.guns[5].do = function() {
if (!input.field && input.down) {
const cycles = Math.floor(input.down ? 120 : 80) //30
const speed = input.down ? 43 : 32
if (!input.field && m.crouch) {
const cycles = Math.floor(m.crouch ? 120 : 80) //30
const speed = m.crouch ? 43 : 32
const v = {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
@@ -1626,7 +1626,7 @@ const b = {
if (m.energy < 0.05) this.dropCaughtPowerUp()
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
player.force.x += momentum.x
player.force.y += momentum.y
// refund ammo
@@ -1709,7 +1709,7 @@ const b = {
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
player.force.x += momentum.x
player.force.y += momentum.y
// }
@@ -1739,7 +1739,7 @@ const b = {
// m.fireCDcycle = m.cycle + 30; // cool down if out of energy
m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
this.endCycle = simulation.cycle + 10
if (input.down) { //down
if (m.crouch) { //down
dist = 0
player.force.y += 5 * player.mass * simulation.g;
}
@@ -1780,7 +1780,7 @@ const b = {
this.endCycle = simulation.cycle + 60
m.fireCDcycle = m.cycle + 120; //fire cooldown
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
player.force.x += momentum.x
player.force.y += momentum.y
}
@@ -1792,7 +1792,7 @@ const b = {
this.do = this.returnToPlayer
this.endCycle = simulation.cycle + 60
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
player.force.x += momentum.x
player.force.y += momentum.y
}
@@ -1951,7 +1951,7 @@ const b = {
// if (m.energy > 0.05) m.fireCDcycle = m.cycle + 20 * b.fireCDscale //lower cd to 25 if it is above 25
// }
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
player.force.x += momentum.x
player.force.y += momentum.y
// refund ammo
@@ -2018,7 +2018,7 @@ const b = {
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
Matter.Sleeping.set(this, false)
this.endCycle = simulation.cycle + 240
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003)) //recoil on jerking line
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.00015 : 0.0003)) //recoil on jerking line
player.force.x += momentum.x
player.force.y += momentum.y
requestAnimationFrame(() => { //delay this for 1 cycle to get the proper hit graphics
@@ -2246,7 +2246,7 @@ const b = {
}
}
this.cycle++
const wiggleMag = (input.down ? 6 : 12) * Math.cos(simulation.cycle * 0.09)
const wiggleMag = (m.crouch ? 6 : 12) * Math.cos(simulation.cycle * 0.09)
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(simulation.cycle * 0.3))
const velocity = Vector.mult(player.velocity, 0.4) //move with player
Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle)))
@@ -2280,7 +2280,7 @@ const b = {
//calculate laser collision
let best;
let range = tech.isPlasmaRange * (120 + (input.down ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(m.cycle * 0.3);
let range = tech.isPlasmaRange * (120 + (m.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(m.cycle * 0.3);
// const dir = m.angle // + 0.04 * (Math.random() - 0.5)
const path = [{
x: m.pos.x + 20 * Math.cos(m.angle),
@@ -3751,24 +3751,36 @@ 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.0008 + 0.0009 * tech.superHarm);
Matter.Body.setDensity(bullet[me], 0.0008 + 0.0005 * tech.isSuperHarm);
bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random());
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 1;
bullet[me].frictionAir = 0;
bullet[me].friction = 0;
if (tech.superHarm) {
bullet[me].frictionStatic = 0;
if (tech.isSuperHarm) {
bullet[me].collidePlayerDo = function() {
this.force.y += this.mass * 0.0012;
this.force.y += this.mass * 0.001;
if (Matter.Query.collides(this, [player]).length) {
this.endCycle = 0
let dmg = 0.015 * this.mass * tech.superHarm
m.damage(dmg);
// 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
// });
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: Math.sqrt(dmg) * 200,
color: simulation.mobDmgColor,
time: simulation.drawTime * 2
radius: radius,
color: "#0ad",
time: 15
});
}
}
@@ -3776,11 +3788,11 @@ const b = {
bullet[me].do = function() {
this.cycle++
if (this.cycle > 2) this.do = this.collidePlayerDo
this.force.y += this.mass * 0.0012;
this.force.y += this.mass * 0.001;
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
this.force.y += this.mass * 0.001;
};
}
bullet[me].beforeDmg = function(who) {
@@ -3796,6 +3808,35 @@ const b = {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
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
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
let count = 5
const wait = () => {
count--
if (count > 0) requestAnimationFrame(wait);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: radius,
color: 'rgba(255, 0, 0, 0.33)',
time: 8
});
}
requestAnimationFrame(wait);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: radius,
color: 'rgba(255, 0, 0, 0.33)',
time: 8
});
}
requestAnimationFrame(cycle);
}
};
},
@@ -4971,7 +5012,7 @@ const b = {
this.cd = simulation.cycle + this.delay;
target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist2) / 60))
const radius = 6 + 7 * Math.random()
const SPEED = 29 - radius * 0.4; //(input.down ? 32 : 20) - radius * 0.7;
const SPEED = 29 - radius * 0.4; //(m.crouch ? 32 : 20) - radius * 0.7;
const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED)
b.foam(this.position, velocity, radius + 7.5 * this.isUpgraded)
break;
@@ -5684,10 +5725,10 @@ const b = {
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
this.baseFire(m.angle + (Math.random() - 0.5) * (input.down ? 0.04 : 0.13) / CD, 45 + 6 * Math.random())
this.baseFire(m.angle + (Math.random() - 0.5) * (m.crouch ? 0.04 : 0.13) / CD, 45 + 6 * Math.random())
//very complex recoil system
if (m.onGround) {
if (input.down) {
if (m.crouch) {
const KNOCK = 0.006
player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
@@ -5715,10 +5756,10 @@ const b = {
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
this.baseFire(m.angle + (Math.random() - 0.5) * (input.down ? 0.05 : 0.3) / CD)
this.baseFire(m.angle + (Math.random() - 0.5) * (m.crouch ? 0.05 : 0.3) / CD)
},
fireNeedles() {
if (input.down) {
if (m.crouch) {
m.fireCDcycle = m.cycle + 30 * b.fireCDscale; // cool down
b.needle()
@@ -5751,14 +5792,14 @@ const b = {
}
},
fireRivets() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 22 : 14) * b.fireCDscale); // cool down
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 22 : 14) * b.fireCDscale); // cool down
const me = bullet.length;
const size = tech.bulletSize * 8
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle));
bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75
Matter.Body.setDensity(bullet[me], 0.002);
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = input.down ? 60 : 44
const SPEED = m.crouch ? 60 : 44
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
@@ -5817,7 +5858,7 @@ const b = {
b.muzzleFlash();
//very complex recoil system
if (m.onGround) {
if (input.down) {
if (m.crouch) {
const KNOCK = 0.01
player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
@@ -5833,7 +5874,7 @@ const b = {
}
},
fireRecoilRivets() {
// m.fireCDcycle = m.cycle + Math.floor((input.down ? 25 : 17) * b.fireCDscale); // cool down
// m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCDscale); // cool down
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
const CD = Math.max(25 - 0.14 * (m.cycle - this.startingHoldCycle), 5) //CD scales with cycles fire is held down
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
@@ -5845,7 +5886,7 @@ const b = {
bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75
Matter.Body.setDensity(bullet[me], 0.002);
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = input.down ? 62 : 52
const SPEED = m.crouch ? 62 : 52
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
@@ -5904,7 +5945,7 @@ const b = {
b.muzzleFlash();
//very complex recoil system
if (m.onGround) {
if (input.down) {
if (m.crouch) {
const KNOCK = 0.03
player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
@@ -5930,7 +5971,7 @@ const b = {
},
fireInstantFireRate() {
m.fireCDcycle = m.cycle + Math.floor(1 * b.fireCDscale); // cool down
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (input.down ? 1.15 : 2) / 2)
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.15 : 2) / 2)
},
baseFire(angle, speed = 30 + 6 * Math.random()) {
b.nail({
@@ -5994,7 +6035,7 @@ const b = {
fire() {
let knock, spread
const coolDown = function() {
if (input.down) {
if (m.crouch) {
spread = 0.65
m.fireCDcycle = m.cycle + Math.floor((73 + 36 * tech.shotgunExtraShots) * b.fireCDscale) // cool down
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(60 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(60 * b.fireCDscale); //player is immune to damage for 30 cycles
@@ -6049,7 +6090,7 @@ const b = {
Matter.Body.setDensity(bullet[me], 0.005 * (tech.isShotgunReversed ? 1.5 : 1));
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = (input.down ? 50 : 43)
const SPEED = (m.crouch ? 50 : 43)
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
@@ -6099,9 +6140,9 @@ const b = {
spray(12); //fires normal shotgun bullets
} else if (tech.isIncendiary) {
spread *= 0.15
const END = Math.floor(input.down ? 8 : 5);
const END = Math.floor(m.crouch ? 8 : 5);
const totalBullets = 9
const angleStep = (input.down ? 0.3 : 0.8) / totalBullets
const angleStep = (m.crouch ? 0.3 : 0.8) / totalBullets
let dir = m.angle - angleStep * totalBullets / 2;
for (let i = 0; i < totalBullets; i++) { //5 -> 7
dir += angleStep
@@ -6129,7 +6170,7 @@ const b = {
} else if (tech.isNailShot) {
spread *= 0.65
const dmg = 2 * (tech.isShotgunReversed ? 1.5 : 1)
if (input.down) {
if (m.crouch) {
for (let i = 0; i < 17; i++) {
speed = 38 + 15 * Math.random()
const dir = m.angle + (Math.random() - 0.5) * spread
@@ -6164,7 +6205,7 @@ const b = {
const number = 2 * (tech.isShotgunReversed ? 1.5 : 1)
for (let i = 0; i < number; i++) {
const angle = m.angle + 0.2 * (Math.random() - 0.5)
const speed = (input.down ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random()))
const speed = (m.crouch ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random()))
b.flea(where, {
x: speed * Math.cos(angle),
y: speed * Math.sin(angle)
@@ -6177,12 +6218,12 @@ const b = {
x: m.pos.x + 35 * Math.cos(m.angle),
y: m.pos.y + 35 * Math.sin(m.angle)
}
const spread = (input.down ? 0.02 : 0.07)
const spread = (m.crouch ? 0.02 : 0.07)
const number = 3 * (tech.isShotgunReversed ? 1.5 : 1)
let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) {
b.worm(where)
const SPEED = (30 + 10 * input.down) * (1 + 0.2 * Math.random())
const SPEED = (30 + 10 * m.crouch) * (1 + 0.2 * Math.random())
Matter.Body.setVelocity(bullet[bullet.length - 1], {
x: player.velocity.x * 0.5 + SPEED * Math.cos(angle),
y: player.velocity.y * 0.5 + SPEED * Math.sin(angle)
@@ -6191,13 +6232,13 @@ const b = {
}
spray(7); //fires normal shotgun bullets
} else if (tech.isIceShot) {
const spread = (input.down ? 0.7 : 1.2)
const spread = (m.crouch ? 0.7 : 1.2)
for (let i = 0, len = 10 * (tech.isShotgunReversed ? 1.5 : 1); i < len; i++) {
b.iceIX(23 + 10 * Math.random(), m.angle + spread * (Math.random() - 0.5))
}
spray(10); //fires normal shotgun bullets
} else if (tech.isFoamShot) {
const spread = (input.down ? 0.15 : 0.4)
const spread = (m.crouch ? 0.15 : 0.4)
const where = {
x: m.pos.x + 25 * Math.cos(m.angle),
y: m.pos.y + 25 * Math.sin(m.angle)
@@ -6213,7 +6254,7 @@ const b = {
}
} else if (tech.isNeedles) {
const number = 9 * (tech.isShotgunReversed ? 1.5 : 1)
const spread = (input.down ? 0.03 : 0.05)
const spread = (m.crouch ? 0.03 : 0.05)
let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) {
b.needle(angle)
@@ -6260,8 +6301,8 @@ const b = {
},
fireOne() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 27 : 19) * b.fireCDscale); // cool down
const speed = input.down ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 27 : 19) * b.fireCDscale); // cool down
const speed = m.crouch ? 43 : 36
b.superBall({
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
@@ -6271,10 +6312,10 @@ const b = {
}, 21 * tech.bulletSize)
},
fireMulti() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
const SPREAD = input.down ? 0.08 : 0.13
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
const SPREAD = m.crouch ? 0.08 : 0.13
const num = 3 + Math.floor(tech.extraSuperBalls * Math.random())
const speed = input.down ? 43 : 36
const speed = m.crouch ? 43 : 36
let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
b.superBall({
@@ -6288,11 +6329,11 @@ const b = {
}
},
fireQueue() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down
const num = 1 + 3 + Math.floor(tech.extraSuperBalls * Math.random()) //1 extra
const speed = input.down ? 43 : 36
const speed = m.crouch ? 43 : 36
const delay = Math.floor((input.down ? 18 : 12) * b.fireCDscale)
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down
function cycle() {
count++
@@ -6448,7 +6489,7 @@ const b = {
}
},
fire360Longitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
this.waves.push({
position: {
x: m.pos.x,
@@ -6574,8 +6615,8 @@ const b = {
}
},
fireLongitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
const halfArc = (input.down ? 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
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // 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) })
@@ -6618,7 +6659,7 @@ const b = {
inertia: Infinity,
frictionAir: 0,
slow: 0,
amplitude: (input.down ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * 0.088), //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
amplitude: (m.crouch ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * 0.088), //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
minDmgSpeed: 0,
dmg: m.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage * (tech.isBulletTeleport ? 1.43 : 1), //also control damage when you divide by mob.mass
classType: "bullet",
@@ -6739,7 +6780,7 @@ const b = {
do() {},
fire() {
const countReduction = Math.pow(0.86, tech.missileCount)
// if (input.down) {
// if (m.crouch) {
// m.fireCDcycle = m.cycle + tech.missileFireCD * b.fireCDscale / countReduction; // cool down
// // for (let i = 0; i < tech.missileCount; i++) {
// // b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5) * Math.sqrt(tech.missileCount), -2, Math.sqrt(countReduction))
@@ -6776,7 +6817,7 @@ const b = {
const sqrtCountReduction = Math.sqrt(countReduction)
// for (let i = 0; i < tech.missileCount; i++) {
// setTimeout(() => {
// if (input.down) {
// if (m.crouch) {
// b.missile(where, m.angle, 20, sqrtCountReduction)
// // bullet[bullet.length - 1].force.x += 0.7 * push.x * (i - (tech.missileCount - 1) / 2);
// // bullet[bullet.length - 1].force.y += 0.7 * push.y * (i - (tech.missileCount - 1) / 2);
@@ -6791,7 +6832,7 @@ const b = {
const launchDelay = 4
let count = 0
const fireMissile = () => {
if (input.down) {
if (m.crouch) {
b.missile({
x: m.pos.x + 30 * direction.x,
y: m.pos.y + 30 * direction.y
@@ -6820,7 +6861,7 @@ const b = {
}
requestAnimationFrame(cycle);
} else {
if (input.down) {
if (m.crouch) {
b.missile({
x: m.pos.x + 40 * direction.x,
y: m.pos.y + 40 * direction.y
@@ -6843,12 +6884,12 @@ const b = {
do() {}, //do is set in b.setGrenadeMode()
fire() {
const countReduction = Math.pow(0.93, tech.missileCount)
m.fireCDcycle = m.cycle + Math.floor((input.down ? 35 : 27) * b.fireCDscale / countReduction); // cool down
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 35 : 27) * b.fireCDscale / countReduction); // cool down
const where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}
const SPREAD = input.down ? 0.12 : 0.2
const SPREAD = m.crouch ? 0.12 : 0.2
let angle = m.angle - SPREAD * (tech.missileCount - 1) / 2;
for (let i = 0; i < tech.missileCount; i++) {
b.grenade(where, angle, countReduction) //function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1)
@@ -6875,7 +6916,7 @@ const b = {
const me = bullet.length;
const dir = m.angle;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false));
b.fireProps(input.down ? 40 : 20, input.down ? 30 : 16, dir, me); //cd , speed
b.fireProps(m.crouch ? 40 : 20, m.crouch ? 30 : 16, dir, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = simulation.cycle + 480 + Math.max(0, 120 - 2 * bullet.length);
bullet[me].frictionAir = 0;
@@ -6944,6 +6985,7 @@ const b = {
onCollide(this)
} else { //if colliding with nothing just fall
this.force.y += this.mass * 0.0006;
simulation.mouseInGame.x
}
}
}
@@ -7061,7 +7103,7 @@ const b = {
do() {},
fire() {
if (tech.isDroneRadioactive) {
if (input.down) {
if (m.crouch) {
b.droneRadioactive({
x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5),
y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5)
@@ -7075,7 +7117,7 @@ const b = {
m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down
}
} else {
if (input.down) {
if (m.crouch) {
b.drone({
x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5),
y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5)
@@ -7110,12 +7152,12 @@ const b = {
},
doStream() {},
fireStream() {
const spread = (input.down ?
const spread = (m.crouch ?
0.04 * (Math.random() - 0.5) + 0.09 * Math.sin(m.cycle * 0.12) :
0.23 * (Math.random() - 0.5) + 0.15 * Math.sin(m.cycle * 0.12)
)
const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = (input.down ? 1.2 : 1) * Math.max(2, 14 - radius * 0.25)
const SPEED = (m.crouch ? 1.2 : 1) * Math.max(2, 14 - radius * 0.25)
const dir = m.angle + 0.15 * (Math.random() - 0.5)
const velocity = {
x: SPEED * Math.cos(dir),
@@ -7139,9 +7181,9 @@ const b = {
ctx.fill();
if (this.isDischarge && m.cycle % 2) {
const spread = (input.down ? 0.04 : 0.5) * (Math.random() - 0.5)
const spread = (m.crouch ? 0.04 : 0.5) * (Math.random() - 0.5)
const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = (input.down ? 1.2 : 1) * 10 - radius * 0.4 + Math.min(5, Math.sqrt(this.charge));
const SPEED = (m.crouch ? 1.2 : 1) * 10 - radius * 0.4 + Math.min(5, Math.sqrt(this.charge));
const dir = m.angle + 0.15 * (Math.random() - 0.5)
const velocity = {
x: SPEED * Math.cos(dir),
@@ -7165,12 +7207,12 @@ const b = {
}
},
fireCharges() {
const spread = (input.down ?
const spread = (m.crouch ?
0.04 * (Math.random() - 0.5) + 0.09 * Math.sin(m.cycle * 0.12) :
0.23 * (Math.random() - 0.5) + 0.15 * Math.sin(m.cycle * 0.12)
)
const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = (input.down ? 1.2 : 1) * Math.max(2, 14 - radius * 0.25)
const SPEED = (m.crouch ? 1.2 : 1) * Math.max(2, 14 - radius * 0.25)
const dir = m.angle + 0.15 * (Math.random() - 0.5)
const velocity = {
x: SPEED * Math.cos(dir),
@@ -7308,7 +7350,7 @@ const b = {
});
}
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.03 : 0.06)
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.03 : 0.06)
player.force.x -= recoil.x
player.force.y -= recoil.y
// tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
@@ -7317,7 +7359,7 @@ const b = {
const thrust = 0.15 * (this.charge)
if (tech.extraHarpoons) {
let targetCount = 0
const SPREAD = 0.06 + 0.05 * (!input.down)
const SPREAD = 0.06 + 0.05 * (!m.crouch)
let angle = m.angle - SPREAD * tech.extraHarpoons / 2;
const dir = {
x: Math.cos(angle),
@@ -7331,7 +7373,7 @@ const b = {
if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //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 > -1) {
// this.ammo--
b.harpoon(where, input.down ? null : mob[i], angle, harpoonSize, false, 35, false, thrust) //harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
b.harpoon(where, m.crouch ? null : mob[i], angle, harpoonSize, false, 35, false, thrust) //harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
angle += SPREAD
targetCount++
if (targetCount > tech.extraHarpoons) break
@@ -7382,7 +7424,7 @@ const b = {
//small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
// let smoothRate = tech.isCapacitor ? 0.85 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
const rate = Math.sqrt(b.fireCDscale) * tech.railChargeRate * (tech.isCapacitor ? 0.6 : 1) * (input.down ? 0.8 : 1)
const rate = Math.sqrt(b.fireCDscale) * tech.railChargeRate * (tech.isCapacitor ? 0.6 : 1) * (m.crouch ? 0.8 : 1)
let smoothRate = Math.min(0.998, 0.94 + 0.05 * rate)
@@ -7428,13 +7470,13 @@ const b = {
this.charge += 0.00001
},
grappleFire() {
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1)
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (m.crouch ? 0.7 : 1)
const where = {
x: m.pos.x + harpoonSize * 40 * Math.cos(m.angle),
y: m.pos.y + harpoonSize * 40 * Math.sin(m.angle)
}
const num = Math.min(this.ammo, tech.extraHarpoons + 1)
if (!input.down && num > 1) { //multiple harpoons
if (!m.crouch && num > 1) { //multiple harpoons
const SPREAD = 0.06
let angle = m.angle - SPREAD * num / 2;
for (let i = 0; i < num; i++) {
@@ -7447,7 +7489,7 @@ const b = {
this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
m.fireCDcycle = m.cycle + Math.floor(75 * b.fireCDscale) // cool down
// } else if (input.down) {
// } else if (m.crouch) {
// b.harpoon(where, null, m.angle, harpoonSize, false, 70)
} else {
if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1
@@ -7467,10 +7509,10 @@ const b = {
target: null
}
//look for closest mob in player's LoS
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1)
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (m.crouch ? 0.7 : 1)
const totalCycles = 6.5 * (tech.isFilament ? 1 + 0.013 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
if (tech.extraHarpoons && !input.down) { //multiple harpoons
if (tech.extraHarpoons && !m.crouch) { //multiple harpoons
const SPREAD = 0.2
let angle = m.angle - SPREAD * tech.extraHarpoons / 2;
const dir = {
@@ -7522,7 +7564,7 @@ const b = {
this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
} else { //input.down makes a single harpoon with longer range
} else { //m.crouch makes a single harpoon with longer range
const dir = {
x: Math.cos(m.angle),
y: Math.sin(m.angle)
@@ -7537,15 +7579,15 @@ const b = {
}
}
}
if (input.down && m.onGround) {
b.harpoon(where, null, m.angle, harpoonSize, true, 1.6 * totalCycles, (input.down && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true) {
if (m.crouch && m.onGround) {
b.harpoon(where, null, m.angle, harpoonSize, true, 1.6 * totalCycles, (m.crouch && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true) {
} else {
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
}
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
}
m.fireCDcycle = m.cycle + 5 + 35 * b.fireCDscale + 60 * (m.energy < 0.05) + tech.extraHarpoons // cool down is set when harpoon bullet returns to player
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.015 : 0.035)
player.force.x -= recoil.x
player.force.y -= recoil.y
},
@@ -7565,7 +7607,7 @@ const b = {
}
},
do() {
if (!input.field && input.down && !tech.isLaserMine) {
if (!input.field && m.crouch && !tech.isLaserMine) {
const cycles = 60 //30
const speed = 40
const v = {
@@ -7583,7 +7625,7 @@ const b = {
}
},
fire() {
if (input.down) {
if (m.crouch) {
if (tech.isLaserMine) {
const speed = 30
const velocity = {
@@ -7735,7 +7777,7 @@ const b = {
if (this.charge > 5) {
m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
if (tech.beamSplitter) {
const divergence = input.down ? 0.15 : 0.35
const divergence = m.crouch ? 0.15 : 0.35
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
} else {
@@ -7784,7 +7826,7 @@ const b = {
} else {
m.fireCDcycle = m.cycle
m.energy -= drain
// const divergence = input.down ? 0.15 : 0.2
// const divergence = m.crouch ? 0.15 : 0.2
// const scale = Math.pow(0.9, tech.beamSplitter)
// const pushScale = scale * scale
let dmg = tech.laserDamage / b.fireCDscale * this.lensDamage // * scale //Math.pow(0.9, tech.laserDamage)
@@ -7792,7 +7834,7 @@ const b = {
x: m.pos.x + 20 * Math.cos(m.angle),
y: m.pos.y + 20 * Math.sin(m.angle)
}
const divergence = input.down ? 0.15 : 0.35
const divergence = m.crouch ? 0.15 : 0.35
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) {
b.laser(where, {

View File

@@ -10,7 +10,7 @@ const level = {
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [],
start() {
@@ -30,21 +30,21 @@ const level = {
// m.setField("metamaterial cloaking") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("foam") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[8].ammo = 10000
// tech.giveTech("aperture")
// tech.giveTech("CPT symmetry")
// tech.giveTech("rebound")
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence")
// for (let i = 0; i < 1; ++i) tech.giveTech("tungsten carbide")
// for (let i = 0; i < 1; ++i) tech.giveTech("Zectron")
// for (let i = 0; i < 1; i++) tech.giveTech("CPT symmetry")
// for (let i = 0; i < 1; i++) tech.giveTech("elasticity")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.yingYang();
// spawn.nodeGroup(1200, 0, "slasher")
// spawn.blinkBoss(1900, -500)
// level.labs();
// spawn.nodeGroup(1200, 0, "starter")
// spawn.mantisBoss(1900, -500)
// spawn.sneakBoss(1900, -500)
// spawn.starter(1900, -500, 200)
// spawn.sneaker(1900, -500, 25)
@@ -56,7 +56,6 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech()
// for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level ************************************************
// simulation.isAutoZoom = false; //look in close
@@ -1558,6 +1557,84 @@ const level = {
}
}
},
mover(x, y, width, height, VxGoal = -6, force = VxGoal > 0 ? 0.0005 : -0.0005) {
//VxGoal below 3 don't move well, maybe try adjusting the force
x = x + width / 2
y = y + height / 2
const rect = map[map.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: {
category: cat.map,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
isNoSetCollision: true,
inertia: Infinity, //prevents rotation
isNotHoldable: true,
friction: 0,
frictionStatic: 0,
restitution: 0,
isClosing: false,
isMover: true,
VxGoal: VxGoal,
force: force,
push() {
if (!m.isBodiesAsleep) {
const touchingPlayer = Matter.Query.collides(this, [jumpSensor])
if (touchingPlayer.length) {
m.moverX = this.VxGoal
if ((this.VxGoal > 0 && player.velocity.x < this.VxGoal) || (this.VxGoal < 0 && player.velocity.x > this.VxGoal)) {
player.force.x += this.force * player.mass
}
m.Vx = player.velocity.x - this.VxGoal
}
let pushBlock = (who) => {
if (!who.isMover) {
if ((this.VxGoal > 0 && who.velocity.x < this.VxGoal) || (this.VxGoal < 0 && who.velocity.x > this.VxGoal)) {
who.force.x += this.force * who.mass
}
const stoppingFriction = 0.5
Matter.Body.setVelocity(who, { x: this.VxGoal * (1 - stoppingFriction) + who.velocity.x * stoppingFriction, y: who.velocity.y });
Matter.Body.setAngularVelocity(who, who.angularVelocity * 0.8)
}
}
const blocks = Matter.Query.collides(this, body)
for (let i = 0; i < blocks.length; i++) {
pushBlock(blocks[i].bodyA)
pushBlock(blocks[i].bodyB)
}
let pushPowerUp = (who) => {
if (!who.isMover) {
if ((this.VxGoal > 0 && who.velocity.x < this.VxGoal) || (this.VxGoal < 0 && who.velocity.x > this.VxGoal)) {
who.force.x += 2 * this.force * who.mass
}
const stoppingFriction = 0.5
Matter.Body.setVelocity(who, { x: this.VxGoal * (1 - stoppingFriction) + who.velocity.x * stoppingFriction, y: who.velocity.y });
}
}
const powers = Matter.Query.collides(this, powerUp)
for (let i = 0; i < powers.length; i++) {
pushPowerUp(powers[i].bodyA)
pushPowerUp(powers[i].bodyB)
}
}
},
draw() {
ctx.beginPath();
const v = this.vertices;
ctx.moveTo(v[0].x + 2, v[0].y);
// for (let i = 1; i < v.length; ++i) ctx.lineTo(v[i].x, v[i].y);
ctx.lineTo(v[1].x - 2, v[1].y);
ctx.strokeStyle = "#000"
ctx.lineWidth = 4;
ctx.setLineDash([40, 40]);
ctx.lineDashOffset = (-simulation.cycle * this.VxGoal) % 80;
ctx.stroke();
ctx.setLineDash([0, 0]);
}
});
Matter.Body.setStatic(rect, true); //make static
return rect
},
chain(x, y, angle = 0, isAttached = true, len = 15, radius = 20, stiffness = 1, damping = 1) {
const gap = 2 * radius
const unit = {
@@ -2255,6 +2332,98 @@ const level = {
}
]
upDownOptions = [ //extra tall vertical section 3000x3000 //this is where the level boss is
(x = offset.x, y = offset.y) => { //mover
const button = level.button(x + 935, y + 0)
button.isUp = true
doCustomTopLayer.push(
() => {
button.draw();
if (button.isUp) {
button.query();
if (!button.isUp) {
const mapStartingLength = map.length //track this so you know how many you added when running addMapToLevelInProgress
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
who.collisionFilter.category = cat.map;
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
Matter.Body.setStatic(who, true); //make static
Composite.add(engine.world, who); //add to world
}
//map elements go here
//box around portals
spawn.mapRect(x + -75, y + -2700, 150, 100);
spawn.mapRect(x + -75, y + -2450, 150, 25);
spawn.mapRect(x + 1925, y + -2725, 125, 550);
spawn.mapRect(x + 1925, y + -2025, 125, 50);
spawn.mapRect(x + 1925, y + -1125, 150, 150);
spawn.mapRect(x + 1925, y + -825, 125, 50);
spawn.mapRect(x + -50, y + -350, 125, 50);
spawn.mapRect(x + -50, y + -650, 125, 150);
const rampSpeed = 4 + Math.floor(9 * Math.random())
const mover4 = level.mover(x, y + -2425, 1000, 50, rampSpeed)
const mover3 = level.mover(x + 1000, y + -2000, 1000, 50, rampSpeed)
const mover2 = level.mover(x + 1000, y + -800, 1000, 50, -rampSpeed)
const mover1 = level.mover(x, y + -325, 1000, 50, -rampSpeed)
const portal1 = level.portal({
x: x + 100,
y: y - 425
}, 2 * Math.PI, { //right
x: x + 100,
y: y - 2525
}, 2 * Math.PI) //right
const portal2 = level.portal({
x: x + 1900,
y: y - 900
}, Math.PI, { //left
x: x + 1900,
y: y - 2100
}, Math.PI) //left
doCustom.push(() => {
portal1[2].query()
portal1[3].query()
portal2[2].query()
portal2[3].query()
mover1.push();
mover2.push();
mover3.push();
mover4.push();
})
doCustomTopLayer.push(() => {
portal1[0].draw();
portal1[1].draw();
portal1[2].draw();
portal1[3].draw();
portal2[0].draw();
portal2[1].draw();
portal2[2].draw();
portal2[3].draw();
mover1.draw();
mover2.draw();
mover3.draw();
mover4.draw();
})
for (let i = 0, numberOfMapElementsAdded = map.length - mapStartingLength; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
simulation.draw.setPaths() //update map graphics
//mobs go here
spawn.randomMob(x + 175, y + -125, 0);
spawn.randomMob(x + 1775, y + -125, 0);
spawn.randomMob(x + 1750, y + -525, 0);
spawn.randomMob(x + 225, y + -1000, 0);
spawn.randomMob(x + 1675, y + -1075, 0);
spawn.randomMob(x + 1575, y + -2450, 0);
spawn.randomMob(x + 425, y + -1850, 0);
spawn.randomMob(x + 1425, y + -1200, 0);
spawn.randomMob(x + 350, y + -1000, 0);
spawn.randomLevelBoss(x + 475, y + -1475);
spawn.secondaryBossChance(x + 1425, y + -1425);
}
}
}
)
},
// (x = offset.x, y = offset.y) => {
// // spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //left ledges
// // spawn.mapVertex(x + 1995, y + -1318, "0 0 0 -250 -125 -250"); // right ledges
@@ -2677,8 +2846,8 @@ const level = {
exit = exitOptions[Math.floor(Math.random() * exitOptions.length)];
empty = emptyOptions[Math.floor(Math.random() * emptyOptions.length)];
loot = lootOptions[Math.floor(Math.random() * lootOptions.length)];
upDown = upDownOptions[Math.floor(Math.random() * upDownOptions.length)];
// upDown = upDownOptions[0] //controls what level spawns for map designing building //********************************* DO !NOT! RUN THIS LINE IN THE FINAL VERSION ***************************************
// upDown = upDownOptions[Math.floor(Math.random() * upDownOptions.length)];
upDown = upDownOptions[0] //controls what level spawns for map designing building //********************************* DO !NOT! RUN THIS LINE IN THE FINAL VERSION ***************************************
//3x2: 4 short rooms (3000x1500), 1 double tall room (3000x3000)
//rooms
let rooms = ["exit", "loot", "enter", "empty"]
@@ -2781,8 +2950,6 @@ const level = {
for (let i = 0, len = doCustomTopLayer.length; i < len; i++) doCustomTopLayer[i]() //runs all the active code from each room
};
powerUps.addResearchToLevel() //needs to run after mobs are spawned
// level.setPosToSpawn(850, -40); //********************************* DO !NOT! RUN THIS LINE IN THE FINAL VERSION ***************************************
},
null() {
level.levels.pop(); //remove lore level from rotation
@@ -2901,11 +3068,20 @@ const level = {
spawn.mapRect(475, -25, 25, 50); //edge shelf
},
testing() {
const mover = level.mover(800, -300, 3000, 25); //x,y,width.height,goal,force
spawn.bodyRect(600, -475, 50, 50);
// const hazard = level.hazard(6000, -1000, 5, 1000, 0.4) //laser
const button = level.button(1000, 0)
spawn.bodyRect(1000, -50, 50, 50);
level.custom = () => {
mover.push();
ctx.fillStyle = "#d4d4d4"
ctx.fillRect(2500, -475, 200, 300)
@@ -2915,6 +3091,7 @@ const level = {
level.enter.draw();
};
level.customTopLayer = () => {
mover.draw();
// hazard.opticalQuery();
button.query();
button.draw();
@@ -15044,6 +15221,95 @@ const level = {
powerUps.spawnStartingPowerUps(0, 0)
powerUps.addResearchToLevel()
},
staircase() {
simulation.makeTextLog(`<strong>staircase</strong> by <span class='color-var'>ryanbear</span>`);
level.custom = () => {
level.exit.drawAndCheck();
level.enter.draw();
};
level.customTopLayer = () => {
aaa.query();
bbb.query();
ccc.query();
ddd.move();
eee.query();
fff.query();
ggg.query();
hhh.query();
iii.query();
jjj.query();
kk.query();
lll.query();
mmm.query();
nnn.query();
ooo.query();
ppp.query();
};
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 7300;
level.exit.y = -5154;
// spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d8dadf";
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
spawn.mapRect(-100, 0, 2100, 100);
spawn.mapRect(1984, 17, 100, 500);
spawn.mapRect(2013, 522, 1618, 100);
spawn.bodyRect(2090, 328, 100, 100);
spawn.mapRect(3619, 14, 100, 500)
var aaa = level.hazard(1999, 10, 1618, 500);
var bbb = level.vanish(2320, -345, 234, 20);
var ccc = level.vanish(2862, -324, 234, 20);
var eee = level.vanish(3002, -1100, 234, 20);
var ddd = level.elevator(3399, -420, 200, 200, -950, 0.003, { up: 0.1, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
var fff = level.vanish(3359, -1300, 234, 20);
var ggg = level.boost(3020, -1600, 700);
var hhh = level.vanish(2700, -1940, 1147, 20);
var iii = level.boost(5038, -2000, 700);
var jjj = level.vanish(5092, -3498, 100, 100);
var kk = level.boost(5092, -3772, 700);
var lll = level.boost(5372, -2824, 700);
var mmm = level.vanish(5112, -3000, 100, 100);
var nnn = level.vanish(5367, -3000, 100, 100);
var ooo = level.boost(4810, -3161, 700);
var ppp = level.vanish(5383, -3485, 100, 100);
spawn.mapRect(5377, -4198, 1000, 100);
spawn.mapRect(6390, -4359, 200, 200);
spawn.mapRect(6605, -4563, 200, 200);
spawn.mapRect(6809, -4758, 200, 200);
spawn.mapRect(7014, -4962, 200, 200);
spawn.mapRect(7212, -5158, 200, 200);
spawn.mapRect(4156, -1898, 1000, 100);
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
// spawn.randomSmallMob(1300, -70);
spawn.randomMob(590, -315);
spawn.randomMob(1343, -757);
spawn.randomMob(4037, -926);
spawn.randomMob(3621, -2376);
spawn.randomMob(5026, -2441);
spawn.randomMob(4253, -2863);
spawn.randomMob(4355, -2430);
spawn.randomMob(5316, -3265);
spawn.randomMob(5885, -4427);
spawn.randomMob(6666, -4979);
spawn.laserBoss(6128, -4905);
// spawn.randomGroup(1700, -900, 0.4);
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
// ********************************************************************************************************
// ********************************************************************************************************

View File

@@ -256,6 +256,7 @@ const m = {
y: Math.max(-10, Math.min(m.standingOn.velocity.y, 10)) //cap velocity contribution from blocks you are standing on to 10 in the vertical
});
},
moverX: 0, //used to tell the player about moving platform x velocity
groundControl() {
//check for crouch or jump
if (m.crouch) {
@@ -265,35 +266,30 @@ const m = {
} else if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
m.jump()
}
const moveX = player.velocity.x - m.moverX //account for mover platforms
if (input.left) {
if (player.velocity.x > -2) {
if (moveX > -2) {
player.force.x -= m.Fx * 1.5
} else {
player.force.x -= m.Fx
}
// }
} else if (input.right) {
if (player.velocity.x < 2) {
if (moveX < 2) {
player.force.x += m.Fx * 1.5
} else {
player.force.x += m.Fx
}
} else {
const stoppingFriction = 0.92; //come to a stop if no move key is pressed
Matter.Body.setVelocity(player, {
x: player.velocity.x * stoppingFriction,
y: player.velocity.y * stoppingFriction
});
Matter.Body.setVelocity(player, { x: m.moverX * 0.08 + player.velocity.x * stoppingFriction, y: player.velocity.y * stoppingFriction });
}
//come to a stop if fast
if (player.speed > 4) {
if (Math.abs(moveX) > 4) { //come to a stop if fast // if (player.speed > 4) { //come to a stop if fast
const stoppingFriction = (m.crouch) ? 0.65 : 0.89; // this controls speed when crouched
Matter.Body.setVelocity(player, {
x: player.velocity.x * stoppingFriction,
y: player.velocity.y * stoppingFriction
});
Matter.Body.setVelocity(player, { x: m.moverX * (1 - stoppingFriction) + player.velocity.x * stoppingFriction, y: player.velocity.y * stoppingFriction });
}
m.moverX = 0 //reset the level mover offset
},
airControl() {
//check for coyote time jump
@@ -302,11 +298,7 @@ const m = {
//check for short jumps //moving up //recently pressed jump //but not pressing jump key now
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {
Matter.Body.setVelocity(player, {
//reduce player y-velocity every cycle
x: player.velocity.x,
y: player.velocity.y * 0.94
});
Matter.Body.setVelocity(player, { x: player.velocity.x, y: player.velocity.y * 0.94 }); //reduce player y-velocity every cycle
}
if (input.left) {
@@ -2106,7 +2098,8 @@ const m = {
const solid = function(that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
// if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
if (dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
that.collisionFilter.category = cat.body; //make solid
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {

View File

@@ -6,7 +6,7 @@ const spawn = {
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss"
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss", "mantisBoss"
],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -3030,14 +3030,20 @@ const spawn = {
let me = mob[mob.length - 1];
me.babyList = [] //list of mobs that are apart of this boss
Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
me.damageReduction = 0.15 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
me.damageReduction = 0.13 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
me.isBoss = true;
me.friction = 0;
me.frictionAir = 0.0067;
me.g = 0.0002; //required if using this.gravity
me.seePlayerFreq = 300;
const springStiffness = 0.00008; //simulation.difficulty
const springDampening = 0.01;
me.seePlayerFreq = 33;
const springStiffness = 0.00003; //simulation.difficulty
const springDampening = 0.0002;
// const springStiffness = 0.00014;
// const springDampening = 0.0005;
me.springTarget = {
x: me.position.x,
y: me.position.y
@@ -3076,8 +3082,9 @@ const spawn = {
ctx.arc(this.cons2.pointA.x, this.cons2.pointA.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = "#222";
ctx.fill();
this.seePlayerCheck()
// this.seePlayerByHistory()
// this.seePlayerCheck()
this.seePlayerByHistory()
this.invulnerabilityCountDown--
if (this.isInvulnerable) {
ctx.beginPath();
let vertices = this.vertices;
@@ -3095,9 +3102,16 @@ const spawn = {
ctx.lineWidth = 13 + 5 * Math.random();
ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`;
ctx.stroke();
} else if (this.invulnerabilityCountDown > 0) {
this.invulnerabilityCountDown--
} else {
if (this.invulnerabilityCountDown < 0) {
this.invulnerabilityCountDown = 110
this.isInvulnerable = false
this.damageReduction = this.startingDamageReduction
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction
}
}
} else if (this.invulnerabilityCountDown < 0) {
this.invulnerabilityCountDown = 120 + 9 * simulation.difficulty
this.isInvulnerable = true
if (this.damageReduction) this.startingDamageReduction = this.damageReduction
this.damageReduction = 0
@@ -3109,7 +3123,7 @@ const spawn = {
}
}
// set new values of the ends of the spring constraints
const stepRange = 1200
const stepRange = 700
if (this.seePlayer.recall && Matter.Query.ray(map, this.position, this.seePlayer.position).length === 0) {
if (!(simulation.cycle % (this.seePlayerFreq * 2))) {
const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
@@ -3118,13 +3132,6 @@ const spawn = {
this.springTarget.y = goal.y;
this.cons.length = -200;
this.cons2.length = 100 + 1.5 * this.radius;
this.isInvulnerable = false
this.invulnerabilityCountDown = 80 + Math.max(0, 70 - simulation.difficulty * 0.5)
this.damageReduction = this.startingDamageReduction
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction
}
} else if (!(simulation.cycle % this.seePlayerFreq)) {
const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
const goal = Vector.add(this.position, Vector.mult(unit, stepRange))
@@ -3132,13 +3139,6 @@ const spawn = {
this.springTarget2.y = goal.y;
this.cons.length = 100 + 1.5 * this.radius;
this.cons2.length = -200;
this.isInvulnerable = false
this.invulnerabilityCountDown = 80 + Math.max(0, 70 - simulation.difficulty)
this.damageReduction = this.startingDamageReduction
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction
}
}
} else {
this.torque = this.lookTorque * this.inertia;
@@ -3231,7 +3231,7 @@ const spawn = {
babyMob.fill = "rgb(68, 102, 119)"
babyMob.isBoss = true;
// Matter.Body.setDensity(babyMob, 0.001); //extra dense //normal is 0.001 //makes effective life much larger and increases damage
babyMob.damageReduction = this.startingDamageReduction
babyMob.damageReduction = this.startingDamageReduction * 0.8
babyMob.collisionFilter.mask = cat.bullet | cat.player //can't touch other mobs //cat.map | cat.body |
babyMob.delay = 60 + 55 * simulation.CDScale + Math.floor(Math.random() * 20);
babyMob.strikeRange = 400
@@ -4131,13 +4131,13 @@ const spawn = {
Matter.Body.rotate(me, Math.PI * 0.1);
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.035 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.034 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.frictionStatic = 0;
me.friction = 0;
me.memory = 240
me.seePlayerFreq = 60
me.blinkRange = 235
me.seePlayerFreq = 55
me.blinkRange = 250
if (0.5 < Math.random()) {
me.grenadeDelay = 260
me.blinkRange *= 1.5
@@ -4166,7 +4166,6 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}
me.do = function() {
// this.armor();
this.seePlayerByHistory(40)
if (this.nextBlinkCycle < simulation.cycle && this.seePlayer.yes) { //teleport towards the player
this.nextBlinkCycle = simulation.cycle + this.delay;

View File

@@ -227,7 +227,7 @@ const tech = {
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.33 * m.coupling)
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
if (tech.isTechDebt) dmg *= Math.max(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount)
if (tech.isTechDebt) dmg *= Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount)
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
@@ -4800,7 +4800,7 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isFoamBall && !tech.superHarm) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isSuperBounce && !tech.isFoamBall && !tech.isSuperHarm) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
},
requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane, Zectron",
effect() {
@@ -4811,10 +4811,29 @@ const tech = {
}
},
{
name: "Zectron",
description: `<strong>+100%</strong> <strong>super ball</strong> density and <strong class='color-d'>damage</strong>, but<br>after colliding with <strong>super balls</strong> <strong>lose</strong> <strong class='color-h'>health</strong>`,
name: "rebound",
description: `after they collide with a mob, <strong>super balls</strong><br>gain <strong>speed</strong>, <strong>duration</strong>, and <strong>+33%</strong> <strong class='color-d'>damage</strong>`,
isGunTech: true,
maxCount: 9,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isIncendiary && !tech.isFoamBall
},
requires: "super balls, not incendiary",
effect() {
tech.isSuperBounce = true
},
remove() {
tech.isSuperBounce = false
}
},
{
name: "Zectron",
description: `<strong>+66%</strong> <strong>super ball</strong> density and <strong class='color-d'>damage</strong>, but<br>after colliding with <strong>super balls</strong> <strong>-25%</strong> <strong class='color-f'>energy</strong>`,
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
@@ -4823,10 +4842,10 @@ const tech = {
},
requires: "super balls not incendiary ammunition",
effect() {
tech.superHarm++
tech.isSuperHarm = true
},
remove() {
tech.superHarm = 0
tech.isSuperHarm = false
}
},
{
@@ -4838,7 +4857,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.haveGunCheck("super balls") || tech.isSuperMine) || (tech.haveGunCheck("harpoon") && !tech.fragments)
return ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isSuperBounce) || (tech.haveGunCheck("harpoon") && !tech.fragments)
},
requires: "super balls, harpoon, not fragmentation",
effect() {
@@ -11336,7 +11355,7 @@ const tech = {
buffedGun: 0,
isGunChoice: null,
railChargeRate: null,
superHarm: null,
isSuperHarm: null,
isZombieMobs: null,
isSuperMine: null,
sentryAmmo: null,
@@ -11345,4 +11364,5 @@ const tech = {
isDiaphragm: null,
hardLanding: null,
isNoGroundDamage: null,
isSuperBounce: null,
}