CPT mods
mod: causality bots - before you rewind, build bots that protect you for for 7 seconds mod grenade: causality bombs - before you rewind, drop some grenades
This commit is contained in:
500
js/bullet.js
500
js/bullet.js
@@ -274,6 +274,307 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
grenade() {
|
||||||
|
|
||||||
|
},
|
||||||
|
setGrenadeMode() {
|
||||||
|
grenadeDefault = function(where = { x: mech.pos.x + 30 * Math.cos(mech.angle), y: mech.pos.y + 30 * Math.sin(mech.angle) }, angle = mech.angle) {
|
||||||
|
const me = bullet.length;
|
||||||
|
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||||
|
Matter.Body.setDensity(bullet[me], 0.0005);
|
||||||
|
bullet[me].explodeRad = 275;
|
||||||
|
bullet[me].onEnd = function() {
|
||||||
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
|
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
||||||
|
}
|
||||||
|
bullet[me].minDmgSpeed = 1;
|
||||||
|
bullet[me].beforeDmg = function() {
|
||||||
|
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
|
||||||
|
};
|
||||||
|
speed = mech.crouch ? 43 : 32
|
||||||
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
|
x: mech.Vx / 2 + speed * Math.cos(angle),
|
||||||
|
y: mech.Vy / 2 + speed * Math.sin(angle)
|
||||||
|
});
|
||||||
|
bullet[me].endCycle = game.cycle + Math.floor(mech.crouch ? 120 : 80);
|
||||||
|
bullet[me].restitution = 0.4;
|
||||||
|
bullet[me].do = function() {
|
||||||
|
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
|
||||||
|
};
|
||||||
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
|
}
|
||||||
|
grenadeRPG = function(where = { x: mech.pos.x + 30 * Math.cos(mech.angle), y: mech.pos.y + 30 * Math.sin(mech.angle) }, angle = mech.angle) {
|
||||||
|
const me = bullet.length;
|
||||||
|
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||||
|
Matter.Body.setDensity(bullet[me], 0.0005);
|
||||||
|
bullet[me].explodeRad = 275;
|
||||||
|
bullet[me].onEnd = function() {
|
||||||
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
|
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
||||||
|
}
|
||||||
|
bullet[me].minDmgSpeed = 1;
|
||||||
|
bullet[me].beforeDmg = function() {
|
||||||
|
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
|
||||||
|
};
|
||||||
|
speed = mech.crouch ? 43 : 32
|
||||||
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
|
x: mech.Vx / 2 + speed * Math.cos(angle),
|
||||||
|
y: mech.Vy / 2 + speed * Math.sin(angle)
|
||||||
|
});
|
||||||
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
|
|
||||||
|
bullet[me].endCycle = game.cycle + 70;
|
||||||
|
bullet[me].frictionAir = 0.07;
|
||||||
|
const MAG = 0.015
|
||||||
|
bullet[me].thrust = {
|
||||||
|
x: bullet[me].mass * MAG * Math.cos(angle),
|
||||||
|
y: bullet[me].mass * MAG * Math.sin(angle)
|
||||||
|
}
|
||||||
|
bullet[me].do = function() {
|
||||||
|
this.force.x += this.thrust.x;
|
||||||
|
this.force.y += this.thrust.y;
|
||||||
|
if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
|
||||||
|
this.endCycle = 0; //explode if touching map or blocks
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
grenadeVacuum = function(where = { x: mech.pos.x + 30 * Math.cos(mech.angle), y: mech.pos.y + 30 * Math.sin(mech.angle) }, angle = mech.angle) {
|
||||||
|
const me = bullet.length;
|
||||||
|
bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false));
|
||||||
|
Matter.Body.setDensity(bullet[me], 0.0003);
|
||||||
|
bullet[me].explodeRad = 325 + Math.floor(Math.random() * 50);;
|
||||||
|
bullet[me].onEnd = function() {
|
||||||
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
|
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
||||||
|
}
|
||||||
|
bullet[me].beforeDmg = function() {};
|
||||||
|
bullet[me].restitution = 0.4;
|
||||||
|
bullet[me].do = function() {
|
||||||
|
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
|
||||||
|
|
||||||
|
const suckCycles = 40
|
||||||
|
if (game.cycle > this.endCycle - suckCycles) { //suck
|
||||||
|
const that = this
|
||||||
|
|
||||||
|
function suck(who, radius = that.explodeRad * 3.2) {
|
||||||
|
for (i = 0, len = who.length; i < len; i++) {
|
||||||
|
const sub = Vector.sub(that.position, who[i].position);
|
||||||
|
const dist = Vector.magnitude(sub);
|
||||||
|
if (dist < radius && dist > 150) {
|
||||||
|
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
|
||||||
|
who[i].force.x += knock.x;
|
||||||
|
who[i].force.y += knock.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mag = 0.1
|
||||||
|
if (game.cycle > this.endCycle - 5) {
|
||||||
|
mag = -0.22
|
||||||
|
suck(mob, this.explodeRad * 3)
|
||||||
|
suck(body, this.explodeRad * 2)
|
||||||
|
suck(powerUp, this.explodeRad * 1.5)
|
||||||
|
suck(bullet, this.explodeRad * 1.5)
|
||||||
|
suck([player], this.explodeRad * 1.3)
|
||||||
|
} else {
|
||||||
|
mag = 0.11
|
||||||
|
suck(mob, this.explodeRad * 3)
|
||||||
|
suck(body, this.explodeRad * 2)
|
||||||
|
suck(powerUp, this.explodeRad * 1.5)
|
||||||
|
suck(bullet, this.explodeRad * 1.5)
|
||||||
|
suck([player], this.explodeRad * 1.3)
|
||||||
|
}
|
||||||
|
//keep bomb in place
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
//draw suck
|
||||||
|
const radius = 2.75 * this.explodeRad * (this.endCycle - game.cycle) / suckCycles
|
||||||
|
ctx.fillStyle = "rgba(0,0,0,0.1)";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
speed = 35
|
||||||
|
bullet[me].endCycle = game.cycle + 70;
|
||||||
|
if (mech.crouch) {
|
||||||
|
speed += 9
|
||||||
|
bullet[me].endCycle += 20;
|
||||||
|
}
|
||||||
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
|
x: mech.Vx / 2 + speed * Math.cos(angle),
|
||||||
|
y: mech.Vy / 2 + speed * Math.sin(angle)
|
||||||
|
});
|
||||||
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
|
}
|
||||||
|
|
||||||
|
grenadeNeutron = function(where = { x: mech.pos.x + 30 * Math.cos(mech.angle), y: mech.pos.y + 30 * Math.sin(mech.angle) }, angle = mech.angle) {
|
||||||
|
const me = bullet.length;
|
||||||
|
bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false));
|
||||||
|
b.fireProps(mech.crouch ? 45 : 25, mech.crouch ? 35 : 20, angle, me); //cd , speed
|
||||||
|
Matter.Body.setDensity(bullet[me], 0.000001);
|
||||||
|
bullet[me].endCycle = Infinity;
|
||||||
|
bullet[me].frictionAir = 0;
|
||||||
|
bullet[me].friction = 1;
|
||||||
|
bullet[me].frictionStatic = 1;
|
||||||
|
bullet[me].restitution = 0;
|
||||||
|
bullet[me].minDmgSpeed = 0;
|
||||||
|
bullet[me].damageRadius = 100;
|
||||||
|
bullet[me].maxDamageRadius = 450 + 130 * mod.isNeutronSlow + 130 * mod.isNeutronImmune //+ 150 * Math.random()
|
||||||
|
bullet[me].radiusDecay = (0.81 + 0.15 * mod.isNeutronSlow + 0.15 * mod.isNeutronImmune) / mod.isBulletsLastLonger
|
||||||
|
bullet[me].stuckTo = null;
|
||||||
|
bullet[me].stuckToRelativePosition = null;
|
||||||
|
bullet[me].vacuumSlow = 0.97;
|
||||||
|
if (mod.isRewindGrenade && input.down) {
|
||||||
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
bullet[me].maxDamageRadius *= 1.3
|
||||||
|
mech.rewind(200, false)
|
||||||
|
}
|
||||||
|
bullet[me].beforeDmg = function() {};
|
||||||
|
bullet[me].stuck = function() {};
|
||||||
|
bullet[me].do = function() {
|
||||||
|
function onCollide(that) {
|
||||||
|
that.collisionFilter.mask = 0; //non collide with everything
|
||||||
|
Matter.Body.setVelocity(that, {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
that.do = that.radiationMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mobCollisions = Matter.Query.collides(this, mob)
|
||||||
|
if (mobCollisions.length) {
|
||||||
|
onCollide(this)
|
||||||
|
this.stuckTo = mobCollisions[0].bodyA
|
||||||
|
mobs.statusDoT(this.stuckTo, 0.5, 360) //apply radiation damage status effect on direct hits
|
||||||
|
|
||||||
|
if (this.stuckTo.isVerticesChange) {
|
||||||
|
this.stuckToRelativePosition = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
||||||
|
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
|
||||||
|
}
|
||||||
|
this.stuck = function() {
|
||||||
|
if (this.stuckTo && this.stuckTo.alive) {
|
||||||
|
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
|
||||||
|
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
|
||||||
|
Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
|
||||||
|
} else {
|
||||||
|
this.collisionFilter.mask = cat.map | cat.body | cat.player | cat.mob; //non collide with everything but map
|
||||||
|
this.stuck = function() {
|
||||||
|
this.force.y += this.mass * 0.001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const bodyCollisions = Matter.Query.collides(this, body)
|
||||||
|
if (bodyCollisions.length) {
|
||||||
|
if (!bodyCollisions[0].bodyA.isNotHoldable) {
|
||||||
|
onCollide(this)
|
||||||
|
this.stuckTo = bodyCollisions[0].bodyA
|
||||||
|
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
||||||
|
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
|
||||||
|
} else {
|
||||||
|
this.do = this.radiationMode;
|
||||||
|
}
|
||||||
|
this.stuck = function() {
|
||||||
|
if (this.stuckTo) {
|
||||||
|
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
|
||||||
|
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
|
||||||
|
// Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
|
||||||
|
} else {
|
||||||
|
this.force.y += this.mass * 0.001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Matter.Query.collides(this, map).length) {
|
||||||
|
onCollide(this)
|
||||||
|
} else { //if colliding with nothing just fall
|
||||||
|
this.force.y += this.mass * 0.001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bullet[me].radiationMode = function() { //the do code after the bullet is stuck on something, projects a damaging radiation field
|
||||||
|
this.stuck(); //runs different code based on what the bullet is stuck to
|
||||||
|
if (!mech.isBodiesAsleep) {
|
||||||
|
this.damageRadius = this.damageRadius * 0.85 + 0.15 * this.maxDamageRadius //smooth radius towards max
|
||||||
|
this.maxDamageRadius -= this.radiusDecay
|
||||||
|
if (this.damageRadius < 15) {
|
||||||
|
this.endCycle = 0;
|
||||||
|
} else {
|
||||||
|
//aoe damage to player
|
||||||
|
if (!mod.isNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
|
||||||
|
const DRAIN = 0.0023
|
||||||
|
if (mech.energy > DRAIN) {
|
||||||
|
mech.energy -= DRAIN
|
||||||
|
} else {
|
||||||
|
mech.energy = 0;
|
||||||
|
mech.damage(0.00015)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//aoe damage to mobs
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) {
|
||||||
|
let dmg = b.dmgScale * 0.082
|
||||||
|
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.25 //reduce damage if a wall is in the way
|
||||||
|
if (mob[i].shield) dmg *= 4 //x5 to make up for the /5 that shields normally take
|
||||||
|
mob[i].damage(dmg);
|
||||||
|
mob[i].locatePlayer();
|
||||||
|
if (mod.isNeutronSlow) {
|
||||||
|
Matter.Body.setVelocity(mob[i], {
|
||||||
|
x: mob[i].velocity.x * this.vacuumSlow,
|
||||||
|
y: mob[i].velocity.y * this.vacuumSlow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(this.position.x, this.position.y, this.damageRadius, 0, 2 * Math.PI);
|
||||||
|
ctx.globalCompositeOperation = "lighter"
|
||||||
|
ctx.fillStyle = `rgba(25,139,170,${0.2+0.06*Math.random()})`;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.globalCompositeOperation = "source-over"
|
||||||
|
if (mod.isNeutronSlow) {
|
||||||
|
const that = this
|
||||||
|
|
||||||
|
function slow(who, radius = that.explodeRad * 3.2) {
|
||||||
|
for (i = 0, len = who.length; i < len; i++) {
|
||||||
|
const sub = Vector.sub(that.position, who[i].position);
|
||||||
|
const dist = Vector.magnitude(sub);
|
||||||
|
if (dist < radius) {
|
||||||
|
Matter.Body.setVelocity(who[i], {
|
||||||
|
x: who[i].velocity.x * that.vacuumSlow,
|
||||||
|
y: who[i].velocity.y * that.vacuumSlow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slow(body, this.damageRadius)
|
||||||
|
slow([player], this.damageRadius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mod.isNeutronBomb) {
|
||||||
|
b.grenade = grenadeNeutron
|
||||||
|
} else if (mod.isVacuumBomb) {
|
||||||
|
b.grenade = grenadeVacuum
|
||||||
|
} else if (mod.isRPG) {
|
||||||
|
b.grenade = grenadeRPG
|
||||||
|
} else {
|
||||||
|
b.grenade = grenadeDefault
|
||||||
|
}
|
||||||
|
},
|
||||||
missile(where, angle, speed, size = 1, spawn = 0) {
|
missile(where, angle, speed, size = 1, spawn = 0) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(where.x, where.y, 30 * size, 4 * size, {
|
bullet[me] = Bodies.rectangle(where.x, where.y, 30 * size, 4 * size, {
|
||||||
@@ -1237,16 +1538,16 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomBot(where = mech.pos, isKeep = true) {
|
randomBot(where = mech.pos, isKeep = true, isAll = true) {
|
||||||
if (Math.random() < 0.2) {
|
if (Math.random() < 0.2 && isAll) {
|
||||||
b.orbitBot();
|
|
||||||
if (isKeep) mod.orbitBotCount++;
|
|
||||||
} else if (Math.random() < 0.25) {
|
|
||||||
b.nailBot(where)
|
|
||||||
if (isKeep) mod.nailBotCount++;
|
|
||||||
} else if (Math.random() < 0.33) {
|
|
||||||
b.laserBot(where)
|
b.laserBot(where)
|
||||||
if (isKeep) mod.laserBotCount++;
|
if (isKeep) mod.laserBotCount++;
|
||||||
|
} else if (Math.random() < 0.25 && isAll) {
|
||||||
|
b.orbitBot();
|
||||||
|
if (isKeep) mod.orbitBotCount++;
|
||||||
|
} else if (Math.random() < 0.33) {
|
||||||
|
b.nailBot(where)
|
||||||
|
if (isKeep) mod.nailBotCount++;
|
||||||
} else if (Math.random() < 0.5) {
|
} else if (Math.random() < 0.5) {
|
||||||
b.foamBot(where)
|
b.foamBot(where)
|
||||||
if (isKeep) mod.foamBotCount++;
|
if (isKeep) mod.foamBotCount++;
|
||||||
@@ -2334,32 +2635,6 @@ const b = {
|
|||||||
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.35) * ((i % 2) ? -1 : 1))
|
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.35) * ((i % 2) ? -1 : 1))
|
||||||
Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
|
Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
|
||||||
}
|
}
|
||||||
// if (mod.isWaveReflect) { //single reflection
|
|
||||||
// const sub = Vector.sub(this.position, mech.pos)
|
|
||||||
// if (Vector.magnitude(sub) > 630) {
|
|
||||||
// // Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(Vector.normalise(sub), -2 * POCKET_RANGE))) //teleport to opposite side
|
|
||||||
// if (!this.isJustReflected) {
|
|
||||||
// Matter.Body.setVelocity(this, Vector.mult(this.velocity, -1)); //reflect
|
|
||||||
// this.isJustReflected = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (mod.isWaveReflect) {
|
|
||||||
// Matter.Body.setPosition(this, Vector.add(this.position, player.velocity)) //bullets move with player
|
|
||||||
|
|
||||||
// Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(Vector.normalise(sub), -2 * POCKET_RANGE))) //teleport to opposite side
|
|
||||||
|
|
||||||
// const sub = Vector.sub(this.position, mech.pos)
|
|
||||||
// if (Vector.magnitude(sub) > 630) {
|
|
||||||
// if (!this.isJustReflected) {
|
|
||||||
// Matter.Body.setVelocity(this, Vector.mult(this.velocity, -1)); //reflect
|
|
||||||
// this.isJustReflected = true;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// this.isJustReflected = false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
@@ -2431,48 +2706,6 @@ 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: "grenades",
|
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",
|
description: "lob a single <strong>bouncy</strong> projectile<br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after one second",
|
||||||
@@ -2480,46 +2713,8 @@ const b = {
|
|||||||
ammoPack: 5,
|
ammoPack: 5,
|
||||||
have: false,
|
have: false,
|
||||||
fire() {
|
fire() {
|
||||||
|
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 40 : 30) * b.fireCD); // cool down
|
||||||
},
|
b.grenade()
|
||||||
fireNormal() {
|
|
||||||
const me = bullet.length;
|
|
||||||
const dir = mech.angle; // + Math.random() * 0.05;
|
|
||||||
bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 15, b.fireAttributes(dir, false));
|
|
||||||
Matter.Body.setDensity(bullet[me], 0.0005);
|
|
||||||
bullet[me].explodeRad = 275;
|
|
||||||
bullet[me].onEnd = function() {
|
|
||||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
|
||||||
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
|
||||||
}
|
|
||||||
bullet[me].minDmgSpeed = 1;
|
|
||||||
bullet[me].beforeDmg = function() {
|
|
||||||
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
|
|
||||||
};
|
|
||||||
if (mod.isRPG) {
|
|
||||||
b.fireProps(35, mech.crouch ? 60 : -15, dir, me); //cd , speed
|
|
||||||
bullet[me].endCycle = game.cycle + 70;
|
|
||||||
bullet[me].frictionAir = 0.07;
|
|
||||||
const MAG = 0.015
|
|
||||||
bullet[me].thrust = {
|
|
||||||
x: bullet[me].mass * MAG * Math.cos(dir),
|
|
||||||
y: bullet[me].mass * MAG * Math.sin(dir)
|
|
||||||
}
|
|
||||||
bullet[me].do = function() {
|
|
||||||
this.force.x += this.thrust.x;
|
|
||||||
this.force.y += this.thrust.y;
|
|
||||||
if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
|
|
||||||
this.endCycle = 0; //explode if touching map or blocks
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
b.fireProps(mech.crouch ? 40 : 30, mech.crouch ? 43 : 32, dir, me); //cd , speed
|
|
||||||
bullet[me].endCycle = game.cycle + Math.floor(mech.crouch ? 120 : 80);
|
|
||||||
bullet[me].restitution = 0.4;
|
|
||||||
bullet[me].do = function() {
|
|
||||||
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
fireNeutron() {
|
fireNeutron() {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
@@ -2539,6 +2734,14 @@ const b = {
|
|||||||
bullet[me].stuckTo = null;
|
bullet[me].stuckTo = null;
|
||||||
bullet[me].stuckToRelativePosition = null;
|
bullet[me].stuckToRelativePosition = null;
|
||||||
bullet[me].vacuumSlow = 0.97;
|
bullet[me].vacuumSlow = 0.97;
|
||||||
|
if (mod.isRewindGrenade && input.down) {
|
||||||
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
bullet[me].maxDamageRadius *= 1.3
|
||||||
|
mech.rewind(200, false)
|
||||||
|
}
|
||||||
bullet[me].beforeDmg = function() {};
|
bullet[me].beforeDmg = function() {};
|
||||||
bullet[me].stuck = function() {};
|
bullet[me].stuck = function() {};
|
||||||
bullet[me].do = function() {
|
bullet[me].do = function() {
|
||||||
@@ -2669,69 +2872,6 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fireVacuum() {
|
|
||||||
const me = bullet.length;
|
|
||||||
const dir = mech.angle; // + Math.random() * 0.05;
|
|
||||||
bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, b.fireAttributes(dir, false));
|
|
||||||
Matter.Body.setDensity(bullet[me], 0.0003);
|
|
||||||
bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50);;
|
|
||||||
bullet[me].onEnd = function() {
|
|
||||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
|
||||||
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
|
||||||
}
|
|
||||||
bullet[me].beforeDmg = function() {};
|
|
||||||
const cd = mech.crouch ? 90 : 75
|
|
||||||
b.fireProps(cd, mech.crouch ? 46 : 35, dir, me); //cd , speed
|
|
||||||
bullet[me].endCycle = game.cycle + cd;
|
|
||||||
bullet[me].restitution = 0.4;
|
|
||||||
bullet[me].do = function() {
|
|
||||||
this.force.y += this.mass * 0.0025; //extra gravity for harder arcs
|
|
||||||
|
|
||||||
const suckCycles = 40
|
|
||||||
if (game.cycle > this.endCycle - suckCycles) { //suck
|
|
||||||
const that = this
|
|
||||||
|
|
||||||
function suck(who, radius = that.explodeRad * 3.2) {
|
|
||||||
for (i = 0, len = who.length; i < len; i++) {
|
|
||||||
const sub = Vector.sub(that.position, who[i].position);
|
|
||||||
const dist = Vector.magnitude(sub);
|
|
||||||
if (dist < radius && dist > 150) {
|
|
||||||
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
|
|
||||||
who[i].force.x += knock.x;
|
|
||||||
who[i].force.y += knock.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mag = 0.1
|
|
||||||
if (game.cycle > this.endCycle - 5) {
|
|
||||||
mag = -0.22
|
|
||||||
suck(mob, this.explodeRad * 3)
|
|
||||||
suck(body, this.explodeRad * 2)
|
|
||||||
suck(powerUp, this.explodeRad * 1.5)
|
|
||||||
suck(bullet, this.explodeRad * 1.5)
|
|
||||||
suck([player], this.explodeRad * 1.3)
|
|
||||||
} else {
|
|
||||||
mag = 0.11
|
|
||||||
suck(mob, this.explodeRad * 3)
|
|
||||||
suck(body, this.explodeRad * 2)
|
|
||||||
suck(powerUp, this.explodeRad * 1.5)
|
|
||||||
suck(bullet, this.explodeRad * 1.5)
|
|
||||||
suck([player], this.explodeRad * 1.3)
|
|
||||||
}
|
|
||||||
//keep bomb in place
|
|
||||||
Matter.Body.setVelocity(this, {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
});
|
|
||||||
//draw suck
|
|
||||||
const radius = 2.75 * this.explodeRad * (this.endCycle - game.cycle) / suckCycles
|
|
||||||
ctx.fillStyle = "rgba(0,0,0,0.1)";
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mine",
|
name: "mine",
|
||||||
@@ -2959,7 +3099,7 @@ const b = {
|
|||||||
if (mod.isRailAreaDamage) {
|
if (mod.isRailAreaDamage) {
|
||||||
mob[i].force.x += 2 * FORCE.x;
|
mob[i].force.x += 2 * FORCE.x;
|
||||||
mob[i].force.y += 2 * FORCE.y;
|
mob[i].force.y += 2 * FORCE.y;
|
||||||
const damage = b.dmgScale * 0.1 * Math.sqrt(DEPTH)
|
const damage = b.dmgScale * 0.13 * Math.sqrt(DEPTH)
|
||||||
mob[i].damage(damage);
|
mob[i].damage(damage);
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
game.drawList.push({ //add dmg to draw queue
|
game.drawList.push({ //add dmg to draw queue
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ const level = {
|
|||||||
// game.zoomScale = 1000;
|
// game.zoomScale = 1000;
|
||||||
// game.setZoom();
|
// game.setZoom();
|
||||||
// mech.setField("wormhole")
|
// mech.setField("wormhole")
|
||||||
// b.giveGuns("shotgun")
|
// b.giveGuns("grenades")
|
||||||
// mod.isIncendiary = true
|
// mod.isIncendiary = true
|
||||||
// mod.is3Missiles = true
|
// mod.is3Missiles = true
|
||||||
// mod.giveMod("shotgun slug")
|
// mod.giveMod("CPT reversal")
|
||||||
// mod.giveMod("diffuse beam")
|
// mod.giveMod("causality bombs")
|
||||||
|
|
||||||
level.intro(); //starting level
|
level.intro(); //starting level
|
||||||
// level.testing(); //not in rotation
|
// level.testing(); //not in rotation
|
||||||
|
|||||||
299
js/mods.js
299
js/mods.js
@@ -108,21 +108,6 @@ const mod = {
|
|||||||
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount + mod.boomBotCount + mod.plasmaBotCount + mod.orbitBotCount
|
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount + mod.boomBotCount + mod.plasmaBotCount + mod.orbitBotCount
|
||||||
},
|
},
|
||||||
mods: [{
|
mods: [{
|
||||||
name: "integrated armament",
|
|
||||||
description: "increase <strong class='color-d'>damage</strong> by <strong>25%</strong><br>your inventory can only hold <strong>1 gun</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return b.inventory.length < 2
|
|
||||||
},
|
|
||||||
requires: "no more than 1 gun",
|
|
||||||
effect() {
|
|
||||||
mod.isOneGun = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.isOneGun = false;
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "capacitor",
|
name: "capacitor",
|
||||||
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>7</strong> stored <strong class='color-f'>energy</strong>",
|
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>7</strong> stored <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -176,7 +161,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.isEnergyLoss && mech.maxEnergy === 1 && !mod.isMissileField && !mod.isSporeField && !mod.isTimeAvoidDeath
|
return mod.isEnergyLoss && mech.maxEnergy === 1 && !mod.isMissileField && !mod.isSporeField && !mod.isRewindAvoidDeath
|
||||||
},
|
},
|
||||||
requires: "heat engine, not max energy increase, CPT, missile or spore nano-scale",
|
requires: "heat engine, not max energy increase, CPT, missile or spore nano-scale",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -210,9 +195,9 @@ const mod = {
|
|||||||
maxCount: 6,
|
maxCount: 6,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true
|
return mech.Fx === 0.016
|
||||||
},
|
},
|
||||||
requires: "",
|
requires: "base movement speed",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mod.restDamage += 0.25
|
mod.restDamage += 0.25
|
||||||
},
|
},
|
||||||
@@ -252,6 +237,22 @@ const mod = {
|
|||||||
mod.isAcidDmg = false;
|
mod.isAcidDmg = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "integrated armament",
|
||||||
|
description: "increase <strong class='color-d'>damage</strong> by <strong>25%</strong><br>your inventory can only hold <strong>1 gun</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return b.inventory.length < 2
|
||||||
|
},
|
||||||
|
requires: "no more than 1 gun",
|
||||||
|
effect() {
|
||||||
|
mod.isOneGun = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.isOneGun = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "negative feedback",
|
name: "negative feedback",
|
||||||
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> missing base <strong>health</strong>",
|
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> missing base <strong>health</strong>",
|
||||||
@@ -371,78 +372,6 @@ const mod = {
|
|||||||
mod.throwChargeRate = 1
|
mod.throwChargeRate = 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "reaction inhibitor",
|
|
||||||
description: "mobs spawn with <strong>12%</strong> less <strong>health</strong>",
|
|
||||||
maxCount: 3,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return mod.nailsDeathMob || mod.sporesOnDeath || mod.isExplodeMob
|
|
||||||
},
|
|
||||||
requires: "zoospore vector or impact shear or thermal runaway",
|
|
||||||
effect: () => {
|
|
||||||
mod.mobSpawnWithHealth *= 0.88
|
|
||||||
|
|
||||||
//set all mobs at full health to 0.85
|
|
||||||
for (let i = 0; i < mob.length; i++) {
|
|
||||||
if (mob.health > mod.mobSpawnWithHealth) mob.health = mod.mobSpawnWithHealth
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.mobSpawnWithHealth = 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "zoospore vector",
|
|
||||||
description: "mobs produce <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> when they <strong>die</strong><br><strong>9%</strong> chance",
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return !mod.nailsDeathMob && !mod.isExplodeMob
|
|
||||||
},
|
|
||||||
requires: "not impact shear or thermal runaway",
|
|
||||||
effect() {
|
|
||||||
mod.sporesOnDeath += 0.09;
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
b.spore(mech.pos)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.sporesOnDeath = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "impact shear",
|
|
||||||
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br>nails target nearby mobs",
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return !mod.sporesOnDeath && !mod.isExplodeMob
|
|
||||||
},
|
|
||||||
requires: "not zoospore vector or thermal runaway",
|
|
||||||
effect: () => {
|
|
||||||
mod.nailsDeathMob++
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.nailsDeathMob = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "thermal runaway",
|
|
||||||
description: "mobs <strong class='color-e'>explode</strong> when they <strong>die</strong><br><em>be careful</em>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return (mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode) && !mod.sporesOnDeath && !mod.nailsDeathMob
|
|
||||||
},
|
|
||||||
requires: "an explosive damage source, not zoospore vector or impact shear",
|
|
||||||
effect: () => {
|
|
||||||
mod.isExplodeMob = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.isExplodeMob = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "ammonium nitrate",
|
name: "ammonium nitrate",
|
||||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>20%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>20%</strong>",
|
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>20%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>20%</strong>",
|
||||||
@@ -508,15 +437,87 @@ const mod = {
|
|||||||
mod.isImmuneExplosion = false;
|
mod.isImmuneExplosion = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "thermal runaway",
|
||||||
|
description: "mobs <strong class='color-e'>explode</strong> when they <strong>die</strong><br><em>be careful</em>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return (mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode) && !mod.sporesOnDeath && !mod.nailsDeathMob && !mod.isBotSpawner
|
||||||
|
},
|
||||||
|
requires: "an explosive damage source, no other mob death mods",
|
||||||
|
effect: () => {
|
||||||
|
mod.isExplodeMob = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.isExplodeMob = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "reaction inhibitor",
|
||||||
|
description: "mobs spawn with <strong>12%</strong> less <strong>health</strong>",
|
||||||
|
maxCount: 3,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return mod.nailsDeathMob || mod.sporesOnDeath || mod.isExplodeMob || mod.isBotSpawner
|
||||||
|
},
|
||||||
|
requires: "any mob death mod",
|
||||||
|
effect: () => {
|
||||||
|
mod.mobSpawnWithHealth *= 0.88
|
||||||
|
|
||||||
|
//set all mobs at full health to 0.85
|
||||||
|
for (let i = 0; i < mob.length; i++) {
|
||||||
|
if (mob.health > mod.mobSpawnWithHealth) mob.health = mod.mobSpawnWithHealth
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.mobSpawnWithHealth = 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zoospore vector",
|
||||||
|
description: "mobs produce <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> when they <strong>die</strong><br><strong>9%</strong> chance",
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return !mod.nailsDeathMob && !mod.isExplodeMob && !mod.isBotSpawner
|
||||||
|
},
|
||||||
|
requires: "no other mob death mods",
|
||||||
|
effect() {
|
||||||
|
mod.sporesOnDeath += 0.09;
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
b.spore(mech.pos)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.sporesOnDeath = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "impact shear",
|
||||||
|
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br>nails target nearby mobs",
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return !mod.sporesOnDeath && !mod.isExplodeMob && !mod.isBotSpawner
|
||||||
|
},
|
||||||
|
requires: "no other mob death mods",
|
||||||
|
effect: () => {
|
||||||
|
mod.nailsDeathMob++
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.nailsDeathMob = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "scrap bots",
|
name: "scrap bots",
|
||||||
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",
|
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,
|
maxCount: 3,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.totalBots() > 0
|
return mod.totalBots() > 0 && !mod.sporesOnDeath && !mod.nailsDeathMob && !mod.isExplodeMob
|
||||||
},
|
},
|
||||||
requires: "a bot",
|
requires: "a bot and no other mob death mods",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isBotSpawner += 0.20;
|
mod.isBotSpawner += 0.20;
|
||||||
},
|
},
|
||||||
@@ -524,23 +525,6 @@ const mod = {
|
|||||||
mod.isBotSpawner = 0;
|
mod.isBotSpawner = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "bot fabrication",
|
|
||||||
description: "anytime you collect <strong>5</strong> <strong class='color-r'>rerolls</strong><br>use them to build a <strong>random bot</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return powerUps.reroll.rerolls > 5 || build.isCustomSelection
|
|
||||||
},
|
|
||||||
requires: "at least 6 rerolls",
|
|
||||||
effect() {
|
|
||||||
mod.isRerollBots = true;
|
|
||||||
powerUps.reroll.changeRerolls(0)
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.isRerollBots = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "nail-bot",
|
name: "nail-bot",
|
||||||
description: "a bot fires <strong>nails</strong> at targets in line of sight",
|
description: "a bot fires <strong>nails</strong> at targets in line of sight",
|
||||||
@@ -664,9 +648,9 @@ const mod = {
|
|||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true
|
return mech.maxEnergy > 0.5
|
||||||
},
|
},
|
||||||
requires: "",
|
requires: "maximum energy above 50%",
|
||||||
effect() {
|
effect() {
|
||||||
mod.laserBotCount++;
|
mod.laserBotCount++;
|
||||||
b.laserBot();
|
b.laserBot();
|
||||||
@@ -746,6 +730,23 @@ const mod = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "bot fabrication",
|
||||||
|
description: "anytime you collect <strong>5</strong> <strong class='color-r'>rerolls</strong><br>use them to build a <strong>random bot</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return powerUps.reroll.rerolls > 5 || build.isCustomSelection
|
||||||
|
},
|
||||||
|
requires: "at least 6 rerolls",
|
||||||
|
effect() {
|
||||||
|
mod.isRerollBots = true;
|
||||||
|
powerUps.reroll.changeRerolls(0)
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.isRerollBots = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "perimeter defense",
|
name: "perimeter defense",
|
||||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>3%</strong><br>for each of your permanent <strong>bots</strong>",
|
description: "reduce <strong class='color-harm'>harm</strong> by <strong>3%</strong><br>for each of your permanent <strong>bots</strong>",
|
||||||
@@ -1039,18 +1040,50 @@ const mod = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "CPT reversal",
|
name: "CPT reversal",
|
||||||
description: "<strong>rewind 1.5 - 5</strong> seconds to avoid <strong class='color-harm'>harm</strong><br>drains <strong>66 - 220</strong> <strong class='color-f'>energy</strong>",
|
description: "<strong class='color-rewind'>rewind</strong> <strong>1.5 - 5</strong> seconds to avoid <strong class='color-harm'>harm</strong><br>drains <strong>66 - 220</strong> <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
|
||||||
return mech.maxEnergy > 0.99 && (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1) && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss && !mod.isPiezo
|
return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss && !mod.isPiezo
|
||||||
},
|
},
|
||||||
requires: "not nano-scale, mass-energy, standing wave, acute stress, piezoelectricity",
|
requires: "not nano-scale, mass-energy, standing wave, acute stress, piezoelectricity",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isTimeAvoidDeath = true;
|
mod.isRewindAvoidDeath = true;
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.isTimeAvoidDeath = false;
|
mod.isRewindAvoidDeath = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "causality bots",
|
||||||
|
description: "when you <strong class='color-rewind'>rewind</strong>, build some <strong>bots</strong><br>that protect you for about <strong>7</strong> seconds",
|
||||||
|
maxCount: 3,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return mod.isRewindAvoidDeath || mod.isRewindEnergy
|
||||||
|
},
|
||||||
|
requires: "CPT",
|
||||||
|
effect() {
|
||||||
|
mod.isRewindBot++;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.isRewindBot = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "causality bombs",
|
||||||
|
description: "before you <strong class='color-rewind'>rewind</strong> drop some <strong>grenades</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return mod.isRewindAvoidDeath
|
||||||
|
},
|
||||||
|
requires: "CPT",
|
||||||
|
effect() {
|
||||||
|
mod.isRewindGrenade = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.isRewindGrenade = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1059,7 +1092,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !mod.isEnergyHealth && !mod.isTimeAvoidDeath
|
return !mod.isEnergyHealth && !mod.isRewindAvoidDeath
|
||||||
},
|
},
|
||||||
requires: "not mass-energy equivalence, CPT reversal",
|
requires: "not mass-energy equivalence, CPT reversal",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -1094,7 +1127,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !mod.isEnergyLoss && !mod.isPiezo && !mod.isTimeAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
|
return !mod.isEnergyLoss && !mod.isPiezo && !mod.isRewindAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
|
||||||
},
|
},
|
||||||
requires: "not piezoelectricity, acute stress response, 1st law, negative mass field",
|
requires: "not piezoelectricity, acute stress response, 1st law, negative mass field",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -1163,7 +1196,7 @@ const mod = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "energy conservation",
|
name: "energy conservation",
|
||||||
description: "<strong>7%</strong> of <strong class='color-d'>damage</strong> done recovered as <strong class='color-f'>energy</strong>",
|
description: "<strong>6%</strong> of <strong class='color-d'>damage</strong> done recovered as <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -1171,7 +1204,7 @@ const mod = {
|
|||||||
},
|
},
|
||||||
requires: "some increased damage",
|
requires: "some increased damage",
|
||||||
effect() {
|
effect() {
|
||||||
mod.energySiphon += 0.07;
|
mod.energySiphon += 0.06;
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.energySiphon = 0;
|
mod.energySiphon = 0;
|
||||||
@@ -2355,12 +2388,14 @@ const mod = {
|
|||||||
allowed() {
|
allowed() {
|
||||||
return mod.haveGunCheck("grenades") && !mod.isVacuumBomb && !mod.isNeutronBomb
|
return mod.haveGunCheck("grenades") && !mod.isVacuumBomb && !mod.isNeutronBomb
|
||||||
},
|
},
|
||||||
requires: "grenades, not vacuum bomb",
|
requires: "grenades, not vacuum bomb, neutron",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isRPG = true;
|
mod.isRPG = true;
|
||||||
|
b.setGrenadeMode()
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.isRPG = false;
|
mod.isRPG = false;
|
||||||
|
b.setGrenadeMode()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2374,17 +2409,11 @@ const mod = {
|
|||||||
requires: "grenades, not rocket-propelled",
|
requires: "grenades, not rocket-propelled",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isVacuumBomb = true;
|
mod.isVacuumBomb = true;
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
b.setGrenadeMode()
|
||||||
if (b.guns[i].name === "grenades") b.guns[i].fire = b.guns[i].fireVacuum
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.isVacuumBomb = false;
|
mod.isVacuumBomb = false;
|
||||||
if (!mod.isNeutronBomb) {
|
b.setGrenadeMode()
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
|
||||||
if (b.guns[i].name === "grenades") b.guns[i].fire = (mod.isNeutronBomb) ? b.guns[i].fireNeutron : b.guns[i].fireNormal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2398,15 +2427,11 @@ const mod = {
|
|||||||
requires: "grenades, not rocket-propelled or fragmentation",
|
requires: "grenades, not rocket-propelled or fragmentation",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isNeutronBomb = true;
|
mod.isNeutronBomb = true;
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
b.setGrenadeMode()
|
||||||
if (b.guns[i].name === "grenades") b.guns[i].fire = b.guns[i].fireNeutron
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.isNeutronBomb = false;
|
mod.isNeutronBomb = false;
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
b.setGrenadeMode()
|
||||||
if (b.guns[i].name === "grenades") b.guns[i].fire = (mod.isVacuumBomb) ? b.guns[i].fireVacuum : b.guns[i].fireNormal
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3671,5 +3696,7 @@ const mod = {
|
|||||||
isBotDamage: null,
|
isBotDamage: null,
|
||||||
isBanish: null,
|
isBanish: null,
|
||||||
isMaxEnergyMod: null,
|
isMaxEnergyMod: null,
|
||||||
isLowEnergyDamage: null
|
isLowEnergyDamage: null,
|
||||||
|
isRewindBot: null,
|
||||||
|
isRewindGrenade: null
|
||||||
}
|
}
|
||||||
143
js/player.js
143
js/player.js
@@ -485,65 +485,104 @@ const mech = {
|
|||||||
if (mod.energyRegen === 0) dmg *= 0.4 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
|
if (mod.energyRegen === 0) dmg *= 0.4 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
|
||||||
if (mod.isTurret && mech.crouch) dmg *= 0.5;
|
if (mod.isTurret && mech.crouch) dmg *= 0.5;
|
||||||
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
|
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
|
||||||
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.85 // 1 - 0.15
|
||||||
dmg *= 0.85 // 1 - 0.15
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dmg
|
return dmg
|
||||||
},
|
},
|
||||||
damage(dmg) {
|
rewind(steps, isDrain = true) {
|
||||||
if (mod.isTimeAvoidDeath && mech.energy > 0.66) {
|
let history = mech.history[(mech.cycle - steps) % 300]
|
||||||
const steps = Math.floor(Math.min(299, 137 * mech.energy)) //go back 2 seconds at 100% energy
|
Matter.Body.setPosition(player, history.position);
|
||||||
let history = mech.history[(mech.cycle - steps) % 300]
|
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||||
Matter.Body.setPosition(player, history.position);
|
// move bots to follow player
|
||||||
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
// move bots to follow player
|
if (bullet[i].botType) {
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
||||||
if (bullet[i].botType) {
|
x: 250 * (Math.random() - 0.5),
|
||||||
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
y: 250 * (Math.random() - 0.5)
|
||||||
x: 250 * (Math.random() - 0.5),
|
}));
|
||||||
y: 250 * (Math.random() - 0.5)
|
Matter.Body.setVelocity(bullet[i], {
|
||||||
}));
|
x: 0,
|
||||||
Matter.Body.setVelocity(bullet[i], {
|
y: 0
|
||||||
x: 0,
|
});
|
||||||
y: 0
|
}
|
||||||
});
|
}
|
||||||
|
if (isDrain) {
|
||||||
|
mech.energy = Math.max(mech.energy - steps / 136, 0.01)
|
||||||
|
}
|
||||||
|
mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
||||||
|
|
||||||
|
let isDrawPlayer = true
|
||||||
|
const shortPause = function() {
|
||||||
|
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
|
||||||
|
game.fpsCap = game.fpsCapDefault
|
||||||
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
|
document.getElementById("dmg").style.transition = "opacity 1s";
|
||||||
|
document.getElementById("dmg").style.opacity = "0";
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(shortPause);
|
||||||
|
if (isDrawPlayer) {
|
||||||
|
isDrawPlayer = false
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(canvas.width2, canvas.height2); //center
|
||||||
|
ctx.scale(game.zoom / game.edgeZoomOutSmooth, game.zoom / game.edgeZoomOutSmooth); //zoom in once centered
|
||||||
|
ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate
|
||||||
|
for (let i = 1; i < steps; i++) {
|
||||||
|
history = mech.history[(mech.cycle - i) % 300]
|
||||||
|
mech.pos.x = history.position.x
|
||||||
|
mech.pos.y = history.position.y
|
||||||
|
mech.draw();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
mech.resetHistory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
mech.energy = Math.max(mech.energy - steps / 136, 0.01)
|
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
|
||||||
mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
game.fpsCap = (isDrain ? 3 : 5) //1 is longest pause, 4 is standard
|
||||||
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
let isDrawPlayer = true
|
mech.defaultFPSCycle = mech.cycle
|
||||||
const shortPause = function() {
|
if (mod.isRewindBot) {
|
||||||
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
|
const len = (isDrain ? steps * 0.042 : 2) * mod.isRewindBot
|
||||||
game.fpsCap = game.fpsCapDefault
|
for (let i = 0; i < len; i++) {
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
where = mech.history[(mech.cycle - i * 40) % 300].position //spread out spawn locations along past history
|
||||||
} else {
|
b.randomBot({
|
||||||
requestAnimationFrame(shortPause);
|
x: where.x + 100 * (Math.random() - 0.5),
|
||||||
if (isDrawPlayer) {
|
y: where.y + 100 * (Math.random() - 0.5)
|
||||||
isDrawPlayer = false
|
}, false, false)
|
||||||
|
bullet[bullet.length - 1].endCycle = game.cycle + 360 + Math.floor(180 * Math.random()) //6-9 seconds
|
||||||
ctx.save();
|
}
|
||||||
ctx.translate(canvas.width2, canvas.height2); //center
|
}
|
||||||
ctx.scale(game.zoom / game.edgeZoomOutSmooth, game.zoom / game.edgeZoomOutSmooth); //zoom in once centered
|
},
|
||||||
ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate
|
damage(dmg) {
|
||||||
for (let i = 1; i < steps; i++) {
|
if (mod.isRewindAvoidDeath && mech.energy > 0.66) {
|
||||||
history = mech.history[(mech.cycle - i) % 300]
|
const steps = Math.floor(Math.min(299, 137 * mech.energy)) //go back 2 seconds at 100% energy
|
||||||
mech.pos.x = history.position.x
|
if (mod.isRewindGrenade) {
|
||||||
mech.pos.y = history.position.y
|
for (let i = 1, len = Math.floor(3 + steps / 60); i < len; i++) {
|
||||||
mech.draw();
|
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
|
||||||
}
|
const who = bullet[bullet.length - 1]
|
||||||
ctx.restore();
|
if (mod.isVacuumBomb) {
|
||||||
mech.resetHistory()
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.5,
|
||||||
|
y: who.velocity.y * 0.5
|
||||||
|
});
|
||||||
|
} else if (mod.isRPG) {
|
||||||
|
who.endCycle = (who.endCycle - game.cycle) * 0.2 + game.cycle
|
||||||
|
} else if (mod.isNeutronBomb) {
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.3,
|
||||||
|
y: who.velocity.y * 0.3
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.5,
|
||||||
|
y: who.velocity.y * 0.5
|
||||||
|
});
|
||||||
|
who.endCycle = (who.endCycle - game.cycle) * 0.5 + game.cycle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
mech.rewind(steps)
|
||||||
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
|
|
||||||
game.fpsCap = 3 //1 is shortest pause, 4 is standard
|
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
|
||||||
mech.defaultFPSCycle = mech.cycle
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mech.lastHarmCycle = mech.cycle
|
mech.lastHarmCycle = mech.cycle
|
||||||
@@ -1765,7 +1804,7 @@ const mech = {
|
|||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp(180);
|
mech.lookForPickUp(180);
|
||||||
|
|
||||||
const DRAIN = 0.0011
|
const DRAIN = 0.0013
|
||||||
if (mech.energy > DRAIN) {
|
if (mech.energy > DRAIN) {
|
||||||
mech.energy -= DRAIN;
|
mech.energy -= DRAIN;
|
||||||
if (mech.energy < DRAIN) {
|
if (mech.energy < DRAIN) {
|
||||||
|
|||||||
@@ -517,13 +517,20 @@ em {
|
|||||||
.color-harm {
|
.color-harm {
|
||||||
/* color: */
|
/* color: */
|
||||||
/* text-shadow: #FC0 1px 0 10px; */
|
/* text-shadow: #FC0 1px 0 10px; */
|
||||||
background-color: hsla(325, 100%, 85%, 0.15);
|
background-color: hsla(51, 100%, 71%, 0.187);
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .color-rewind {
|
||||||
|
background-image: linear-gradient(to left, #fff, #bbb);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 2px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
} */
|
||||||
|
|
||||||
.color-r {
|
.color-r {
|
||||||
color: #f7b;
|
color: #f7b;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
|
|||||||
63
todo.txt
63
todo.txt
@@ -1,21 +1,19 @@
|
|||||||
*********** NEXT PATCH ***********
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
added more requirements to various mods
|
mod: causality bots - before you rewind, build bots that protect you for for 7 seconds
|
||||||
|
|
||||||
CPT reversal is more flexible with energy
|
mod grenade: causality bombs - before you rewind, drop some grenades
|
||||||
1.5-5 seconds of rewind drains 66% - 220% energy
|
|
||||||
|
|
||||||
mod: exothermic process - renamed acute stress response
|
|
||||||
mod: heat engine - reduce max energy by 50 increase damage by 40%
|
|
||||||
mod: Gibbs free energy - gain 5% damage for every 10 energy below 100
|
|
||||||
|
|
||||||
************** BUGS **************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
(fixed) red square mobs no longer die on contact
|
mod and mob are too similar
|
||||||
might be side effects (we put the player invincibility after mob on damage code)
|
|
||||||
|
|
||||||
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
||||||
|
|
||||||
|
(always) is there a way to check if the player is stuck inside the map or block
|
||||||
|
trigger a short term non-collide if that occurs
|
||||||
|
|
||||||
(4+ reports before potential fix) bug - crouch and worm hole? -> crouch locked in
|
(4+ reports before potential fix) bug - crouch and worm hole? -> crouch locked in
|
||||||
players have extra gravity
|
players have extra gravity
|
||||||
might be from the short jump code
|
might be from the short jump code
|
||||||
@@ -31,20 +29,39 @@ mod: Gibbs free energy - gain 5% damage for every 10 energy below 100
|
|||||||
|
|
||||||
(repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping
|
(repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping
|
||||||
|
|
||||||
************** TODO **************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
mod that gives a bonus for low energy
|
combine fragmentation grenades that that mod that makes railguns fragment into nails into one single mod, and let it apply to shotgun slug
|
||||||
damage again or something different
|
|
||||||
requires heat engine
|
|
||||||
|
|
||||||
CPT like mods
|
mod: power up magnetism - power ups drift towards player
|
||||||
delayed rewind: after taking damage, play for 2 seconds, then rewind to just before you took damage
|
where would this code go?
|
||||||
and return lost health
|
|
||||||
this might need code to run in a field to work
|
super balls start at 3, not 4
|
||||||
time dilation field?
|
have to balance damage
|
||||||
gain a scrap bot after rewinding
|
|
||||||
use ammo to rewind instead of energy
|
RPG might need a buff
|
||||||
explode the area where you were hit before rewinding
|
|
||||||
|
retrocausality bomb should fire 3 grenades at once that spread out a small bit before they explode?
|
||||||
|
this means you'd have to make grenades a method.
|
||||||
|
|
||||||
|
make different move methods
|
||||||
|
mod: crouch charge jump
|
||||||
|
mod: double jump
|
||||||
|
|
||||||
|
mod: when mobs are at full health you do 40% to them
|
||||||
|
|
||||||
|
mechanic: failed technology - add mods to the mod pool with a dumb effect
|
||||||
|
don't show up in custom?
|
||||||
|
negative effect (one time effects are better to avoid code clutter)
|
||||||
|
remove all your energy
|
||||||
|
eject all your rerolls (not bad with dup)
|
||||||
|
teleport to the start of the level
|
||||||
|
remove your bots (requires you to have some bots)
|
||||||
|
your bots are changed to random bots
|
||||||
|
|
||||||
|
mod - move super fast, go intangible, drain energy very fast
|
||||||
|
this is like a dodge roll
|
||||||
|
mod for standing wave?, cloaking?
|
||||||
|
|
||||||
spawn a few power ups on the final boss level
|
spawn a few power ups on the final boss level
|
||||||
|
|
||||||
@@ -279,7 +296,7 @@ n-gon outreach ideas
|
|||||||
javascript:(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()
|
javascript:(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()
|
||||||
|
|
||||||
|
|
||||||
************** LORE **************
|
******************************************************** LORE ********************************************************
|
||||||
|
|
||||||
lore - a robot (the player) gains self awareness
|
lore - a robot (the player) gains self awareness
|
||||||
each mod/gun/field is a new tech
|
each mod/gun/field is a new tech
|
||||||
|
|||||||
Reference in New Issue
Block a user