diff --git a/.DS_Store b/.DS_Store
index 2273425..711383d 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 302e2bd..4c459ce 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -311,6 +311,9 @@ const b = {
},
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius
+
+ // radius = Math.max(0, Math.min(radius, (distanceToPlayer - 70) / b.explosionRange()))
+
let dist, sub, knock;
let dmg = radius * 0.017 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1);
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
@@ -322,6 +325,7 @@ const b = {
if (tech.isExplodeRadio) { //radiation explosion
radius *= 1.25; //alert range
+ if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
color = "rgba(25,139,170,0.25)"
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
@@ -359,6 +363,7 @@ const b = {
}
}
} else { //normal explosions
+ if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
@@ -1103,6 +1108,185 @@ const b = {
b.grenade = grenadeDefault
}
},
+ harpoon(where, target, scale = 1, isReturn = false, ropeLength = 15, speed = 0) {
+ const me = bullet.length;
+ let vector = "-40 2 -40 -2 30 -2 50 0 30 2"
+ if (scale !== 1) vector = `${-40*scale} 2 ${-40*scale} -2 ${30*scale} -2 ${50*scale} 0 ${30*scale} 2`
+ bullet[me] = Bodies.fromVertices(where.x, where.y, Vertices.fromPath(vector), {
+ // bullet[me] = Bodies.rectangle(where.x, where.y, 70 * size, 4.5 * size, {
+ cycle: 0,
+ angle: m.angle,
+ friction: 1,
+ frictionAir: 0.4,
+ thrustMag: 0.1,
+ turnRate: isReturn ? 0.1 : 0.03, //0.015
+ drawStringControlMagnitude: 3000 + 5000 * Math.random(),
+ drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
+ dmg: 0, //damage done in addition to the damage from momentum
+ classType: "bullet",
+ endCycle: simulation.cycle + 50,
+ collisionFilter: {
+ category: cat.bullet,
+ mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
+ },
+ minDmgSpeed: 0,
+ lookFrequency: Math.floor(7 + Math.random() * 3),
+ density: 0.005, //0.001 is normal
+ beforeDmg(who) {
+ if (!who.isBadTarget) {
+ if (tech.fragments) {
+ b.targetedNail(this.position, tech.fragments * 5)
+ } else if (isReturn) {
+ this.do = this.returnToPlayer
+ } else {
+ this.frictionAir = 0.01
+ this.do = () => {
+ this.force.y += this.mass * 0.003; //gravity
+ }
+ }
+
+ }
+ },
+ onEnd() {},
+ drawString() {
+ if (isReturn) {
+ const where = {
+ x: m.pos.x + 30 * Math.cos(m.angle),
+ y: m.pos.y + 30 * Math.sin(m.angle)
+ }
+ const sub = Vector.sub(where, this.vertices[0])
+ const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub))))
+ const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular)
+ ctx.strokeStyle = "#000" // "#0ce"
+ ctx.lineWidth = 0.5
+ ctx.beginPath();
+ ctx.moveTo(where.x, where.y);
+ ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
+ // ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
+ ctx.stroke();
+
+ if (m.energy > 0.003) m.energy -= 0.003
+ }
+ },
+ returnToPlayer() {
+ if (Vector.magnitude(Vector.sub(this.position, m.pos)) < 100) { //near player
+ this.endCycle = 0;
+ if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 25 * b.fireCDscale
+ //recoil on catching
+ const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), this.mass * (m.crouch ? 0.0001 : 0.0002))
+ player.force.x += momentum.x
+ player.force.y += momentum.y
+ // refund ammo
+ for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
+ if (b.guns[i].name === "harpoon") {
+ b.guns[i].ammo++;
+ simulation.updateGunHUD();
+ break;
+ }
+ }
+ // if you grabbed a power up, stop it near the player
+ for (let i = 0, len = powerUp.length; i < len; ++i) { //near power up
+ if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 6000) {
+ Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 })
+ // Matter.Body.setPosition(powerUp[i], this.position)
+ break
+ }
+ }
+ } else {
+ for (let i = 0, len = powerUp.length; i < len; ++i) { //near power up
+ if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 3000) {
+ Matter.Body.setVelocity(powerUp[i], this.velocity)
+ Matter.Body.setPosition(powerUp[i], this.position)
+ break
+ }
+ }
+ const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), this.thrustMag * this.mass)
+ this.force.x -= returnForce.x
+ this.force.y -= returnForce.y
+ this.drawString()
+ }
+ },
+ do() {
+ if (!m.isBodiesAsleep) {
+ this.cycle++
+ if (isReturn && this.cycle > ropeLength) {
+ if (m.energy < 0.05) { //snap rope if not enough energy
+ const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
+ this.force.x -= returnForce.x
+ this.force.y -= returnForce.y
+ this.frictionAir = 0.003
+ this.do = () => {
+ this.force.y += this.mass * 0.003; //gravity
+ }
+ } else { //return to player
+ this.do = this.returnToPlayer
+ if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
+ this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
+ }
+ }
+ if (this.cycle > 30) {
+ this.frictionAir = 0.003
+ this.do = () => {
+ this.force.y += this.mass * 0.003; //gravity
+ }
+ }
+
+ if (target) { //rotate missile towards the target
+ const face = {
+ x: Math.cos(this.angle),
+ y: Math.sin(this.angle)
+ };
+ const vectorGoal = Vector.normalise(Vector.sub(this.position, target.position));
+ if (Vector.cross(vectorGoal, face) > 0) {
+ Matter.Body.rotate(this, this.turnRate);
+ } else {
+ Matter.Body.rotate(this, -this.turnRate);
+ }
+ }
+ // else if (!(this.cycle % 2)) { //look for a target if you don't have one
+ // simulation.drawList.push({ //add dmg to draw queue
+ // x: this.position.x,
+ // y: this.position.y,
+ // radius: 10,
+ // color: simulation.mobDmgColor,
+ // time: simulation.drawTime
+ // });
+ // let closest = {
+ // distance: 2000,
+ // target: null
+ // }
+ // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1
+ // for (let i = 0, len = mob.length; i < len; ++i) {
+ // if (
+ // mob[i].alive && !mob[i].isBadTarget &&
+ // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight
+ // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors
+ // ) {
+ // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position))
+ // if (dist < closest.distance) {
+ // closest.distance = dist
+ // closest.target = mob[i]
+ // }
+ // }
+ // }
+ // if (closest.target) {
+ // target = closest.target
+ // this.turnRate = 0.05
+ // this.frictionAir = 0.8
+ // }
+ // }
+ this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
+ this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
+ }
+ this.drawString()
+ },
+ });
+ Matter.Body.setVelocity(bullet[me], {
+ x: m.Vx / 2 + speed * Math.cos(bullet[me].angle),
+ y: m.Vy / 2 + speed * Math.sin(bullet[me].angle)
+ });
+ Composite.add(engine.world, bullet[me]); //add bullet to world
+ },
missile(where, angle, speed, size = 1) {
if (tech.missileSize) size *= 1.5
const me = bullet.length;
@@ -1438,12 +1622,12 @@ const b = {
const reflectivity = 1 - 1 / (reflections * 1.5)
let damage = b.dmgScale * dmg
let best = {
- x: null,
- y: null,
+ x: 1,
+ y: 1,
dist2: Infinity,
who: null,
- v1: null,
- v2: null
+ v1: 1,
+ v2: 1
};
const path = [{
x: where.x,
@@ -1497,12 +1681,12 @@ const b = {
const checkForCollisions = function() {
best = {
- x: null,
- y: null,
+ x: 1,
+ y: 1,
dist2: Infinity,
who: null,
- v1: null,
- v2: null
+ v1: 1,
+ v2: 1
};
vertexCollision(path[path.length - 2], path[path.length - 1], mob);
vertexCollision(path[path.length - 2], path[path.length - 1], map);
@@ -4436,13 +4620,11 @@ const b = {
ammoPack: 4,
have: false,
fireCycle: 0,
- ammoLoaded: 0,
do() {},
fire() {
const countReduction = Math.pow(0.9, tech.missileCount)
if (m.crouch) {
m.fireCDcycle = m.cycle + 10 * b.fireCDscale / countReduction; // cool down
-
// for (let i = 0; i < tech.missileCount; i++) {
// b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5) * Math.sqrt(tech.missileCount), -2, Math.sqrt(countReduction))
// bullet[bullet.length - 1].force.x += 0.004 * countReduction * (i - (tech.missileCount - 1) / 2);
@@ -4818,7 +5000,59 @@ const b = {
this.charge++
m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCDscale);
},
- }, {
+ },
+ {
+ name: "harpoon",
+ description: "fire a self-steering harpoon that uses energy
to retract and refund its ammo cost",
+ ammo: 0,
+ ammoPack: 1,
+ have: false,
+ fireCycle: 0,
+ do() {},
+ fire() {
+ const where = {
+ x: m.pos.x + 30 * Math.cos(m.angle),
+ y: m.pos.y + 30 * Math.sin(m.angle)
+ }
+ const closest = {
+ distance: 10000,
+ target: null
+ }
+ //look for closest mob in player's LoS
+ const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1
+ if (m.crouch) {
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
+ const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
+ const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
+ if (dist < closest.distance && dot > 0.95 && dist * dot * dot * dot * dot > 880) { //target closest mob that player is looking at and isn't too close to target
+ closest.distance = dist
+ closest.target = mob[i]
+ }
+ }
+ }
+ b.harpoon(where, closest.target, 1 + tech.isLargeHarpoon * this.ammo / 100, false)
+ m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
+ } else {
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
+ const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
+ const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
+ if (dist < closest.distance && dot > 0.95) { //target closest mob that player is looking at and isn't too close to target
+ closest.distance = dist
+ closest.target = mob[i]
+ }
+ }
+ }
+ b.harpoon(where, closest.target, 1 + tech.isLargeHarpoon * this.ammo / 100, true, (m.crouch ? 10 : 8) * (tech.isFilament ? 1 + this.ammo / 100 : 1))
+ m.fireCDcycle = m.cycle + 180 //Infinity; // cool down
+ }
+ const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), m.crouch ? 0.015 : 0.035)
+ player.force.x -= recoil.x
+ player.force.y -= recoil.y
+ }
+ },
+ {
name: "rail gun",
description: "use energy to launch a high-speed dense rod
hold left mouse to charge, release to fire",
ammo: 0,
diff --git a/js/level.js b/js/level.js
index 800be9a..cf02a55 100644
--- a/js/level.js
+++ b/js/level.js
@@ -15,8 +15,8 @@ const level = {
// localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
- // m.setField("metamaterial cloaking")
- // b.giveGuns("spores")
+ // m.setField("time dilation")
+ // b.giveGuns("harpoon")
// tech.giveTech("nematodes")
// tech.giveTech("necrophage")
// for (let i = 0; i < 3; i++) tech.giveTech("super sized")
@@ -2273,7 +2273,7 @@ const level = {
spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// spawn.starter(1900, -500, 200) //big boy
- spawn.blockBoss(1900, -500)
+ // spawn.blockGroup(1900, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
// spawn.laserBombingBoss(1900, -500)
// for (let i = 0; i < 5; i++) spawn.focuser(1900, -500)
@@ -2295,7 +2295,11 @@ const level = {
// spawn.laserTargetingBoss(1600, -500)
// spawn.striker(1200, -500)
- // spawn.nodeGroup(1200, -500, "grenadier")
+ spawn.nodeGroup(1200, -500, "grenadier")
+ // spawn.nodeGroup(1800, -500, "grenadier")
+ // spawn.nodeGroup(1200, 0, "grenadier")
+
+
// spawn.snakeBoss(1200, -500)
// spawn.suckerBoss(2900, -500)
// spawn.randomMob(1600, -500)
diff --git a/js/spawn.js b/js/spawn.js
index 372db82..59e8f9c 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1,7 +1,7 @@
//main object for spawning things in a level
const spawn = {
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"],
- randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "blockBoss"]) {
+ randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
@@ -696,11 +696,13 @@ const spawn = {
me.groupingStrength = 0.0005
me.memory = 200;
me.isGrouper = true;
+ me.seeAtDistance2 = 600 * 600
+ me.seePlayerFreq = Math.floor(50 + 50 * Math.random())
me.do = function() {
this.gravity();
this.checkStatus();
+ this.seePlayerCheck();
if (this.seePlayer.recall) {
- this.seePlayerCheck();
this.attraction();
//tether to other blocks
ctx.beginPath();
diff --git a/js/tech.js b/js/tech.js
index 4f7bcbd..b48895f 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -864,6 +864,28 @@
tech.isExplosionStun = false;
}
},
+ {
+ name: "controlled explosion",
+ description: `use ${powerUps.orb.research(3)} to dynamically reduce all
explosions until they do no harm`,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 2) && (tech.haveGunCheck("missiles") || tech.isMissileField || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
+ },
+ requires: "an explosive damage source, not electric reactive armor",
+ effect: () => {
+ tech.isSmartRadius = true;
+ for (let i = 0; i < 3; i++) {
+ if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
+ }
+ },
+ remove() {
+ tech.isSmartRadius = false;
+ if (this.count > 0) powerUps.research.changeRerolls(3)
+ }
+ },
{
name: "electric reactive armor",
// description: "explosions do no harm
while your energy is above 98%",
@@ -873,7 +895,7 @@
frequency: 2,
frequencyDefault: 2,
allowed() {
- return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck()
+ return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck()
},
requires: "an explosive damage source, not iridium-192",
effect: () => {
@@ -903,15 +925,15 @@
},
{
name: "fragmentation",
- description: "some detonations and collisions eject nails
blocks, rail gun, grenades, missiles, shotgun slugs",
+ description: "some detonations and collisions eject nails
blocks, rail gun, grenades, missiles, slugs, harpoon",
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
- return (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.haveGunCheck("rail gun") || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.throwChargeRate > 1
+ return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.haveGunCheck("rail gun") || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.throwChargeRate > 1
},
- requires: "grenades, missiles, rail gun, shotgun slugs, or mass driver",
+ requires: "grenades, missiles, rail gun, shotgun slugs, harpoon, or mass driver",
effect() {
tech.fragments++
},
@@ -3881,7 +3903,6 @@
if (b.guns[i].name === "shotgun") {
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.5);
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.5
- simulation.makeGunHUD();
break;
}
}
@@ -3894,10 +3915,10 @@
if (b.guns[i].name === "shotgun") {
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 2);
- simulation.makeGunHUD();
break;
}
}
+ simulation.updateGunHUD();
}
}
},
@@ -4954,6 +4975,63 @@
tech.isAmmoFoamSize = false;
}
},
+ {
+ name: "filament",
+ description: "increase the length of your harpoon's rope
by 1% per harpoon ammo",
+ isGunTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("harpoon")
+ },
+ requires: "harpoon, not spear",
+ effect() {
+ tech.isFilament = true;
+ },
+ remove() {
+ tech.isFilament = false;
+ }
+ },
+ {
+ name: "unaaq",
+ description: "increase the length of your harpoon
by 1% per harpoon ammo",
+ isGunTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("harpoon")
+ },
+ requires: "harpoon",
+ effect() {
+ tech.isLargeHarpoon = true;
+ },
+ remove() {
+ tech.isLargeHarpoon = false;
+ }
+ },
+ // {
+ // name: "spear",
+ // description: "harpoons fired while crouched
have no rope and improved steering",
+ // isGunTech: true,
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 2,
+ // frequencyDefault: 2,
+ // allowed() {
+ // return tech.haveGunCheck("harpoon") && !tech.isFilament
+ // },
+ // requires: "harpoon, not filament",
+ // effect() {
+ // tech.isSpear = true;
+ // },
+ // remove() {
+ // tech.isSpear = false;
+ // }
+ // },
{
name: "half-wave rectifier",
description: "charging the rail gun gives you energy
instead of draining it",
@@ -6355,6 +6433,82 @@
// },
// remove() {}
// },
+ {
+ name: "true colors",
+ description: `set all power ups to their real world colors`,
+ maxCount: 1,
+ count: 0,
+ frequency: 0,
+ isExperimentHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ // const colors = shuffle(["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"])
+ const colors = shuffle([powerUps.research.color, powerUps.heal.color, powerUps.ammo.color, powerUps.ammo.color, powerUps.field.color, powerUps.gun.color])
+ powerUps.research.color = colors[0]
+ powerUps.heal.color = colors[1]
+ powerUps.ammo.color = colors[2]
+ powerUps.field.color = colors[3]
+ powerUps.tech.color = colors[4]
+ powerUps.gun.color = colors[5]
+ for (let i = 0; i < powerUp.length; i++) {
+ switch (powerUp[i].name) {
+ case "research":
+ powerUp[i].color = colors[0]
+ break;
+ case "heal":
+ powerUp[i].color = colors[1]
+ break;
+ case "ammo":
+ powerUp[i].color = colors[2]
+ break;
+ case "field":
+ powerUp[i].color = colors[3]
+ break;
+ case "tech":
+ powerUp[i].color = colors[4]
+ break;
+ case "gun":
+ powerUp[i].color = colors[5]
+ break;
+ }
+ }
+ },
+ remove() {
+ const colors = ["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"] //no shuffle
+ powerUps.research.color = colors[0]
+ powerUps.heal.color = colors[1]
+ powerUps.ammo.color = colors[2]
+ powerUps.field.color = colors[3]
+ powerUps.tech.color = colors[4]
+ powerUps.gun.color = colors[5]
+ for (let i = 0; i < powerUp.length; i++) {
+ switch (powerUp[i].name) {
+ case "research":
+ powerUp[i].color = colors[0]
+ break;
+ case "heal":
+ powerUp[i].color = colors[1]
+ break;
+ case "ammo":
+ powerUp[i].color = colors[2]
+ break;
+ case "field":
+ powerUp[i].color = colors[3]
+ break;
+ case "tech":
+ powerUp[i].color = colors[4]
+ break;
+ case "gun":
+ powerUp[i].color = colors[5]
+ break;
+ }
+ }
+ }
+ },
{
name: "emergency broadcasting",
description: "emit 2 sound sine waveforms at 853 Hz and 960 Hz
lower your volume",
@@ -7942,5 +8096,9 @@
wormSurviveDmg: null,
isExtraGunField: null,
isBigField: null,
- isMineStun: null
+ isMineStun: null,
+ isSmartRadius: null,
+ isFilament: null,
+ // isSpear: null,
+ isLargeHarpoon: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 8a8ecf8..9c5d577 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,22 +1,43 @@
******************************************************** NEXT PATCH **************************************************
-all explosions do 33% more damage to mobs
- and 75% more damage to player
- boom bot explosions are 16% smaller
+new gun harpoon
+tech: filament - harpoon rope gets 1% longer for every harpoon ammo in your inventory
+tech: unaaq - harpoon gets 1% longer for every harpoon ammo in your inventory
+ harpoon is pretty unbalanced, but I'm pushing it out so ya'll can let me know how I should balance it
+ more harpoon tech to come
+ 2+ harpoons out at once
+ hold fire to extend rope longer
+ improved targeting: so it can hit the same target a few times
-laser-bot does 15% more damage
-missile bot fires 15% quicker
-tech: phase velocity also adds 15% wave damage (because it disables phonon is was a bad choice)
-many duplication tech add less duplication
-Maxwell's demon now requires current energy above your max to unlock
+tech: controlled explosion - explosions shrink to prevent them from hitting you, cost 3 research
-power ups in the intro tube get pushed around a bit, this might stop them from sliding on the walls
-mines when they are stuck to walls no longer collide with blocks (to not block elevator)
-more bug fixes
+JUNK tech: true colors - set all power ups to their real world colors (just makes random colors)
******************************************************** TODO ********************************************************
-JUNK tech: add a score to in game console every 10 seconds
+"Interstellar Disturbance": Cosmic String applies to mobs who cross the wormhole's path, even after initial wormholing, but at reduced damage and stun time.
+
+disable zoom progress when paused
+
+gun: harpoon
+ if no target no thrust and no airfriction
+ stuck in walls, and don't return ammo
+ return to player is slower for heavier harpoons
+harpoon tech
+ holding down fire lets the string extend farther,
+ can't have 2+ harpoons
+ it uses up ammo as extends, and returns it as it contracts?
+ will this effect performance?
+ fire 2+ harpoons at the same time but different angles
+ 2+ harpoons, with separate CDs
+ can't have extended string?
+ post launch tracking: more airFriction, more thrust, harder turning
+ if no target found slow down and aim much better?
+ tracking so good harpoon can hit a target, circle around and hit it again
+
+level:lab too much walking around and too much platforming
+
+set blockBoss frequency to 1x not 2x
tech - explode after getting hit, but while you are immune to harm
@@ -32,17 +53,6 @@ make a boss with a tail
stabbers maybe
suckers maybe
-set blockBoss frequency to 1x not 3x
-
-block groups should look for player, so the player doesn't step on them?
- remove heath bar?
-
-fix simulation.CDScale // it's always zero so it does nothing
-some mobs can't see player...
-3 laser boss isn't rotating...
- it's always null
- you shouldn't of removes lookFrequency scale var...
-
tech remove all JUNK tech
but you can't research
maybe spend research
@@ -436,6 +446,7 @@ level boss: fires a line intersection in a random direction every few seconds.
******************************************************** LORE ********************************************************
possible names for tech
+ astrophage
strange loop
holonomy - parallel transport of a vector leads to movement (applies to curved space)
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.