portal level work in progress

This commit is contained in:
landgreen
2020-07-18 11:37:37 -07:00
parent c63d0ac5f0
commit 08e09b59c4
8 changed files with 552 additions and 217 deletions

View File

@@ -740,6 +740,7 @@ const b = {
const DIST = Vector.magnitude(TARGET_VECTOR); const DIST = Vector.magnitude(TARGET_VECTOR);
if (DIST < closeDist) { if (DIST < closeDist) {
if (DIST < 60) { //eat the power up if close enough if (DIST < 60) { //eat the power up if close enough
powerUps.onPickUp();
powerUp[i].effect(); powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); powerUp.splice(i, 1);
@@ -988,6 +989,7 @@ const b = {
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (12 + 4 * Math.random()) const RADIUS = (12 + 4 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1043,6 +1045,7 @@ const b = {
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (10 + 5 * Math.random()) const RADIUS = (10 + 5 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 6, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 6, RADIUS, {
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1098,6 +1101,7 @@ const b = {
const dir = mech.angle; const dir = mech.angle;
const RADIUS = 21 const RADIUS = 21
bullet[me] = Bodies.polygon(position.x, position.y, 5, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 5, RADIUS, {
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1288,6 +1292,7 @@ const b = {
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (7 + 2 * Math.random()) const RADIUS = (7 + 2 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1364,6 +1369,7 @@ const b = {
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (14 + 6 * Math.random()) const RADIUS = (14 + 6 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1391,11 +1397,6 @@ const b = {
}, },
onEnd() {}, onEnd() {},
do() { do() {
//move in a circle
// const radius = 1.5
// this.offPlayer.x -= radius * Math.cos(game.cycle * 0.02)
// this.offPlayer.y -= radius * Math.sin(game.cycle * 0.02)
const playerPos = Vector.add(Vector.add(this.offPlayer, mech.pos), Vector.mult(player.velocity, 20)) //also include an offset unique to this bot to keep many bots spread out const playerPos = Vector.add(Vector.add(this.offPlayer, mech.pos), Vector.mult(player.velocity, 20)) //also include an offset unique to this bot to keep many bots spread out
const farAway = Math.max(0, (Vector.magnitude(Vector.sub(this.position, playerPos))) / this.followRange) //linear bounding well const farAway = Math.max(0, (Vector.magnitude(Vector.sub(this.position, playerPos))) / this.followRange) //linear bounding well
const mag = Math.min(farAway, 4) * this.mass * this.acceleration const mag = Math.min(farAway, 4) * this.mass * this.acceleration
@@ -1405,7 +1406,6 @@ const b = {
x: this.velocity.x * 0.95, x: this.velocity.x * 0.95,
y: this.velocity.y * 0.95 y: this.velocity.y * 0.95
}); });
//find targets //find targets
if (!(game.cycle % this.lookFrequency) && !mech.isStealth) { if (!(game.cycle % this.lookFrequency) && !mech.isStealth) {
this.lockedOn = null; this.lockedOn = null;
@@ -1420,7 +1420,6 @@ const b = {
this.lockedOn = mob[i] this.lockedOn = mob[i]
} }
} }
//randomize position relative to player //randomize position relative to player
if (Math.random() < 0.15) { if (Math.random() < 0.15) {
this.offPlayer = { this.offPlayer = {
@@ -1429,7 +1428,6 @@ const b = {
} }
} }
} }
//hit target with laser //hit target with laser
if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) { if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) {
mech.energy -= 0.0014 * mod.isLaserDiode mech.energy -= 0.0014 * mod.isLaserDiode
@@ -1526,12 +1524,11 @@ const b = {
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.01 : 0.1); const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.01 : 0.1);
bullet[me] = Bodies.rectangle(mech.pos.x + 23 * Math.cos(mech.angle), mech.pos.y + 23 * Math.sin(mech.angle), 20 * mod.bulletSize, 6 * mod.bulletSize, b.fireAttributes(dir)); bullet[me] = Bodies.rectangle(mech.pos.x + 23 * Math.cos(mech.angle), mech.pos.y + 23 * Math.sin(mech.angle), 20 * mod.bulletSize * mod.highCaliber, 6 * mod.bulletSize, b.fireAttributes(dir));
//fire delay decreases as you hold fire, down to 3 from 15 //fire delay decreases as you hold fire, down to 3 from 15
if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing
const CD = Math.max(11 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down const CD = Math.max(11 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) * mod.highCaliber //CD scales with cycles fire is held down
this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down
b.fireProps(CD, mech.crouch ? 38 : 34, dir, me); //cd , speed b.fireProps(CD, mech.crouch ? 38 : 34, dir, me); //cd , speed
// b.fireProps(mech.crouch ? 7 : 4, mech.crouch ? 40 : 34, dir, me); //cd , speed // b.fireProps(mech.crouch ? 7 : 4, mech.crouch ? 40 : 34, dir, me); //cd , speed
@@ -1583,8 +1580,6 @@ const b = {
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
} }
b.muzzleFlash(35); b.muzzleFlash(35);
if (mod.isNailShot) { if (mod.isNailShot) {
for (let i = 0; i < 14; i++) { for (let i = 0; i < 14; i++) {
@@ -1635,8 +1630,8 @@ const b = {
num: 5, num: 5,
isEasyToAim: true, isEasyToAim: true,
fire() { fire() {
const SPEED = mech.crouch ? 40 : 30 const SPEED = mech.crouch ? 43 : 32
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 28 : 20) * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 18) * b.fireCD); // cool down
if (mod.oneSuperBall) { if (mod.oneSuperBall) {
let dir = mech.angle let dir = mech.angle
const me = bullet.length; const me = bullet.length;
@@ -1649,7 +1644,7 @@ const b = {
// Matter.Body.setDensity(bullet[me], 0.0001); // Matter.Body.setDensity(bullet[me], 0.0001);
bullet[me].endCycle = game.cycle + Math.floor((300 + 60 * Math.random()) * mod.isBulletsLastLonger); bullet[me].endCycle = game.cycle + Math.floor((300 + 60 * Math.random()) * mod.isBulletsLastLonger);
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.999; bullet[me].restitution = 1;
bullet[me].friction = 0; bullet[me].friction = 0;
bullet[me].do = function () { bullet[me].do = function () {
this.force.y += this.mass * 0.001; this.force.y += this.mass * 0.001;
@@ -1663,7 +1658,7 @@ const b = {
let dir = mech.angle - SPREAD * (mod.superBallNumber - 1) / 2; let dir = mech.angle - SPREAD * (mod.superBallNumber - 1) / 2;
for (let i = 0; i < mod.superBallNumber; i++) { for (let i = 0; i < mod.superBallNumber; i++) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 12, 7 * mod.bulletSize, b.fireAttributes(dir, false)); bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 12, 7.5 * mod.bulletSize, b.fireAttributes(dir, false));
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir), x: SPEED * Math.cos(dir),
@@ -1927,7 +1922,7 @@ const b = {
name: "missiles", name: "missiles",
description: "launch missiles that <strong>accelerate</strong> towards <strong>mobs</strong><br><strong class='color-e'>explodes</strong> when near target", description: "launch missiles that <strong>accelerate</strong> towards <strong>mobs</strong><br><strong class='color-e'>explodes</strong> when near target",
ammo: 0, ammo: 0,
ammoPack: 4, ammoPack: 5,
have: false, have: false,
isEasyToAim: true, isEasyToAim: true,
fireCycle: 0, fireCycle: 0,
@@ -2094,7 +2089,7 @@ const b = {
bullet[me].restitution = 0.2; bullet[me].restitution = 0.2;
bullet[me].friction = 0.3; bullet[me].friction = 0.3;
bullet[me].endCycle = Infinity bullet[me].endCycle = Infinity
bullet[me].explodeRad = 440 + Math.floor(Math.random() * 30); bullet[me].explodeRad = 450 + Math.floor(Math.random() * 30);
bullet[me].onEnd = function () { bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
@@ -2218,7 +2213,7 @@ const b = {
bullet[me].restitution = 0; bullet[me].restitution = 0;
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].damageRadius = 100; bullet[me].damageRadius = 100;
bullet[me].maxDamageRadius = (425 + 125 * Math.random()) * (mod.isNeutronImmune ? 1.2 : 1) bullet[me].maxDamageRadius = (435 + 150 * Math.random()) * (mod.isNeutronImmune ? 1.2 : 1)
bullet[me].stuckTo = null; bullet[me].stuckTo = null;
bullet[me].stuckToRelativePosition = null; bullet[me].stuckToRelativePosition = null;
bullet[me].onDmg = function () {}; bullet[me].onDmg = function () {};
@@ -2283,8 +2278,6 @@ const b = {
} else { } else {
const bodyCollisions = Matter.Query.collides(this, body) const bodyCollisions = Matter.Query.collides(this, body)
if (bodyCollisions.length) { if (bodyCollisions.length) {
if (!bodyCollisions[0].bodyA.isNotSticky) { if (!bodyCollisions[0].bodyA.isNotSticky) {
onCollide(this) onCollide(this)
this.stuckTo = bodyCollisions[0].bodyA this.stuckTo = bodyCollisions[0].bodyA
@@ -2329,7 +2322,6 @@ const b = {
this.endCycle = 0; this.endCycle = 0;
} else { } else {
//aoe damage to player //aoe damage to player
if (!mod.isNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) { if (!mod.isNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
const DRAIN = 0.0015 const DRAIN = 0.0015
if (mech.energy > DRAIN) { if (mech.energy > DRAIN) {
@@ -2380,7 +2372,7 @@ const b = {
x: speed * Math.cos(mech.angle), x: speed * Math.cos(mech.angle),
y: speed * Math.sin(mech.angle) y: speed * Math.sin(mech.angle)
}, 0, mod.isMineAmmoBack) }, 0, mod.isMineAmmoBack)
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 60 : 20) * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 50 : 25) * b.fireCD); // cool down
} }
}, },
{ {
@@ -2508,7 +2500,7 @@ const b = {
name: "drones", name: "drones",
description: "deploy drones that <strong>crash</strong> into mobs<br>crashes reduce their <strong>lifespan</strong> by 1 second", description: "deploy drones that <strong>crash</strong> into mobs<br>crashes reduce their <strong>lifespan</strong> by 1 second",
ammo: 0, ammo: 0,
ammoPack: 14, ammoPack: 15,
have: false, have: false,
isEasyToAim: true, isEasyToAim: true,
fire() { fire() {
@@ -2621,7 +2613,10 @@ const b = {
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
} }
} }
if (mod.isRailTimeSlow) {
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
}
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it) Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
this.endCycle = game.cycle + 140 this.endCycle = game.cycle + 140
@@ -2672,7 +2667,12 @@ const b = {
let chargeRate = (mech.crouch) ? 0.975 : 0.987 let chargeRate = (mech.crouch) ? 0.975 : 0.987
chargeRate *= Math.pow(b.fireCD, 0.03) chargeRate *= Math.pow(b.fireCD, 0.03)
this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1 this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1
mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen if (mod.isRailTimeSlow) {
game.fpsCap = 30 //new fps
game.fpsInterval = 1000 / game.fpsCap;
} else {
mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
}
//draw targeting //draw targeting
let best; let best;

View File

@@ -205,6 +205,7 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))); // const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)));
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
console.log(dmg)
if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5 if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
mob[k].foundPlayer(); mob[k].foundPlayer();
mob[k].damage(dmg); mob[k].damage(dmg);

View File

@@ -39,6 +39,7 @@ const game = {
b.bulletDraw(); b.bulletDraw();
b.bulletDo(); b.bulletDo();
game.drawCircle(); game.drawCircle();
level.customTopLayer();
// game.clip(); // game.clip();
ctx.restore(); ctx.restore();
game.drawCursor(); game.drawCursor();
@@ -67,6 +68,7 @@ const game = {
game.draw.testing(); game.draw.testing();
game.drawCircle(); game.drawCircle();
game.constructCycle() game.constructCycle()
level.customTopLayer();
ctx.restore(); ctx.restore();
game.testingOutput(); game.testingOutput();
game.drawCursor(); game.drawCursor();
@@ -691,6 +693,9 @@ const game = {
mech.holdingTarget.collisionFilter.category = 0; mech.holdingTarget.collisionFilter.category = 0;
mech.holdingTarget.collisionFilter.mask = 0; mech.holdingTarget.collisionFilter.mask = 0;
} }
//set fps back to default
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
}, },
getCoords: { getCoords: {
//used when building maps, outputs a draw rect command to console, only works in testing mode //used when building maps, outputs a draw rect command to console, only works in testing mode
@@ -735,12 +740,16 @@ const game = {
x: level.enter.x + 50, x: level.enter.x + 50,
y: level.enter.y - 20 y: level.enter.y - 20
}); });
// Matter.Body.setPosition(player, { // move bots
// x: player.position.x, for (let i = 0; i < bullet.length; i++) {
// y: -7000 if (bullet[i].isBot) {
// }); Matter.Body.setPosition(bullet[i], player.position);
// game.noCameraScroll() Matter.Body.setVelocity(bullet[i], {
x: 0,
y: 0
});
}
}
if (game.difficultyMode === 2) mech.damage(0.3); if (game.difficultyMode === 2) mech.damage(0.3);
if (game.difficultyMode === 1) mech.damage(0.1); if (game.difficultyMode === 1) mech.damage(0.1);
mech.energy = 0; mech.energy = 0;

View File

@@ -12,18 +12,18 @@ const level = {
if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps(); if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps();
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// level.difficultyIncrease(4) // level.difficultyIncrease(4)
// game.enableConstructMode() //used to build maps in testing mode game.enableConstructMode() //used to build maps in testing mode
// game.zoomScale = 1000;
// game.setZoom();
// mech.isStealth = true; // mech.isStealth = true;
// mod.giveMod("bot fabrication"); // mod.giveMod("nail-bot");
// b.giveGuns("ice IX") // b.giveGuns("ice IX")
// mech.setField("plasma torch") // mech.setField("plasma torch")
level.intro(); //starting level
// level.sewers();
// level.testing(); // level.testing();
// level.template() // level.intro(); //starting level
// level.bosses(); level.testChamber()
// level.stronghold() // level.sewers();
// level.satellite(); // level.satellite();
// level.skyscrapers(); // level.skyscrapers();
// level.aerie(); // level.aerie();
@@ -31,7 +31,9 @@ const level = {
// level.warehouse(); // level.warehouse();
// level.highrise(); // level.highrise();
// level.office(); // level.office();
// level.bosses();
// level.template()
// level.stronghold() //fan level
} else { } else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"] // spawn.pickList = ["focuser", "focuser"]
@@ -43,24 +45,12 @@ const level = {
game.setZoom(); game.setZoom();
level.addToWorld(); //add bodies to game engine level.addToWorld(); //add bodies to game engine
game.draw.setPaths(); game.draw.setPaths();
for (let i = 0; i < mod.laserBotCount; i++) { for (let i = 0; i < mod.laserBotCount; i++) b.laserBot()
b.laserBot() for (let i = 0; i < mod.nailBotCount; i++) b.nailBot()
} for (let i = 0; i < mod.foamBotCount; i++) b.foamBot()
for (let i = 0; i < mod.nailBotCount; i++) { for (let i = 0; i < mod.boomBotCount; i++) b.boomBot()
b.nailBot() for (let i = 0; i < mod.plasmaBotCount; i++) b.plasmaBot()
}
for (let i = 0; i < mod.foamBotCount; i++) {
b.foamBot()
}
for (let i = 0; i < mod.boomBotCount; i++) {
b.boomBot()
}
for (let i = 0; i < mod.plasmaBotCount; i++) {
b.plasmaBot()
}
if (mod.isArmorFromPowerUps) { if (mod.isArmorFromPowerUps) {
// for (let i = 0; i < powerUps.totalPowerUps; i++) {}
mech.maxHealth += 0.05 * powerUps.totalPowerUps mech.maxHealth += 0.05 * powerUps.totalPowerUps
if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300) if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300)
} }
@@ -69,140 +59,249 @@ const level = {
mech.displayHealth(); mech.displayHealth();
} }
}, },
custom() {},
customTopLayer() {},
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
rotor(x, y, rotate = 0, radius = 900, width = 50, density = 0.0005) { portal(centerA, angleA, centerB, angleB) {
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, { const width = 30
density: density, const height = 150
isNotSticky: true, const mapWidth = 200
isNotHoldable: true const unitA = Matter.Vector.rotate({
}); x: 1,
const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, { y: 0
angle: Math.PI / 2, }, angleA)
density: density, const unitB = Matter.Vector.rotate({
isNotSticky: true, x: 1,
isNotHoldable: true y: 0
}); }, angleB)
rotor = Body.create({ //combine rotor1 and rotor2
parts: [rotor1, rotor2],
restitution: 0,
collisionFilter: {
category: cat.body,
mask: cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.powerUp | cat.player | cat.bullet
},
});
Matter.Body.setPosition(rotor, {
x: x,
y: y
});
World.add(engine.world, [rotor]);
body[body.length] = rotor1
body[body.length] = rotor2
setTimeout(function () { draw = function () {
rotor.collisionFilter.category = cat.body; ctx.beginPath(); //portal
rotor.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet //| cat.map sensor = this.vertices;
}, 1000); ctx.moveTo(sensor[0].x, sensor[0].y);
for (let i = 1; i < sensor.length; ++i) {
const constraint = Constraint.create({ //fix rotor in place, but allow rotation ctx.lineTo(sensor[i].x, sensor[i].y);
pointA: {
x: x,
y: y
},
bodyB: rotor
});
World.add(engine.world, constraint);
if (rotate) {
rotor.rotate = function () {
if (!mech.isBodiesAsleep) {
Matter.Body.applyForce(rotor, {
x: rotor.position.x + 100,
y: rotor.position.y + 100
}, {
x: rotate * rotor.mass,
y: 0
})
} else {
Matter.Body.setAngularVelocity(rotor, 0);
}
} }
ctx.fillStyle = this.color
ctx.fill();
} }
composite[composite.length] = rotor query = function () {
return rotor if (Matter.Query.collides(this, [player]).length === 0) { //not touching player
}, if (player.isInPortal === this) player.isInPortal = null
button(x, y, width = 70) { } else if (player.isInPortal !== this) { //touching player
spawn.mapVertex(x + 35, y + 2, "70 10 -70 10 -40 -10 40 -10"); //teleport
return { player.isInPortal = this.portalPair
isUp: false, Matter.Body.setPosition(player, this.portalPair.position);
min: { //rotate velocity
x: x, // const unit = Vector.normalise(Vector.rotate(player.velocity, this.angle - this.portalPair.angle + Math.PI)) //rotate and flip velocity
y: y - 15 // const mag = Math.max(20, Math.min(50, Vector.magnitude(player.velocity))) //20 is lowest speed, 50 is highest speed
}, // const v = Vector.mult(unit, mag)
max: {
x: x + width, let mag
y: y - 5 if (this.angle === -Math.PI / 2) {
}, //portal that fires the player up
width: width, mag = Math.max(10, Math.min(50, player.velocity.y * 0.8)) + 11
height: 20,
query() {
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
this.isUp = true;
} else { } else {
this.isUp = false; mag = Math.max(3, Math.min(50, Vector.magnitude(player.velocity)))
} }
}, console.log(mag)
draw() { const v = Vector.mult(this.portalPair.unit, mag)
ctx.fillStyle = "hsl(0, 100%, 70%)" Matter.Body.setVelocity(player, v);
if (this.isUp) { mech.buttonCD_jump = 0 //disable short jumps when letting go of jump key
ctx.fillRect(this.min.x, this.min.y - 10, this.width, 20) // move bots to follow player
} else { for (let i = 0; i < bullet.length; i++) {
ctx.fillRect(this.min.x, this.min.y, this.width, 25) if (bullet[i].isBot) {
} Matter.Body.setPosition(bullet[i], this.portalPair.portal.position);
} Matter.Body.setVelocity(bullet[i], {
} x: 0,
}, y: 0
hazard(x, y, width, height, damage = 0.0005, color = "hsl(160, 100%, 35%)") { });
return {
min: {
x: x,
y: y
},
max: {
x: x + width,
y: y + height
},
width: width,
height: height,
maxHeight: height,
query() {
if (this.height > 0 && Matter.Query.region([player], this).length && !mech.isStealth) {
mech.damage(damage)
const drain = 0.005
if (mech.energy > drain) mech.energy -= drain
}
},
draw() {
ctx.fillStyle = color
ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
},
level(isFill) {
const growSpeed = 1
if (isFill) {
if (this.height < this.maxHeight) {
this.height += growSpeed
this.min.y -= growSpeed
this.max.y = this.min.y + this.height
} }
} else if (this.height > 0) {
this.height -= growSpeed
this.min.y += growSpeed
this.max.y = this.min.y + this.height
} }
} }
} }
const portalA = Bodies.rectangle(centerA.x, centerA.y, width, height, {
isSensor: true,
angle: angleA,
color: "hsla(197, 100%, 50%,0.7)",
draw: draw,
});
const portalB = Bodies.rectangle(centerB.x, centerB.y, width, height, {
isSensor: true,
angle: angleB,
color: "hsla(29, 100%, 50%, 0.7)",
draw: draw
});
const mapA = Bodies.rectangle(centerA.x - 0.5 * unitA.x * mapWidth, centerA.y - 0.5 * unitA.y * mapWidth, mapWidth, height + 100, {
collisionFilter: {
category: cat.map,
mask: cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
unit: unitA,
angle: angleA,
color: game.draw.mapFill,
draw: draw,
query: query,
lastPortalCycle: 0
});
Matter.Body.setStatic(mapA, true); //make static
World.add(engine.world, mapA); //add to world
const mapB = Bodies.rectangle(centerB.x - 0.5 * unitB.x * mapWidth, centerB.y - 0.5 * unitB.y * mapWidth, mapWidth, height + 100, {
collisionFilter: {
category: cat.map,
mask: cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
unit: unitB,
angle: angleB,
color: game.draw.mapFill,
draw: draw,
query: query,
lastPortalCycle: 0
});
Matter.Body.setStatic(mapB, true); //make static
World.add(engine.world, mapB); //add to world
mapA.portal = portalA
mapB.portal = portalB
mapA.portalPair = mapB
mapB.portalPair = mapA
return [portalA, portalB, mapA, mapB]
},
testChamber() {
const portal = level.portal({
x: 2500,
y: -100
}, Math.PI, { //left
x: 2500,
y: -3100
}, Math.PI) //left
const portal2 = level.portal({
x: 100,
y: -2150
}, -Math.PI / 2, { //up
x: 1300,
y: -2150
}, -Math.PI / 2) //up
level.custom = () => {
level.playerExitCheck();
portal[2].query()
portal[3].query()
portal2[2].query()
portal2[3].query()
};
level.customTopLayer = () => {
portal[0].draw();
portal[1].draw();
portal[2].draw();
portal[3].draw();
portal2[0].draw();
portal2[1].draw();
portal2[2].draw();
portal2[3].draw();
};
if (false) {
level.setPosToSpawn(0, -50); //lower spawn
level.exit.y = level.enter.y - 550;
level.fillBG.push({
x: -300,
y: -1000,
width: 650,
height: 500,
color: "#d4f4f4"
});
} else {
level.setPosToSpawn(0, -600); //upper spawn
level.exit.y = level.enter.y + 550;
level.fillBG.push({
x: -300,
y: -500,
width: 650,
height: 500,
color: "#d4f4f4"
});
}
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = level.enter.x;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
//outer wall
spawn.mapRect(-500, -3800, 200, 4000); //left map wall
spawn.mapRect(2500, -2975, 200, 2375); //right map middle wall
spawn.mapRect(-400, -3800, 3100, 200); //map ceiling
spawn.mapRect(-400, 0, 3100, 200); //floor
//entrance
spawn.mapRect(300, -550, 50, 350); //right entrance wall
spawn.mapRect(-400, -550, 3000, 50); //ceiling
//entrance clutter
const xPos = shuffle([550, 1100, 1850]);
spawn.mapRect(xPos[0], -350, 400, 100);
spawn.mapRect(xPos[1], -350, 300, 400);
spawn.mapRect(xPos[2], -150, 300, 200);
//exit
spawn.mapRect(-400, -1050, 750, 50);
spawn.mapRect(300, -1050, 50, 300);
//portal bottom
spawn.mapRect(2500, -700, 200, 540); //right portal wall
spawn.mapRect(2525, -200, 175, 250); //right portal back wall
//portal top
spawn.mapRect(1400, -3000, 1300, 50); //floor
spawn.mapRect(2500, -3700, 200, 540); //right portal wall
spawn.mapRect(2525, -3200, 175, 250); //right portal back wall
// spawn.mapRect(700, -3250, 775, 350);
spawn.mapRect(0, -3250, 1450, 50);
spawn.mapRect(1400, -3250, 50, 300);
// spawn.mapRect(-350, -2875, 175, 325);
spawn.mapRect(-150, -3000, 150, 50);
spawn.mapRect(-350, -2750, 175, 200);
//portal 2
spawn.mapRect(-300, -2600, 300, 700);
spawn.mapRect(-25, -1975, 250, 75);
spawn.mapRect(1400, -2600, 300, 700);
spawn.mapRect(1175, -1975, 250, 75);
// spawn.mapRect(200, -2150, 25, 250);
// spawn.mapRect(475, -2150, 25, 250);
//portal walls
// spawn.mapRect(575, -8, 100, 50);
// spawn.mapRect(925, -8, 100, 50);
// spawn.mapRect(675,t -625, 250, 675);
// spawn.mapRect(1700, 75, 150, 25);
// spawn.mapRect(1700, -700, 150, 25);
// spawn.mapRect(1850, 0, 525, 100);
// spawn.mapRect(1850, -700, 525, 100);
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
// spawn.boost(4150, 0, 1300);
// spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8);
// spawn.randomBoss(1700, -900, 0.4);
// if (game.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
sewers() { sewers() {
const rotor = level.rotor(5100, 2425, -0.001) const rotor = level.rotor(5100, 2425, -0.001)
@@ -2356,4 +2455,161 @@ const level = {
World.add(engine.world, consBB[i]); World.add(engine.world, consBB[i]);
} }
}, },
rotor(x, y, rotate = 0, radius = 900, width = 50, density = 0.0005) {
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
density: density,
isNotSticky: true,
isNotHoldable: true
});
const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, {
angle: Math.PI / 2,
density: density,
isNotSticky: true,
isNotHoldable: true
});
rotor = Body.create({ //combine rotor1 and rotor2
parts: [rotor1, rotor2],
restitution: 0,
collisionFilter: {
category: cat.body,
mask: cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.powerUp | cat.player | cat.bullet
},
});
Matter.Body.setPosition(rotor, {
x: x,
y: y
});
World.add(engine.world, [rotor]);
body[body.length] = rotor1
body[body.length] = rotor2
setTimeout(function () {
rotor.collisionFilter.category = cat.body;
rotor.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet //| cat.map
}, 1000);
const constraint = Constraint.create({ //fix rotor in place, but allow rotation
pointA: {
x: x,
y: y
},
bodyB: rotor
});
World.add(engine.world, constraint);
if (rotate) {
rotor.rotate = function () {
if (!mech.isBodiesAsleep) {
Matter.Body.applyForce(rotor, {
x: rotor.position.x + 100,
y: rotor.position.y + 100
}, {
x: rotate * rotor.mass,
y: 0
})
} else {
Matter.Body.setAngularVelocity(rotor, 0);
}
}
}
composite[composite.length] = rotor
return rotor
},
button(x, y, width = 66) {
spawn.mapVertex(x + 35, y + 2, "70 10 -70 10 -40 -10 40 -10");
map[map.length - 1].restitution = 0;
map[map.length - 1].friction = 1;
map[map.length - 1].frictionStatic = 1;
// const buttonSensor = Bodies.rectangle(x + 35, y - 1, 70, 20, {
// isSensor: true
// });
return {
isUp: false,
min: {
x: x + 2,
y: y - 11
},
max: {
x: x + width,
y: y - 10
},
width: width,
height: 20,
query() {
// if (Matter.Query.collides(buttonSensor, body).length === 0 && Matter.Query.collides(buttonSensor, [player]).length === 0) {
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
this.isUp = true;
} else {
this.isUp = false;
// const list = Matter.Query.collides(buttonSensor, body)
// if (list.length > 0) {
// Matter.Body.setVelocity(list[0].bodyB, {
// x: 0,
// y: 0
// });
// }
}
},
draw() {
ctx.fillStyle = "hsl(0, 100%, 70%)"
if (this.isUp) {
ctx.fillRect(this.min.x, this.min.y - 10, this.width, 20)
} else {
ctx.fillRect(this.min.x, this.min.y, this.width, 25)
}
//draw sensor zone
// ctx.beginPath();
// sensor = buttonSensor.vertices;
// ctx.moveTo(sensor[0].x, sensor[0].y);
// for (let i = 1; i < sensor.length; ++i) {
// ctx.lineTo(sensor[i].x, sensor[i].y);
// }
// ctx.lineTo(sensor[0].x, sensor[0].y);
// ctx.fillStyle = "rgba(255, 255, 0, 0.3)";
// ctx.fill();
}
}
},
hazard(x, y, width, height, damage = 0.0005, color = "hsl(160, 100%, 35%)") {
return {
min: {
x: x,
y: y
},
max: {
x: x + width,
y: y + height
},
width: width,
height: height,
maxHeight: height,
query() {
if (this.height > 0 && Matter.Query.region([player], this).length && !mech.isStealth) {
mech.damage(damage)
const drain = 0.005
if (mech.energy > drain) mech.energy -= drain
}
},
draw() {
ctx.fillStyle = color
ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
},
level(isFill) {
const growSpeed = 1
if (isFill) {
if (this.height < this.maxHeight) {
this.height += growSpeed
this.min.y -= growSpeed
this.max.y = this.min.y + this.height
}
} else if (this.height > 0) {
this.height -= growSpeed
this.min.y += growSpeed
this.max.y = this.min.y + this.height
}
}
}
},
}; };

View File

@@ -643,7 +643,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return game.fpsCapDefault > 45 return game.fpsCapDefault > 45 && !mod.isRailTimeSlow
}, },
requires: "FPS above 45", requires: "FPS above 45",
effect() { effect() {
@@ -852,22 +852,6 @@ const mod = {
mech.displayHealth(); mech.displayHealth();
} }
}, },
{
name: "negentropy",
description: "at the start of each <strong>level</strong><br><strong class='color-h'>heal</strong> up to <strong>66%</strong> of <strong>maximum health</strong>",
maxCount: 1,
count: 0,
allowed() {
return mech.maxHealth > 1 || mod.isArmorFromPowerUps
},
requires: "increased max health",
effect() {
mod.isHealLowHealth = true;
},
remove() {
mod.isHealLowHealth = false;
}
},
{ {
name: "crystallized armor", name: "crystallized armor",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>5%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>", description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>5%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
@@ -884,6 +868,38 @@ const mod = {
mod.isArmorFromPowerUps = false; mod.isArmorFromPowerUps = false;
} }
}, },
{
name: "negentropy",
description: "at the start of each <strong>level</strong><br><strong class='color-h'>heal</strong> up to <strong>66%</strong> of <strong>maximum health</strong>",
maxCount: 1,
count: 0,
allowed() {
return mech.maxHealth > 1 || mod.isArmorFromPowerUps
},
requires: "increased max health",
effect() {
mod.isHealLowHealth = true;
},
remove() {
mod.isHealLowHealth = false;
}
},
// {
// name: "prismatic cleavage",
// description: "harm that would be fatal no longer kills you<br>instead it is removed from your maximum health",
// maxCount: 1,
// count: 0,
// allowed() {
// return mech.maxHealth > 1 || mod.isArmorFromPowerUps
// },
// requires: "increased max health",
// effect() {
// mod.isMaxHealthRemove = true;
// },
// remove() {
// mod.isMaxHealthRemove = false;
// }
// },
{ {
name: "recursive healing", name: "recursive healing",
description: "<strong class='color-h'>healing</strong> <strong>power ups</strong> trigger <strong>1</strong> more time", description: "<strong class='color-h'>healing</strong> <strong>power ups</strong> trigger <strong>1</strong> more time",
@@ -1245,6 +1261,22 @@ const mod = {
mod.bulletSize = 1; mod.bulletSize = 1;
} }
}, },
{
name: "high caliber",
description: "<strong>100%</strong> increased <strong>minigun</strong> bullet size<br><strong>100%</strong> increased <strong>delay</strong> after firing",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("minigun")
},
requires: "minigun",
effect() {
mod.highCaliber = 2
},
remove() {
mod.highCaliber = 1
}
},
{ {
name: "ice crystal nucleation", name: "ice crystal nucleation",
description: "your <strong>minigun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>bullets</strong> from water vapor", description: "your <strong>minigun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>bullets</strong> from water vapor",
@@ -1813,7 +1845,22 @@ const mod = {
mod.isFoamGrowOnDeath = false; mod.isFoamGrowOnDeath = false;
} }
}, },
{
name: "frame-dragging",
description: "<strong>slow time</strong> while charging the <strong>rail gun</strong><br>charging no longer drains <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
allowed() {
return game.fpsCapDefault > 45 && mod.haveGunCheck("rail gun") && !mod.isSlowFPS
},
requires: "rail gun && FPS above 45",
effect() {
mod.isRailTimeSlow = true;
},
remove() {
mod.isRailTimeSlow = false;
}
},
{ {
name: "fragmenting projectiles", name: "fragmenting projectiles",
description: "<strong>rail gun</strong> fragments into <strong>nails</strong><br>after hitting mobs at high speeds", description: "<strong>rail gun</strong> fragments into <strong>nails</strong><br>after hitting mobs at high speeds",
@@ -2384,5 +2431,7 @@ const mod = {
isRerollHaste: null, isRerollHaste: null,
rerollHaste: null, rerollHaste: null,
isMineDrop: null, isMineDrop: null,
isRerollBots: null isRerollBots: null,
isRailTimeSlow: null
// isMaxHealthRemove: null
} }

View File

@@ -945,14 +945,7 @@ const mech = {
y: powerUp[i].velocity.y * 0.11 y: powerUp[i].velocity.y * 0.11
}); });
if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough
if (mod.isMassEnergy) mech.energy = mech.maxEnergy * 3; powerUps.onPickUp();
if (mod.isMineDrop) b.mine({
x: mech.pos.x,
y: mech.pos.y
}, {
x: 0,
y: 0
}, 0, mod.isMineAmmoBack)
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
x: player.velocity.x + ((powerUp[i].velocity.x * powerUp[i].mass) / player.mass) * 0.3, x: player.velocity.x + ((powerUp[i].velocity.x * powerUp[i].mass) / player.mass) * 0.3,
y: player.velocity.y + ((powerUp[i].velocity.y * powerUp[i].mass) / player.mass) * 0.3 y: player.velocity.y + ((powerUp[i].velocity.y * powerUp[i].mass) / player.mass) * 0.3
@@ -1663,7 +1656,7 @@ const mech = {
mech.grabPowerUp(); mech.grabPowerUp();
mech.lookForPickUp(180); mech.lookForPickUp(180);
const DRAIN = 0.0017 const DRAIN = 0.0014
if (mech.energy > DRAIN) { if (mech.energy > DRAIN) {
mech.energy -= DRAIN; mech.energy -= DRAIN;
if (mech.energy < DRAIN) { if (mech.energy < DRAIN) {

View File

@@ -195,7 +195,9 @@ const powerUps = {
let choice2 = -1 let choice2 = -1
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>` let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft()'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
if (!mod.isDeterminism) { if (!mod.isDeterminism) {
choice2 = pick(mech.fieldUpgrades, choice1) choice2 = pick(mech.fieldUpgrades, choice1)
@@ -263,7 +265,9 @@ const powerUps = {
} }
} }
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>` let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft()'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
let choice1 = pick() let choice1 = pick()
let choice2 = -1 let choice2 = -1
let choice3 = -1 let choice3 = -1
@@ -333,7 +337,9 @@ const powerUps = {
let choice2 = -1 let choice2 = -1
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>` let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft()'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
if (!mod.isDeterminism) { if (!mod.isDeterminism) {
choice2 = pick(b.guns, choice1) choice2 = pick(b.guns, choice1)
@@ -365,6 +371,16 @@ const powerUps = {
} }
} }
}, },
onPickUp() {
if (mod.isMassEnergy) mech.energy = mech.maxEnergy * 3;
if (mod.isMineDrop) b.mine({
x: mech.pos.x,
y: mech.pos.y
}, {
x: 0,
y: 0
}, 0, mod.isMineAmmoBack)
},
giveRandomAmmo() { giveRandomAmmo() {
const ammoTarget = Math.floor(Math.random() * (b.guns.length)); const ammoTarget = Math.floor(Math.random() * (b.guns.length));
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6); const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6);

View File

@@ -1,8 +1,18 @@
determinism mod no longer lets you cancel power ups
rerolls now spawn at about 1 per level mod: frame dragging - rail gun doesn't drain energy, and slows time while charging
mod: high caliber - minigun bullets are bigger, but fire slower
************** TODO - n-gon ************** ************** TODO - n-gon **************
using a reroll gives you, a heal or ammo
level boss: boss that dies and comes back to life but with one less side until it hits 3 sides
change color too (hsl)
boss shrinks and moves faster after each death
mechanic: lose max health instead of taking fatal damage
map: laboratory map: laboratory
rooms with switches that change physics rooms with switches that change physics
gravity room gravity room
@@ -10,10 +20,17 @@ map: laboratory
laser room laser room
radiation room radiation room
map: observatory
button controls rotation of telescope
laser beam shoots out of telescope
button opens the dome
map: prison map: prison
doors linked to buttons doors linked to buttons
mobs inside the doors? mobs inside the doors?
map: airport
button: blocks that are on the button at an angle will slowly slide off the button button: blocks that are on the button at an angle will slowly slide off the button
maybe just avoid long blocks near the button? maybe just avoid long blocks near the button?
maybe actively hold the button in place? maybe actively hold the button in place?
@@ -42,12 +59,6 @@ field that pushes blocks and mobs away
mod - AoE radiation might work when the effect ends mod - AoE radiation might work when the effect ends
or maybe just anytime another mob is near or maybe just anytime another mob is near
medium caliber gun in between minigun and rail gun
mod: electricity damages mobs that get near the bullet
get ammo back if it hits mobs
ammo returns to you if it misses
bullets have a gentle arc?
mob that flashes the player (makes the graphics not update for a couple seconds) mob that flashes the player (makes the graphics not update for a couple seconds)
mod - do 50% more damage in close, but 50% less at a distance mod - do 50% more damage in close, but 50% less at a distance