mover
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:
BIN
img/rebound.webp
Normal file
BIN
img/rebound.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@@ -99,6 +99,7 @@
|
||||
<option value="islands">
|
||||
<option value="tunnel">
|
||||
<option value="coliseum">
|
||||
<option value="staircase">
|
||||
<option value="perplex">
|
||||
<option value="n-gon">
|
||||
<option value="vats">
|
||||
|
||||
258
js/bullet.js
258
js/bullet.js
@@ -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, {
|
||||
|
||||
290
js/level.js
290
js/level.js
@@ -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
|
||||
},
|
||||
|
||||
// ********************************************************************************************************
|
||||
// ********************************************************************************************************
|
||||
|
||||
31
js/player.js
31
js/player.js
@@ -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 {
|
||||
|
||||
59
js/spawn.js
59
js/spawn.js
@@ -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;
|
||||
|
||||
38
js/tech.js
38
js/tech.js
@@ -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,
|
||||
}
|
||||
48
todo.txt
48
todo.txt
@@ -1,20 +1,25 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
tech: aerostat - +88% damage off the ground, but -22% damage on the ground
|
||||
negative mass field required
|
||||
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
|
||||
|
||||
tetherBoss now has beetle babies, and immunity
|
||||
skins have a unique orb for their description card
|
||||
and some new images
|
||||
cloaking field has a new graphic for sneak attack on the cross hairs
|
||||
new community level - staircase by ryanbear
|
||||
|
||||
new community map yingYang by Richard0820
|
||||
|
||||
|
||||
bug fixes
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
level element - mover
|
||||
test effect of changing m.Vx on things like: shooting bullets?
|
||||
ad mobs
|
||||
|
||||
|
||||
|
||||
extend uncertainty to superballs
|
||||
maybe make aiming them more random?
|
||||
|
||||
live updating defense and damage HUD?
|
||||
makes more sense for defense
|
||||
for damage many effects only apply to one type of damage so it would show up
|
||||
@@ -42,13 +47,16 @@ live updating defense and damage HUD?
|
||||
color: red if not used for health
|
||||
scales from 1-infinity maps to 0->1
|
||||
1-1/(1+damage)
|
||||
diagetic UI Elements
|
||||
ammo number?
|
||||
doesn't text look choppy when camera moves?
|
||||
health bar could be rendered similarly to energy bar
|
||||
what about 2 bezier curves on left and right of player head that looks like 1/3 circleRadiusScale
|
||||
rotate the curves as the head rotates
|
||||
what about 2 bezier both above player
|
||||
as the total energy and health increases the curses could asymptotically approach a maximum length as max energy/health goes to infinity
|
||||
|
||||
|
||||
|
||||
|
||||
map element - conveyor belt
|
||||
for blocks, player, power ups touching map element apply vector force
|
||||
|
||||
perfect diamagnatism could bounce on mobs, or even map elements?
|
||||
could work like a rocket jump?
|
||||
|
||||
@@ -82,14 +90,6 @@ tech - after standing wave runs out of energy from blocking, gain a buff
|
||||
aoe damage like railgun
|
||||
push mobs away
|
||||
|
||||
diagetic UI Elements
|
||||
ammo number?
|
||||
doesn't text look choppy when camera moves?
|
||||
health bar could be rendered similarly to energy bar
|
||||
what about 2 bezier curves on left and right of player head that looks like 1/3 circleRadiusScale
|
||||
rotate the curves as the head rotates
|
||||
what about 2 bezier both above player
|
||||
as the total energy and health increases the curses could asymptotically approach a maximum length as max energy/health goes to infinity
|
||||
|
||||
level: lock
|
||||
should there be something in the top part of the map?
|
||||
@@ -1227,7 +1227,7 @@ if pause is pressed while selecting power ups, display pause menu on top of sele
|
||||
laser
|
||||
supercritical fission
|
||||
***past style themes***
|
||||
field emitter - isometric, clean white robot spherical gun turret on bird legs, blender 3d, style of artstation and behance, Disney Pixar, cute
|
||||
field emitter - bipedal white robot spherical gun turret on bird legs
|
||||
damaged dirty white robot spherical gun turret on bird legs in the style of Solarpunk
|
||||
standing wave - concentric transparent blue geometric circles science
|
||||
perfect diamagnetism - physics magnetic field chalk diagram
|
||||
|
||||
Reference in New Issue
Block a user