mines are even more sticky, fixed quantum immortality

This commit is contained in:
landgreen
2020-01-12 11:05:47 -08:00
parent 69b7035a0b
commit c6afd8982c
5 changed files with 161 additions and 159 deletions

View File

@@ -31,7 +31,7 @@ const b = {
modNailBotCount: null,
modCollisionImmuneCycles: null,
modBlockDmg: null,
modPiezo: null,
isModPiezo: null,
setModDefaults() {
b.modCount = 0;
b.modFireRate = 1;
@@ -60,7 +60,7 @@ const b = {
b.modNailBotCount = 0;
b.modCollisionImmuneCycles = 30;
b.modBlockDmg = 0;
b.modPiezo = 0;
b.isModPiezo = false;
mech.Fx = 0.015;
mech.jumpForce = 0.38;
mech.maxHealth = 1;
@@ -262,11 +262,12 @@ const b = {
},
{
name: "piezoelectricity", //17
description: "after <strong>colliding</strong> with enemies gain 50% <strong class='color-f'>energy</strong>",
description: "<strong>colliding</strong> with enemies fills your <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
effect() {
b.modPiezo = 0.50
b.isModPiezo = true;
mech.fieldMeter = mech.fieldEnergyMax;
}
},
{
@@ -355,6 +356,7 @@ const b = {
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
}
b.setModDefaults(); // remove all mods
//have state is checked in mech.death()
}
},
{
@@ -714,8 +716,134 @@ const b = {
}
}
}
},
mine(where, velocity, angle = 0) {
const bIndex = bullet.length;
bullet[bIndex] = Bodies.rectangle(where.x, where.y, 45 * b.modBulletSize, 16 * b.modBulletSize, {
angle: angle,
friction: 1,
frictionAir: 0,
restitution: 0,
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet
},
minDmgSpeed: 5,
stillCount: 0,
isArmed: false,
endCycle: game.cycle + 2000 + 360 * Math.random(),
lookFrequency: 41 + Math.floor(23 * Math.random()),
range: 700,
onDmg() {},
do() {
this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) {
// console.log(collide)
const angle = Matter.Vector.angle(collide[i].normal, {
x: 1,
y: 0
})
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation
for (let j = 0; j < 10; j++) {
if (Matter.Query.collides(this, map).length > 0) {
Matter.Body.setStatic(this, true) //don't set to static if not touching map
this.arm();
// Vector.magnitudeSquared(Vector.sub(bullet[me].position, mob[i].position))
//sometimes the mine can't attach to map and it just needs to explode
const that = this
setTimeout(function () {
if (Matter.Query.collides(that, map).length === 0) {
that.endCycle = 0 // if not touching map explode
that.isArmed = false
b.mine(that.position, that.velocity, that.angle)
}
}, 100, that);
break
}
//move until you are touching the wall
Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2)))
}
} else if (this.speed < 1 && this.angularSpeed < 0.01 && !mech.isBodiesAsleep) {
this.stillCount += 2
}
}
}
} else {
if (this.speed < 1 && this.angularSpeed < 0.01 && !mech.isBodiesAsleep) {
this.stillCount++
}
}
if (this.stillCount > 35) this.arm();
},
arm() {
this.isArmed = true
game.drawList.push({
//add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: 10,
color: "#f00",
time: 4
});
this.do = function () { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity
if (!(game.cycle % this.lookFrequency)) { //find mob targets
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 &&
mob[i].dropPowerUp &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
this.endCycle = 0 //end life if mob is near and visible
}
}
}
}
},
onEnd() {
if (this.isArmed) {
const targets = [] //target nearby mobs
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].dropPowerUp) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
if (dist < 1440000 && //1200*1200
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
}
}
}
for (let i = 0; i < 16; i++) {
const speed = 53 + 10 * Math.random()
if (targets.length > 0) { // aim near a random target in array
const index = Math.floor(Math.random() * targets.length)
const SPREAD = 150 / targets.length
const WHERE = {
x: targets[index].x + SPREAD * (Math.random() - 0.5),
y: targets[index].y + SPREAD * (Math.random() - 0.5)
}
b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1)
} else { // aim in random direction
const ANGLE = 2 * Math.PI * Math.random()
b.nail(this.position, {
x: speed * Math.cos(ANGLE),
y: speed * Math.sin(ANGLE)
})
}
}
}
}
});
bullet[bIndex].torque += bullet[bIndex].inertia * 0.0001 * (0.5 - Math.random())
Matter.Body.setVelocity(bullet[bIndex], velocity);
World.add(engine.world, bullet[bIndex]); //add bullet to world
},
spore(who) { //used with the mod upgrade in mob.death()
const bIndex = bullet.length;
@@ -1730,153 +1858,21 @@ const b = {
}
}, {
name: "mine", //10
description: "drop a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>fires <strong>nails</strong> at enemies within range",
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>fires <strong>nails</strong> at enemies within range",
ammo: 0,
ammoPack: 4,
ammoPack: 3,
have: false,
isStarterGun: false,
fire() {
const me = bullet.length;
const dir = mech.angle;
if (mech.crouch) {
bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 45 * b.modBulletSize, 16 * b.modBulletSize, {
angle: 0,
friction: 1,
frictionAir: 0,
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet
},
minDmgSpeed: 5,
onDmg() {},
onEnd() {}
});
mech.fireCDcycle = mech.cycle + Math.floor(35 * b.modFireRate); // cool down
Matter.Body.setVelocity(bullet[me], {
x: mech.Vx / 2 + 26 * Math.cos(dir),
y: mech.Vy / 2 + 26 * Math.sin(dir)
});
bullet[me].torque += bullet[me].inertia * 0.0001 * (0.5 - Math.random())
} else {
bullet[me] = Bodies.rectangle(mech.pos.x, mech.pos.y + 25, 45 * b.modBulletSize, 16 * b.modBulletSize, {
angle: 0,
friction: 1,
frictionAir: 0,
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet
},
minDmgSpeed: 5,
onDmg() {},
onEnd() {}
});
mech.fireCDcycle = mech.cycle + Math.floor(20 * b.modFireRate); // cool down
Matter.Body.setVelocity(bullet[me], {
x: mech.Vx,
y: mech.Vy
});
}
World.add(engine.world, bullet[me]); //add bullet to world
bullet[me].endCycle = game.cycle + 2000 + 360 * Math.random();
bullet[me].restitution = 0;
bullet[me].lookFrequency = 41 + Math.floor(23 * Math.random())
bullet[me].range = 700
bullet[me].arm = function () {
this.do = function () { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity
if (!(game.cycle % this.lookFrequency)) { //find mob targets
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 &&
mob[i].dropPowerUp &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
this.endCycle = 0 //end life if mob is near and visible
}
}
}
}
}
bullet[me].do = function () {
this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) {
// console.log(collide)
const angle = Matter.Vector.angle(collide[i].normal, {
x: 1,
y: 0
})
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation
for (let j = 0; j < 10; j++) {
if (Matter.Query.collides(this, map).length > 0) {
Matter.Body.setStatic(this, true) //don't set to static if not touching map
this.arm();
//sometimes the mine can't attach to map and it just needs to explode
const who = this
setTimeout(function () {
if (Matter.Query.collides(who, map).length === 0) who.endCycle = 0 // if not touching map explode
}, 100, who);
break
}
//move until you are touching the wall
Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2)))
}
} else if (this.speed < 1) {
this.arm();
}
}
}
} else if (this.speed < 1) { //check if collides with a body
collide = Matter.Query.collides(this, body)
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.body || collide[i].bodyB.collisionFilter.category === cat.body) {
this.arm();
}
}
}
}
}
bullet[me].onEnd = function () {
const targets = [] //target nearby mobs
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].dropPowerUp) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
if (dist < 1440000 && //1200*1200
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
}
}
}
for (let i = 0; i < 16; i++) {
const speed = 53 + 10 * Math.random()
if (targets.length > 0) { // aim near a random target in array
const index = Math.floor(Math.random() * targets.length)
const SPREAD = 150 / targets.length
const WHERE = {
x: targets[index].x + SPREAD * (Math.random() - 0.5),
y: targets[index].y + SPREAD * (Math.random() - 0.5)
}
b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 0.8)
} else { // aim in random direction
const ANGLE = 2 * Math.PI * Math.random()
b.nail(this.position, {
x: speed * Math.cos(ANGLE),
y: speed * Math.sin(ANGLE)
})
}
}
}
const speed = mech.crouch ? 34 : 20
b.mine({
x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 30 * Math.sin(mech.angle)
}, {
x: speed * Math.cos(mech.angle),
y: speed * Math.sin(mech.angle)
})
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 60 : 40) * b.modFireRate); // cool down
}
},
{

View File

@@ -138,7 +138,7 @@ function collisionChecks(event) {
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
mech.damage(dmg);
if (mob[k].onHit) mob[k].onHit(k);
mech.fieldMeter += b.modPiezo
if (b.isModPiezo) mech.fieldMeter = mech.fieldEnergyMax;
if (b.isModAnnihilation && mob[k].dropPowerUp && !mob[k].isShielded) {
mob[k].death();
game.drawList.push({

View File

@@ -4,13 +4,6 @@
add setting for random drops instead of choosing
mines: move targeting position to be perpendicular to stuck wall
mines change shape of mine (maybe a octagon?)
mines: collide with bots
probably don't have to fix...
mines: add high friction, like vacuum bomb and trigger static mode after not moving for a bit
no need to watch collisions
rework custom mode
custom mode grey out mods that are bad, like selection based mods
enable recursive mods

View File

@@ -14,7 +14,7 @@ const level = {
start() {
if (level.levelsCleared === 0) {
// game.difficulty = 6; //for testing to simulate possible mobs spawns
b.giveGuns(10)
// b.giveGuns(10)
// mech.setField(3)
// b.giveMod(3);
@@ -1569,7 +1569,17 @@ const level = {
}
},
levelAnnounce() {
document.title = "n-gon: L" + (level.levelsCleared) + " " + level.levels[level.onLevel];
let mode = document.getElementById("difficulty-select").value
if (mode === "0") {
mode = "(easy)"
} else if (mode === "1") {
mode = "(normal)"
} else if (mode === "2") {
mode = "(hard)"
} else if (mode === "6") {
mode = "(why)"
}
document.title = "n-gon: L" + (level.levelsCleared) + " " + level.levels[level.onLevel] + " " + mode;
// game.makeTextLog(`<div style='font-size: 25px;'>level ${game.difficulty} </div> <div style='font-size: 32px;'>${level.levels[level.onLevel]} </div>`, 300);
// if (game.difficulty === 0) text = "";
// text = "Level " + (game.difficulty + 1) + ": " + spawn.pickList[0] + "s + " + spawn.pickList[1] + "s";

View File

@@ -307,13 +307,16 @@ const mech = {
function randomizeMods() {
b.setModDefaults(); //remove all mods
//remove all bullets
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
for (let i = 0; i < totalMods; i++) {
//find what mods I don't have
let options = [];
for (let i = 0, len = b.mods.length; i < len; i++) {
//can't get quantum immortality or multiverse
if (b.mods[i].name !== "quantum immortality" &&
b.mods[i].name !== "level II multiverse" &&
b.mods[i].name !== "Born rule" &&
b.mods[i].count < b.mods[i].maxCount) options.push(i);
}
//add a new mod