drone rework, reroll mods

anthropic principle - now consumes 1 rerolls, and heals player to 50% health instead of letting them die
many worlds - 66% chance for rerolls
quantum immortality - also gives 3 rerolls
mod drones - Brushless Motor: drones move faster
mod drones - redundant systems: removed
choices in power up selection should no longer repeat the previous choices when possible
This commit is contained in:
landgreen
2020-05-16 09:46:43 -07:00
parent 30518de6cb
commit 0ff8021ea8
8 changed files with 215 additions and 172 deletions

View File

@@ -36,7 +36,7 @@ const b = {
modCollisionImmuneCycles: null,
modBlockDmg: null,
isModPiezo: null,
isModDroneCollide: null,
isModFastDrones: null,
isModFastSpores: null,
modSuperBallNumber: null,
modOneSuperBall: null,
@@ -49,7 +49,6 @@ const b = {
isModHealthRecovery: null,
isModEnergyLoss: null,
isModDeathAvoid: null,
isModDeathAvoidOnCD: null,
modWaveSpeedMap: null,
modWaveSpeedBody: null,
isModSporeField: null,
@@ -531,7 +530,7 @@ const b = {
},
{
name: "Pauli exclusion",
description: `unable to <strong>collide</strong> with mobs for <strong>+2</strong> seconds<br>activates after being <strong>harmed</strong> from a collision`,
description: `<strong>immune</strong> to <strong>harm</strong> for <strong>+1</strong> seconds<br>activates after being <strong>harmed</strong> from a collision`,
maxCount: 9,
count: 0,
allowed() {
@@ -539,8 +538,8 @@ const b = {
},
requires: "",
effect() {
b.modCollisionImmuneCycles += 120;
mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
b.modCollisionImmuneCycles += 60;
mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
},
remove() {
b.modCollisionImmuneCycles = 30;
@@ -562,40 +561,6 @@ const b = {
b.isModSlowFPS = false;
}
},
{
name: "quantum immortality",
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br><em>guns, ammo, field, and mods are randomized</em>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
b.isModImmortal = true;
},
remove() {
b.isModImmortal = false;
}
},
{
name: "anthropic principle",
description: "<strong>fatal harm</strong> can't happen<br><strong>saves</strong> you up to once every <strong>3</strong> seconds",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
b.isModDeathAvoid = true;
b.isModDeathAvoidOnCD = false;
},
remove() {
b.isModDeathAvoid = false;
b.isModDeathAvoidOnCD = false;
}
},
{
name: "entanglement",
nameInfo: "<span id = 'mod-entanglement'></span>",
@@ -780,7 +745,7 @@ const b = {
},
{
name: "Bayesian inference",
description: "<strong>33%</strong> chance for double <strong>power ups</strong> to drop<br><strong>remove</strong> all future <strong>ammo</strong> power ups",
description: "<strong>37%</strong> chance for double <strong>power ups</strong> to drop<br><strong>remove</strong> all future <strong>ammo</strong> power ups",
maxCount: 1,
count: 0,
allowed() {
@@ -788,7 +753,7 @@ const b = {
},
requires: "",
effect: () => {
b.modBayesian = 0.33;
b.modBayesian = 0.37;
},
remove() {
b.modBayesian = 0;
@@ -828,7 +793,7 @@ const b = {
},
{
name: "determinism",
description: "spawn <strong>4</strong> <strong class='color-m'>mods</strong> and 2 <strong class='color-h'>heal</strong> power ups<br>future <strong>power ups</strong> are limited to <strong>one choice</strong>",
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong> and 2 <strong class='color-h'>heal</strong> power ups<br>future <strong>power ups</strong> are limited to <strong>one choice</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -837,7 +802,7 @@ const b = {
requires: "not cardinality",
effect: () => {
b.isModDeterminism = true;
for (let i = 0; i < 4; i++) { //if you change the six also change it in Born rule
for (let i = 0; i < 5; i++) { //if you change the six also change it in Born rule
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
}
@@ -852,7 +817,7 @@ const b = {
},
{
name: "many worlds",
description: "spawn a <strong class='color-r'>reroll</strong> after choosing a power up",
description: "after choosing a <strong>gun</strong>, <strong>field</strong>, or <strong class='color-m'>mod</strong><br><strong>66%</strong> chance to spawn a <strong class='color-r'>reroll</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -870,6 +835,45 @@ const b = {
b.manyWorlds = false;
}
},
{
name: "anthropic principle",
nameInfo: "<span id = 'mod-anthropic'></span>",
description: "<strong class='color-h'>heal</strong> to <strong>50%</strong> health instead of <strong>dying</strong><br>consumes <strong>1</strong> <strong class='color-r'>reroll</strong>",
maxCount: 1,
count: 0,
allowed() {
return powerUps.reroll.rerolls > 0 || build.isCustomSelection
},
requires: "at least 1 reroll",
effect() {
b.isModDeathAvoid = true;
setTimeout(function () {
powerUps.reroll.changeRerolls(0)
}, 1000);
},
remove() {
b.isModDeathAvoid = false;
}
},
{
name: "quantum immortality",
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br>spawn <strong>3</strong> <strong class='color-r'>rerolls</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
b.isModImmortal = true;
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
},
remove() {
b.isModImmortal = false;
}
},
{
name: "Born rule",
description: "<strong>remove</strong> all current <strong class='color-m'>mods</strong><br>spawn new <strong class='color-m'>mods</strong> to replace them",
@@ -991,7 +995,7 @@ const b = {
},
{
name: "shotgun spin-statistics",
description: "firing the <strong>shotgun</strong> makes you <br><strong>immune</strong> to collisions for <strong>1 second</strong>",
description: "firing the <strong>shotgun</strong> makes you <br><strong>immune</strong> to <strong>harm</strong> for <strong>1 second</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1364,8 +1368,8 @@ const b = {
}
},
{
name: "redundant systems",
description: "<strong>drone</strong> collisions no longer reduce their <strong>lifespan</strong>",
name: "brushless motor",
description: "<strong>drones</strong> accelerate <strong>50%</strong> faster",
maxCount: 1,
count: 0,
allowed() {
@@ -1373,10 +1377,10 @@ const b = {
},
requires: "drones",
effect() {
b.isModDroneCollide = true
b.isModFastDrones = true
},
remove() {
b.isModDroneCollide = true;
b.isModFastDrones = false
}
},
{
@@ -2133,7 +2137,7 @@ const b = {
let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) {
if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) {
const angle = Matter.Vector.angle(collide[i].normal, {
x: 1,
y: 0
@@ -2141,7 +2145,7 @@ const b = {
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation
for (let j = 0; j < 10; j++) {
if (Matter.Query.collides(this, map).length > 0) {
if (Matter.Query.collides(this, map).length > 0) { //touching map
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setStatic(this, true) //don't set to static if not touching map
} else {
@@ -2156,7 +2160,8 @@ const b = {
//sometimes the mine can't attach to map and it just needs to be reset
const that = this
setTimeout(function () {
if (Matter.Query.collides(that, map).length === 0) {
if (Matter.Query.collides(that, map).length === 0 || Matter.Query.point(map, that.position).length > 0) {
console.log(that)
that.endCycle = 0 // if not touching map explode
that.isArmed = false
b.mine(that.position, that.velocity, that.angle)
@@ -2366,17 +2371,18 @@ const b = {
},
drone(speed = 1) {
const me = bullet.length;
const THRUST = 0.0015
const dir = mech.angle + 0.2 * (Math.random() - 0.5);
const THRUST = b.isModFastDrones ? 0.0025 : 0.0015
const FRICTION = b.isModFastDrones ? 0.008 : 0.0005
const dir = mech.angle + 0.4 * (Math.random() - 0.5);
const RADIUS = (4.5 + 3 * Math.random())
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 8, RADIUS, {
angle: dir,
inertia: Infinity,
friction: 0.05,
frictionAir: 0.0005,
frictionAir: FRICTION,
restitution: 1,
dmg: 0.23, //damage done in addition to the damage from momentum
lookFrequency: 107 + Math.floor(47 * Math.random()),
lookFrequency: 100 + Math.floor(23 * Math.random()),
endCycle: game.cycle + Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
collisionFilter: {
@@ -2396,7 +2402,7 @@ const b = {
});
this.lockedOn = null
if (this.endCycle > game.cycle + this.deathCycles && b.isModDroneCollide) {
if (this.endCycle > game.cycle + this.deathCycles) {
this.endCycle -= 60
if (game.cycle + this.deathCycles > this.endCycle) this.endCycle = game.cycle + this.deathCycles
}
@@ -2966,7 +2972,7 @@ const b = {
}
player.force.x -= knock * Math.cos(mech.angle)
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
if (b.isModShotgunImmune) mech.collisionImmuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
if (b.isModShotgunImmune) mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
b.muzzleFlash(35);
const side = 19 * b.modBulletSize
for (let i = 0; i < 15; i++) {
@@ -3687,11 +3693,15 @@ const b = {
isStarterGun: false,
isEasyToAim: true,
fire() {
const speed = mech.crouch ? 36 : 22
b.mine({
const pos = {
x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 30 * Math.sin(mech.angle)
}, {
}
let speed = mech.crouch ? 36 : 22
if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map
speed = -2
}
b.mine(pos, {
x: speed * Math.cos(mech.angle),
y: speed * Math.sin(mech.angle)
}, 0, b.isModMineAmmoBack)
@@ -3820,13 +3830,13 @@ const b = {
name: "drones",
description: "deploy drones that <strong>crash</strong> into mobs<br>collisions reduce their <strong>lifespan</strong> by 1 second",
ammo: 0,
ammoPack: 14,
ammoPack: 15,
have: false,
isStarterGun: true,
isEasyToAim: true,
fire() {
b.drone(mech.crouch ? 45 : 1)
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 5) * b.modFireRate); // cool down
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 13 : 5) * b.modFireRate); // cool down
}
},
{

View File

@@ -97,8 +97,7 @@ function collisionChecks(event) {
function collidePlayer(obj) {
//player dmg from hitting a body
// if ( mech.collisionImmuneCycle < mech.cycle) {
if (obj.classType === "body" && obj.speed > 10 && mech.collisionImmuneCycle < mech.cycle) {
if (obj.classType === "body" && obj.speed > 10 && mech.immuneCycle < mech.cycle) {
const velocityThreshold = 30 //keep this lines up with player.enterLand numbers (130/5 = 26)
if (player.position.y > obj.position.y) { //block is above the player look at total momentum difference
const velocityDiffMag = Vector.magnitude(Vector.sub(player.velocity, obj.velocity))
@@ -109,7 +108,7 @@ function collisionChecks(event) {
}
function hit(dmg) {
mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
dmg = Math.min(Math.max(Math.sqrt(dmg) * obj.mass * 0.01, 0.02), 0.15);
mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue
@@ -123,27 +122,6 @@ function collisionChecks(event) {
}
}
// function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
// //player dmg from hitting a body
// if (obj.classType === "body" && mech.collisionImmuneCycle < mech.cycle && obj.speed > speedThreshold && obj.mass > massThreshold) {
// const v = Vector.magnitude(Vector.sub(player.velocity, obj.velocity));
// if ((Math.abs(obj.velocity.x - player.velocity.x) > speedThreshold) || (player.position.y > obj.position.y && v > speedThreshold)) {
// mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
// let dmg = Math.sqrt((v - speedThreshold + 0.1) * (obj.mass - massThreshold)) * 0.01;
// dmg = Math.min(Math.max(dmg, 0.02), 0.15);
// mech.damage(dmg);
// game.drawList.push({ //add dmg to draw queue
// x: pairs[i].activeContacts[0].vertex.x,
// y: pairs[i].activeContacts[0].vertex.y,
// radius: dmg * 500,
// color: game.mobDmgColor,
// time: game.drawTime
// });
// return;
// }
// }
// }
//mob + (player,bullet,body) collisions
for (let k = 0; k < mob.length; k++) {
if (mob[k].alive && mech.alive) {
@@ -157,8 +135,8 @@ function collisionChecks(event) {
function collideMob(obj) {
//player + mob collision
if (mech.collisionImmuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
if (mech.immuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (b.isModPiezo) {

View File

@@ -17,9 +17,9 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(9)
// mech.setField("time dilation field")
// b.giveMod("many worlds");
// b.giveGuns("neutron bomb")
// b.giveGuns("foam")
// b.giveMod("brushless motor");
// b.giveGuns("drones")
// b.giveGuns("mine")
// mech.setField("pilot wave")
// mech.setField("phase decoherence field")
@@ -135,7 +135,7 @@ const level = {
spawn.mapRect(-250, -700, 1000, 900); // shelf
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
powerUps.spawnStartingPowerUps(600, -800);
powerUps.spawn(550, -800, "reroll", false); //starting gun
powerUps.spawn(550, -800, "reroll", false);
function blockDoor(x, y, blockSize = 58) {
spawn.mapRect(x, y - 290, 40, 60); // door lip

View File

@@ -373,7 +373,7 @@ const mobs = {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(game.cycle % 215);
if (this.distanceToPlayer() < this.laserRange && !mech.isStealth) {
if (mech.collisionImmuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
if (mech.immuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
if (mech.energy > 0.1) mech.energy -= 0.003
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -461,13 +461,15 @@ const mobs = {
if (!mech.isStealth) vertexCollision(this.position, look, [player]);
// hitting player
if (best.who === player) {
if (mech.collisionImmuneCycle < mech.cycle) dmg = 0.0012 * game.dmgScale;
mech.damage(dmg);
//draw damage
ctx.fillStyle = "#f00";
ctx.beginPath();
ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
ctx.fill();
if (mech.immuneCycle < mech.cycle) {
const dmg = 0.0012 * game.dmgScale;
mech.damage(dmg);
//draw damage
ctx.fillStyle = "#f00";
ctx.beginPath();
ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
ctx.fill();
}
}
//draw beam
if (best.dist2 === Infinity) {

View File

@@ -215,9 +215,6 @@ const mech = {
mech.yOff = mech.yOffWhen.jump;
mech.hardLandCD = mech.cycle + Math.min(momentum / 6.5 - 6, 40)
// if (b.isModStompPauli) {
// mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
// }
if (b.isModStomp) {
const len = Math.min(25, (momentum - 120) * 0.1)
for (let i = 0; i < len; i++) {
@@ -363,7 +360,7 @@ const mech = {
if (b.isModImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
spawn.setSpawnList(); //new mob types
game.clearNow = true; //triggers a map reset
powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 8)
powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 12)
//count mods
let totalMods = 0;
@@ -511,7 +508,7 @@ const mech = {
}
},
defaultFPSCycle: 0, //tracks when to return to normal fps
collisionImmuneCycle: 0, //used in engine
immuneCycle: 0, //used in engine
harmReduction() {
let dmg = 1
dmg *= mech.fieldDamageResistance
@@ -548,24 +545,23 @@ const mech = {
if (b.isModEnergyHealth) {
mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) {
if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
b.isModDeathAvoidOnCD = true;
mech.energy += dmg //undo the damage
if (mech.energy < 0.05) mech.energy = 0.05
mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
if (b.isModDeathAvoid && powerUps.reroll.rerolls) { //&& Math.random() < 0.5
powerUps.reroll.changeRerolls(-1)
mech.energy = mech.maxEnergy * 0.5
// if (mech.energy < 0.05) mech.energy = 0.05
mech.immuneCycle = mech.cycle + 120 //disable this.immuneCycle bonus seconds
game.makeTextLog("<span style='font-size:115%;'> <strong>death</strong> avoided<br><strong>1</strong> <strong class='color-r'>reroll</strong> consumed</span>", 300)
game.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.02)";
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
game.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// game.replaceTextLog = true;
// game.makeTextLog("death avoided", 360);
b.isModDeathAvoidOnCD = false;
}, 3000);
}, 2000);
return;
} else {
@@ -578,24 +574,22 @@ const mech = {
} else {
mech.health -= dmg;
if (mech.health < 0 || isNaN(mech.health)) {
if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
b.isModDeathAvoidOnCD = true;
mech.health += dmg //undo the damage
if (mech.health < 0.05) mech.health = 0.05
mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
if (b.isModDeathAvoid && powerUps.reroll.rerolls > 0) { //&& Math.random() < 0.5
powerUps.reroll.changeRerolls(-1)
mech.health = mech.maxHealth * 0.5
// if (mech.health < 0.05) mech.health = 0.05
mech.immuneCycle = mech.cycle + 120 //disable this.immuneCycle bonus seconds
game.makeTextLog("<span style='font-size:115%;'> <strong>death</strong> avoided<br><strong>1</strong> <strong class='color-r'>reroll</strong> consumed</span>", 300)
game.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.02)";
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
game.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// game.replaceTextLog = true;
// game.makeTextLog("death avoided", 360);
b.isModDeathAvoidOnCD = false;
}, 3000);
}, 2000);
} else {
mech.health = 0;
mech.death();
@@ -711,19 +705,12 @@ const mech = {
// },
draw() {
// mech.fillColor = (mech.collisionImmuneCycle < mech.cycle) ? "#fff" : "rgba(255,255,255,0.1)" //"#cff"
ctx.fillStyle = mech.fillColor;
mech.walk_cycle += mech.flipLegs * mech.Vx;
//draw body
ctx.save();
// if (mech.collisionImmuneCycle < mech.cycle) {
// ctx.globalAlpha = 1
// if (mech.collisionImmune) mech.collisionImmune = false;
// } else {
// ctx.globalAlpha = 0.7
// }
ctx.globalAlpha = (mech.collisionImmuneCycle < mech.cycle) ? 1 : 0.7
ctx.globalAlpha = (mech.immuneCycle < mech.cycle) ? 1 : 0.7
ctx.translate(mech.pos.x, mech.pos.y);
mech.calcLeg(Math.PI, -3);
mech.drawLeg("#4a4a4a");
@@ -1672,8 +1659,8 @@ const mech = {
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { //friction
x: best.who.velocity.x * 0.6,
y: best.who.velocity.y * 0.6
x: best.who.velocity.x * 0.7,
y: best.who.velocity.y * 0.7
});
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
// const mass = Math.min(Math.sqrt(best.who.mass), 6);

View File

@@ -21,7 +21,7 @@ const powerUps = {
powerUps.endDraft();
},
endDraft() {
if (b.manyWorlds) {
if (b.manyWorlds && Math.random() < 0.66) {
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
}
@@ -47,9 +47,16 @@ const powerUps = {
return 20;
},
effect() {
powerUps.reroll.rerolls++
powerUps.reroll.changeRerolls(1)
game.makeTextLog("<div class='circle reroll'></div> &nbsp; <span style='font-size:115%;'> <strong>+1 reroll</strong></span>", 300)
},
changeRerolls(amount) {
powerUps.reroll.rerolls += amount
if (powerUps.reroll.rerolls < 0) powerUps.reroll.rerolls = 0
if (b.isModDeathAvoid && document.getElementById("mod-anthropic")) {
document.getElementById("mod-anthropic").innerHTML = `(${powerUps.reroll.rerolls})`
}
},
diceText() {
const r = powerUps.reroll.rerolls
const fullDice = Math.floor(r / 6)
@@ -71,25 +78,8 @@ const powerUps = {
}
return out
},
// diceText() {
// if (powerUps.reroll.rerolls === 1) {
// return '⚀'
// } else if (powerUps.reroll.rerolls === 2) {
// return '⚁'
// } else if (powerUps.reroll.rerolls === 3) {
// return '⚂'
// } else if (powerUps.reroll.rerolls === 4) {
// return '⚃'
// } else if (powerUps.reroll.rerolls === 5) {
// return '⚄'
// } else if (powerUps.reroll.rerolls === 6) {
// return '⚅'
// } else if (powerUps.reroll.rerolls > 6) {
// return '⚅+'
// }
// },
use(type) {
powerUps.reroll.rerolls--;
powerUps.reroll.changeRerolls(-1)
powerUps[type].effect();
},
},
@@ -153,13 +143,30 @@ const powerUps = {
size() {
return 45;
},
choiceLog: [], //records all previous choice options
effect() {
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 1; i < who.length; i++) {
if (i !== mech.fieldMode && (!game.isEasyToAimMode || mech.fieldUpgrades[i].isEasyToAim) && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
}
if (options.length > 0) return options[Math.floor(Math.random() * options.length)]
//remove repeats from last selection
const totalChoices = b.isModDeterminism ? 1 : 3 + b.isModExtraChoice * 2
if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break
}
}
}
}
}
if (options.length > 0) {
return options[Math.floor(Math.random() * options.length)]
}
}
let choice1 = pick(mech.fieldUpgrades)
@@ -179,7 +186,13 @@ const powerUps = {
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice4].name}</div> ${mech.fieldUpgrades[choice4].description}</div>`
let choice5 = pick(mech.fieldUpgrades, choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice5})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice5].name}</div> ${mech.fieldUpgrades[choice5].description}</div>`
powerUps.field.choiceLog.push(choice4)
powerUps.field.choiceLog.push(choice5)
}
powerUps.field.choiceLog.push(choice1)
powerUps.field.choiceLog.push(choice2)
powerUps.field.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('field')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>`
// text += `<div style = 'color:#fff'>${game.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>`
@@ -196,6 +209,7 @@ const powerUps = {
size() {
return 42;
},
choiceLog: [], //records all previous choice options
effect() {
function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
@@ -204,7 +218,23 @@ const powerUps = {
options.push(i);
}
}
if (options.length > 0) return options[Math.floor(Math.random() * options.length)]
//remove repeats from last selection
const totalChoices = b.isModDeterminism ? 1 : 3 + b.isModExtraChoice * 2
if (powerUps.mod.choiceLog.length > totalChoices || powerUps.mod.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break
}
}
}
}
}
if (options.length > 0) {
return options[Math.floor(Math.random() * options.length)]
}
}
let choice1 = pick()
@@ -224,7 +254,12 @@ const powerUps = {
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice4})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${b.mods[choice4].name}</div> ${b.mods[choice4].description}</div>`
let choice5 = pick(choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice5})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${b.mods[choice5].name}</div> ${b.mods[choice5].description}</div>`
powerUps.mod.choiceLog.push(choice4)
powerUps.mod.choiceLog.push(choice5)
}
powerUps.mod.choiceLog.push(choice1)
powerUps.mod.choiceLog.push(choice2)
powerUps.mod.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('mod')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>`
document.getElementById("choose-grid").innerHTML = text
@@ -240,13 +275,33 @@ const powerUps = {
size() {
return 35;
},
choiceLog: [], //records all previous choice options
effect() {
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 0; i < who.length; i++) {
if (!who[i].have && (!game.isEasyToAimMode || b.guns[i].isEasyToAim) && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
if (!who[i].have && (!game.isEasyToAimMode || b.guns[i].isEasyToAim) && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
options.push(i);
}
}
//remove repeats from last selection
const totalChoices = b.isModDeterminism ? 1 : 3 + b.isModExtraChoice * 2
if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break
}
}
}
}
}
if (options.length > 0) {
return options[Math.floor(Math.random() * options.length)]
}
if (options.length > 0) return options[Math.floor(Math.random() * options.length)]
}
let choice1 = pick(b.guns)
@@ -267,10 +322,17 @@ const powerUps = {
let choice5 = pick(b.guns, choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice5})">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice5].name}</div> ${b.guns[choice5].description}</div>`
powerUps.gun.choiceLog.push(choice4)
powerUps.gun.choiceLog.push(choice5)
}
powerUps.gun.choiceLog.push(choice1)
powerUps.gun.choiceLog.push(choice2)
powerUps.gun.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('gun')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>`
// console.log(powerUps.gun.choiceLog)
// console.log(choice1, choice2, choice3)
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {

View File

@@ -1019,8 +1019,8 @@ const spawn = {
vertexCollision(where, look, map);
vertexCollision(where, look, body);
if (!mech.isStealth) vertexCollision(where, look, [player]);
if (best.who && best.who === player && mech.collisionImmuneCycle < mech.cycle) {
mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
if (best.who && best.who === player && mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
const dmg = 0.14 * game.dmgScale;
mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue
@@ -1445,7 +1445,7 @@ const spawn = {
// Matter.Body.rotate(me, Math.PI)
me.memory = 120;
me.fireFreq = 0.006 + Math.random() * 0.003;
me.fireFreq = 0.007 + Math.random() * 0.003;
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale;

View File

@@ -1,20 +1,24 @@
mod - many worlds: spawn a reroll after choosing (or canceling) a power up
new mob type - launcher: similar to the shooter, but fires bullets that chase you
plasma torch - reduces harm to player by 1/3 and has more reliable stopping power against charging mobs
explosions and neutron bomb do 50% less damage through walls
drone bullets bounce off mobs more predictably
anthropic principle - now consumes 1 rerolls, and heals player to 50% health instead of letting them die
many worlds - 66% chance for rerolls
quantum immortality - also gives 3 rerolls
mod drones - Brushless Motor: drones move faster
mod drones - redundant systems: removed
choices in power up selection should no longer repeat the previous choices when possible
************** TODO - n-gon **************
what about a neutron bomb mod, that cause the bomb to activate right after you fire and slowly move forward with no gravity
bug - mines spawn extra mines when fired at thin map wall while jumping
Drop a reroll when the player exits the selection screen without picking one of the choices
mod - negative mass field move faster
less friction, more like flying?
what about a neutron bomb mod, that causes the bomb to activate right after you fire and slowly move forward with no gravity
redblobgames.com/articles/visibility
https://github.com/Silverwolf90/2d-visibility/tree/master/src
could apply to explosions, neutron bomb, player LOS
sticking bullets don't always gain the correct speed from mobs after they die
bug - sticking bullets don't always gain the correct speed from mobs after they die
possible names for mods
Hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.