grappling hook field
grappling hook is now a field (work in progress) reworked physics to allow faster speeds, but more control improved rate of power up grabbing more player control to hook retraction rate changed hook shape and field image graphics grappling hook field coupling, more tech, bug fixes, and general polish to be added soon aerostat - 88->100% damage in air 22-> 25% damage on ground foam damage reduced 10%, ammo increased about 10% after hitting an invulnerable mob (drones,spores,worms,iceIX,fleas) don't die or lose cycles added JUNK tech: mobs! - summon 20 random mobs added announcement of mob names in console at start of new level bug fixes
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
BIN
img/field/grappling hook.webp
Normal file
BIN
img/field/grappling hook.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
429
js/bullet.js
429
js/bullet.js
@@ -1460,50 +1460,89 @@ const b = {
|
||||
// Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
|
||||
// },
|
||||
grapple(where, angle = m.angle, harpoonSize = 1) {
|
||||
grapple(where, angle = m.angle) {
|
||||
const me = bullet.length;
|
||||
const returnRadius = 100 * Math.sqrt(harpoonSize)
|
||||
const returnRadius = 100
|
||||
bullet[me] = Bodies.fromVertices(where.x, where.y, [{
|
||||
x: -50 * harpoonSize,
|
||||
y: 2 * harpoonSize,
|
||||
x: -40,
|
||||
y: 2,
|
||||
index: 0,
|
||||
isInternal: false
|
||||
}, {
|
||||
x: -50 * harpoonSize,
|
||||
y: -2 * harpoonSize,
|
||||
x: -40,
|
||||
y: -2,
|
||||
index: 1,
|
||||
isInternal: false
|
||||
}, {
|
||||
x: 45 * harpoonSize,
|
||||
y: -3 * harpoonSize,
|
||||
x: 37,
|
||||
y: -2,
|
||||
index: 2,
|
||||
isInternal: false
|
||||
}, {
|
||||
x: 50 * harpoonSize,
|
||||
y: 0,
|
||||
x: 40,
|
||||
y: -1,
|
||||
index: 3,
|
||||
isInternal: false
|
||||
}, {
|
||||
x: 45 * harpoonSize,
|
||||
y: 3 * harpoonSize,
|
||||
x: 34,
|
||||
y: 5,
|
||||
index: 4,
|
||||
isInternal: false
|
||||
}], {
|
||||
}],
|
||||
|
||||
// [{
|
||||
// x: -10,
|
||||
// y: 2,
|
||||
// index: 0,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: -10,
|
||||
// y: -2,
|
||||
// index: 1,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: 35,
|
||||
// y: -3,
|
||||
// index: 2,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: 37,
|
||||
// y: -2,
|
||||
// index: 3,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: 40,
|
||||
// y: 0,
|
||||
// index: 4,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: 37,
|
||||
// y: 2,
|
||||
// index: 5,
|
||||
// isInternal: false
|
||||
// }, {
|
||||
// x: 35,
|
||||
// y: 3,
|
||||
// index: 6,
|
||||
// isInternal: false
|
||||
// }],
|
||||
{
|
||||
angle: angle,
|
||||
friction: 1,
|
||||
frictionAir: 0.4,
|
||||
thrustMag: 0.1,
|
||||
thrustMag: 0.13,
|
||||
dmg: 6, //damage done in addition to the damage from momentum
|
||||
classType: "bullet",
|
||||
endCycle: simulation.cycle + 70,
|
||||
isSlowPull: false,
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
|
||||
},
|
||||
minDmgSpeed: 4,
|
||||
lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||
density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
||||
drain: tech.isRailEnergy ? 0.0006 : 0.006,
|
||||
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
||||
density: 0.004, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
||||
drain: 0.001,
|
||||
beforeDmg(who) {
|
||||
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||
who.isShielded = false
|
||||
@@ -1511,20 +1550,22 @@ const b = {
|
||||
who.isShielded = true
|
||||
});
|
||||
}
|
||||
if (tech.fragments) {
|
||||
b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
|
||||
}
|
||||
if (tech.isFoamBall) {
|
||||
for (let i = 0, len = 3 * this.mass; i < len; i++) {
|
||||
const radius = 5 + 8 * Math.random()
|
||||
const velocity = {
|
||||
x: Math.max(0.5, 2 - radius * 0.1),
|
||||
y: 0
|
||||
}
|
||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
}
|
||||
// this.endCycle = 0;
|
||||
}
|
||||
// if (tech.fragments) {
|
||||
// b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
|
||||
// }
|
||||
// if (tech.isFoamBall) {
|
||||
// for (let i = 0, len = 3 * this.mass; i < len; i++) {
|
||||
// const radius = 5 + 8 * Math.random()
|
||||
// const velocity = {
|
||||
// x: Math.max(0.5, 2 - radius * 0.1),
|
||||
// y: 0
|
||||
// }
|
||||
// b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
// }
|
||||
// // this.endCycle = 0;
|
||||
// }
|
||||
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
||||
this.retract()
|
||||
},
|
||||
caughtPowerUp: null,
|
||||
dropCaughtPowerUp() {
|
||||
@@ -1582,32 +1623,26 @@ const b = {
|
||||
ctx.fillStyle = '#000'
|
||||
ctx.fill();
|
||||
},
|
||||
returnToPlayer() {
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
|
||||
this.endCycle = 0;
|
||||
// if (m.energy < 0.05) {
|
||||
// m.fireCDcycle = m.cycle + 120; //fire cooldown
|
||||
// } else if (m.cycle + 15 * b.fireCDscale < m.fireCDcycle) {
|
||||
// m.fireCDcycle = m.cycle + 15 * b.fireCDscale //lower cd to 25 if it is above 25
|
||||
// }
|
||||
|
||||
if (m.energy < 0.05) this.dropCaughtPowerUp()
|
||||
|
||||
//recoil on catching
|
||||
retract() {
|
||||
this.do = this.returnToPlayer
|
||||
this.endCycle = simulation.cycle + 60
|
||||
Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
||||
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
|
||||
this.collisionFilter.mask = 0//cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
|
||||
//recoil on pulling grapple back
|
||||
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
|
||||
},
|
||||
returnToPlayer() {
|
||||
if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
|
||||
this.endCycle = 0;
|
||||
//recoil on catching grapple
|
||||
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
|
||||
b.guns[9].ammo++;
|
||||
simulation.updateGunHUD();
|
||||
|
||||
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
// if (b.guns[i].name === "harpoon") {
|
||||
// b.guns[i].ammo++;
|
||||
// simulation.updateGunHUD();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
if (m.energy > this.drain) m.energy -= this.drain
|
||||
const sub = Vector.sub(this.position, m.pos)
|
||||
@@ -1619,48 +1654,71 @@ const b = {
|
||||
}
|
||||
this.draw();
|
||||
},
|
||||
destroyBlocks() {
|
||||
const blocks = Matter.Query.collides(this, body)
|
||||
if (blocks.length && !blocks[0].bodyA.isNotHoldable) {
|
||||
if (blocks[0].bodyA.mass > 2.5) this.retract()
|
||||
const block = blocks[0].bodyA.vertices
|
||||
Composite.remove(engine.world, blocks[0].bodyA)
|
||||
body.splice(body.indexOf(blocks[0].bodyA), 1)
|
||||
//animate the block fading away
|
||||
simulation.ephemera.push({
|
||||
name: "blockFadeOut",
|
||||
count: 25, //cycles before it self removes
|
||||
do() {
|
||||
this.count--
|
||||
if (this.count < 0) simulation.removeEphemera(this.name)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(block[0].x, block[0].y);
|
||||
for (let j = 1; j < block.length; j++) ctx.lineTo(block[j].x, block[j].y);
|
||||
ctx.lineTo(block[0].x, block[0].y);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = `rgba(0,0,0,${this.count / 25})`
|
||||
ctx.stroke();
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
grabPowerUp() { //grab power ups near the tip of the harpoon
|
||||
if (this.caughtPowerUp) {
|
||||
Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
||||
Matter.Body.setVelocity(this.caughtPowerUp, {
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
} else { //&& simulation.cycle % 2
|
||||
Matter.Body.setVelocity(this.caughtPowerUp, { x: 0, y: 0 })
|
||||
} else {
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
const radius = powerUp[i].circleRadius + 50
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius) {
|
||||
if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
|
||||
this.caughtPowerUp = powerUp[i]
|
||||
Matter.Body.setVelocity(powerUp[i], {
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 })
|
||||
Matter.Body.setPosition(powerUp[i], this.vertices[2])
|
||||
powerUp[i].collisionFilter.category = 0
|
||||
powerUp[i].collisionFilter.mask = 0
|
||||
this.thrustMag *= 0.6
|
||||
this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
|
||||
this.retract()
|
||||
break //just pull 1 power up if possible
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m.grabPowerUp();
|
||||
},
|
||||
do() {
|
||||
if (input.fire) { //&& !Matter.Query.collides(this, body).length
|
||||
if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
||||
if (input.field) { //&& !Matter.Query.collides(this, body).length
|
||||
this.destroyBlocks()
|
||||
this.grabPowerUp()
|
||||
if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction
|
||||
this.endCycle = simulation.cycle + 60
|
||||
// m.fireCDcycle = m.cycle + 120 // cool down
|
||||
this.do = this.returnToPlayer
|
||||
Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
||||
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
|
||||
}
|
||||
// if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down field, force retraction
|
||||
// this.endCycle = simulation.cycle + 30
|
||||
// // m.fireCDcycle = m.cycle + 120 // cool down
|
||||
// this.do = this.returnToPlayer
|
||||
// Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
||||
// 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
|
||||
// }
|
||||
} else {
|
||||
//if not enough energy
|
||||
if (m.energy < 0.05) this.dropCaughtPowerUp()
|
||||
// if (m.energy < 0.01) this.dropCaughtPowerUp()
|
||||
// const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
|
||||
// this.force.x -= returnForce.x
|
||||
// this.force.y -= returnForce.y
|
||||
@@ -1671,103 +1729,90 @@ const b = {
|
||||
|
||||
// } else {
|
||||
//return to player
|
||||
this.do = this.returnToPlayer
|
||||
this.endCycle = simulation.cycle + 60
|
||||
Matter.Body.setDensity(this, 0.0005); //reduce density on return
|
||||
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), (m.crouch ? 0.0001 : 0.0002))
|
||||
player.force.x += momentum.x
|
||||
player.force.y += momentum.y
|
||||
this.retract()
|
||||
// }
|
||||
}
|
||||
//grappling hook
|
||||
if (input.fire && Matter.Query.collides(this, map).length) {
|
||||
Matter.Body.setPosition(this, Vector.add(this.position, {
|
||||
x: 20 * Math.cos(this.angle),
|
||||
y: 20 * Math.sin(this.angle)
|
||||
}))
|
||||
if (input.field && Matter.Query.collides(this, map).length) {
|
||||
Matter.Body.setPosition(this, Vector.add(this.position, { x: -20 * Math.cos(this.angle), y: -20 * Math.sin(this.angle) }))
|
||||
if (Matter.Query.collides(this, map).length) {
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
||||
Matter.Sleeping.set(this, true)
|
||||
this.endCycle = simulation.cycle + 5
|
||||
this.dropCaughtPowerUp()
|
||||
// this.dropCaughtPowerUp()
|
||||
this.do = () => {
|
||||
if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
||||
// if (this.caughtPowerUp) {
|
||||
// Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
||||
// Matter.Body.setVelocity(this.caughtPowerUp, { x: 0, y: 0 })
|
||||
// }
|
||||
this.grabPowerUp()
|
||||
|
||||
//between player nose and the grapple
|
||||
const sub = Vector.sub(this.vertices[0], {
|
||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
||||
})
|
||||
const sub = Vector.sub(this.vertices[0], { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) })
|
||||
let dist = Vector.magnitude(sub)
|
||||
if (input.fire) {
|
||||
if (input.field) {
|
||||
// m.fireCDcycle = m.cycle + 30; // cool down if out of energy
|
||||
m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
|
||||
// m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
|
||||
// if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
||||
this.endCycle = simulation.cycle + 10
|
||||
if (input.down) { //down
|
||||
this.isSlowPull = true
|
||||
dist = 0
|
||||
player.force.y += 5 * player.mass * simulation.g;
|
||||
player.force.y += 2.5 * player.mass * simulation.g; //adjust this to control fall rate while hooked and pressing down
|
||||
} else if (input.up) {
|
||||
this.isSlowPull = false
|
||||
}
|
||||
if (m.energy > this.drain) {
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: player.velocity.x * 0.8,
|
||||
y: player.velocity.y * 0.8
|
||||
});
|
||||
if (m.energy < this.drain) this.isSlowPull = true
|
||||
|
||||
// pulling friction that allowed a slight swinging, but has high linear pull at short dist
|
||||
const drag = 1 - 30 / Math.min(Math.max(100, dist), 700) - 0.1 * (player.speed > 70)
|
||||
// console.log(player.speed)
|
||||
Matter.Body.setVelocity(player, { x: player.velocity.x * drag, y: player.velocity.y * drag });
|
||||
const pullScale = 0.0004
|
||||
const pull = Vector.mult(Vector.normalise(sub), pullScale * Math.min(Math.max(15, dist), this.isSlowPull ? 70 : 200))
|
||||
//original pulling force with high friction and very linear pull
|
||||
// Matter.Body.setVelocity(player, { x: player.velocity.x * 0.85, y: player.velocity.y * 0.85 });
|
||||
// const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), this.isSlowPull ? 100 : 200))
|
||||
|
||||
//need to scale the friction differently based on distance?
|
||||
// if (dist > 500) {
|
||||
const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200))
|
||||
player.force.x += pull.x
|
||||
player.force.y += pull.y
|
||||
// }
|
||||
|
||||
if (dist > 500) {
|
||||
m.energy -= this.drain
|
||||
if (m.energy < 0) {
|
||||
this.endCycle = 0;
|
||||
if (m.cycle + 50 < m.fireCDcycle) m.fireCDcycle = m.cycle + 50
|
||||
// refund ammo
|
||||
b.guns[9].ammo++;
|
||||
simulation.updateGunHUD();
|
||||
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
// if (b.guns[i].name === "harpoon") {
|
||||
// break;
|
||||
// if (m.energy < 0) this.endCycle = 0;
|
||||
}
|
||||
|
||||
// if (tech.isImmuneGrapple && m.immuneCycle < m.cycle + 10) {
|
||||
// m.immuneCycle = m.cycle + 10;
|
||||
// if (m.energy > 0.001) {
|
||||
// m.energy -= 0.001
|
||||
// } else { //out of energy
|
||||
// Matter.Sleeping.set(this, false)
|
||||
// this.collisionFilter.category = 0
|
||||
// this.collisionFilter.mask = 0
|
||||
// this.do = this.returnToPlayer
|
||||
// this.endCycle = simulation.cycle + 60
|
||||
// // m.fireCDcycle = m.cycle + 120; //fire cooldown
|
||||
// if (m.fieldCDcycle < m.cycle + 120) m.fieldCDcycle = m.cycle + 120
|
||||
|
||||
// //recoil on catching
|
||||
// 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
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tech.isImmuneGrapple && m.immuneCycle < m.cycle + 10) {
|
||||
m.immuneCycle = m.cycle + 10;
|
||||
if (m.energy > 0.001) {
|
||||
m.energy -= 0.001
|
||||
} else { //out of energy
|
||||
Matter.Sleeping.set(this, false)
|
||||
this.collisionFilter.category = 0
|
||||
this.collisionFilter.mask = 0
|
||||
this.do = this.returnToPlayer
|
||||
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), (m.crouch ? 0.0001 : 0.0002))
|
||||
player.force.x += momentum.x
|
||||
player.force.y += momentum.y
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Matter.Sleeping.set(this, false)
|
||||
this.collisionFilter.category = 0
|
||||
this.collisionFilter.mask = 0
|
||||
this.do = this.returnToPlayer
|
||||
this.endCycle = simulation.cycle + 60
|
||||
//recoil on catching
|
||||
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
|
||||
this.retract()
|
||||
// Matter.Sleeping.set(this, false)
|
||||
// this.collisionFilter.category = 0
|
||||
// this.collisionFilter.mask = 0
|
||||
// this.do = this.returnToPlayer
|
||||
// this.endCycle = simulation.cycle + 60
|
||||
// //recoil on catching
|
||||
// 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
|
||||
}
|
||||
this.draw();
|
||||
}
|
||||
@@ -3178,6 +3223,9 @@ const b = {
|
||||
y: 100 * (Math.random() - 0.5)
|
||||
},
|
||||
beforeDmg(who) {
|
||||
if (who.isInvulnerable) {
|
||||
Matter.Body.setVelocity(this, Vector.mult(this.velocity, 0.1));
|
||||
} else {
|
||||
if (tech.isSpawnBulletsOnDeath && who.alive && who.isDropPowerUp) {
|
||||
setTimeout(() => {
|
||||
if (!who.alive) {
|
||||
@@ -3192,6 +3240,7 @@ const b = {
|
||||
this.endCycle = 0; //bullet ends cycle after doing damage
|
||||
}
|
||||
if (this.isFreeze) mobs.statusSlow(who, 90)
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
|
||||
@@ -3295,8 +3344,10 @@ const b = {
|
||||
y: 100 * (Math.random() - 0.5)
|
||||
},
|
||||
beforeDmg(who) {
|
||||
if (!who.isInvulnerable) {
|
||||
this.endCycle = 0; //bullet ends cycle after doing damage
|
||||
if (this.isFreeze) mobs.statusSlow(who, 90)
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
|
||||
@@ -3304,7 +3355,7 @@ const b = {
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
}
|
||||
console.log(this.dmg)
|
||||
// console.log(this.dmg)
|
||||
},
|
||||
do() {
|
||||
if (this.lockedOn && this.lockedOn.alive) {
|
||||
@@ -3425,6 +3476,7 @@ const b = {
|
||||
minDmgSpeed: 0,
|
||||
lockedOn: null,
|
||||
beforeDmg(who) {
|
||||
if (!who.isInvulnerable) {
|
||||
if (tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) {
|
||||
setTimeout(() => {
|
||||
if (!who.alive) m.energy += tech.iceEnergy * 0.8
|
||||
@@ -3432,6 +3484,7 @@ const b = {
|
||||
}
|
||||
mobs.statusSlow(who, tech.iceIXFreezeTime)
|
||||
this.endCycle = simulation.cycle
|
||||
}
|
||||
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
|
||||
},
|
||||
onEnd() { },
|
||||
@@ -3507,8 +3560,9 @@ const b = {
|
||||
},
|
||||
beforeDmg(who) {
|
||||
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), 10 + 10 * Math.random())); //push away from target
|
||||
this.endCycle -= 130
|
||||
this.cd = simulation.cycle + this.delay;
|
||||
if (!who.isInvulnerable) {
|
||||
this.endCycle -= 130
|
||||
if (tech.isSporeFreeze) mobs.statusSlow(who, 90)
|
||||
if (tech.isSpawnBulletsOnDeath && who.alive && who.isDropPowerUp) {
|
||||
setTimeout(() => {
|
||||
@@ -3528,6 +3582,7 @@ const b = {
|
||||
setTimeout(() => {
|
||||
this.dmg = 0
|
||||
})
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
|
||||
@@ -3659,15 +3714,18 @@ const b = {
|
||||
deathCycles: 110 + RADIUS * 5,
|
||||
isImproved: false,
|
||||
beforeDmg(who) {
|
||||
if (who.isInvulnerable) {
|
||||
//move away from target after hitting
|
||||
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20)
|
||||
Matter.Body.setVelocity(this, { x: unit.x, y: unit.y });
|
||||
this.lockedOn = null
|
||||
} else {
|
||||
if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle && !tech.isForeverDrones) {
|
||||
const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0)
|
||||
b.explosion(this.position, max * 0.1 + this.isImproved * 110 + 60 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.isForeverDrones) {
|
||||
this.endCycle = 0
|
||||
b.drone({
|
||||
x: m.pos.x + 30 * (Math.random() - 0.5),
|
||||
y: m.pos.y + 30 * (Math.random() - 0.5)
|
||||
}, 5)
|
||||
b.drone({ x: m.pos.x + 30 * (Math.random() - 0.5), y: m.pos.y + 30 * (Math.random() - 0.5) }, 5)
|
||||
bullet[bullet.length - 1].endCycle = Infinity
|
||||
} else {
|
||||
this.endCycle -= max
|
||||
@@ -3682,6 +3740,7 @@ const b = {
|
||||
if (simulation.cycle + this.deathCycles > this.endCycle) this.endCycle = simulation.cycle + this.deathCycles
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isDroneRespawn) {
|
||||
@@ -4193,6 +4252,7 @@ const b = {
|
||||
};
|
||||
}
|
||||
bullet[me].beforeDmg = function (who) {
|
||||
if (!who.isInvulnerable) {
|
||||
if (tech.oneSuperBall) mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
|
||||
if (tech.isFoamBall) {
|
||||
for (let i = 0, len = 5 * this.mass; i < len; i++) {
|
||||
@@ -4235,6 +4295,7 @@ const b = {
|
||||
}
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
targetedBall(position, num = 1, speed = 42 + 12 * Math.random(), range = 1200, isRandomAim = true) {
|
||||
@@ -5394,7 +5455,7 @@ const b = {
|
||||
cd: 0,
|
||||
fireCount: 0,
|
||||
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
|
||||
delay: Math.floor((150 + (tech.isFoamBotUpgrade ? 0 : 250)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
||||
delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
|
||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
||||
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), //how far from the player the bot will move
|
||||
endCycle: Infinity,
|
||||
@@ -7717,7 +7778,7 @@ const b = {
|
||||
return `spray bubbly <strong>foam</strong> that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time<br><strong>${this.ammoPack.toFixed(0)}</strong> bubbles per ${powerUps.orb.ammo()}`
|
||||
},
|
||||
ammo: 0,
|
||||
ammoPack: 24,
|
||||
ammoPack: 28,
|
||||
have: false,
|
||||
charge: 0,
|
||||
isDischarge: false,
|
||||
@@ -7842,9 +7903,9 @@ const b = {
|
||||
if (tech.isRailGun) {
|
||||
this.do = this.railDo
|
||||
this.fire = this.railFire
|
||||
} else if (tech.isGrapple) {
|
||||
this.do = () => { }
|
||||
this.fire = this.grappleFire
|
||||
// } else if (tech.isGrapple) {
|
||||
// this.do = () => { }
|
||||
// this.fire = this.grappleFire
|
||||
} else {
|
||||
this.do = () => { }
|
||||
this.fire = this.harpoonFire
|
||||
@@ -8054,36 +8115,36 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + 10 //can't fire until mouse is released
|
||||
this.charge += 0.00001
|
||||
},
|
||||
grappleFire() {
|
||||
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 (!m.crouch && num > 1) { //multiple harpoons
|
||||
const SPREAD = 0.06
|
||||
let angle = m.angle - SPREAD * num / 2;
|
||||
for (let i = 0; i < num; i++) {
|
||||
if (this.ammo > 0) {
|
||||
this.ammo--
|
||||
b.grapple(where, angle, true, harpoonSize)
|
||||
angle += SPREAD
|
||||
}
|
||||
}
|
||||
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 (m.crouch) {
|
||||
// b.harpoon(where, null, m.angle, harpoonSize, false, 70)
|
||||
} else {
|
||||
if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1
|
||||
b.grapple(where, m.angle, harpoonSize)
|
||||
}
|
||||
// grappleFire() {
|
||||
// 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 (!m.crouch && num > 1) { //multiple harpoons
|
||||
// const SPREAD = 0.06
|
||||
// let angle = m.angle - SPREAD * num / 2;
|
||||
// for (let i = 0; i < num; i++) {
|
||||
// if (this.ammo > 0) {
|
||||
// this.ammo--
|
||||
// b.grapple(where, angle, true, harpoonSize)
|
||||
// angle += SPREAD
|
||||
// }
|
||||
// }
|
||||
// this.ammo++ //make up for the ammo used up in fire()
|
||||
// simulation.updateGunHUD();
|
||||
// m.fireCDcycle = m.cycle + Math.floor(75 * b.fireCDscale) // cool down
|
||||
m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
|
||||
// // } else if (m.crouch) {
|
||||
// // b.harpoon(where, null, m.angle, harpoonSize, false, 70)
|
||||
// } else {
|
||||
// if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1
|
||||
// b.grapple(where, m.angle, harpoonSize)
|
||||
// }
|
||||
// // m.fireCDcycle = m.cycle + Math.floor(75 * b.fireCDscale) // cool down
|
||||
// m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
|
||||
|
||||
},
|
||||
// },
|
||||
harpoonFire() {
|
||||
const where = {
|
||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
||||
|
||||
34
js/level.js
34
js/level.js
@@ -28,17 +28,17 @@ const level = {
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// tech.tech[297].frequency = 100
|
||||
// m.couplingChange(10)
|
||||
// m.setField("wormhole") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole
|
||||
// m.setField("grappling hook") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.energy = 0
|
||||
// simulation.molecularMode = 2
|
||||
// m.damage(0.1);
|
||||
// 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("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("harpoon") //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 = 100000000
|
||||
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("electrostatic induction")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("enthalpy")
|
||||
// for (let i = 0; i < 10; ++i) tech.giveTech("quasiparticles")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("superdeterminism")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("fine-structure constant")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("nail-bot upgrade")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 30; i++) tech.giveTech("laser-bot") });
|
||||
@@ -49,11 +49,11 @@ const level = {
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||
|
||||
// level.biohazard();
|
||||
// level.testing();
|
||||
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
||||
// for (let i = 0; i < 0; ++i) spawn.hopper(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500)
|
||||
// spawn.suckerBoss(1900, -500, 25)
|
||||
// spawn.beetleBoss(1900, -500, 25)
|
||||
// spawn.slasher2(2000, -1150)
|
||||
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
|
||||
// for (let i = 0; i < 20; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
|
||||
@@ -239,6 +239,10 @@ const level = {
|
||||
// <br><span class='color-var'>m</span>.field.description = "<span class='color-text'>${m.fieldUpgrades[m.fieldMode].description}</span>"
|
||||
// `, 1200);
|
||||
},
|
||||
announceMobTypes() {
|
||||
simulation.makeTextLog(`spawn<span class='color-symbol'>.</span>${spawn.pickList[0]}<span class='color-symbol'>(</span>x<span class='color-symbol'>,</span>y<span class='color-symbol'>)</span>`)
|
||||
simulation.makeTextLog(`spawn<span class='color-symbol'>.</span>${spawn.pickList[1]}<span class='color-symbol'>(</span>x<span class='color-symbol'>,</span>y<span class='color-symbol'>)</span>`)
|
||||
},
|
||||
disableExit: false,
|
||||
nextLevel() {
|
||||
if (!level.disableExit) {
|
||||
@@ -1874,6 +1878,7 @@ const level = {
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
template() {
|
||||
// level.announceMobTypes()
|
||||
simulation.enableConstructMode()
|
||||
level.setPosToSpawn(0, -50); //normal spawn
|
||||
level.exit.x = 1500;
|
||||
@@ -2375,9 +2380,6 @@ const level = {
|
||||
ctx.fillStyle = "rgba(68, 68, 68,0.95)"
|
||||
ctx.fillRect(2030, 0, 150, 1800);
|
||||
};
|
||||
|
||||
|
||||
|
||||
level.setPosToSpawn(460, -100); //normal spawn
|
||||
// level.enter.x = -1000000; //hide enter graphic for first level by moving to the far left
|
||||
level.exit.x = 2800;
|
||||
@@ -3451,6 +3453,7 @@ const level = {
|
||||
simulation.draw.drawMapPath = simulation.draw.drawMapSight
|
||||
},
|
||||
reservoir() {
|
||||
level.announceMobTypes()
|
||||
level.exit.x = 1700;
|
||||
level.exit.y = -4510;
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
|
||||
@@ -3966,6 +3969,7 @@ const level = {
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
factory() {
|
||||
level.announceMobTypes()
|
||||
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
|
||||
|
||||
@@ -4249,6 +4253,7 @@ const level = {
|
||||
powerUps.spawn(5200, -1300, "ammo");
|
||||
},
|
||||
labs() {
|
||||
level.announceMobTypes()
|
||||
level.isProcedural = true //used in generating text for the level builder
|
||||
level.defaultZoom = 1700
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
@@ -5347,6 +5352,7 @@ const level = {
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
pavilion() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const vanish = []
|
||||
level.exit.x = -850;
|
||||
@@ -5499,6 +5505,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
testChamber() {
|
||||
level.announceMobTypes()
|
||||
level.setPosToSpawn(0, -50); //lower start
|
||||
level.exit.y = level.enter.y - 550;
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
@@ -5757,6 +5764,7 @@ const level = {
|
||||
|
||||
},
|
||||
lock() {
|
||||
level.announceMobTypes()
|
||||
level.setPosToSpawn(0, -65); //lower start
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.y = 2010;
|
||||
@@ -6006,6 +6014,7 @@ const level = {
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
sewers() {
|
||||
level.announceMobTypes()
|
||||
const button1 = level.button(6600, 2675)
|
||||
// const hazard = level.hazard(4550, 2750, 4550, 150)
|
||||
const hazard = level.hazard(simulation.isHorizontalFlipped ? -4550 - 4550 : 4550, 2750, 4550, 150)
|
||||
@@ -6196,6 +6205,7 @@ const level = {
|
||||
|
||||
},
|
||||
satellite() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const boost1 = level.boost(5825, 235, 1400)
|
||||
const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 }
|
||||
@@ -6372,6 +6382,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
rooftops() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
// level.fallPosition = { x: 5000, y:-4000}
|
||||
const elevator = level.elevator(1450, -990, 235, 45, -2000)
|
||||
@@ -6560,6 +6571,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
aerie() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const boost1 = level.boost(-425, 100, 1400)
|
||||
const boost2 = level.boost(5350, 275, 2850);
|
||||
@@ -6789,6 +6801,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
skyscrapers() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const boost1 = level.boost(475, 0, 1300)
|
||||
const boost2 = level.boost(4450, 0, 1300);
|
||||
@@ -6927,6 +6940,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
highrise() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, {
|
||||
up: 0.01,
|
||||
@@ -7212,6 +7226,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
warehouse() {
|
||||
level.announceMobTypes()
|
||||
level.isEndlessFall = true;
|
||||
level.custom = () => {
|
||||
ctx.fillStyle = "#444" //light fixtures
|
||||
@@ -7531,6 +7546,7 @@ const level = {
|
||||
}
|
||||
},
|
||||
office() {
|
||||
level.announceMobTypes()
|
||||
let button, door
|
||||
let isReverse = false
|
||||
if (Math.random() < 0.75) { //normal direction start in top left
|
||||
|
||||
132
js/player.js
132
js/player.js
@@ -568,7 +568,7 @@ const m = {
|
||||
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
||||
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
|
||||
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25
|
||||
if (tech.isHarmReduce && input.field) dmg *= 0.25
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
|
||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||
@@ -2779,14 +2779,10 @@ const m = {
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#48f" //"#0c5"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
|
||||
m.fieldShieldingScale = 0;
|
||||
m.fieldBlockCD = 3;
|
||||
m.grabPowerUpRange2 = 10000000
|
||||
m.fieldPosition = {
|
||||
x: m.pos.x,
|
||||
y: m.pos.y
|
||||
}
|
||||
m.fieldPosition = { x: m.pos.x, y: m.pos.y }
|
||||
m.fieldAngle = m.angle
|
||||
m.perfectPush = (isFree = false) => {
|
||||
if (m.fieldCDcycle < m.cycle) {
|
||||
@@ -2794,10 +2790,7 @@ const m = {
|
||||
if (
|
||||
Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange &&
|
||||
!mob[i].isUnblockable &&
|
||||
Vector.dot({
|
||||
x: Math.cos(m.fieldAngle),
|
||||
y: Math.sin(m.fieldAngle)
|
||||
}, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold &&
|
||||
Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold &&
|
||||
Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0
|
||||
) {
|
||||
mob[i].locatePlayer();
|
||||
@@ -2816,11 +2809,7 @@ const m = {
|
||||
}
|
||||
}
|
||||
if (tech.blockDmg) { //electricity
|
||||
Matter.Body.setVelocity(mob[i], {
|
||||
x: 0.5 * mob[i].velocity.x,
|
||||
y: 0.5 * mob[i].velocity.y
|
||||
});
|
||||
|
||||
Matter.Body.setVelocity(mob[i], { x: 0.5 * mob[i].velocity.x, y: 0.5 * mob[i].velocity.y });
|
||||
if (mob[i].isShielded) {
|
||||
for (let j = 0, len = mob.length; j < len; j++) {
|
||||
if (mob[j].id === mob[i].shieldID) mob[j].damage(tech.blockDmg * m.dmgScale * (tech.isBlockRadiation ? 6 : 2), true)
|
||||
@@ -3684,6 +3673,94 @@ const m = {
|
||||
ctx.strokeStyle = "rgba(255,0,110,0.06)"
|
||||
ctx.stroke();
|
||||
}
|
||||
// } else if (true) { //plasma sword slash
|
||||
// const plasmaSweepCycles = 30
|
||||
// m.plasmaSweep = 0
|
||||
// m.plasmaSlashDirection = m.flipLegs//Math.random() > 0.5 ? 1 : -1;
|
||||
// m.hold = function () {
|
||||
// if (m.isHolding) {
|
||||
// m.drawHold(m.holdingTarget);
|
||||
// m.holding();
|
||||
// m.throwBlock();
|
||||
// m.plasmaSweep = 0
|
||||
// // } else if (true) { //not hold but field button is pressed
|
||||
// } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
|
||||
// if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
|
||||
// m.grabPowerUp();
|
||||
// m.lookForPickUp();
|
||||
|
||||
// //graphics
|
||||
// if (m.plasmaSweep === 0) m.plasmaSlashDirection = m.flipLegs //Math.random() > 0.5 ? 1 : -1;
|
||||
// const angle = m.angle //+ 1 * (m.plasmaSweep - plasmaSweepCycles / 2) / plasmaSweepCycles * m.plasmaSlashDirection
|
||||
// const plasmaSweepCapped = Math.min(m.plasmaSweep, plasmaSweepCycles - 8) / plasmaSweepCycles
|
||||
// const range = 100 * plasmaSweepCapped
|
||||
// const arc = 1.3
|
||||
// const A = { x: m.pos.x + range * Math.cos(angle - arc), y: m.pos.y + range * Math.sin(angle - arc) }
|
||||
// const B = { x: m.pos.x + range * Math.cos(angle + arc), y: m.pos.y + range * Math.sin(angle + arc) }
|
||||
// const controlRange = 500 * plasmaSweepCapped
|
||||
// const AC = { x: m.pos.x + controlRange * Math.cos(angle - arc / 2), y: m.pos.y + controlRange * Math.sin(angle - arc / 2) }
|
||||
// const BC = { x: m.pos.x + controlRange * Math.cos(angle + arc / 2), y: m.pos.y + controlRange * Math.sin(angle + arc / 2) }
|
||||
// const innerControlRange = 300 * plasmaSweepCapped
|
||||
// const ACinner = { x: m.pos.x + innerControlRange * Math.cos(angle - arc / 2), y: m.pos.y + innerControlRange * Math.sin(angle - arc / 2) }
|
||||
// const BCinner = { x: m.pos.x + innerControlRange * Math.cos(angle + arc / 2), y: m.pos.y + innerControlRange * Math.sin(angle + arc / 2) }
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(A.x, A.y)
|
||||
// ctx.bezierCurveTo(AC.x, AC.y, BC.x, BC.y, B.x, B.y); //outer curve
|
||||
// ctx.bezierCurveTo(BCinner.x, BCinner.y, ACinner.x, ACinner.y, A.x, A.y); //inner curve
|
||||
// // ctx.strokeStyle = "#000"
|
||||
// // ctx.stroke();
|
||||
// ctx.fillStyle = "rgba(255,0,255,0.5)"
|
||||
// ctx.fill();
|
||||
|
||||
// //draw control points for graphics reference
|
||||
// ctx.lineWidth = '0.5'
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(A.x, A.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(B.x, B.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(AC.x, AC.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(BC.x, BC.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(ACinner.x, ACinner.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(BCinner.x, BCinner.y, 5, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
|
||||
// //mob collision detection
|
||||
// collideRange = 160
|
||||
// const collideCenter = {
|
||||
// x: m.pos.x + collideRange * Math.cos(angle),
|
||||
// y: m.pos.y + collideRange * Math.sin(angle)
|
||||
// }
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(collideCenter.x, collideCenter.y, 140, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
|
||||
// //push mob away and slow them?
|
||||
|
||||
|
||||
// //sweeping motion and cooldown
|
||||
// m.plasmaSweep++
|
||||
// if (m.plasmaSweep > plasmaSweepCycles) {
|
||||
// m.plasmaSweep = 0
|
||||
// if (m.fireCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
|
||||
// }
|
||||
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
|
||||
// m.pickUp();
|
||||
// m.plasmaSweep = 0
|
||||
// } else {
|
||||
// m.plasmaSweep = 0
|
||||
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
// }
|
||||
// m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
|
||||
// }
|
||||
} else {
|
||||
m.hold = function () {
|
||||
if (m.isHolding) {
|
||||
@@ -4864,6 +4941,31 @@ const m = {
|
||||
// m.drawRegenEnergy()
|
||||
// },
|
||||
},
|
||||
{
|
||||
name: "grappling hook",
|
||||
// description: `use <strong class='color-f'>energy</strong> to pull yourself towards the <strong>map</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to fire a hook that attaches to <strong>map</strong>,<br>pulls player, <strong class='color-d'>damages</strong> mobs, and destroys <strong class='color-block'>blocks</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.fieldHarmReduction = 0.45; //55% reduction
|
||||
|
||||
m.hold = function () {
|
||||
if (input.field) {
|
||||
if (m.fieldCDcycle < m.cycle) {
|
||||
if (m.energy > 0.02) m.energy -= 0.02
|
||||
const where = { x: m.pos.x + 40 * Math.cos(m.angle), y: m.pos.y + 40 * Math.sin(m.angle) }
|
||||
b.grapple(where, m.angle)
|
||||
if (m.fieldCDcycle < m.cycle + 20) m.fieldCDcycle = m.cycle + 20
|
||||
}
|
||||
m.grabPowerUp();
|
||||
}
|
||||
m.drawRegenEnergy()
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
//************************************************************************************
|
||||
//************************************************************************************
|
||||
|
||||
@@ -914,6 +914,8 @@ const powerUps = {
|
||||
for (let i = 0; i < b.guns.length; i++) {
|
||||
if (!b.guns[i].have) options.push(i);
|
||||
}
|
||||
// console.log(options.length)
|
||||
if (options.length > 0 || !tech.isSuperDeterminism) {
|
||||
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
|
||||
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
|
||||
function removeOption(index) {
|
||||
@@ -962,6 +964,7 @@ const powerUps = {
|
||||
if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
|
||||
document.getElementById("choose-grid").innerHTML = text
|
||||
powerUps.showDraft();
|
||||
}
|
||||
// }
|
||||
}
|
||||
},
|
||||
|
||||
180
js/tech.js
180
js/tech.js
@@ -232,7 +232,7 @@ const tech = {
|
||||
// }
|
||||
// }
|
||||
if (tech.isDivisor && b.activeGun && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
|
||||
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.78 : 1.88
|
||||
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.75 : 2
|
||||
if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075)
|
||||
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
|
||||
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
|
||||
@@ -955,9 +955,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !m.isShipMode && !tech.isAlwaysFire, !tech.isGrapple
|
||||
return !m.isShipMode && !tech.isAlwaysFire
|
||||
},
|
||||
requires: "not ship mode, automatic, grappling hook",
|
||||
requires: "not ship mode, automatic",
|
||||
effect() {
|
||||
tech.isFireMoveLock = true;
|
||||
b.setFireCD();
|
||||
@@ -6682,10 +6682,10 @@ const tech = {
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
tech.foamDamage += 0.011 * 0.43
|
||||
tech.foamDamage += 0.01 * 0.43
|
||||
},
|
||||
remove() {
|
||||
tech.foamDamage = 0.011;
|
||||
tech.foamDamage = 0.01;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -6831,9 +6831,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple && !tech.isBoostReplaceAmmo
|
||||
return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isBoostReplaceAmmo
|
||||
},
|
||||
requires: "harpoon, not UHMWPE, induction furnace, grappling hook, quasiparticles",
|
||||
requires: "harpoon, not UHMWPE, induction furnace, quasiparticles",
|
||||
ammoBonus: 9,
|
||||
effect() {
|
||||
tech.isRailGun = true;
|
||||
@@ -6852,52 +6852,52 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "grappling hook",
|
||||
description: `<strong>harpoons</strong> attach to the <strong>map</strong> and pull you<br>your <strong>rope</strong> extends while holding <strong>fire</strong>`,
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isRailGun && !tech.isFireMoveLock
|
||||
},
|
||||
requires: "harpoon, not railgun, UHMWPE, induction furnace, Higgs mechanism",
|
||||
effect() {
|
||||
tech.isGrapple = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod()
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
if (tech.isGrapple) {
|
||||
tech.isGrapple = false;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bulk modulus",
|
||||
description: `while <strong>grappling</strong> become <strong>invulnerable</strong><br>drain <strong class='color-f'>energy</strong>`,
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && tech.isGrapple && !tech.isRailEnergy
|
||||
},
|
||||
requires: "grappling hook, not alternator",
|
||||
effect() {
|
||||
tech.isImmuneGrapple = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isImmuneGrapple = false
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "grappling hook",
|
||||
// description: `<strong>harpoons</strong> attach to the <strong>map</strong> and pull you<br>your <strong>rope</strong> extends while holding <strong>fire</strong>`,
|
||||
// isGunTech: true,
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 2,
|
||||
// frequencyDefault: 2,
|
||||
// allowed() {
|
||||
// return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isRailGun && !tech.isFireMoveLock
|
||||
// },
|
||||
// requires: "harpoon, not railgun, UHMWPE, induction furnace, Higgs mechanism",
|
||||
// effect() {
|
||||
// tech.isGrapple = true;
|
||||
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
// if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod()
|
||||
// }
|
||||
// },
|
||||
// remove() {
|
||||
// if (tech.isGrapple) {
|
||||
// tech.isGrapple = false;
|
||||
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
// if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// name: "bulk modulus",
|
||||
// description: `while <strong>grappling</strong> become <strong>invulnerable</strong><br>drain <strong class='color-f'>energy</strong>`,
|
||||
// isGunTech: true,
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 2,
|
||||
// frequencyDefault: 2,
|
||||
// allowed() {
|
||||
// return tech.haveGunCheck("harpoon") && !tech.isRailEnergy
|
||||
// },
|
||||
// requires: "not alternator",
|
||||
// effect() {
|
||||
// tech.isImmuneGrapple = true;
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isImmuneGrapple = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "alternator",
|
||||
description: "<strong>+90%</strong> <strong>harpoon</strong> <strong class='color-f'>energy</strong> efficiency",
|
||||
@@ -6907,9 +6907,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && !tech.isImmuneGrapple
|
||||
return tech.haveGunCheck("harpoon")
|
||||
},
|
||||
requires: "harpoon, not bulk modulus",
|
||||
requires: "harpoon",
|
||||
effect() {
|
||||
tech.isRailEnergy = true;
|
||||
},
|
||||
@@ -6994,9 +6994,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && !tech.isRailGun && !tech.isGrapple
|
||||
return tech.haveGunCheck("harpoon") && !tech.isRailGun
|
||||
},
|
||||
requires: "harpoon, not grappling hook, railgun",
|
||||
requires: "harpoon, not railgun",
|
||||
effect() {
|
||||
tech.isFilament = true;
|
||||
},
|
||||
@@ -7013,9 +7013,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("harpoon") && !tech.isRailGun && !tech.isGrapple
|
||||
return tech.haveGunCheck("harpoon") && !tech.isRailGun
|
||||
},
|
||||
requires: "harpoon, not grappling hook, railgun",
|
||||
requires: "harpoon, not railgun",
|
||||
effect() {
|
||||
tech.isHarpoonPowerUp = true
|
||||
},
|
||||
@@ -7657,9 +7657,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 2 || m.fieldMode === 3) && (build.isExperimentSelection || powerUps.research.count > 3)
|
||||
return (m.fieldMode === 8 || m.fieldMode === 2 || m.fieldMode === 3 || m.fieldMode === 10) && (build.isExperimentSelection || powerUps.research.count > 3)
|
||||
},
|
||||
requires: "perfect diamagnetism, negative mass, pilot wave",
|
||||
requires: "perfect diamagnetism, negative mass, grappling hook, pilot wave",
|
||||
effect() {
|
||||
tech.isFieldHarmReduction = true
|
||||
for (let i = 0; i < 2; i++) {
|
||||
@@ -7706,9 +7706,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 3) && !tech.isCloakHealLastHit
|
||||
return m.fieldMode === 8 || m.fieldMode === 3
|
||||
},
|
||||
requires: "negative mass, pilot wave, not patch",
|
||||
requires: "negative mass, pilot wave",
|
||||
effect() {
|
||||
tech.lastHitDamage += 4;
|
||||
},
|
||||
@@ -7746,16 +7746,16 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "aerostat",
|
||||
description: `<strong>+88%</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>-22%</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong>`,
|
||||
description: `<strong>+100%</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>-25%</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong>`,
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 3
|
||||
return m.fieldMode === 3 || m.fieldMode === 10
|
||||
},
|
||||
requires: "negative mass",
|
||||
requires: "negative mass, grappling hook",
|
||||
effect() {
|
||||
tech.isNoGroundDamage = true
|
||||
},
|
||||
@@ -7831,9 +7831,9 @@ const tech = {
|
||||
isBotTech: true,
|
||||
isNonRefundable: true,
|
||||
allowed() {
|
||||
return powerUps.research.count > 1 && (m.fieldMode === 4 || m.fieldMode === 8)
|
||||
return powerUps.research.count > 1 && (m.fieldMode === 4 || m.fieldMode === 10 || m.fieldMode === 8)
|
||||
},
|
||||
requires: "molecular assembler, pilot wave",
|
||||
requires: "molecular assembler, grappling hook, pilot wave",
|
||||
effect() {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
@@ -7856,9 +7856,9 @@ const tech = {
|
||||
isBotTech: true,
|
||||
isNonRefundable: true,
|
||||
allowed() {
|
||||
return powerUps.research.count > 2 && (m.fieldMode === 4 || m.fieldMode === 8)
|
||||
return powerUps.research.count > 2 && (m.fieldMode === 4 || m.fieldMode === 10 || m.fieldMode === 8)
|
||||
},
|
||||
requires: "molecular assembler, pilot wave",
|
||||
requires: "molecular assembler, grappling hook, pilot wave",
|
||||
effect() {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
|
||||
@@ -8121,9 +8121,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 2 || m.fieldMode === 8)
|
||||
return (m.fieldMode === 10 || m.fieldMode === 4 || m.fieldMode === 8)
|
||||
},
|
||||
requires: "molecular assembler, plasma torch, perfect diamagnetism, pilot wave",
|
||||
requires: "plasma torch, grappling hook, pilot wave",
|
||||
effect() {
|
||||
tech.isHarmReduce = true
|
||||
},
|
||||
@@ -8479,9 +8479,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldMode === 7 && !tech.lastHitDamage && !tech.isEnergyHealth
|
||||
return m.fieldMode === 7 && !tech.isEnergyHealth
|
||||
},
|
||||
requires: "metamaterial cloaking, not dynamic equilibrium, mass-energy",
|
||||
requires: "metamaterial cloaking, not mass-energy",
|
||||
effect() {
|
||||
tech.isCloakHealLastHit = true;
|
||||
},
|
||||
@@ -8586,9 +8586,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldMode === 8 || m.fieldMode === 3 || m.fieldMode === 6 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
return (m.fieldMode === 8 || m.fieldMode === 6 || m.fieldMode === 9 || m.fieldMode === 10) && (build.isExperimentSelection || powerUps.research.count > 2)
|
||||
},
|
||||
requires: "wormhole, time dilation, negative mass, pilot wave",
|
||||
requires: "wormhole, time dilation, negative mass, pilot wave, grappling hook",
|
||||
effect() {
|
||||
tech.fieldDuplicate = 0.11
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
@@ -10982,6 +10982,30 @@ const tech = {
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "mobs!",
|
||||
descriptionFunction() {
|
||||
if (this.mobType === "") this.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]
|
||||
return `spawn 20 <strong>${this.mobType}</strong> mobs`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isNonRefundable: true,
|
||||
isJunk: true,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
mobType: "",
|
||||
effect() {
|
||||
if (this.mobType === "") this.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]
|
||||
for (let i = 0; i < 20; i++) {
|
||||
spawn[this.mobType](m.pos.x, m.pos.y - 700)
|
||||
}
|
||||
simulation.makeTextLog(`spawn<span class='color-symbol'>.</span>${this.mobType}<span class='color-symbol'>(</span>x<span class='color-symbol'>,</span>y<span class='color-symbol'>)</span>`)
|
||||
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "black hole cluster",
|
||||
description: `spawn <strong>30</strong> nearby <strong>black holes</strong>`,
|
||||
@@ -11718,8 +11742,8 @@ const tech = {
|
||||
isTimeCrystals: null,
|
||||
isGroundState: null,
|
||||
isRailGun: null,
|
||||
isGrapple: null,
|
||||
isImmuneGrapple: null,
|
||||
// isGrapple: null,
|
||||
// isImmuneGrapple: null,
|
||||
isDronesTravel: null,
|
||||
isTechDebt: null,
|
||||
isPlasmaBall: null,
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// https://ncase.me/sight-and-light/
|
||||
// redblobgames.com/articles/visibility
|
||||
// https://github.com/Silverwolf90/2d-visibility/tree/master/src
|
||||
// could apply to explosions, neutron bomb, player LOS
|
||||
|
||||
|
||||
const v = {
|
||||
points: [],
|
||||
populate() {
|
||||
v.points = [{
|
||||
x: -150,
|
||||
y: -950
|
||||
}, {
|
||||
x: 710,
|
||||
y: -950
|
||||
}, {
|
||||
x: 710,
|
||||
y: -940
|
||||
}, {
|
||||
x: 710,
|
||||
y: -710
|
||||
}, {
|
||||
x: 710,
|
||||
y: -700
|
||||
}, {
|
||||
x: -150,
|
||||
y: -700
|
||||
}]
|
||||
},
|
||||
draw() {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(v.points[0].x, v.points[0].y)
|
||||
for (let i = 0, len = v.points.length; i < len; i++) {
|
||||
ctx.lineTo(v.points[i].x, v.points[i].y)
|
||||
}
|
||||
// ctx.fillStyle = "#333"
|
||||
ctx.globalCompositeOperation = "destination-in";
|
||||
ctx.fill();
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.clip();
|
||||
}
|
||||
}
|
||||
v.populate();
|
||||
// console.log(v.points)
|
||||
58
todo.txt
58
todo.txt
@@ -1,20 +1,58 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
new community map - LaunchSite by Des Boot
|
||||
grappling hook is now a field (work in progress)
|
||||
reworked physics to allow faster speeds, but more control
|
||||
improved rate of power up grabbing
|
||||
more player control to hook retraction rate
|
||||
changed hook shape and field image graphics
|
||||
grappling hook field coupling, more tech, bug fixes, and general polish to be added soon
|
||||
|
||||
added a short color animation after grabbing basic power ups
|
||||
aerostat - 88->100% damage in air 22-> 25% damage on ground
|
||||
foam damage reduced 10%, ammo increased about 10%
|
||||
after hitting an invulnerable mob (drones,spores,worms,iceIX,fleas) don't die or lose cycles
|
||||
added JUNK tech: mobs! - summon 20 random mobs
|
||||
added announcement of mob names in console at start of new level
|
||||
|
||||
reduced overall damage done to player by ~6%
|
||||
commodities exchange spawns 5-10 -> 6-12 power ups on cancel
|
||||
residual dipolar coupling spawns 5 -> 6 coupling power ups
|
||||
|
||||
bots maintain relative position to player after the no camera tracking teleport
|
||||
for portals and falling off level
|
||||
|
||||
the once every 7 seconds stuck check now also check to see if you stay stuck for 3 seconds before resetting you.
|
||||
bug fixes
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
grappling hook is a field
|
||||
check for places that the player could get into but not out of
|
||||
maybe grapple could grab more then 1 power up?
|
||||
grapple slices blocks
|
||||
cut large blocks into 2,3
|
||||
use dead mob code for mobs > 5 sides
|
||||
write code to cut large blocks in half and remove one half
|
||||
need several field tech
|
||||
new field tech ideas
|
||||
increase hook damage
|
||||
hook damage aura
|
||||
hook's line does damage
|
||||
make several auto targeting harpoons after taking damage
|
||||
how to make them not drain energy
|
||||
generate ___ after destroying blocks
|
||||
energy, drones, iceIX, explosion, nails, junk bots?
|
||||
coupling effect: defense?, bonus from ammo power ups, fire rate
|
||||
|
||||
tech - killing a mob heals for the last damage you took
|
||||
disable cloaking heal? maybe you don't need to disable, just don't heal twice
|
||||
heal for 50%?
|
||||
heal from mob damage or from kills?
|
||||
|
||||
make phonon the default wave gun type and make a tech to switch to the normal wave beam
|
||||
nerf phonon, buff wave
|
||||
|
||||
sword slash for plasma torch (giving up on this for now, had trouble making graphics look good)
|
||||
activates when mouse is close to player
|
||||
gradual activation
|
||||
sharp cut off
|
||||
use length of torch as cut off length
|
||||
make it look like hollow knight slash
|
||||
what about upgrades to extruder,plasma ball
|
||||
give them their own version of a slash?
|
||||
make a tech that buffs the slash, but it disables extruder,plasma ball
|
||||
|
||||
more (all) bosses need to be made of parts
|
||||
good examples: spiderBoss, dragonFlyBoss, beetleBoss
|
||||
methods:
|
||||
|
||||
Reference in New Issue
Block a user