incendiary ammunition

bug - spider boss move at full speed again (watch out)
bots that uses energy stop when you hit 50% energy if you have mass-energy mod

you get a warning before you overwrite your current gun due to integrated armament

gun - flak is removed
mod: High-explosive incendiary, or incendiary rounds
  shotgun: several large explosions
  nail gun: rapid fire explosions
  drones: drones explode on impact
  super balls: explode on contact
This commit is contained in:
landgreen
2020-11-14 05:37:27 -08:00
parent 72e61eab78
commit 6e90ed2376
9 changed files with 876 additions and 869 deletions

View File

@@ -928,17 +928,22 @@ const b = {
deathCycles: 110 + RADIUS * 5,
isImproved: false,
beforeDmg(who) {
//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
});
if (mod.isIncendiary) {
b.explosion(this.position, 120 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
this.endCycle = 0
} else {
//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
if (this.endCycle > game.cycle + this.deathCycles) {
this.endCycle -= 60
if (game.cycle + this.deathCycles > this.endCycle) this.endCycle = game.cycle + this.deathCycles
this.lockedOn = null
if (this.endCycle > game.cycle + this.deathCycles) {
this.endCycle -= 60
if (game.cycle + this.deathCycles > this.endCycle) this.endCycle = game.cycle + this.deathCycles
}
}
},
onEnd() {},
@@ -1377,6 +1382,7 @@ const b = {
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 40 + Math.floor(7 * Math.random()),
drainThreshold: mod.isEnergyHealth ? 0.5 : 0.15,
acceleration: 0.0015 * (1 + 0.3 * Math.random()),
range: 700 * (1 + 0.1 * Math.random()) + 250 * mod.isLaserBotUpgrade,
followRange: 150 + Math.floor(30 * Math.random()),
@@ -1430,47 +1436,9 @@ const b = {
}
}
//hit target with laser
if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) {
if (this.lockedOn && this.lockedOn.alive && mech.energy > this.drainThreshold) {
mech.energy -= 0.0012 * mod.isLaserDiode
// const sub = Vector.sub(this.lockedOn.position, this.vertices[0])
// const angle = Math.atan2(sub.y, sub.x);
b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.06 + 0.1 * this.isUpgraded))
// //make sure you can still see vertex
// const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position));
// if (DIST - this.lockedOn.radius < this.range + 150 &&
// Matter.Query.ray(map, this.vertices[0], this.lockedOn.position).length === 0 &&
// Matter.Query.ray(body, this.vertices[0], this.lockedOn.position).length === 0) {
// //move towards the target
// this.force = Vector.add(this.force, Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), 0.0013))
// //find the closest vertex
// let bestVertexDistance = Infinity
// let bestVertex = null
// for (let i = 0; i < this.lockedOn.vertices.length; i++) {
// const dist = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.vertices[i]));
// if (dist < bestVertexDistance) {
// bestVertex = i
// bestVertexDistance = dist
// }
// }
// const dmg = b.dmgScale * (0.06 + 0.08 * this.isUpgraded);
// this.lockedOn.damage(dmg);
// this.lockedOn.locatePlayer();
// ctx.beginPath(); //draw laser
// ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
// ctx.lineTo(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y);
// ctx.strokeStyle = "#f00";
// ctx.lineWidth = "2"
// ctx.lineDashOffset = 300 * Math.random()
// ctx.setLineDash([50 + 100 * Math.random(), 100 * Math.random()]);
// ctx.stroke();
// ctx.setLineDash([0, 0]);
// ctx.beginPath();
// ctx.arc(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI);
// ctx.fillStyle = "#f00";
// ctx.fill();
// }
}
}
})
@@ -1571,6 +1539,7 @@ const b = {
cd: 0,
acceleration: 0.009,
endCycle: Infinity,
drainThreshold: mod.isEnergyHealth ? 0.5 : 0.15,
classType: "bullet",
collisionFilter: {
category: cat.bullet,
@@ -1608,9 +1577,8 @@ const b = {
const sub = Vector.sub(this.lockedOn.position, this.position)
const DIST = Vector.magnitude(sub);
const unit = Vector.normalise(sub)
const DRAIN = 0.0012
if (DIST < mod.isPlasmaRange * 450 && mech.energy > DRAIN) {
mech.energy -= DRAIN;
if (DIST < mod.isPlasmaRange * 450 && mech.energy > this.drainThreshold) {
mech.energy -= 0.0012;
if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
@@ -1904,27 +1872,58 @@ const b = {
mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down
const speed = 30 + 6 * Math.random() + 9 * mod.nailInstantFireRate
const angle = mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD
const dmg = 0.9
b.nail({
x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 30 * Math.sin(mech.angle)
}, {
x: mech.Vx / 2 + speed * Math.cos(angle),
y: mech.Vy / 2 + speed * Math.sin(angle)
}, dmg) //position, velocity, damage
if (mod.isIceCrystals) {
bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 30)
if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
if (mod.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center
};
if (mod.isIncendiary) {
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 25, 2, {
density: 0.0001, //frictionAir: 0.01, //restitution: 0,
angle: angle,
friction: 0.5,
frictionAir: 0,
dmg: 0, //damage done in addition to the damage from momentum
endCycle: Math.floor(mech.crouch ? 28 : 13) + Math.random() * 5 + game.cycle,
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 10,
beforeDmg() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
},
onEnd() {
b.explosion(this.position, 72 + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end
},
do() {}
});
Matter.Body.setVelocity(bullet[me], {
x: speed * Math.cos(angle),
y: speed * Math.sin(angle)
});
World.add(engine.world, bullet[me]); //add bullet to world
} else {
const dmg = 0.9
b.nail({
x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 30 * Math.sin(mech.angle)
}, {
x: mech.Vx / 2 + speed * Math.cos(angle),
y: mech.Vy / 2 + speed * Math.sin(angle)
}, dmg) //position, velocity, damage
if (mod.isIceCrystals) {
bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 30)
if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
if (mod.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center
};
if (mech.energy < 0.01) {
mech.fireCDcycle = mech.cycle + 60; // cool down
} else {
mech.energy -= mech.fieldRegen + 0.009
if (mech.energy < 0.01) {
mech.fireCDcycle = mech.cycle + 60; // cool down
} else {
mech.energy -= mech.fieldRegen + 0.009
}
}
}
}
},
{
@@ -1958,7 +1957,57 @@ const b = {
}
b.muzzleFlash(35);
if (mod.isNailShot) {
if (mod.isIncendiary) {
const SPEED = mech.crouch ? 35 : 25
const END = Math.floor(mech.crouch ? 9 : 6);
const totalBullets = 8
const angleStep = (mech.crouch ? 0.1 : 0.33) / totalBullets
let dir = mech.angle - angleStep * totalBullets / 2;
for (let i = 0; i < totalBullets; i++) { //5 -> 7
dir += angleStep
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 17, 4, b.fireAttributes(dir));
const end = END + Math.random() * 3
bullet[me].endCycle = 2 * end + game.cycle
const speed = SPEED * end / END
const dirOff = dir + 0.15 * (Math.random() - 0.5)
Matter.Body.setVelocity(bullet[me], {
x: speed * Math.cos(dirOff),
y: speed * Math.sin(dirOff)
});
bullet[me].onEnd = function() {
b.explosion(this.position, 60 + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
};
bullet[me].do = function() {}
World.add(engine.world, bullet[me]); //add bullet to world
}
// for (let i = 0; i < totalBullets; i++) { //5 -> 7
// dir += angleStep
// const me = bullet.length;
// bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 17, 4, b.fireAttributes(dir));
// World.add(engine.world, bullet[me]); //add bullet to world
// Matter.Body.setVelocity(bullet[me], {
// x: (SPEED + 15 * Math.random() - 2 * i) * Math.cos(dir),
// y: (SPEED + 15 * Math.random() - 2 * i) * Math.sin(dir)
// });
// bullet[me].endCycle = 2 * i + END
// bullet[me].restitution = 0;
// bullet[me].friction = 1;
// bullet[me].onEnd = function() {
// b.explosion(this.position, (mech.crouch ? 95 : 75) + (Math.random() - 0.5) * 50); //makes bullet do explosive damage at end
// }
// bullet[me].beforeDmg = function() {
// this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
// };
// bullet[me].do = function() {
// // this.force.y += this.mass * 0.0004;
// }
// }
} else if (mod.isNailShot) {
for (let i = 0; i < 14; i++) {
const dir = mech.angle + (Math.random() - 0.5) * spread * 0.2
const pos = {
@@ -2349,48 +2398,48 @@ const b = {
}
}
},
{
name: "flak",
description: "fire a <strong>cluster</strong> of short range <strong>projectiles</strong><br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after half a second",
ammo: 0,
ammoPack: 4,
defaultAmmoPack: 4, //use to revert ammoPack after mod changes drop rate
have: false,
fire() {
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down
b.muzzleFlash(30);
const SPEED = mech.crouch ? 29 : 25
const END = Math.floor(mech.crouch ? 30 : 18);
const side1 = 17
const side2 = 4
const totalBullets = 6
const angleStep = (mech.crouch ? 0.06 : 0.25) / totalBullets
let dir = mech.angle - angleStep * totalBullets / 2;
for (let i = 0; i < totalBullets; i++) { //5 -> 7
dir += angleStep
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), side1, side2, b.fireAttributes(dir));
World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: (SPEED + 15 * Math.random() - 2 * i) * Math.cos(dir),
y: (SPEED + 15 * Math.random() - 2 * i) * Math.sin(dir)
});
bullet[me].endCycle = 2 * i + game.cycle + END
bullet[me].restitution = 0;
bullet[me].friction = 1;
bullet[me].explodeRad = (mech.crouch ? 95 : 75) + (Math.random() - 0.5) * 50;
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
};
bullet[me].do = function() {
// this.force.y += this.mass * 0.0004;
}
}
}
},
// {
// name: "flak",
// description: "fire a <strong>cluster</strong> of short range <strong>projectiles</strong><br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after half a second",
// ammo: 0,
// ammoPack: 4,
// defaultAmmoPack: 4, //use to revert ammoPack after mod changes drop rate
// have: false,
// fire() {
// mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down
// b.muzzleFlash(30);
// const SPEED = mech.crouch ? 29 : 25
// const END = Math.floor(mech.crouch ? 30 : 18);
// const side1 = 17
// const side2 = 4
// const totalBullets = 6
// const angleStep = (mech.crouch ? 0.06 : 0.25) / totalBullets
// let dir = mech.angle - angleStep * totalBullets / 2;
// for (let i = 0; i < totalBullets; i++) { //5 -> 7
// dir += angleStep
// const me = bullet.length;
// bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), side1, side2, b.fireAttributes(dir));
// World.add(engine.world, bullet[me]); //add bullet to world
// Matter.Body.setVelocity(bullet[me], {
// x: (SPEED + 15 * Math.random() - 2 * i) * Math.cos(dir),
// y: (SPEED + 15 * Math.random() - 2 * i) * Math.sin(dir)
// });
// bullet[me].endCycle = 2 * i + game.cycle + END
// bullet[me].restitution = 0;
// bullet[me].friction = 1;
// bullet[me].explodeRad = (mech.crouch ? 95 : 75) + (Math.random() - 0.5) * 50;
// bullet[me].onEnd = function() {
// b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
// }
// bullet[me].beforeDmg = function() {
// this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
// };
// bullet[me].do = function() {
// // this.force.y += this.mass * 0.0004;
// }
// }
// }
// },
{
name: "grenades",
description: "lob a single <strong>bouncy</strong> projectile<br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after one second",

View File

@@ -24,8 +24,29 @@ function playerOnGroundCheck(event) {
//runs on collisions events
function enter() {
mech.numTouching++;
if (!mech.onGround) mech.enterLand();
if (!mech.onGround) {
mech.onGround = true;
if (mech.crouch) {
if (mech.checkHeadClear()) {
mech.undoCrouch();
} else {
mech.yOffGoal = mech.yOffWhen.crouch;
}
} else {
//sets a hard land where player stays in a crouch for a bit and can't jump
//crouch is forced in groundControl below
const momentum = player.velocity.y * player.mass //player mass is 5 so this triggers at 26 down velocity, unless the player is holding something
if (momentum > 130) {
mech.doCrouch();
mech.yOff = mech.yOffWhen.jump;
mech.hardLandCD = mech.cycle + Math.min(momentum / 6.5 - 6, 40)
} else {
mech.yOffGoal = mech.yOffWhen.stand;
}
}
}
}
const pairs = event.pairs;
for (let i = 0, j = pairs.length; i != j; ++i) {
let pair = pairs[i];
@@ -42,76 +63,26 @@ function playerOnGroundCheck(event) {
function playerOffGroundCheck(event) {
//runs on collisions events
function enter() {
if (mech.onGround && mech.numTouching === 0) mech.enterAir();
}
const pairs = event.pairs;
for (let i = 0, j = pairs.length; i != j; ++i) {
if (pairs[i].bodyA === jumpSensor) {
enter();
} else if (pairs[i].bodyB === jumpSensor) {
enter();
if (pairs[i].bodyA === jumpSensor || pairs[i].bodyB === jumpSensor) {
if (mech.onGround && mech.numTouching === 0) {
mech.onGround = false;
mech.hardLandCD = 0 // disable hard landing
if (mech.checkHeadClear()) {
if (mech.crouch) {
mech.undoCrouch();
}
mech.yOffGoal = mech.yOffWhen.jump;
}
}
}
}
}
// function playerHeadCheck(event) {
// //runs on collisions events
// if (mech.crouch) {
// mech.isHeadClear = true;
// const pairs = event.pairs;
// for (let i = 0, j = pairs.length; i != j; ++i) {
// if (pairs[i].bodyA === headSensor) {
// mech.isHeadClear = false;
// } else if (pairs[i].bodyB === headSensor) {
// mech.isHeadClear = false;
// }
// }
// }
// }
function collisionChecks(event) {
const pairs = event.pairs;
for (let i = 0, j = pairs.length; i != j; i++) {
// //map + bullet collisions
// if (pairs[i].bodyA.collisionFilter.category === cat.map && pairs[i].bodyB.collisionFilter.category === cat.bullet) {
// collideBulletStatic(pairs[i].bodyB)
// } else if (pairs[i].bodyB.collisionFilter.category === cat.map && pairs[i].bodyA.collisionFilter.category === cat.bullet) {
// collideBulletStatic(pairs[i].bodyA)
// }
// //triggers when the bullets hits something static
// function collideBulletStatic(obj, speedThreshold = 12, massThreshold = 2) {
// if (obj.onWallHit) obj.onWallHit();
// }
// function collidePlayer(obj) {
// //player dmg from hitting a body
// if (obj.classType === "body" && obj.speed > 10 && mech.immuneCycle < mech.cycle) {
// const velocityThreshold = 30 //keep this lines up with player.enterLand numbers (130/5 = 26)
// if (player.position.y > obj.position.y) { //block is above the player look at total momentum difference
// const velocityDiffMag = Vector.magnitude(Vector.sub(player.velocity, obj.velocity))
// if (velocityDiffMag > velocityThreshold) hit(velocityDiffMag - velocityThreshold)
// } else { //block is below player only look at horizontal momentum difference
// const velocityDiffMagX = Math.abs(obj.velocity.x - player.velocity.x)
// if (velocityDiffMagX > velocityThreshold) hit(velocityDiffMagX - velocityThreshold)
// }
// function hit(dmg) {
// mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
// dmg = Math.min(Math.max(Math.sqrt(dmg) * obj.mass * 0.01, 0.02), 0.15);
// mech.damage(dmg);
// game.drawList.push({ //add dmg to draw queue
// x: pairs[i].activeContacts[0].vertex.x,
// y: pairs[i].activeContacts[0].vertex.y,
// radius: dmg * 500,
// color: game.mobDmgColor,
// time: game.drawTime
// });
// }
// }
// }
//mob + (player,bullet,body) collisions
for (let k = 0; k < mob.length; k++) {
if (mob[k].alive && mech.alive) {

View File

@@ -987,8 +987,8 @@ document.getElementById("updates").addEventListener("toggle", function() {
loadJSON('https://api.github.com/repos/landgreen/n-gon/commits',
function(data) {
// console.log(data)
for (let i = 0, len = 4; i < len; i++) {
text += data[i].commit.author.date.substr(0, 10) + ": "; //+ "<br>"
for (let i = 0, len = 3; i < len; i++) {
text += "<strong>" + data[i].commit.author.date.substr(0, 10) + "</strong> - "; //+ "<br>"
text += data[i].commit.message
if (i < len - 1) text += "<hr>"
}

View File

@@ -12,20 +12,19 @@ const level = {
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// level.difficultyIncrease(8)
level.difficultyIncrease(8)
// game.enableConstructMode() //used to build maps in testing mode
// game.zoomScale = 1000;
// game.setZoom();
// mech.setField("wormhole")
// b.giveGuns("mine")
// mod.giveMod("sentry")
// b.giveGuns("drones")
// mod.giveMod("incendiary ammunition")
level.intro(); //starting level
// level.intro(); //starting level
level.testing(); //not in rotation
// level.finalBoss() //final boss level
// level.gauntlet(); //before final boss level
// level.testing(); //not in rotation
// level.template() //not in rotation
// level.testChamber() //less mobs, more puzzle
// level.sewers();
// level.satellite();
@@ -141,16 +140,16 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.boost(1500, 0, 900);
// spawn.starter(1600, -500)
spawn.starter(1600, -500, 200)
// spawn.bomberBoss(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.spawner(1600, -500)
// spawn.sniper(1700, -120, 50)
// spawn.bomberBoss(1400, -500)
spawn.sucker(1800, -120)
// spawn.sucker(1800, -120)
// spawn.cellBossCulture(1600, -500)
// spawn.powerUpBoss(1600, -500)
// spawn.spiderBoss(1600, -500)
// spawn.sniper(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);

View File

@@ -197,7 +197,7 @@ const mod = {
},
{
name: "fluoroantimonic acid",
description: "increase <strong class='color-d'>damage</strong> by <strong>40%</strong><br>when your base <strong>health</strong> is above <strong>100%</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>40%</strong><br>when your <strong>health</strong> is above <strong>100%</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -408,7 +408,7 @@ const mod = {
maxCount: 9,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
return mod.haveGunCheck("missiles") || mod.isIncendiary || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
@@ -424,7 +424,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
return mod.haveGunCheck("missiles") || mod.isIncendiary || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
@@ -440,7 +440,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.isFlechetteExplode
return mod.haveGunCheck("missiles") || mod.isIncendiary || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
@@ -457,7 +457,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob || mod.isFlechetteExplode || mod.isPulseLaser
return mod.haveGunCheck("missiles") || mod.isIncendiary || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob || mod.isFlechetteExplode || mod.isPulseLaser
},
requires: "an explosive damage source",
effect: () => {
@@ -469,7 +469,7 @@ const mod = {
},
{
name: "scrap bots",
description: "<strong>20%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot last for about <strong>20</strong> seconds",
description: "<strong>20%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot lasts for about <strong>20</strong> seconds",
maxCount: 3,
count: 0,
allowed() {
@@ -1574,9 +1574,25 @@ const mod = {
//************************************************** gun
//************************************************** mods
//**************************************************
{
name: "incendiary ammunition",
description: "your <strong>bullets</strong> <strong class='color-e'>explode</strong> after a short time<br>(nail gun, shotgun, super balls, drones)",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("drones") || mod.haveGunCheck("super balls") || (mod.haveGunCheck("nail gun") && !mod.isIceCrystals && !mod.isNailCrit) || (mod.haveGunCheck("shotgun") && !mod.isNailShot)
},
requires: "drones, super balls, nail gun, shotgun",
effect() {
mod.isIncendiary = true
},
remove() {
mod.isIncendiary = false;
}
},
{
name: "Lorentzian topology",
description: "your <strong>bullets</strong> last <strong>33% longer</strong>",
description: "your <strong>bullets</strong> last <strong>33% longer</strong><br><span style = 'font-size: 85%'>drones, spores, super balls, foam, wave, ice IX, neutron</span>",
maxCount: 3,
count: 0,
allowed() {
@@ -1612,9 +1628,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("nail gun") && !mod.nailInstantFireRate
return mod.haveGunCheck("nail gun") && !mod.nailInstantFireRate && !mod.isIncendiary
},
requires: "nail gun",
requires: "nail gun, not incendiary, not powder-actuated",
effect() {
mod.isIceCrystals = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -1645,9 +1661,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("nail gun")
return mod.haveGunCheck("nail gun") && !mod.isIncendiary
},
requires: "nail gun",
requires: "nail gun, not incendiary",
effect() {
mod.isNailCrit = true
},
@@ -1731,7 +1747,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("shotgun")
return mod.haveGunCheck("shotgun") && !mod.isIncendiary
},
requires: "shotgun",
effect() {
@@ -1765,7 +1781,7 @@ const mod = {
allowed() {
return mod.haveGunCheck("super balls") && !mod.oneSuperBall
},
requires: "super balls",
requires: "super balls, but not the mod super ball",
effect() {
mod.superBallNumber += 2
},
@@ -1781,7 +1797,7 @@ const mod = {
allowed() {
return mod.haveGunCheck("super balls") && mod.superBallNumber === 4
},
requires: "super balls",
requires: "super balls, but not super duper",
effect() {
mod.oneSuperBall = true;
},
@@ -1999,26 +2015,6 @@ const mod = {
mod.is3Missiles = false;
}
},
{
name: "optimized shell packing",
description: "<strong>flak</strong> <strong class='color-g'>ammo</strong> drops contain <strong>2x</strong> more shells",
maxCount: 3,
count: 0,
allowed() {
return mod.haveGunCheck("flak")
},
requires: "flak",
effect() {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "flak") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * (2 * (1 + this.count));
}
},
remove() {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "flak") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
}
}
},
{
name: "fragmentation grenade",
description: "<strong>grenades</strong> are loaded with <strong>5</strong> nails<br>on detonation <strong>nails</strong> are ejected towards mobs",
@@ -2143,7 +2139,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + mod.haveGunCheck("nail gun")) * 2 > 1
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
},
requires: "nails",
effect() {
@@ -2159,7 +2155,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + mod.haveGunCheck("nail gun")) * 2 > 1
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
},
requires: "nails",
effect() {
@@ -3259,5 +3255,6 @@ const mod = {
timeEnergyRegen: null,
isRadioactive: null,
isRailEnergyGain: null,
isMineSentry: null
isMineSentry: null,
isIncendiary: null
}

View File

@@ -186,39 +186,6 @@ const mech = {
return true
}
},
enterAir() {
//triggered in engine.js on collision
mech.onGround = false;
mech.hardLandCD = 0 // disable hard landing
if (mech.checkHeadClear()) {
if (mech.crouch) {
mech.undoCrouch();
}
mech.yOffGoal = mech.yOffWhen.jump;
}
},
//triggered in engine.js on collision
enterLand() {
mech.onGround = true;
if (mech.crouch) {
if (mech.checkHeadClear()) {
mech.undoCrouch();
} else {
mech.yOffGoal = mech.yOffWhen.crouch;
}
} else {
//sets a hard land where player stays in a crouch for a bit and can't jump
//crouch is forced in groundControl below
const momentum = player.velocity.y * player.mass //player mass is 5 so this triggers at 26 down velocity, unless the player is holding something
if (momentum > 130) {
mech.doCrouch();
mech.yOff = mech.yOffWhen.jump;
mech.hardLandCD = mech.cycle + Math.min(momentum / 6.5 - 6, 40)
} else {
mech.yOffGoal = mech.yOffWhen.stand;
}
}
},
buttonCD_jump: 0, //cool down for player buttons
groundControl() {
//check for crouch or jump
@@ -516,7 +483,6 @@ const mech = {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
return;
} else { //death
mech.health = 0;
@@ -2410,6 +2376,7 @@ const mech = {
mech.hole.isReady = false;
mech.fieldRange = 0
Matter.Body.setPosition(player, game.mouseInGame);
mech.buttonCD_jump = 0 //this might fix a bug with jumping
const velocity = Vector.mult(Vector.normalise(sub), 18)
Matter.Body.setVelocity(player, {
x: velocity.x,

File diff suppressed because it is too large Load Diff

View File

@@ -159,7 +159,7 @@ const spawn = {
}
this.mode = 3
this.fill = "#000";
this.eventHorizon = 700
this.eventHorizon = 750
this.spawnInterval = 600
this.rotateVelocity = 0.001 * (player.position.x > this.position.x ? 1 : -1) //rotate so that the player can get away
if (!this.isShielded) spawn.shield(this, x, y, 1); //regen shield here ?
@@ -200,7 +200,7 @@ const spawn = {
me.eventHorizonCycleRate = 4 * Math.PI / me.endCycle
me.modeSuck = function() {
//eventHorizon waves in and out
if (!mech.isBodiesAsleep) eventHorizon = this.eventHorizon * (1 - 0.25 * Math.cos(this.cycle * this.eventHorizonCycleRate)) //0.014
const eventHorizon = this.eventHorizon * (1 - 0.25 * Math.cos(game.cycle * this.eventHorizonCycleRate)) //0.014
//draw darkness
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
@@ -763,7 +763,7 @@ const spawn = {
this.checkStatus();
if (this.seePlayer.recall) {
//eventHorizon waves in and out
eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(game.cycle * 0.011))
const eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(game.cycle * 0.011))
//accelerate towards the player
const forceMag = this.accelMag * this.mass;
@@ -860,7 +860,7 @@ const spawn = {
this.force.y += forceMag * dy / mag;
//eventHorizon waves in and out
eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(game.cycle * 0.008))
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(game.cycle * 0.008))
// zoom camera in and out with the event horizon
//draw darkness
@@ -910,7 +910,6 @@ const spawn = {
}
},
spiderBoss(x, y, radius = 60 + Math.ceil(Math.random() * 10)) {
const isDaddyLongLegs = Math.random() < 0.25
let targets = [] //track who is in the node boss, for shields
mobs.spawn(x, y, 6, radius, "#b386e8");
let me = mob[mob.length - 1];
@@ -919,10 +918,10 @@ const spawn = {
me.friction = 0;
me.frictionAir = 0.0065;
me.lookTorque = 0.0000008; //controls spin while looking for player
me.g = 0.00025; //required if using 'gravity'
me.g = 0.0002; //required if using 'gravity'
me.seePlayerFreq = Math.round((30 + 20 * Math.random()) * game.lookFreqScale);
const springStiffness = isDaddyLongLegs ? 0.0001 : 0.000065;
const springDampening = isDaddyLongLegs ? 0 : 0.0006;
const springStiffness = 0.00014;
const springDampening = 0.0005;
me.springTarget = {
x: me.position.x,
@@ -935,8 +934,8 @@ const spawn = {
stiffness: springStiffness,
damping: springDampening
});
World.add(engine.world, cons[cons.length - 1]);
cons[len].length = 100 + 1.5 * radius;
me.cons = cons[len];
me.springTarget2 = {
@@ -948,11 +947,12 @@ const spawn = {
pointA: me.springTarget2,
bodyB: me,
stiffness: springStiffness,
damping: springDampening
damping: springDampening,
length: 0
});
World.add(engine.world, cons[cons.length - 1]);
cons[len2].length = 100 + 1.5 * radius;
me.cons2 = cons[len2];
if (isDaddyLongLegs) Matter.Body.setDensity(me, 0.017); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() {
this.removeCons();
@@ -974,15 +974,12 @@ const spawn = {
for (let i = 0; i < nodes; ++i) {
spawn.stabber(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius, 12);
if (isDaddyLongLegs) Matter.Body.setDensity(mob[mob.length - 1], 0.01); //extra dense //normal is 0.001 //makes effective life much larger
targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields
}
//spawn shield around all nodes
if (!isDaddyLongLegs) spawn.bossShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
spawn.allowShields = true;
const attachmentStiffness = isDaddyLongLegs ? 0.0003 : 0.05
if (!isDaddyLongLegs) spawn.constrain2AdjacentMobs(nodes + 2, attachmentStiffness, true); //loop mobs together
const attachmentStiffness = 0.05
spawn.constrain2AdjacentMobs(nodes, attachmentStiffness, true); //loop mobs together
for (let i = 0; i < nodes; ++i) { //attach to center mob
consBB[consBB.length] = Constraint.create({
bodyA: me,
@@ -992,6 +989,9 @@ const spawn = {
});
World.add(engine.world, consBB[consBB.length - 1]);
}
//spawn shield around all nodes
spawn.bossShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
spawn.allowShields = true;
},
timeSkipBoss(x, y, radius = 55) {
mobs.spawn(x, y, 6, radius, '#000');

View File

@@ -1,32 +1,56 @@
*********** NEXT PATCH ***********
you can view the patch notes for the last few commits from the game menu
this uses the github API, so it might have some delay
overfill mods add energy instead of setting energy to a value
bug - spider boss move at full speed again (watch out)
bots that uses energy stop when you hit 50% energy if you have mass-energy mod
bug - blocks in vertical portals can get stuck inside the portals
fixed, but only for one portal... oh well
you get a warning before you overwrite your current gun due to integrated armament
mobs that make a scrap bot, don't leave a block body anymore
gun - flak is removed
mod: High-explosive incendiary, or incendiary rounds
shotgun: several large explosions
nail gun: rapid fire explosions
drones: drones explode on impact
super balls: explode on contact
************** BUGS **************
bug - crouch and worm hole? -> crouch locked in
bug - getting locked into crouch on community levels, but showing the player as still standing
(4+ reports before potential fix) bug - crouch and worm hole? -> crouch locked in
players have extra gravity
might be from the short jump code
added a line to wormhole to reset possible short jump
bug - capping the fps causes random slow downs, that can be fixed with pause
(3 reports) bug - getting locked into crouch on community levels, but showing the player as still standing
maybe improper vertices for map bodies
bug - mine spawned one new mine every second
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
(once) bug - mine spawned one new mine every second
after sticking to the top right corner of a wall
notes: had only gun mine, mod mine reclamation, field plasma,
bug - mines spawn extra mines when fired at thin map wall while jumping
************** MODS **************
(repeatable almost everytime) bug - mines spawn extra mines when fired at thin map wall while jumping
************** TODO **************
rework super balls - start with more damage, ramp slower from mods
+1 ball per shot from mods
small scale size increased
or incendiary and no size increase
mod - make neutron bomb a grenade mod
mod - railgun's push effect is increased, and it does some damage to nearby mobs
maybe only triggers at max energy
mod - neutron bomb needs a method to "catch" mobs in it's field
apply stun status effect
too similar to the stun effect?
mod - a 4th mod selection option that is always a gun or field
mod - nano scale field could be a mod
excess energy is converted to bullets
run this code in the energy overfill code check
@@ -35,10 +59,7 @@ mod - nano scale field could be a mod
pair production - nerf and give it to anyone
cloaking field - maybe just don't spawn bullets when cloaked
mod - sentry fires other bullet types
laser or missile
flak could be a mod for shotgun?
Mod: "Solar Power": Energy regeneration is doubled while standing still
mod - self destruct - drones explode when they die
drones lose extra time on collisions, so they often explode after a collision
@@ -85,14 +106,15 @@ mod - foam is attracted to mobs
name - static cling
could also do bremsstrahlung radiation like damage on attachment
************** TODO **************
field - one block orbits you, it can protect you a bit and do collision damage
use field to fire and press field again to pull it back
mod - more blocks
mod - attach a permanent neutron bomb to the block
lowers energy regen, but it can damage mobs
wormholes need to give feedback on where a portal can go
or automatically put portals in safe places
field - You have a permanent neutron bomb oscillating on you. Energy regeneration and heal powerup effectiveness is halved.
neutron field could be a passive outwards push, replacing the defined, oscillating border of SWH with a less powerful, larger border
find a way to automatically show patch information from github on n-gon main page
repeat map in vertical and horizontal space