radioisotope generator
tech - radioisotope generator - drones have the effect of neutron bomb, but you get less ammo bug fix - reduced tolerances now properly gives extra ammo water shielding now protects you from all radioactivity, but only gives 75% protection (drones, neutron bomb, radioactive explosions, and even slime) final boss has more durability in it's final phase final boss no longers gets knocked around as much from explosions level.warehouse predraw lighting for performance bug fix on sewers where slime was doing too much harm
This commit is contained in:
299
js/bullet.js
299
js/bullet.js
@@ -326,11 +326,12 @@ const b = {
|
||||
|
||||
//player damage
|
||||
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
|
||||
const drain = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
|
||||
m.energy -= drain
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
// * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
|
||||
m.energy -= DRAIN
|
||||
if (m.energy < 0) {
|
||||
m.energy = 0
|
||||
m.damage(0.03);
|
||||
m.damage(0.03 * (tech.isRadioactiveResistance ? 0.25 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -922,11 +923,10 @@ const b = {
|
||||
bullet[me].restitution = 0;
|
||||
bullet[me].minDmgSpeed = 0;
|
||||
bullet[me].damageRadius = 100;
|
||||
bullet[me].maxDamageRadius = 450 + 130 * tech.isNeutronSlow + 130 * tech.isNeutronImmune //+ 150 * Math.random()
|
||||
bullet[me].radiusDecay = (0.81 + 0.15 * tech.isNeutronSlow + 0.15 * tech.isNeutronImmune) / tech.isBulletsLastLonger
|
||||
bullet[me].maxDamageRadius = 450 + 130 * tech.isNeutronSlow //+ 150 * Math.random()
|
||||
bullet[me].radiusDecay = (0.81 + 0.15 * tech.isNeutronSlow) / tech.isBulletsLastLonger
|
||||
bullet[me].stuckTo = null;
|
||||
bullet[me].stuckToRelativePosition = null;
|
||||
bullet[me].vacuumSlow = 0.97;
|
||||
|
||||
if (tech.isRPG) {
|
||||
const SCALE = 2
|
||||
@@ -1030,27 +1030,27 @@ const b = {
|
||||
this.endCycle = 0;
|
||||
} else {
|
||||
//aoe damage to player
|
||||
if (!tech.isNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
|
||||
const DRAIN = 0.0023
|
||||
if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.0025 * 0.25 : 0.0025
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage(0.00015)
|
||||
m.damage(tech.isRadioactiveResistance ? 0.00016 * 0.25 : 0.00016) //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
|
||||
let dmg = b.dmgScale * 0.09
|
||||
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 (tech.isNeutronSlow) {
|
||||
Matter.Body.setVelocity(mob[i], {
|
||||
x: mob[i].velocity.x * this.vacuumSlow,
|
||||
y: mob[i].velocity.y * this.vacuumSlow
|
||||
x: mob[i].velocity.x * 0.97,
|
||||
y: mob[i].velocity.y * 0.97
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1062,22 +1062,21 @@ const b = {
|
||||
ctx.fill();
|
||||
ctx.globalCompositeOperation = "source-over"
|
||||
if (tech.isNeutronSlow) {
|
||||
const that = this
|
||||
|
||||
function slow(who, radius = that.explodeRad * 3.2) {
|
||||
let slow = (who, radius = this.explodeRad * 3.2) => {
|
||||
for (i = 0, len = who.length; i < len; i++) {
|
||||
const sub = Vector.sub(that.position, who[i].position);
|
||||
const sub = Vector.sub(this.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
|
||||
x: who[i].velocity.x * 0.975,
|
||||
y: who[i].velocity.y * 0.975
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
slow(body, this.damageRadius)
|
||||
if (!tech.isNeutronImmune) slow([player], this.damageRadius)
|
||||
slow([player], this.damageRadius)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2210,6 +2209,242 @@ const b = {
|
||||
y: speed * Math.sin(dir)
|
||||
});
|
||||
},
|
||||
droneRadioactive(where = { x: m.pos.x + 30 * Math.cos(m.angle) + 20 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 20 * (Math.random() - 0.5) }, speed = 1) {
|
||||
const me = bullet.length;
|
||||
const THRUST = tech.isFastDrones ? 0.002 : 0.0012
|
||||
const dir = m.angle + 0.4 * (Math.random() - 0.5);
|
||||
const RADIUS = (4 + 1 * Math.random())
|
||||
bullet[me] = Bodies.polygon(where.x, where.y, 8, RADIUS, {
|
||||
angle: dir,
|
||||
inertia: Infinity,
|
||||
friction: 0.05,
|
||||
frictionAir: 0,
|
||||
restitution: 1,
|
||||
dmg: 0.24, //damage done in addition to the damage from momentum
|
||||
lookFrequency: 120 + Math.floor(23 * Math.random()),
|
||||
endCycle: simulation.cycle + Math.floor((900 + 400 * Math.random()) * tech.isBulletsLastLonger) + 140 + RADIUS * 5,
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield //self collide
|
||||
},
|
||||
minDmgSpeed: 0,
|
||||
lockedOn: null,
|
||||
isFollowMouse: true,
|
||||
deathCycles: 110 + RADIUS * 5,
|
||||
isImproved: false,
|
||||
radioRadius: 0,
|
||||
maxRadioRadius: 400 + Math.floor(75 * Math.random()) + 80 * tech.isNeutronSlow,
|
||||
beforeDmg(who) {
|
||||
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20) //move away from target after hitting
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: unit.x,
|
||||
y: unit.y
|
||||
});
|
||||
this.lockedOn = null
|
||||
if (this.endCycle > simulation.cycle + this.deathCycles) {
|
||||
this.endCycle -= 60
|
||||
if (simulation.cycle + this.deathCycles > this.endCycle) this.endCycle = simulation.cycle + this.deathCycles
|
||||
}
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isDroneRespawn) {
|
||||
const who = b.guns[b.activeGun]
|
||||
if (who.name === "drones" && who.ammo > 0 && mob.length) {
|
||||
b.droneRadioactive({ x: this.position.x, y: this.position.y }, 0)
|
||||
if (Math.random() < 0.33) {
|
||||
b.guns[b.activeGun].ammo--;
|
||||
simulation.updateGunHUD();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
do() {
|
||||
//radioactive zone
|
||||
this.radioRadius = this.radioRadius * 0.993 + 0.007 * this.maxRadioRadius //smooth radius towards max
|
||||
//aoe damage to player
|
||||
if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.radioRadius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.0023 * 0.25 : 0.0023
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage(tech.isRadioactiveResistance ? 0.00015 * 0.25 : 0.00015) //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.radioRadius) {
|
||||
let dmg = b.dmgScale * 0.035 //neutron bombs dmg = 0.09
|
||||
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 (tech.isNeutronSlow) {
|
||||
Matter.Body.setVelocity(mob[i], {
|
||||
x: mob[i].velocity.x * 0.97,
|
||||
y: mob[i].velocity.y * 0.97
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
//draw
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.radioRadius, 0, 2 * Math.PI);
|
||||
ctx.globalCompositeOperation = "lighter"
|
||||
ctx.fillStyle = `rgba(25,139,170,${0.1+0.05*Math.random()})`;
|
||||
ctx.fill();
|
||||
ctx.globalCompositeOperation = "source-over"
|
||||
|
||||
if (tech.isNeutronSlow) {
|
||||
const slow = (who, radius = this.radioRadius * 3.2) => {
|
||||
for (i = 0, len = who.length; i < len; i++) {
|
||||
const sub = Vector.sub(this.position, who[i].position);
|
||||
const dist = Vector.magnitude(sub);
|
||||
if (dist < radius) {
|
||||
Matter.Body.setVelocity(who[i], {
|
||||
x: who[i].velocity.x * 0.975,
|
||||
y: who[i].velocity.y * 0.975
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
slow(body, this.radioRadius)
|
||||
slow([player], this.radioRadius)
|
||||
}
|
||||
|
||||
|
||||
//normal drone actions
|
||||
if (simulation.cycle + this.deathCycles > this.endCycle) { //fall shrink and die
|
||||
this.force.y += this.mass * 0.0012;
|
||||
this.restitution = 0.2;
|
||||
const scale = 0.995;
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
this.maxRadioRadius = 0
|
||||
this.radioRadius = this.radioRadius * 0.98 //let radioactivity decrease
|
||||
} else {
|
||||
this.force.y += this.mass * 0.0002; //gravity
|
||||
|
||||
if (!(simulation.cycle % this.lookFrequency)) {
|
||||
//find mob targets
|
||||
this.lockedOn = null;
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
if (
|
||||
!mob[i].isBadTarget &&
|
||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = mob[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
//power ups
|
||||
if (!this.isImproved && !simulation.isChoosing && !tech.isExtraMaxEnergy) {
|
||||
if (this.lockedOn) {
|
||||
//grab, but don't lock onto nearby power up
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism) &&
|
||||
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000
|
||||
) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(powerUp[i].position.x, powerUp[i].position.y);
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.lineWidth = 4
|
||||
ctx.stroke();
|
||||
//pick up nearby power ups
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (tech.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2.25
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
this.endCycle += 1000 * tech.isBulletsLastLonger
|
||||
this.maxRadioRadius *= 1.25
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//look for power ups to lock onto
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
(powerUp[i].name !== "heal" || m.health < 0.9 * m.maxHealth || tech.isDroneGrab) &&
|
||||
(powerUp[i].name !== "field" || !tech.isDeterminism)
|
||||
) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
|
||||
//draw pickup for a single cycle
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(powerUp[i].position.x, powerUp[i].position.y);
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.lineWidth = 4
|
||||
ctx.stroke();
|
||||
//pick up nearby power ups
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (tech.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2.25
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30 + Math.floor(11 * Math.random());
|
||||
this.endCycle += 1000 * tech.isBulletsLastLonger
|
||||
this.maxRadioRadius *= 1.25
|
||||
}
|
||||
break;
|
||||
}
|
||||
//look for power ups to lock onto
|
||||
if (
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
if (DIST < closeDist) {
|
||||
closeDist = DIST;
|
||||
this.lockedOn = powerUp[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.lockedOn) { //accelerate towards mobs
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST)
|
||||
} else { //accelerate towards mouse
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, simulation.mouseInGame)), -this.mass * THRUST)
|
||||
}
|
||||
// speed cap instead of friction to give more agility
|
||||
if (this.speed > 6) {
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: this.velocity.x * 0.97,
|
||||
y: this.velocity.y * 0.97
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
Matter.Body.setVelocity(bullet[me], {
|
||||
x: speed * Math.cos(dir),
|
||||
y: speed * Math.sin(dir)
|
||||
});
|
||||
},
|
||||
foam(position, velocity, radius) {
|
||||
// radius *= Math.sqrt(tech.bulletSize)
|
||||
const me = bullet.length;
|
||||
@@ -3323,7 +3558,7 @@ const b = {
|
||||
if (tech.isNailRadiation) {
|
||||
mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
||||
} else {
|
||||
let dmg = b.dmgScale * 5
|
||||
let dmg = b.dmgScale * 5.5
|
||||
if (tech.isCrit && who.isStunned) dmg *= 4
|
||||
who.damage(dmg, tech.isNeedleShieldPierce);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -3356,18 +3591,18 @@ const b = {
|
||||
x: m.Vx / 2 + SPEED * Math.cos(angle),
|
||||
y: m.Vy / 2 + SPEED * Math.sin(angle)
|
||||
});
|
||||
Matter.Body.setDensity(bullet[me], 0.00001);
|
||||
// Matter.Body.setDensity(bullet[me], 0.00001);
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
}
|
||||
|
||||
if (m.crouch) {
|
||||
m.fireCDcycle = m.cycle + 50 * b.fireCD; // cool down
|
||||
m.fireCDcycle = m.cycle + 45 * b.fireCD; // cool down
|
||||
makeNeedle()
|
||||
for (let i = 1; i < 4; i++) { //4 total needles
|
||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||
}
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + 30 * b.fireCD; // cool down
|
||||
m.fireCDcycle = m.cycle + 25 * b.fireCD; // cool down
|
||||
makeNeedle()
|
||||
for (let i = 1; i < 3; i++) { //3 total needles
|
||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||
@@ -4145,12 +4380,22 @@ const b = {
|
||||
have: false,
|
||||
do() {},
|
||||
fire() {
|
||||
if (m.crouch) {
|
||||
b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
||||
m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCD); // cool down
|
||||
if (tech.isDroneRadioactive) {
|
||||
if (m.crouch) {
|
||||
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
||||
m.fireCDcycle = m.cycle + Math.floor(7 * 13 * b.fireCD); // cool down
|
||||
} else {
|
||||
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 10)
|
||||
m.fireCDcycle = m.cycle + Math.floor(7 * 6 * b.fireCD); // cool down
|
||||
}
|
||||
} else {
|
||||
b.drone()
|
||||
m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCD); // cool down
|
||||
if (m.crouch) {
|
||||
b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
|
||||
m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCD); // cool down
|
||||
} else {
|
||||
b.drone()
|
||||
m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCD); // cool down
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
133
js/level.js
133
js/level.js
@@ -16,12 +16,15 @@ const level = {
|
||||
// simulation.difficulty = 20
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// level.difficultyIncrease(99)
|
||||
// m.setField("standing wave harmonics")
|
||||
// tech.giveTech("spherical harmonics")
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||
// m.setField("nano-scale manufacturing")
|
||||
// b.giveGuns("grenades")
|
||||
// tech.giveTech("neutron bomb")
|
||||
// b.giveGuns("drones")
|
||||
// tech.giveTech("radioactive drones")
|
||||
// tech.isRadioactiveResistance = true
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
|
||||
// tech.isExplodeRadio = true
|
||||
// tech.giveTech("chain reaction")
|
||||
// tech.giveTech("vacuum permittivity")
|
||||
// tech.giveTech("quenching")
|
||||
// tech.giveTech("decoherence")
|
||||
// tech.giveTech("supertemporal")
|
||||
@@ -96,7 +99,7 @@ const level = {
|
||||
powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
|
||||
}
|
||||
if (tech.isHealLowHealth) {
|
||||
const len = Math.ceil((m.maxHealth - m.health) / 0.33)
|
||||
const len = Math.ceil((m.maxHealth - m.health) / 0.25)
|
||||
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
|
||||
}
|
||||
if (tech.isMACHO) spawn.MACHO()
|
||||
@@ -965,23 +968,12 @@ const level = {
|
||||
ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset)
|
||||
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
const drain = 0.003 + m.fieldRegen
|
||||
if (m.energy > drain) {
|
||||
m.energy -= drain
|
||||
const DRAIN = 0.003 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
|
||||
console.log(DRAIN)
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
} else {
|
||||
if (damage < 0.02) {
|
||||
m.damage(damage)
|
||||
} else if (m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
|
||||
m.damage(damage)
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: player.position.x,
|
||||
y: player.position.y,
|
||||
radius: damage * 1500,
|
||||
color: simulation.mobDmgColor,
|
||||
time: 20
|
||||
});
|
||||
}
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
|
||||
}
|
||||
//float
|
||||
if (player.velocity.y > 5) player.force.y -= 0.95 * player.mass * simulation.g
|
||||
@@ -1926,7 +1918,7 @@ const level = {
|
||||
const doorWidth2 = 15 + Math.floor(100 * Math.random() * Math.random())
|
||||
spawn.bodyRect(offset.x + 2050 - doorWidth2 / 2, offset.y - 175, doorWidth2, 165); //block door
|
||||
} else {
|
||||
spawn.mapRect(offset.x + 2000, offset.y - 2800, 100, 2800); //right wall
|
||||
spawn.mapRect(offset.x + 2000, offset.y - 2800, 100, 2900); //right wall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2086,7 +2078,7 @@ const level = {
|
||||
},
|
||||
testing() {
|
||||
// const button = level.button(200, -700)
|
||||
const toggle = level.toggle(200, -700)
|
||||
// const toggle = level.toggle(200, -700)
|
||||
level.custom = () => {
|
||||
// button.draw();
|
||||
ctx.fillStyle = "rgba(0,255,255,0.1)";
|
||||
@@ -2096,7 +2088,7 @@ const level = {
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
toggle.query();
|
||||
// toggle.query();
|
||||
};
|
||||
|
||||
level.setPosToSpawn(0, -750); //normal spawn
|
||||
@@ -2127,11 +2119,9 @@ const level = {
|
||||
function blockDoor(x, y, blockSize = 58) {
|
||||
spawn.mapRect(x, y - 290, 40, 60); // door lip
|
||||
spawn.mapRect(x, y, 40, 50); // door lip
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
|
||||
}
|
||||
for (let i = 0; i < 4; ++i) spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
|
||||
}
|
||||
blockDoor(710, -710);
|
||||
// blockDoor(710, -710);
|
||||
// for (let i = 0; i < 30; i++) powerUps.directSpawn(710, -710, "tech");
|
||||
|
||||
spawn.mapRect(2500, -1200, 200, 750); //right wall
|
||||
@@ -2151,10 +2141,10 @@ const level = {
|
||||
// spawn.shooterBoss(1900, -500)
|
||||
// spawn.historyBoss(1200, -500)
|
||||
// spawn.laserTargetingBoss(1600, -400)
|
||||
// spawn.striker(1600, -500)
|
||||
spawn.hopper(1600, -500)
|
||||
// spawn.laserTargetingBoss(1700, -120)
|
||||
// spawn.bomberBoss(1400, -500)
|
||||
// spawn.ghoster(1800, -120)
|
||||
spawn.hopBoss(1800, -120)
|
||||
// spawn.streamBoss(1600, -500)
|
||||
// spawn.orbitalBoss(1600, -500)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
@@ -2962,8 +2952,6 @@ const level = {
|
||||
|
||||
button1.query();
|
||||
button1.draw();
|
||||
hazard.query();
|
||||
hazard.level(button1.isUp)
|
||||
rotor.rotate();
|
||||
|
||||
ctx.fillStyle = "hsl(175, 15%, 76%)"
|
||||
@@ -4017,43 +4005,54 @@ const level = {
|
||||
level.enter.draw();
|
||||
};
|
||||
|
||||
|
||||
// simulation.draw.mapPath = new Path2D();
|
||||
// for (let i = 0, len = map.length; i < len; ++i) {
|
||||
// let vertices = map[i].vertices;
|
||||
// simulation.draw.mapPath.moveTo(vertices[0].x, vertices[0].y);
|
||||
// for (let j = 1; j < vertices.length; j += 1) {
|
||||
// simulation.draw.mapPath.lineTo(vertices[j].x, vertices[j].y);
|
||||
// }
|
||||
// simulation.draw.mapPath.lineTo(vertices[0].x, vertices[0].y);
|
||||
// }
|
||||
const lightingPath = new Path2D() //pre-draw the complex lighting path to save processing
|
||||
lightingPath.moveTo(-1800, -500)
|
||||
lightingPath.lineTo(-910, -500) //3rd floor light
|
||||
lightingPath.lineTo(-1300, 0)
|
||||
lightingPath.lineTo(-500, 0)
|
||||
lightingPath.lineTo(-890, -500)
|
||||
lightingPath.lineTo(-175, -500)
|
||||
lightingPath.lineTo(-175, -250)
|
||||
lightingPath.lineTo(175, -250)
|
||||
lightingPath.lineTo(175, 0)
|
||||
lightingPath.lineTo(-910, 100) //2nd floor light left
|
||||
lightingPath.lineTo(-1300, 600)
|
||||
lightingPath.lineTo(-500, 600)
|
||||
lightingPath.lineTo(-890, 100)
|
||||
lightingPath.lineTo(190, 100) //2nd floor light right
|
||||
lightingPath.lineTo(-200, 600)
|
||||
lightingPath.lineTo(600, 600)
|
||||
lightingPath.lineTo(210, 100)
|
||||
lightingPath.lineTo(1100, 100)
|
||||
lightingPath.lineTo(1100, 1400)
|
||||
lightingPath.lineTo(600, 1400) //1st floor light right
|
||||
lightingPath.lineTo(10, 700)
|
||||
lightingPath.lineTo(-10, 700)
|
||||
lightingPath.lineTo(-600, 1400)
|
||||
lightingPath.lineTo(-1950, 1400) //1st floor light left
|
||||
lightingPath.lineTo(-2290, 950)
|
||||
lightingPath.lineTo(-2310, 950)
|
||||
lightingPath.lineTo(-2650, 1400)
|
||||
lightingPath.lineTo(-3025, 1400)
|
||||
lightingPath.lineTo(-3025, 150)
|
||||
lightingPath.lineTo(-2590, 150)
|
||||
lightingPath.lineTo(-2600, -150)
|
||||
lightingPath.lineTo(-1800, -150)
|
||||
lightingPath.lineTo(-1800, -500) //top left end/start of path
|
||||
|
||||
level.customTopLayer = () => {
|
||||
ctx.fillStyle = "rgba(0,0,0,0.15)"; //shadows and lights
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(-1800, -500)
|
||||
ctx.lineTo(-910, -500) //3rd floor light
|
||||
ctx.lineTo(-1300, 0)
|
||||
ctx.lineTo(-500, 0)
|
||||
ctx.lineTo(-890, -500)
|
||||
ctx.lineTo(-175, -500)
|
||||
ctx.lineTo(-175, -250)
|
||||
ctx.lineTo(175, -250)
|
||||
ctx.lineTo(175, 0)
|
||||
ctx.lineTo(-910, 100) //2nd floor light left
|
||||
ctx.lineTo(-1300, 600)
|
||||
ctx.lineTo(-500, 600)
|
||||
ctx.lineTo(-890, 100)
|
||||
ctx.lineTo(190, 100) //2nd floor light right
|
||||
ctx.lineTo(-200, 600)
|
||||
ctx.lineTo(600, 600)
|
||||
ctx.lineTo(210, 100)
|
||||
ctx.lineTo(1100, 100)
|
||||
ctx.lineTo(1100, 1400)
|
||||
ctx.lineTo(600, 1400) //1st floor light right
|
||||
ctx.lineTo(10, 700)
|
||||
ctx.lineTo(-10, 700)
|
||||
ctx.lineTo(-600, 1400)
|
||||
ctx.lineTo(-1950, 1400) //1st floor light left
|
||||
ctx.lineTo(-2290, 950)
|
||||
ctx.lineTo(-2310, 950)
|
||||
ctx.lineTo(-2650, 1400)
|
||||
ctx.lineTo(-3025, 1400)
|
||||
ctx.lineTo(-3025, 150)
|
||||
ctx.lineTo(-2590, 150)
|
||||
ctx.lineTo(-2600, -150)
|
||||
ctx.lineTo(-1800, -150)
|
||||
ctx.lineTo(-1800, -500) //top left end/start of path
|
||||
ctx.fill()
|
||||
ctx.fill(lightingPath);
|
||||
};
|
||||
|
||||
level.setPosToSpawn(25, -55); //normal spawn
|
||||
|
||||
@@ -495,7 +495,7 @@ const m = {
|
||||
if (tech.isSlowFPS) dmg *= 0.8
|
||||
// if (tech.isPiezo) dmg *= 0.85
|
||||
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4
|
||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||
if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34
|
||||
if (tech.energyRegen === 0) dmg *= 0.34
|
||||
@@ -1682,6 +1682,9 @@ const m = {
|
||||
} else if (tech.isIceField) {
|
||||
m.energy -= 0.04;
|
||||
b.iceIX(1)
|
||||
} else if (tech.isDroneRadioactive) {
|
||||
m.energy -= 1;
|
||||
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25)
|
||||
} else {
|
||||
m.energy -= 0.45 * tech.droneEnergyReduction;
|
||||
b.drone()
|
||||
|
||||
@@ -736,7 +736,11 @@ const powerUps = {
|
||||
|
||||
//bonus power ups for clearing runs in the last game
|
||||
if (level.levelsCleared === 0 && !simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
|
||||
simulation.makeTextLog(`for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++)`);
|
||||
simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech") //simulation superposition }`);
|
||||
}
|
||||
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
|
||||
114
js/spawn.js
114
js/spawn.js
@@ -170,13 +170,13 @@ const spawn = {
|
||||
Matter.Body.setVelocity(this, { x: 0, y: 0 });
|
||||
|
||||
//aoe damage to player
|
||||
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(player.position, this.position)) < this.radius && !tech.isNeutronImmune) {
|
||||
const DRAIN = 0.07
|
||||
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(player.position, this.position)) < this.radius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.07 * 0.25 : 0.07
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage(0.007 * simulation.dmgScale)
|
||||
m.damage((tech.isRadioactiveResistance ? 0.007 * 0.25 : 0.007) * simulation.dmgScale)
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -233,7 +233,7 @@ const spawn = {
|
||||
y: me.position.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.001,
|
||||
stiffness: 1,
|
||||
damping: 1
|
||||
});
|
||||
World.add(engine.world, me.constraint);
|
||||
@@ -244,7 +244,7 @@ const spawn = {
|
||||
me.memory = Infinity;
|
||||
me.hasRunDeathScript = false
|
||||
me.locatePlayer();
|
||||
const density = 0.25
|
||||
const density = 0.23
|
||||
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// spawn.shield(me, x, y, 1);
|
||||
me.onDeath = function() {
|
||||
@@ -416,7 +416,7 @@ const spawn = {
|
||||
}
|
||||
} else if (this.mode !== 3) { //all three modes at once
|
||||
this.cycle = 0;
|
||||
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
Matter.Body.setDensity(me, 10 * density); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
if (this.mode === 2) {
|
||||
Matter.Body.scale(this, 5, 5);
|
||||
} else {
|
||||
@@ -1017,6 +1017,8 @@ const spawn = {
|
||||
me.accelMag = 0.04;
|
||||
me.g = 0.0017; //required if using 'gravity'
|
||||
me.frictionAir = 0.01;
|
||||
me.friction = 1
|
||||
me.frictionStatic = 1
|
||||
me.restitution = 0;
|
||||
me.delay = 120 * simulation.CDScale;
|
||||
me.randomHopFrequency = 200 + Math.floor(Math.random() * 150);
|
||||
@@ -1032,7 +1034,7 @@ const spawn = {
|
||||
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
|
||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
this.force.x += forceMag * Math.cos(angle);
|
||||
this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.07 + 0.02) * this.mass; //antigravity
|
||||
this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.07 + 0.06) * this.mass; //antigravity
|
||||
}
|
||||
} else {
|
||||
//randomly hob if not aware of player
|
||||
@@ -1048,6 +1050,96 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
},
|
||||
hopBoss(x, y, radius = 90) {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.g = 0.005; //required if using 'gravity'
|
||||
me.frictionAir = 0.01;
|
||||
me.friction = 1
|
||||
me.frictionStatic = 1
|
||||
me.restitution = 0;
|
||||
me.accelMag = 0.07;
|
||||
me.delay = 120 * simulation.CDScale;
|
||||
me.randomHopFrequency = 200
|
||||
me.randomHopCD = simulation.cycle + me.randomHopFrequency;
|
||||
// me.memory = 420;
|
||||
me.isInAir = false
|
||||
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 60, 1)
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
};
|
||||
me.lastSpeed = me.speed
|
||||
me.do = function() {
|
||||
this.gravity();
|
||||
this.seePlayerCheck();
|
||||
this.checkStatus();
|
||||
if (this.seePlayer.recall) {
|
||||
const deltaSpeed = this.lastSpeed - this.speed
|
||||
this.lastSpeed = this.speed
|
||||
if (deltaSpeed > 13 && this.speed < 5) { //if the player slows down greatly in one cycle
|
||||
//damage and push player away, push away blocks
|
||||
const range = 800 //Math.min(800, 50 * deltaSpeed)
|
||||
for (let i = body.length - 1; i > -1; i--) {
|
||||
if (!body[i].isNotHoldable) {
|
||||
sub = Vector.sub(body[i].position, this.position);
|
||||
dist = Vector.magnitude(sub);
|
||||
if (dist < range) {
|
||||
knock = Vector.mult(Vector.normalise(sub), Math.min(20, 50 * body[i].mass / dist));
|
||||
body[i].force.x += knock.x;
|
||||
body[i].force.y += knock.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulation.drawList.push({ //draw radius
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: range,
|
||||
color: "rgba(0,200,180,0.6)",
|
||||
time: 4
|
||||
});
|
||||
}
|
||||
|
||||
if (this.isInAir) {
|
||||
if (this.velocity.y > -0.01 && Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) { //not moving up, and has hit the map or a body
|
||||
this.isInAir = false //landing
|
||||
this.cd = simulation.cycle + this.delay
|
||||
|
||||
}
|
||||
} else { //on ground
|
||||
if (this.cd < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) { //jump
|
||||
this.isInAir = true
|
||||
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
|
||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
this.force.x += forceMag * Math.cos(angle);
|
||||
this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.05 + 0.04) * this.mass; //antigravity
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.cd < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
|
||||
// this.cd = simulation.cycle + this.delay;
|
||||
// const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
|
||||
// const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
// this.force.x += forceMag * Math.cos(angle);
|
||||
// this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.05 + 0.04) * this.mass; //antigravity
|
||||
// }
|
||||
} else {
|
||||
//randomly hob if not aware of player
|
||||
if (this.randomHopCD < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
|
||||
this.randomHopCD = simulation.cycle + this.randomHopFrequency;
|
||||
//slowly change randomHopFrequency after each hop
|
||||
this.randomHopFrequency = Math.max(100, this.randomHopFrequency + 200 * (0.5 - Math.random()));
|
||||
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.5 + Math.random() * 0.2);
|
||||
const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
|
||||
this.force.x += forceMag * Math.cos(angle);
|
||||
this.force.y += forceMag * Math.sin(angle) - (0.1 + 0.08 * Math.random()) * this.mass; //antigravity
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
spinner(x, y, radius = 30 + Math.ceil(Math.random() * 35)) {
|
||||
mobs.spawn(x, y, 5, radius, "#000000");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -2063,7 +2155,7 @@ const spawn = {
|
||||
y: me.position.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.001,
|
||||
stiffness: 1,
|
||||
damping: 1
|
||||
});
|
||||
World.add(engine.world, me.constraint);
|
||||
@@ -2575,8 +2667,8 @@ const spawn = {
|
||||
y: me.position.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.0002,
|
||||
damping: 1
|
||||
stiffness: 0.00004,
|
||||
damping: 0.1
|
||||
});
|
||||
World.add(engine.world, me.constraint);
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
@@ -2912,7 +3004,7 @@ const spawn = {
|
||||
y: me.position.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.001,
|
||||
stiffness: 0.0001,
|
||||
damping: 1
|
||||
});
|
||||
World.add(engine.world, me.constraint);
|
||||
|
||||
129
js/tech.js
129
js/tech.js
@@ -177,7 +177,7 @@
|
||||
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.22
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015)
|
||||
if (tech.isBotDamage) dmg *= 1 + 0.05 * b.totalBots()
|
||||
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
|
||||
return dmg * tech.slowFire * tech.aimDamage
|
||||
},
|
||||
duplicationChance() {
|
||||
@@ -716,7 +716,7 @@
|
||||
},
|
||||
requires: "an explosive damage source, not ammonium nitrate or nitroglycerin",
|
||||
effect: () => {
|
||||
tech.isExplodeRadio = true;
|
||||
tech.isExplodeRadio = true; //iridium-192
|
||||
},
|
||||
remove() {
|
||||
tech.isExplodeRadio = false;
|
||||
@@ -823,9 +823,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source",
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
tech.isImmuneExplosion = true;
|
||||
},
|
||||
@@ -841,9 +841,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) || tech.haveGunCheck("drones") || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
|
||||
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
|
||||
},
|
||||
requires: "drones, super balls, shotgun",
|
||||
requires: "super balls, shotgun, drones, not radioactive drones",
|
||||
effect() {
|
||||
tech.isIncendiary = true
|
||||
},
|
||||
@@ -1376,7 +1376,7 @@
|
||||
},
|
||||
{
|
||||
name: "perimeter defense",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>6%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>7%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -1394,7 +1394,7 @@
|
||||
},
|
||||
{
|
||||
name: "network effect",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>5%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -2509,7 +2509,7 @@
|
||||
},
|
||||
{
|
||||
name: "negentropy",
|
||||
description: `at the start of each <strong>level</strong><br>spawn a <strong class='color-h'>heal</strong> for every <strong>33</strong> missing health`,
|
||||
description: `at the start of each <strong>level</strong><br>spawn a <strong class='color-h'>heal</strong> for every <strong>25</strong> missing health`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -4039,7 +4039,7 @@
|
||||
},
|
||||
{
|
||||
name: "neutron bomb",
|
||||
description: "<strong>grenades</strong> are irradiated with <strong class='color-p'>Cf-252</strong><br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>",
|
||||
description: "<strong>grenades</strong> are <strong class='color-p'>irradiated</strong> with <strong class='color-p'>Cf-252</strong><br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4060,35 +4060,35 @@
|
||||
},
|
||||
{
|
||||
name: "water shielding",
|
||||
description: "increase <strong>neutron bomb's</strong> range by <strong>20%</strong><br>you are <strong>immune</strong> to its harmful effects",
|
||||
description: "<strong class='color-p'>radioactive</strong> effects on you are reduced by 75%<br><em>neutron bomb, drones, explosions, slime</em>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isNeutronBomb
|
||||
return tech.isNeutronBomb || tech.isDroneRadioactive
|
||||
},
|
||||
requires: "neutron bomb",
|
||||
requires: "neutron bomb or radioactive drones",
|
||||
effect() {
|
||||
tech.isNeutronImmune = true
|
||||
tech.isRadioactiveResistance = true
|
||||
},
|
||||
remove() {
|
||||
tech.isNeutronImmune = false
|
||||
tech.isRadioactiveResistance = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "vacuum permittivity",
|
||||
description: "increase <strong>neutron bomb's</strong> range by <strong>20%</strong><br>objects in range of the bomb are <strong>slowed</strong>",
|
||||
description: "increase <strong class='color-p'>radioactive</strong> range by <strong>20%</strong><br>objects in range of the bomb are <strong>slowed</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isNeutronBomb
|
||||
return tech.isNeutronBomb || tech.isDroneRadioactive
|
||||
},
|
||||
requires: "neutron bomb",
|
||||
requires: "neutron bomb or radioactive drones",
|
||||
effect() {
|
||||
tech.isNeutronSlow = true
|
||||
},
|
||||
@@ -4270,6 +4270,39 @@
|
||||
tech.isMutualism = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "radioisotope generator",
|
||||
description: "<strong class='color-p'>irradiate</strong> <strong>drones</strong>, reduce <strong class='color-g'>ammo</strong> by <strong>75%</strong><br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("drones") && tech.droneCycleReduction === 1 && !tech.isIncendiary
|
||||
},
|
||||
requires: "drone gun, not reduced tolerances or incendiary",
|
||||
effect() {
|
||||
tech.isDroneRadioactive = true
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") {
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.25
|
||||
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.25)
|
||||
}
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
if (tech.isDroneRadioactive) {
|
||||
tech.isDroneRadioactive = false
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") {
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||
b.guns[i].ammo = b.guns[i].ammo * 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "brushless motor",
|
||||
description: "<strong>drones</strong> accelerate <strong>50%</strong> faster",
|
||||
@@ -4308,33 +4341,6 @@
|
||||
tech.isDroneGrab = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "reduced tolerances",
|
||||
description: "increase <strong>drone</strong> <strong class='color-g'>ammo</strong>/<strong class='color-f'>efficiency</strong> by <strong>66%</strong><br>reduce the average <strong>drone</strong> lifetime by <strong>40%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField))
|
||||
},
|
||||
requires: "drones",
|
||||
effect() {
|
||||
tech.droneCycleReduction = Math.pow(0.6, 1 + this.count)
|
||||
tech.droneEnergyReduction = Math.pow(0.333, 1 + this.count)
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * Math.pow(3, this.count)
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.droneCycleReduction = 1
|
||||
tech.droneEnergyReduction = 1
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "drone repair",
|
||||
description: "broken <strong>drones</strong> <strong>repair</strong> if the drone <strong class='color-g'>gun</strong> is active<br><strong>repairing</strong> has a <strong>33%</strong> chance to use <strong>1</strong> <strong class='color-g'>ammo</strong>",
|
||||
@@ -4354,6 +4360,36 @@
|
||||
tech.isDroneRespawn = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "reduced tolerances",
|
||||
description: "increase <strong>drone</strong> <strong class='color-g'>ammo</strong>/<strong class='color-f'>efficiency</strong> by <strong>66%</strong><br>reduce the average <strong>drone</strong> lifetime by <strong>40%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isDroneRadioactive && (tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)))
|
||||
},
|
||||
requires: "drones",
|
||||
effect() {
|
||||
tech.droneCycleReduction = Math.pow(0.6, 1 + this.count)
|
||||
tech.droneEnergyReduction = Math.pow(0.333, 1 + this.count)
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") {
|
||||
const scale = Math.pow(3, this.count + 1)
|
||||
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * scale
|
||||
}
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.droneCycleReduction = 1
|
||||
tech.droneEnergyReduction = 1
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "drones") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "necrophoresis",
|
||||
description: "<strong>foam</strong> bubbles grow and split into 3 <strong>copies</strong><br> when the mob they are stuck to <strong>dies</strong>",
|
||||
@@ -7209,5 +7245,6 @@
|
||||
isBlockExplosion: null,
|
||||
superBallDelay: null,
|
||||
isBlockExplode: null,
|
||||
isOverHeal: null
|
||||
isOverHeal: null,
|
||||
isDroneRadioactive: null
|
||||
}
|
||||
235
todo.txt
235
todo.txt
@@ -1,20 +1,22 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
new level labs is done (it's kinda randomized, so expect it to feel different each run)
|
||||
(I know there are tons of bugs, but I figure we can find them together :)
|
||||
tech - radioisotope generator - drones have the effect of neutron bomb, but you get less ammo
|
||||
bug fix - reduced tolerances now properly gives extra ammo
|
||||
water shielding now protects you from all radioactivity, but only gives 75% protection
|
||||
(drones, neutron bomb, radioactive explosions, and even slime)
|
||||
|
||||
foam gun now gets about 20% less ammo
|
||||
new junk tech: "emergency broadcasting" - plays some fun sounds and gives you health
|
||||
final boss has more durability in it's final phase
|
||||
final boss no longers gets knocked around as much from explosions
|
||||
|
||||
updated matter.js to a newer build matter-js 0.17.1 by @liabru
|
||||
(was matter-js 0.14.2 by @liabru 2018-06-11)
|
||||
matter.js patch notes suggest a possible 30% physics performance increase
|
||||
decomp.min.js was removed because I don't think it does anything anymore
|
||||
I did get one error message about it being missing, but there were other bugs too
|
||||
level.warehouse predraw lighting for performance
|
||||
bug fix on sewers where slime was doing too much harm
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
Final boss acts super weird when hit by explosions
|
||||
slime does extra damage on flipped levels?
|
||||
|
||||
using time dilatation breaks constraints
|
||||
on map n-gon, toggles
|
||||
|
||||
player can become crouched while not touching the ground if they exit the ground while crouched
|
||||
|
||||
@@ -38,9 +40,18 @@ is there a way to check if the player is stuck inside the map or block
|
||||
|
||||
******************************************************** LEVELS ********************************************************
|
||||
|
||||
make a power up you can carry around like the heal power up when at full health
|
||||
drop it on a map element to turn it on?
|
||||
use it in combat?
|
||||
|
||||
labs - procedural generation
|
||||
bugs
|
||||
mob spawns shouldn't be based on probability?
|
||||
style
|
||||
graphics look too bright?
|
||||
add shadows and lighting and graphic details?
|
||||
what about performance?
|
||||
with the mobs staggered spawning it should be fine
|
||||
feel
|
||||
disrupt the flat ground
|
||||
less platforming / easier platforming
|
||||
@@ -49,7 +60,13 @@ labs - procedural generation
|
||||
is it laggy?
|
||||
in loot room, spawn mobs after power up is grabbed
|
||||
more background graphics, better colors
|
||||
science theme, with a cool technology showcased
|
||||
loot room:
|
||||
make it more interesting to get the power up
|
||||
slow player and reduce damage in region
|
||||
increase the size of the region
|
||||
don't have space for much
|
||||
make graphics more unique
|
||||
push player away, so that normal pick up methods don't work, but add a button to disable region
|
||||
room ideas -
|
||||
portal room
|
||||
endlessly falling blocks down a slide, that the player has to climb up
|
||||
@@ -57,18 +74,95 @@ labs - procedural generation
|
||||
slime room
|
||||
sound room, with buttons to control sound
|
||||
color room with r,g,b buttons to control color
|
||||
test fire room, button fires blocks at a wall
|
||||
mob buff zone: Map element: "Orbital Pickup Zone": Mobs that enter a specific area of the map gain +1 orbital per second, or a shield
|
||||
could put in the loot room
|
||||
|
||||
buttons can now on/off boosts
|
||||
|
||||
repeat map in vertical when you fall teleport to above the mab, as if the map repeats
|
||||
camera looks strange when you teleport player with a high velocity
|
||||
|
||||
map element - player rotates a rotor that makes a platform go up or down
|
||||
|
||||
level element: a zone with wind, anti-gravity, extra gravity
|
||||
control with button
|
||||
|
||||
map: observatory
|
||||
button controls rotation of telescope
|
||||
laser beam shoots out of telescope
|
||||
button opens the dome
|
||||
|
||||
map: prison
|
||||
doors linked to buttons
|
||||
mobs inside the doors?
|
||||
|
||||
boss levels - small levels just a boss, and maybe a few mobs
|
||||
boss level for timeSkipBoss because of game instability for boss on normal levels
|
||||
this might not fix issues
|
||||
|
||||
******************************************************** MOBS ********************************************************
|
||||
|
||||
mob mechanics
|
||||
use the force at a location effect, like the plasma field
|
||||
|
||||
mob - after taking damage
|
||||
release seekers
|
||||
teleports
|
||||
|
||||
hop boss:
|
||||
AoE damage when landing
|
||||
pull in player? and blocks?
|
||||
extra gravity on falling?
|
||||
immune to damage while falling?
|
||||
|
||||
mob: molecule shapes - 2 separate mobs joined by a bond
|
||||
use constraints: just spawn 2x or 3x groupings
|
||||
low friction so they can spin around
|
||||
spin when attacking player?
|
||||
increase constraint length when attacking
|
||||
|
||||
mob vision: look at player history
|
||||
build a new type of attraction for mobs
|
||||
if mobs can't see player, they check to see if they can see where the player was in the history
|
||||
if mobs can't see player, they could check to see if they can find player in the past
|
||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||
write find in spawn undo exploder, but commented out
|
||||
|
||||
Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage.
|
||||
maybe it could be immune to damage? but it is spawned by an actual mob
|
||||
|
||||
level Boss: fractal Sierpiński triangle
|
||||
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
|
||||
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
|
||||
they spawn once at the start of the level
|
||||
if a version dies, one can be replaced every ten seconds by the largest version
|
||||
|
||||
give mobs more animal-like behaviors like rain world
|
||||
mobs play, look for food, explore
|
||||
mobs some times aren't aggressive
|
||||
when low on life or after taking a large hit
|
||||
mobs can fight each other
|
||||
this might be hard to code
|
||||
isolated mobs try to group up
|
||||
|
||||
mob: wall mounted guns / lasers
|
||||
not part of randomized mob pool, customized to each level
|
||||
|
||||
level boss: fires a line intersection in a random direction every few seconds.
|
||||
the last two intersections have a destructive laser between them.
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
tech foam teleports around, like a quantum wave function collapse
|
||||
|
||||
should ammo apply to all guns, or just one of your guns?
|
||||
if one gun only, it would make multi-gun builds weaker
|
||||
|
||||
nail bots should benefit from nail gun tech
|
||||
|
||||
tech: picking up heal power ups at max health does harm, but increases max health
|
||||
scales with heal value
|
||||
|
||||
does catabolism give too much ammo?
|
||||
synergy with shotgun harm immunity
|
||||
|
||||
let standing wave harmonics get tech decorrelation
|
||||
|
||||
tech: cloaking field - decrease/increase cooldown on sneak attack?
|
||||
@@ -88,24 +182,12 @@ tech plasma : plasma length increases then decreases as you hold down the field
|
||||
|
||||
tech: at the start of a new level remove 5 research and spawn a second boss
|
||||
|
||||
what about the single axis graphic? (find the code in standing wave harmonic)
|
||||
maybe just save it for a mob
|
||||
maybe use it on lore
|
||||
|
||||
buttons can now on/off boosts
|
||||
|
||||
energy conservation 6% damage recovered as energy
|
||||
add a negative effect:
|
||||
junk tech
|
||||
|
||||
Weak Anthropic Principle: you get a second chance at life, but ....
|
||||
|
||||
mob: molecule shapes - 2 separate mobs joined by a bond
|
||||
use constraints: just spawn 2x or 3x groupings
|
||||
low friction so they can spin around
|
||||
spin when attacking player?
|
||||
increase constraint length when attacking
|
||||
|
||||
tech: use the ability for power ups to have custom code
|
||||
(note: this code is half way done, it just needs to be completed)
|
||||
attracted to player
|
||||
@@ -138,30 +220,11 @@ apply the new gun.do functions to other guns
|
||||
works similar to foam
|
||||
performance issues?
|
||||
|
||||
tech plasma field - plasma field becomes an aoe damage field with the same radius
|
||||
200% more energy drain, 100% more damage
|
||||
draw a square (or two) that rapidly spins
|
||||
|
||||
look into improving mouse lag with pointer lock?
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
|
||||
https://www.vsynctester.com/game.html
|
||||
https://news.ycombinator.com/item?id=26530272
|
||||
|
||||
mob vision: look at player history
|
||||
build a new type of attraction for mobs
|
||||
if mobs can't see player, they check to see if they can see where the player was in the history
|
||||
if mobs can't see player, they could check to see if they can find player in the past
|
||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||
write find in spawn undo exploder, but commented out
|
||||
|
||||
Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage.
|
||||
maybe it could be immune to damage? but it is spawned by an actual mob
|
||||
|
||||
mob - after taking damage
|
||||
attack outwardly
|
||||
grows
|
||||
teleports
|
||||
|
||||
mobile requirements:
|
||||
detect mobile, flip to landscape
|
||||
detect no keyboard, no mouse
|
||||
@@ -170,20 +233,12 @@ mobile requirements:
|
||||
tap screen regions to move (WASD)
|
||||
reduce font size
|
||||
|
||||
lore: a tutorial / lore intro
|
||||
needs to be optional so it doesn't slow experienced players
|
||||
put something on the intro map
|
||||
maybe a button triggers something
|
||||
|
||||
add back in gamepad support
|
||||
but does anyone care?
|
||||
https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected
|
||||
|
||||
rename intro level to something lore related
|
||||
|
||||
rename ?
|
||||
health -> integrity, unity
|
||||
heal -> also integrity, unity
|
||||
|
||||
RPG default or tech: grenades detonate on your cursor / where your cursor was when they were fired
|
||||
|
||||
@@ -219,18 +274,6 @@ tech pilot wave: antigravity - blocks have no gravity for a few seconds after ex
|
||||
|
||||
wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks
|
||||
|
||||
flavor - your bullets destroy blocks
|
||||
this isn't really a bonus, so maybe just add this as flavor to another tech field/gun
|
||||
a chance for destroyed blocks to drop stuff
|
||||
power ups
|
||||
spores
|
||||
|
||||
using a reroll gives 3 options for tech, and 3 options for guns/fields/tech
|
||||
or 6 options for tech (rewrite tech selection to work with 1-6 options)
|
||||
the second stack of 3 tech could have repeats, so you don't have to write new tech code
|
||||
adjust css to make 2 columns of 3
|
||||
can't use with cardinality
|
||||
|
||||
new power up - increase damage and fire speed, for 15 seconds
|
||||
named boost?
|
||||
enabled by a tech
|
||||
@@ -242,9 +285,6 @@ tech- do 50% more damage in close, but 50% less at a distance
|
||||
code it like techisFarAwayDmg
|
||||
have these tech disable each other
|
||||
|
||||
repeat map in vertical and horizontal space
|
||||
or at least vertical space
|
||||
camera looks strange when you teleport player with a high velocity
|
||||
new status effect: weakness, mobs do 75% les damage
|
||||
graphic indication?
|
||||
|
||||
@@ -267,45 +307,8 @@ look for tech that could update description text with count and tech is informat
|
||||
can only use variables that change in effect() and remove()
|
||||
this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${techduplicateChance}</em>`
|
||||
|
||||
map element - player rotates a rotor that makes a platform go up or down
|
||||
|
||||
use mac automator to speed up your n-gon -> git sync
|
||||
|
||||
level Boss: fractal Sierpiński triangle
|
||||
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
|
||||
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
|
||||
they spawn once at the start of the level
|
||||
if a version dies, one can be replaced every ten seconds by the largest version
|
||||
|
||||
level element: a zone with wind, anti-gravity, extra gravity
|
||||
control with button
|
||||
|
||||
give mobs more animal-like behaviors like rain world
|
||||
mobs play, look for food, explore
|
||||
mobs some times aren't aggressive
|
||||
when low on life or after taking a large hit
|
||||
mobs can fight each other
|
||||
this might be hard to code
|
||||
isolated mobs try to group up
|
||||
|
||||
mob: wall mounted guns / lasers
|
||||
not part of randomized mob pool, customized to each level
|
||||
|
||||
level boss: fires a line intersection in a random direction every few seconds.
|
||||
the last two intersections have a destructive laser between them.
|
||||
|
||||
map: observatory
|
||||
button controls rotation of telescope
|
||||
laser beam shoots out of telescope
|
||||
button opens the dome
|
||||
|
||||
map: prison
|
||||
doors linked to buttons
|
||||
mobs inside the doors?
|
||||
|
||||
graphic idea: bezier curve that moves smoothly from mob to mob
|
||||
loops around player
|
||||
|
||||
movement fluidity
|
||||
let legs jump on mobs, but player will still take damage
|
||||
like: ori and the blind forest, celeste
|
||||
@@ -328,14 +331,6 @@ have a mob apply a positive status effect on other mobs,
|
||||
damage bonus, but how?
|
||||
possible balance issues
|
||||
|
||||
boss levels - small levels just a boss, and maybe a few mobs
|
||||
boss level for timeSkipBoss because of game instability for boss on normal levels
|
||||
this might not fix issues
|
||||
|
||||
an effect when canceling a power up
|
||||
ammo? heals?
|
||||
50% chance for a tech 25% heal, 25% ammo
|
||||
|
||||
css transition for pause menu
|
||||
|
||||
animate new level spawn by having the map aspects randomly fly into place
|
||||
@@ -344,6 +339,7 @@ n-gon outreach ideas
|
||||
blips - errant signal on youtube
|
||||
reddit - r/IndieGaming
|
||||
hacker news - show hacker news post
|
||||
twitch - lets play
|
||||
|
||||
|
||||
******************************************************** LORE ********************************************************
|
||||
@@ -369,6 +365,17 @@ possible names for tech
|
||||
phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston
|
||||
Laplace's demon was a notable published articulation of causal determinism on a scientific basis by Pierre-Simon Laplace in 1814.[1] According to determinism, if someone (the demon) knows the precise location and momentum of every atom in the universe, their past and future values for any given time are entailed; they can be calculated from the laws of classical mechanics.
|
||||
Degenerate matter is a highly dense state of fermionic matter in which the Pauli exclusion principle exerts significant pressure in addition to, or in lieu of thermal pressure.
|
||||
evolutionary cosmology
|
||||
eternal inflation
|
||||
|
||||
a tutorial / lore intro
|
||||
needs to be optional so it doesn't slow experienced players
|
||||
put something on the intro map
|
||||
maybe a button triggers something
|
||||
|
||||
rename ?
|
||||
health -> integrity, unity
|
||||
heal -> also integrity, unity
|
||||
|
||||
|
||||
plot script:
|
||||
|
||||
Reference in New Issue
Block a user