grappling hook 2nd update
grappling hook
added coupling effect - 4% extra ammo per coupling
doesn't destroy blocks, instead the player grabs blocks
doesn't automatically retract after hitting power ups
improved momentum conservation on yank and catching blocks, power ups
removed accidental 55% defense for grapple field
tech (no images yet)
autonomous defense - fire harpoons at nearby mobs
rupture - explosion on impact with map, block, mob
negative mass field has horizontal block motion by default
fixed tech sorting by "allowed tech" in experiment mode
This commit is contained in:
189
js/bullet.js
189
js/bullet.js
@@ -1484,54 +1484,17 @@ const b = {
|
|||||||
index: 3,
|
index: 3,
|
||||||
isInternal: false
|
isInternal: false
|
||||||
}, {
|
}, {
|
||||||
x: 34,
|
x: 37,
|
||||||
y: 5,
|
y: 3,
|
||||||
index: 4,
|
index: 4,
|
||||||
isInternal: false
|
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,
|
angle: angle,
|
||||||
friction: 1,
|
friction: 1,
|
||||||
frictionAir: 0.4,
|
frictionAir: 0.4,
|
||||||
thrustMag: 0.13,
|
thrustMag: 0.13,
|
||||||
dmg: 6, //damage done in addition to the damage from momentum
|
dmg: 8, //damage done in addition to the damage from momentum
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
endCycle: simulation.cycle + 70,
|
endCycle: simulation.cycle + 70,
|
||||||
isSlowPull: false,
|
isSlowPull: false,
|
||||||
@@ -1543,6 +1506,70 @@ const b = {
|
|||||||
// lookFrequency: Math.floor(7 + Math.random() * 3),
|
// 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
|
density: 0.004, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
|
||||||
drain: 0.001,
|
drain: 0.001,
|
||||||
|
draw() {
|
||||||
|
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||||
|
const sub = Vector.sub(where, this.vertices[0])
|
||||||
|
const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
|
||||||
|
//draw rope
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(where.x, where.y);
|
||||||
|
ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
|
||||||
|
// ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
// if (tech.isHookWire) {
|
||||||
|
// //draw wire
|
||||||
|
// const hitMob = Matter.Query.ray(mob, this.position, m.pos, 10)
|
||||||
|
// if (hitMob.length && m.immuneCycle < m.cycle) {
|
||||||
|
// for (let i = 0; i < hitMob.length; i++) {
|
||||||
|
// console.log(hitMob[i].bodyA)
|
||||||
|
// // simulation.drawList.push({ //add dmg to draw queue
|
||||||
|
// // x: path[path.length - 1].x,
|
||||||
|
// // y: path[path.length - 1].y,
|
||||||
|
// // radius: Math.sqrt(2000 * damage * best.who.damageReduction) + 2,
|
||||||
|
// // color: tech.laserColorAlpha,
|
||||||
|
// // time: simulation.drawTime
|
||||||
|
// // });
|
||||||
|
// hitMob[i].bodyA.damage(0.001)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// //draw glow around wire
|
||||||
|
// ctx.strokeStyle = "rgba(0,255,255,0.2)" // "#0ce"
|
||||||
|
// ctx.lineWidth = 20
|
||||||
|
// ctx.stroke();
|
||||||
|
// }
|
||||||
|
ctx.strokeStyle = "rgba(0,255,255,0.2)" // "#0ce"
|
||||||
|
ctx.lineWidth = 10
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.strokeStyle = "#000" // "#0ce"
|
||||||
|
ctx.lineWidth = 0.5
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//draw harpoon spikes
|
||||||
|
// ctx.beginPath();
|
||||||
|
// ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
|
||||||
|
// // const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), 3))
|
||||||
|
// // ctx.lineTo(spike1.x, spike1.y);
|
||||||
|
// const controlPoint2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), 20))
|
||||||
|
// ctx.quadraticCurveTo(controlPoint2.x, controlPoint2.y, this.vertices[2].x, this.vertices[2].y)
|
||||||
|
// ctx.fillStyle = '#000'
|
||||||
|
// ctx.fill();
|
||||||
|
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
||||||
|
const spikeLength = 2
|
||||||
|
// const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength))
|
||||||
|
// ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
||||||
|
// ctx.lineTo(spike1.x, spike1.y);
|
||||||
|
// ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
|
||||||
|
const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength))
|
||||||
|
ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
||||||
|
ctx.lineTo(spike2.x, spike2.y);
|
||||||
|
ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
|
||||||
|
ctx.fillStyle = '#000'
|
||||||
|
ctx.fill();
|
||||||
|
},
|
||||||
beforeDmg(who) {
|
beforeDmg(who) {
|
||||||
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||||
who.isShielded = false
|
who.isShielded = false
|
||||||
@@ -1565,7 +1592,9 @@ const b = {
|
|||||||
// // this.endCycle = 0;
|
// // this.endCycle = 0;
|
||||||
// }
|
// }
|
||||||
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
|
||||||
|
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||||
this.retract()
|
this.retract()
|
||||||
|
|
||||||
},
|
},
|
||||||
caughtPowerUp: null,
|
caughtPowerUp: null,
|
||||||
dropCaughtPowerUp() {
|
dropCaughtPowerUp() {
|
||||||
@@ -1594,35 +1623,6 @@ const b = {
|
|||||||
this.dropCaughtPowerUp()
|
this.dropCaughtPowerUp()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
draw() {
|
|
||||||
const where = {
|
|
||||||
x: m.pos.x + 30 * Math.cos(m.angle),
|
|
||||||
y: m.pos.y + 30 * Math.sin(m.angle)
|
|
||||||
}
|
|
||||||
const sub = Vector.sub(where, this.vertices[0])
|
|
||||||
const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
|
|
||||||
ctx.strokeStyle = "#000" // "#0ce"
|
|
||||||
ctx.lineWidth = 0.5
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(where.x, where.y);
|
|
||||||
ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
|
|
||||||
// ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
|
|
||||||
ctx.stroke();
|
|
||||||
//draw harpoon spikes
|
|
||||||
const spikeLength = 2
|
|
||||||
ctx.beginPath();
|
|
||||||
const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength))
|
|
||||||
ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
|
||||||
ctx.lineTo(spike1.x, spike1.y);
|
|
||||||
ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
|
|
||||||
|
|
||||||
const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength))
|
|
||||||
ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
|
|
||||||
ctx.lineTo(spike2.x, spike2.y);
|
|
||||||
ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
|
|
||||||
ctx.fillStyle = '#000'
|
|
||||||
ctx.fill();
|
|
||||||
},
|
|
||||||
retract() {
|
retract() {
|
||||||
this.do = this.returnToPlayer
|
this.do = this.returnToPlayer
|
||||||
this.endCycle = simulation.cycle + 60
|
this.endCycle = simulation.cycle + 60
|
||||||
@@ -1630,7 +1630,8 @@ const b = {
|
|||||||
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
|
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
|
this.collisionFilter.mask = 0//cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
|
||||||
//recoil on pulling grapple back
|
//recoil on pulling grapple back
|
||||||
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
|
const mag = this.pickUpTarget ? Math.max(this.pickUpTarget.mass, 0.5) : 0.5
|
||||||
|
const momentum = Vector.mult(Vector.sub(this.position, m.pos), mag * (m.crouch ? 0.0001 : 0.0002))
|
||||||
player.force.x += momentum.x
|
player.force.x += momentum.x
|
||||||
player.force.y += momentum.y
|
player.force.y += momentum.y
|
||||||
},
|
},
|
||||||
@@ -1642,7 +1643,20 @@ const b = {
|
|||||||
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 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.x += momentum.x
|
||||||
player.force.y += momentum.y
|
player.force.y += momentum.y
|
||||||
|
if (this.pickUpTarget) {
|
||||||
|
m.holdingTarget = this.pickUpTarget
|
||||||
|
// give block to player after it returns
|
||||||
|
m.isHolding = true;
|
||||||
|
//conserve momentum when player mass changes
|
||||||
|
totalMomentum = Vector.add(Vector.mult(player.velocity, player.mass), Vector.mult(Vector.normalise(this.velocity), 15 * Math.min(20, this.pickUpTarget.mass)))
|
||||||
|
Matter.Body.setVelocity(player, Vector.mult(totalMomentum, 1 / (m.defaultMass + this.pickUpTarget.mass)));
|
||||||
|
|
||||||
|
m.definePlayerMass(m.defaultMass + this.pickUpTarget.mass * m.holdingMassScale)
|
||||||
|
//make block collide with nothing
|
||||||
|
m.holdingTarget.collisionFilter.category = 0;
|
||||||
|
m.holdingTarget.collisionFilter.mask = 0;
|
||||||
|
this.pickUpTarget = null
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m.energy > this.drain) m.energy -= this.drain
|
if (m.energy > this.drain) m.energy -= this.drain
|
||||||
const sub = Vector.sub(this.position, m.pos)
|
const sub = Vector.sub(this.position, m.pos)
|
||||||
@@ -1651,10 +1665,11 @@ const b = {
|
|||||||
this.force.x -= returnForce.x
|
this.force.x -= returnForce.x
|
||||||
this.force.y -= returnForce.y
|
this.force.y -= returnForce.y
|
||||||
this.grabPowerUp()
|
this.grabPowerUp()
|
||||||
|
this.grabBlocks()
|
||||||
}
|
}
|
||||||
this.draw();
|
this.draw();
|
||||||
},
|
},
|
||||||
destroyBlocks() {
|
destroyBlocks() {//not used?
|
||||||
const blocks = Matter.Query.collides(this, body)
|
const blocks = Matter.Query.collides(this, body)
|
||||||
if (blocks.length && !blocks[0].bodyA.isNotHoldable) {
|
if (blocks.length && !blocks[0].bodyA.isNotHoldable) {
|
||||||
if (blocks[0].bodyA.mass > 2.5) this.retract()
|
if (blocks[0].bodyA.mass > 2.5) this.retract()
|
||||||
@@ -1679,6 +1694,32 @@ const b = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
pickUpTarget: null,
|
||||||
|
grabBlocks() {
|
||||||
|
if (this.pickUpTarget) {
|
||||||
|
//position block on hook
|
||||||
|
Matter.Body.setPosition(this.pickUpTarget, Vector.add(this.vertices[2], this.velocity))
|
||||||
|
Matter.Body.setVelocity(this.pickUpTarget, { x: 0, y: 0 })
|
||||||
|
} else if (!input.down) {
|
||||||
|
const blocks = Matter.Query.collides(this, body)
|
||||||
|
if (blocks.length) {
|
||||||
|
// console.log(blocks)
|
||||||
|
for (let i = 0; i < blocks.length; i++) {
|
||||||
|
if (blocks[i].bodyA.classType === "body" && !blocks[i].bodyA.isNotHoldable && !blocks[0].bodyA.mass < 60) {
|
||||||
|
this.retract()
|
||||||
|
this.pickUpTarget = blocks[i].bodyA
|
||||||
|
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||||
|
} else if (blocks[i].bodyB.classType === "body" && !blocks[i].bodyB.isNotHoldable && !blocks[0].bodyB.mass < 60) {
|
||||||
|
this.retract()
|
||||||
|
this.pickUpTarget = blocks[i].bodyB
|
||||||
|
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (blocks[0].bodyA.mass > 2.5 && blocks[0].bodyA.mass > 15) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
grabPowerUp() { //grab power ups near the tip of the harpoon
|
grabPowerUp() { //grab power ups near the tip of the harpoon
|
||||||
if (this.caughtPowerUp) {
|
if (this.caughtPowerUp) {
|
||||||
Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
|
||||||
@@ -1695,7 +1736,7 @@ const b = {
|
|||||||
powerUp[i].collisionFilter.mask = 0
|
powerUp[i].collisionFilter.mask = 0
|
||||||
this.thrustMag *= 0.6
|
this.thrustMag *= 0.6
|
||||||
this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
|
this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
|
||||||
this.retract()
|
// this.retract()
|
||||||
break //just pull 1 power up if possible
|
break //just pull 1 power up if possible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1706,7 +1747,8 @@ const b = {
|
|||||||
do() {
|
do() {
|
||||||
if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
if (m.fieldCDcycle < m.cycle + 5) m.fieldCDcycle = m.cycle + 5
|
||||||
if (input.field) { //&& !Matter.Query.collides(this, body).length
|
if (input.field) { //&& !Matter.Query.collides(this, body).length
|
||||||
this.destroyBlocks()
|
// this.destroyBlocks()
|
||||||
|
this.grabBlocks()
|
||||||
this.grabPowerUp()
|
this.grabPowerUp()
|
||||||
// if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down field, force retraction
|
// if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down field, force retraction
|
||||||
// this.endCycle = simulation.cycle + 30
|
// this.endCycle = simulation.cycle + 30
|
||||||
@@ -1736,6 +1778,7 @@ const b = {
|
|||||||
if (input.field && Matter.Query.collides(this, map).length) {
|
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) }))
|
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) {
|
if (Matter.Query.collides(this, map).length) {
|
||||||
|
if (tech.isHookExplosion) b.explosion(this.position, 150 + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||||
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
||||||
Matter.Sleeping.set(this, true)
|
Matter.Sleeping.set(this, true)
|
||||||
this.endCycle = simulation.cycle + 5
|
this.endCycle = simulation.cycle + 5
|
||||||
|
|||||||
18
js/engine.js
18
js/engine.js
@@ -204,6 +204,24 @@ function collisionChecks(event) {
|
|||||||
// time: 25
|
// time: 25
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
// if (true) { //fire harpoons at mobs after getting hit
|
||||||
|
// const countMax = 12
|
||||||
|
// let count = countMax
|
||||||
|
// const range = 300
|
||||||
|
// for (let i = 0; i < mob.length; i++) {
|
||||||
|
// if (count > 0 && Vector.magnitude(Vector.sub(m.pos, mob[i].position)) < range) {
|
||||||
|
// count--
|
||||||
|
// if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
|
||||||
|
// const angle = Math.atan2(mob[i].position.y - player.position.y, mob[i].position.x - player.position.x);
|
||||||
|
// b.harpoon(m.pos, mob[i], angle, 0.75, true, 20) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
||||||
|
// for (; count > 0; count--) {
|
||||||
|
// b.harpoon(m.pos, mob[i], count * Math.PI / countMax, 0.75, true, 9) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
||||||
|
// bullet[bullet.length - 1].drain = 0
|
||||||
|
// }
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
if (tech.isStimulatedEmission) powerUps.ejectTech()
|
if (tech.isStimulatedEmission) powerUps.ejectTech()
|
||||||
if (mob[k].onHit) mob[k].onHit();
|
if (mob[k].onHit) mob[k].onHit();
|
||||||
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||||
|
|||||||
28
js/index.js
28
js/index.js
@@ -524,12 +524,10 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
|||||||
if (!aHasKeyword && bHasKeyword) return 1;
|
if (!aHasKeyword && bHasKeyword) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (find === 'guntech') {
|
if (find === 'guntech') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.isGunTech && b.isGunTech) {
|
if (a.isGunTech && b.isGunTech) {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
}
|
}
|
||||||
if (a.isGunTech && !b.isGunTech) return -1; //sort to the top
|
if (a.isGunTech && !b.isGunTech) return -1; //sort to the top
|
||||||
if (!a.isGunTech && b.isGunTech) return 1; //sort to the bottom
|
if (!a.isGunTech && b.isGunTech) return 1; //sort to the bottom
|
||||||
@@ -538,30 +536,30 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
|||||||
} else if (find === 'fieldtech') {
|
} else if (find === 'fieldtech') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.isFieldTech && b.isFieldTech) {
|
if (a.isFieldTech && b.isFieldTech) {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
}
|
}
|
||||||
if (a.isFieldTech && !b.isFieldTech) return -1; //sort to the top
|
if (a.isFieldTech && !b.isFieldTech) return -1; //sort to the top
|
||||||
if (!a.isFieldTech && b.isFieldTech) return 1; //sort to the bottom
|
if (!a.isFieldTech && b.isFieldTech) return 1; //sort to the bottom
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
} else if (find === 'allowed') {
|
} else if (find === 'allowed') {
|
||||||
|
// tech.tech.sort((a, b) => {
|
||||||
|
// if (a.allowed() > !b.allowed()) return -1; //sort to the top
|
||||||
|
// if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
||||||
|
// return 0;
|
||||||
|
// });
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
} else if (find === 'have') {
|
} else if (find === 'have') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.count > b.count) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.count < b.count) return 1; //sort to the bottom
|
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
} else if (find === 'heal') {
|
} else if (find === 'heal') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.isHealTech && b.isHealTech) {
|
if (a.isHealTech && b.isHealTech) {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
}
|
}
|
||||||
if (a.isHealTech && !b.isHealTech) return -1; //sort to the top
|
if (a.isHealTech && !b.isHealTech) return -1; //sort to the top
|
||||||
if (!a.isHealTech && b.isHealTech) return 1; //sort to the bottom
|
if (!a.isHealTech && b.isHealTech) return 1; //sort to the bottom
|
||||||
@@ -570,8 +568,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
|||||||
} else if (find === 'bot') {
|
} else if (find === 'bot') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.isBotTech && b.isBotTech) {
|
if (a.isBotTech && b.isBotTech) {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
}
|
}
|
||||||
if (a.isBotTech && !b.isBotTech) return -1; //sort to the top
|
if (a.isBotTech && !b.isBotTech) return -1; //sort to the top
|
||||||
if (!a.isBotTech && b.isBotTech) return 1; //sort to the bottom
|
if (!a.isBotTech && b.isBotTech) return 1; //sort to the bottom
|
||||||
@@ -580,8 +577,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
|||||||
} else if (document.getElementById("sort-input").value === 'skin') {
|
} else if (document.getElementById("sort-input").value === 'skin') {
|
||||||
tech.tech.sort((a, b) => {
|
tech.tech.sort((a, b) => {
|
||||||
if (a.isSkin && b.isSkin) {
|
if (a.isSkin && b.isSkin) {
|
||||||
if (a.allowed() > b.allowed()) return -1; //sort to the top
|
return (a.allowed() === b.allowed()) ? 0 : a.allowed() ? -1 : 1;
|
||||||
if (!a.allowed() < b.allowed()) return 1; //sort to the bottom
|
|
||||||
}
|
}
|
||||||
if (a.isSkin && !b.isSkin) return -1; //sort to the top
|
if (a.isSkin && !b.isSkin) return -1; //sort to the top
|
||||||
if (!a.isSkin && b.isSkin) return 1; //sort to the bottom
|
if (!a.isSkin && b.isSkin) return 1; //sort to the bottom
|
||||||
|
|||||||
17
js/level.js
17
js/level.js
@@ -19,16 +19,18 @@ const level = {
|
|||||||
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||||
// simulation.isHorizontalFlipped = true
|
// simulation.isHorizontalFlipped = true
|
||||||
// tech.giveTech("performance")
|
// tech.giveTech("performance")
|
||||||
// level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
|
// level.difficultyIncrease(1 * 4) //30 is near max on hard //60 is near max on why
|
||||||
// spawn.setSpawnList();
|
// spawn.setSpawnList();
|
||||||
// spawn.setSpawnList();
|
// spawn.setSpawnList();
|
||||||
// m.maxHealth = m.health = 100
|
// m.maxHealth = m.health = 100
|
||||||
|
// m.maxEnergy = m.energy = 10000000
|
||||||
// tech.isRerollDamage = true
|
// tech.isRerollDamage = true
|
||||||
// powerUps.research.changeRerolls(99999)
|
// powerUps.research.changeRerolls(99999)
|
||||||
// m.immuneCycle = Infinity //you can't take damage
|
// m.immuneCycle = Infinity //you can't take damage
|
||||||
// tech.tech[297].frequency = 100
|
// tech.tech[297].frequency = 100
|
||||||
// m.couplingChange(10)
|
// m.couplingChange(10)
|
||||||
// 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.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
|
||||||
|
// tech.isHookWire = true
|
||||||
// m.energy = 0
|
// m.energy = 0
|
||||||
// simulation.molecularMode = 2
|
// simulation.molecularMode = 2
|
||||||
// m.damage(0.1);
|
// m.damage(0.1);
|
||||||
@@ -36,10 +38,8 @@ const level = {
|
|||||||
// 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.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
|
// b.guns[8].ammo = 100000000
|
||||||
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
|
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("electrostatic induction")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("rupture")
|
||||||
// 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")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("nail-bot upgrade")
|
||||||
// requestAnimationFrame(() => { for (let i = 0; i < 30; i++) tech.giveTech("laser-bot") });
|
// requestAnimationFrame(() => { for (let i = 0; i < 30; i++) tech.giveTech("laser-bot") });
|
||||||
// for (let i = 0; i < 1; i++) tech.giveTech("laser-bot upgrade")
|
// for (let i = 0; i < 1; i++) tech.giveTech("laser-bot upgrade")
|
||||||
@@ -47,11 +47,11 @@ const level = {
|
|||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("mechanical resonance")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("mechanical resonance")
|
||||||
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
||||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
|
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||||
|
|
||||||
// level.testing();
|
// level.testing();
|
||||||
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
// 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 < 5; ++i) spawn.starter(1900, -500)
|
||||||
// for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500)
|
// for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500)
|
||||||
// spawn.beetleBoss(1900, -500, 25)
|
// spawn.beetleBoss(1900, -500, 25)
|
||||||
// spawn.slasher2(2000, -1150)
|
// spawn.slasher2(2000, -1150)
|
||||||
@@ -63,7 +63,8 @@ const level = {
|
|||||||
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
||||||
|
|
||||||
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
|
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
|
||||||
|
// spawn.bodyRect(2425, -120, 200, 200);
|
||||||
|
// console.log(body[body.length - 1].mass)
|
||||||
// simulation.isAutoZoom = false; //look in close
|
// simulation.isAutoZoom = false; //look in close
|
||||||
// simulation.zoomScale *= 0.5;
|
// simulation.zoomScale *= 0.5;
|
||||||
// simulation.setZoom();
|
// simulation.setZoom();
|
||||||
|
|||||||
76
js/player.js
76
js/player.js
@@ -2496,7 +2496,6 @@ const m = {
|
|||||||
// set pick up target for when mouse is released
|
// set pick up target for when mouse is released
|
||||||
if (body[grabbing.targetIndex]) {
|
if (body[grabbing.targetIndex]) {
|
||||||
m.holdingTarget = body[grabbing.targetIndex];
|
m.holdingTarget = body[grabbing.targetIndex];
|
||||||
//
|
|
||||||
ctx.beginPath(); //draw on each valid body
|
ctx.beginPath(); //draw on each valid body
|
||||||
let vertices = m.holdingTarget.vertices;
|
let vertices = m.holdingTarget.vertices;
|
||||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
@@ -2588,6 +2587,8 @@ const m = {
|
|||||||
return `<strong>+${(4 * couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
return `<strong>+${(4 * couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
||||||
case 9: //wormhole
|
case 9: //wormhole
|
||||||
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(2 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
|
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(2 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
|
||||||
|
case 10: //grappling hook
|
||||||
|
return `${powerUps.orb.ammo(1)} give ${(4 * couple).toFixed(0)}% more ammo`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
couplingChange(change = 0) {
|
couplingChange(change = 0) {
|
||||||
@@ -2659,12 +2660,6 @@ const m = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// <div id="cube" style="width: 4em; height: 8em;">
|
|
||||||
// <div style="transform: translate3d(1em, 0em, 0em)">1</div>
|
|
||||||
// <div style="transform: translate3d(2em, 0em, 0em)">2</div>
|
|
||||||
// <div style="transform: translate3d(3em, 0em, 0em)">3</div>
|
|
||||||
// <div style="transform: translate3d(4em, 0em, 0em)">4</div>
|
|
||||||
// </div>
|
|
||||||
{
|
{
|
||||||
name: "standing wave",
|
name: "standing wave",
|
||||||
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
|
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
|
||||||
@@ -3083,7 +3078,20 @@ const m = {
|
|||||||
for (let i = 0, len = who.length; i < len; ++i) {
|
for (let i = 0, len = who.length; i < len; ++i) {
|
||||||
sub = Vector.sub(who[i].position, m.pos);
|
sub = Vector.sub(who[i].position, m.pos);
|
||||||
dist = Vector.magnitude(sub);
|
dist = Vector.magnitude(sub);
|
||||||
if (dist < range) who[i].force.y -= who[i].mass * (simulation.g * mag);
|
if (dist < range) {
|
||||||
|
who[i].force.y -= who[i].mass * (simulation.g * mag); //add a bit more then standard gravity
|
||||||
|
if (input.left) { //blocks move horizontally with the same force as the player
|
||||||
|
who[i].force.x -= m.FxAir * who[i].mass / 10; // move player left / a
|
||||||
|
} else if (input.right) {
|
||||||
|
who[i].force.x += m.FxAir * who[i].mass / 10; //move player right / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// sub = Vector.sub(who[i].position, m.pos);
|
||||||
|
// dist = Vector.magnitude(sub);
|
||||||
|
// if (dist < range) who[i].force.y -= who[i].mass * (simulation.g * mag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//control horizontal acceleration
|
//control horizontal acceleration
|
||||||
@@ -3825,7 +3833,8 @@ const m = {
|
|||||||
}
|
}
|
||||||
if (tech.isRewindField) {
|
if (tech.isRewindField) {
|
||||||
this.rewindCount = 0
|
this.rewindCount = 0
|
||||||
m.grabPowerUpRange2 = 300000
|
m.grabPowerUpRange2 = 300000// m.grabPowerUpRange2 = 200000;
|
||||||
|
|
||||||
m.hold = function () {
|
m.hold = function () {
|
||||||
// console.log(m.fieldCDcycle)
|
// console.log(m.fieldCDcycle)
|
||||||
m.grabPowerUp();
|
m.grabPowerUp();
|
||||||
@@ -4944,25 +4953,64 @@ const m = {
|
|||||||
{
|
{
|
||||||
name: "grappling hook",
|
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 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`,
|
description: `use <strong class='color-f'>energy</strong> to fire a hook that <strong>pulls</strong> player<br><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: () => {
|
effect: () => {
|
||||||
m.fieldFire = true;
|
m.fieldFire = true;
|
||||||
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||||
m.fieldMeterColor = "#333"
|
m.fieldMeterColor = "#333"
|
||||||
m.eyeFillColor = m.fieldMeterColor
|
m.eyeFillColor = m.fieldMeterColor
|
||||||
m.fieldHarmReduction = 0.45; //55% reduction
|
m.grabPowerUpRange2 = 300000 //m.grabPowerUpRange2 = 200000;
|
||||||
|
// m.fieldHarmReduction = 0.45; //55% reduction
|
||||||
|
|
||||||
m.hold = function () {
|
m.hold = function () {
|
||||||
if (input.field) {
|
if (m.isHolding) {
|
||||||
|
m.drawHold(m.holdingTarget);
|
||||||
|
m.holding();
|
||||||
|
m.throwBlock();
|
||||||
|
} else if (input.field) {
|
||||||
|
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
if (m.fieldCDcycle < m.cycle) {
|
if (m.fieldCDcycle < m.cycle) {
|
||||||
if (m.energy > 0.02) m.energy -= 0.02
|
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({ x: m.pos.x + 40 * Math.cos(m.angle), y: m.pos.y + 40 * Math.sin(m.angle) }, m.angle)
|
||||||
b.grapple(where, m.angle)
|
|
||||||
if (m.fieldCDcycle < m.cycle + 20) m.fieldCDcycle = m.cycle + 20
|
if (m.fieldCDcycle < m.cycle + 20) m.fieldCDcycle = m.cycle + 20
|
||||||
}
|
}
|
||||||
m.grabPowerUp();
|
m.grabPowerUp();
|
||||||
|
} else {
|
||||||
|
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
|
if (tech.isHookDefense && m.energy > 0.33 && m.fieldCDcycle < m.cycle) {
|
||||||
|
const maxCount = 6 //scale the number of hooks fired
|
||||||
|
let count = maxCount
|
||||||
|
const range = 300
|
||||||
|
for (let i = 0; i < mob.length; i++) {
|
||||||
|
if (!mob[i].isBadTarget &&
|
||||||
|
!mob[i].isInvulnerable &&
|
||||||
|
Vector.magnitude(Vector.sub(m.pos, mob[i].position)) < range &&
|
||||||
|
Matter.Query.ray(map, m.pos, mob[i].position).length === 0
|
||||||
|
) {
|
||||||
|
count--
|
||||||
|
m.energy -= 0.2
|
||||||
|
if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
|
||||||
|
const angle = Math.atan2(mob[i].position.y - player.position.y, mob[i].position.x - player.position.x);
|
||||||
|
b.harpoon(m.pos, mob[i], angle, 0.75, true, 20) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
|
||||||
|
bullet[bullet.length - 1].drain = 0
|
||||||
|
for (; count > 0; count--) {
|
||||||
|
b.harpoon(m.pos, mob[i], angle + count * 2 * Math.PI / maxCount, 0.75, true, 10)
|
||||||
|
bullet[bullet.length - 1].drain = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.pos.x, m.pos.y, range, 0, 2 * Math.PI);
|
||||||
|
ctx.strokeStyle = "#000";
|
||||||
|
ctx.lineWidth = 0.25;
|
||||||
|
ctx.setLineDash([10, 30]);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m.drawRegenEnergy()
|
m.drawRegenEnergy()
|
||||||
|
//look for nearby mobs and fire harpoons at them
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -621,17 +621,18 @@ const powerUps = {
|
|||||||
return 17;
|
return 17;
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
|
const couplingExtraAmmo = m.fieldMode === 10 ? 1 + 0.04 * m.coupling : 1
|
||||||
if (b.inventory.length > 0) {
|
if (b.inventory.length > 0) {
|
||||||
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
|
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
|
||||||
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
|
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
|
||||||
const target = b.guns[b.activeGun]
|
const target = b.guns[b.activeGun]
|
||||||
if (target.ammo !== Infinity) {
|
if (target.ammo !== Infinity) {
|
||||||
if (tech.ammoCap) {
|
if (tech.ammoCap) {
|
||||||
const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap * 0.8) //0.7 is average
|
const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap * 0.8 * couplingExtraAmmo) //0.7 is average
|
||||||
target.ammo = ammoAdded
|
target.ammo = ammoAdded
|
||||||
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}`)
|
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}`)
|
||||||
} else {
|
} else {
|
||||||
const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack * 0.8)
|
const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack * 0.8 * couplingExtraAmmo)
|
||||||
target.ammo += ammoAdded
|
target.ammo += ammoAdded
|
||||||
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`)
|
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`)
|
||||||
}
|
}
|
||||||
@@ -642,11 +643,12 @@ const powerUps = {
|
|||||||
const target = b.guns[b.inventory[i]]
|
const target = b.guns[b.inventory[i]]
|
||||||
if (target.ammo !== Infinity) {
|
if (target.ammo !== Infinity) {
|
||||||
if (tech.ammoCap) {
|
if (tech.ammoCap) {
|
||||||
const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average
|
const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap * couplingExtraAmmo) //0.45 is average
|
||||||
target.ammo = ammoAdded
|
target.ammo = ammoAdded
|
||||||
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}<br>`
|
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}<br>`
|
||||||
} else {
|
} else { //default ammo behavior
|
||||||
const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack)
|
const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack * couplingExtraAmmo) //Math.ceil(Math.random() * target.ammoPack)
|
||||||
|
// console.log(ammoAdded, Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack))
|
||||||
target.ammo += ammoAdded
|
target.ammo += ammoAdded
|
||||||
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}<br>`
|
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}<br>`
|
||||||
}
|
}
|
||||||
@@ -1270,24 +1272,25 @@ const powerUps = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < localSettings.entanglement.techIndexes.length; i++) { //add tech
|
for (let i = 0; i < localSettings.entanglement.techIndexes.length; i++) { //add tech
|
||||||
let choose = localSettings.entanglement.techIndexes[i]
|
let choose = localSettings.entanglement.techIndexes[i]
|
||||||
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
|
if (tech.tech[choose]) {
|
||||||
|
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
|
||||||
if (choose === null || tech.tech[choose].count + 1 > tech.tech[choose].maxCount || !tech.tech[choose].allowed()) {
|
if (choose === null || tech.tech[choose].count + 1 > tech.tech[choose].maxCount || !tech.tech[choose].allowed()) {
|
||||||
// text += `<div class="choose-grid-module" style = "background-color: #efeff5; border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[choose].name} <span style = "color: #aaa;font-weight: normal;font-size:80%;">- incoherent</span></div></div>`
|
// text += `<div class="choose-grid-module" style = "background-color: #efeff5; border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[choose].name} <span style = "color: #aaa;font-weight: normal;font-size:80%;">- incoherent</span></div></div>`
|
||||||
text += powerUps.incoherentTechText(choose)
|
text += powerUps.incoherentTechText(choose)
|
||||||
} else {
|
} else {
|
||||||
if (tech.tech[choose].isFieldTech) {
|
if (tech.tech[choose].isFieldTech) {
|
||||||
text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`)
|
text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||||
} else if (tech.tech[choose].isGunTech) {
|
} else if (tech.tech[choose].isGunTech) {
|
||||||
text += powerUps.gunTechText(choose, `powerUps.choose('tech',${choose})`)
|
text += powerUps.gunTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||||
} else if (tech.tech[choose].isLore) {
|
} else if (tech.tech[choose].isLore) {
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title lore-text"><div class="circle-grid lore"></div> ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title lore-text"><div class="circle-grid lore"></div> ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
|
||||||
} else if (tech.tech[choose].isJunk) {
|
} else if (tech.tech[choose].isJunk) {
|
||||||
text += powerUps.junkTechText(choose, `powerUps.choose('tech',${choose})`)
|
text += powerUps.junkTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||||
} else if (tech.tech[choose].isSkin) {
|
} else if (tech.tech[choose].isSkin) {
|
||||||
text += powerUps.skinTechText(choose, `powerUps.choose('tech',${choose})`)
|
text += powerUps.skinTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||||
} else { //normal tech
|
} else { //normal tech
|
||||||
text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`)
|
text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
89
js/tech.js
89
js/tech.js
@@ -4545,7 +4545,7 @@ const tech = {
|
|||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles
|
return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles || tech.isHookDefense
|
||||||
},
|
},
|
||||||
requires: "needle gun, harpoon, not Bessemer process",
|
requires: "needle gun, harpoon, not Bessemer process",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -5149,7 +5149,7 @@ const tech = {
|
|||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isSuperBounce) || (tech.haveGunCheck("harpoon") && !tech.fragments)
|
return ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isSuperBounce) || (tech.haveGunCheck("harpoon") && !tech.fragments) || tech.isHookDefense
|
||||||
},
|
},
|
||||||
requires: "super balls, harpoon, not fragmentation",
|
requires: "super balls, harpoon, not fragmentation",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -5574,7 +5574,7 @@ const tech = {
|
|||||||
frequency: 1,
|
frequency: 1,
|
||||||
frequencyDefault: 1,
|
frequencyDefault: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isExplodeRadio && ((tech.haveGunCheck("harpoon") && !tech.isFoamBall) || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075)
|
return !tech.isExplodeRadio && ((tech.haveGunCheck("harpoon") && !tech.isFoamBall) || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075 || tech.isHookDefense)
|
||||||
},
|
},
|
||||||
requires: "grenades, missiles, rivets, harpoon, or mass driver, not iridium-192, not polyurethane foam",
|
requires: "grenades, missiles, rivets, harpoon, or mass driver, not iridium-192, not polyurethane foam",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -7784,7 +7784,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inertial mass",
|
name: "inertial mass",
|
||||||
description: "<strong>negative mass</strong> is larger and <strong>faster</strong><br><strong class='color-block'>blocks</strong> also move <strong>horizontally</strong> with the field",
|
description: "<strong>negative mass</strong> is larger and <strong>faster</strong>", //<br><strong class='color-block'>blocks</strong> also move <strong>horizontally</strong> with the field
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8052,7 +8052,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "electric generator",
|
name: "electric generator",
|
||||||
description: "after <strong>deflecting</strong> mobs<br>molecular assembler generates <strong>+50</strong> <strong class='color-f'>energy</strong>",
|
description: "after <strong>deflecting</strong> mobs<br><strong>molecular assembler</strong> generates <strong>+50</strong> <strong class='color-f'>energy</strong>",
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -8754,6 +8754,82 @@ const tech = {
|
|||||||
tech.isWormholeMapIgnore = false
|
tech.isWormholeMapIgnore = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "autonomous defense",
|
||||||
|
description: "<strong>grappling hook</strong> uses <strong>20</strong> <strong class='color-f'>energy</strong><br> to fire <strong>harpoons</strong> at nearby mobs",
|
||||||
|
isFieldTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return m.fieldMode === 10
|
||||||
|
},
|
||||||
|
requires: "grappling hook",
|
||||||
|
effect() {
|
||||||
|
tech.isHookDefense = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isHookDefense = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "rupture",
|
||||||
|
description: "after <strong>grappling hook</strong> impacts solid objects<br>generate an <strong class='color-e'>explosion</strong>",
|
||||||
|
isFieldTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 2,
|
||||||
|
frequencyDefault: 2,
|
||||||
|
allowed() {
|
||||||
|
return m.fieldMode === 10
|
||||||
|
},
|
||||||
|
requires: "grappling hook",
|
||||||
|
effect() {
|
||||||
|
tech.isHookExplosion = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isHookExplosion = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: "autonomous defense",
|
||||||
|
// description: "if you <strong>collide</strong> with a mob<br>fire <strong>harpoons</strong> at nearby mobs",
|
||||||
|
// isFieldTech: true,
|
||||||
|
// maxCount: 1,
|
||||||
|
// count: 0,
|
||||||
|
// frequency: 2,
|
||||||
|
// frequencyDefault: 2,
|
||||||
|
// allowed() {
|
||||||
|
// return m.fieldMode === 10 && !tech.isHookDefense
|
||||||
|
// },
|
||||||
|
// requires: "grappling hook, not automatic offense",
|
||||||
|
// effect() {
|
||||||
|
// tech.isHookDefense = true
|
||||||
|
// },
|
||||||
|
// remove() {
|
||||||
|
// tech.isHookDefense = false
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: "wire",
|
||||||
|
// description: "",
|
||||||
|
// isFieldTech: true,
|
||||||
|
// maxCount: 1,
|
||||||
|
// count: 0,
|
||||||
|
// frequency: 2,
|
||||||
|
// frequencyDefault: 2,
|
||||||
|
// allowed() {
|
||||||
|
// return m.fieldMode === 10
|
||||||
|
// },
|
||||||
|
// requires: "grappling hook",
|
||||||
|
// effect() {
|
||||||
|
// tech.isHookWire = true
|
||||||
|
// },
|
||||||
|
// remove() {
|
||||||
|
// tech.isHookWire = false
|
||||||
|
// }
|
||||||
|
// },
|
||||||
//**************************************************
|
//**************************************************
|
||||||
//************************************************** experimental
|
//************************************************** experimental
|
||||||
//************************************************** modes
|
//************************************************** modes
|
||||||
@@ -11800,4 +11876,7 @@ const tech = {
|
|||||||
isHealBrake: null,
|
isHealBrake: null,
|
||||||
isMassProduction: null,
|
isMassProduction: null,
|
||||||
isPrinter: null,
|
isPrinter: null,
|
||||||
|
// isHookWire: null,
|
||||||
|
isHookDefense: null,
|
||||||
|
isHookExplosion: null,
|
||||||
}
|
}
|
||||||
46
todo.txt
46
todo.txt
@@ -1,39 +1,29 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
grappling hook is now a field (work in progress)
|
grappling hook
|
||||||
reworked physics to allow faster speeds, but more control
|
added coupling effect - 4% extra ammo per coupling
|
||||||
improved rate of power up grabbing
|
doesn't destroy blocks, instead the player grabs blocks
|
||||||
more player control to hook retraction rate
|
doesn't automatically retract after hitting power ups
|
||||||
changed hook shape and field image graphics
|
improved momentum conservation on yank and catching blocks, power ups
|
||||||
grappling hook field coupling, more tech, bug fixes, and general polish to be added soon
|
removed accidental 55% defense for grapple field
|
||||||
|
tech (no images yet)
|
||||||
|
autonomous defense - fire harpoons at nearby mobs
|
||||||
|
rupture - explosion on impact with map, block, mob
|
||||||
|
|
||||||
aerostat - 88->100% damage in air 22-> 25% damage on ground
|
negative mass field has horizontal block motion by default
|
||||||
foam damage reduced 10%, ammo increased about 10%
|
fixed tech sorting by "allowed tech" in experiment mode
|
||||||
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
|
|
||||||
|
|
||||||
*********************************************************** TODO *****************************************************
|
*********************************************************** TODO *****************************************************
|
||||||
|
|
||||||
grappling hook is a field
|
grappling hook is a field
|
||||||
check for places that the player could get into but not out of
|
check for places that the player could get into but not out of
|
||||||
maybe grapple could grab more then 1 power up?
|
field tech ideas
|
||||||
grapple slices blocks
|
hook and line stuns?
|
||||||
cut large blocks into 2,3
|
increase hook damage
|
||||||
use dead mob code for mobs > 5 sides
|
hook damage aura
|
||||||
write code to cut large blocks in half and remove one half
|
hook's line does damage
|
||||||
need several field tech
|
generate ___ after destroying blocks
|
||||||
new field tech ideas
|
energy, drones, iceIX, explosion, nails, junk bots?
|
||||||
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
|
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
|
disable cloaking heal? maybe you don't need to disable, just don't heal twice
|
||||||
|
|||||||
Reference in New Issue
Block a user