diff --git a/.DS_Store b/.DS_Store
index b80255a..4469fa6 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 125b9f7..ded5cbb 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -765,7 +765,7 @@ const b = {
bullet[me].explodeRad = 300 * size;
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
- if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random()))
+ if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
}
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function() {
@@ -790,7 +790,7 @@ const b = {
bullet[me].explodeRad = 305 * size;
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
- if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random()))
+ if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
}
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function() {
@@ -825,7 +825,7 @@ const b = {
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
- if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random()))
+ if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
}
bullet[me].minDmgSpeed = 1;
bullet[me].beforeDmg = function() {
@@ -902,7 +902,7 @@ const b = {
bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
bullet[me].onEnd = function() {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
- if (tech.fragments) b.targetedNail(this.position, tech.fragments * 5)
+ if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
@@ -1253,7 +1253,7 @@ const b = {
requestAnimationFrame(() => { who.isShielded = true });
}
if (tech.fragments) {
- b.targetedNail(this.vertices[2], tech.fragments * 4)
+ b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random()))
this.endCycle = 0;
}
if (!who.isBadTarget) {
@@ -1373,7 +1373,7 @@ const b = {
requestAnimationFrame(() => { who.isShielded = true });
}
if (tech.fragments) {
- b.targetedNail(this.vertices[2], tech.fragments * 3)
+ b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
}
// if (!who.isBadTarget) {
// this.do = this.returnToPlayer
@@ -1635,7 +1635,7 @@ const b = {
requestAnimationFrame(() => { who.isShielded = true });
}
if (tech.fragments) {
- b.targetedNail(this.vertices[2], tech.fragments * 3)
+ b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
if (!isReturn) this.endCycle = 0;
}
if (!who.isBadTarget) {
@@ -1927,7 +1927,7 @@ const b = {
},
onEnd() {
b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end
- if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random()))
+ if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random()))
},
lockedOn: null,
tryToLockOn() {
@@ -2002,7 +2002,7 @@ const b = {
didExtruderDrain: false,
canExtruderFire: true,
extruder() {
- const DRAIN = 0.0021
+ const DRAIN = 0.0018
if (m.energy > DRAIN && b.canExtruderFire) {
m.energy -= DRAIN
if (m.energy < 0) {
@@ -2854,7 +2854,6 @@ const b = {
},
minDmgSpeed: 0,
lockedOn: null,
- isFollowMouse: true,
beforeDmg(who) {
mobs.statusSlow(who, 180)
this.endCycle = simulation.cycle
@@ -2923,17 +2922,17 @@ const b = {
lookFrequency: (tech.isDroneFastLook ? 20 : 70) + Math.floor(17 * Math.random()),
endCycle: simulation.cycle + Math.floor((950 + 400 * Math.random()) * tech.isBulletsLastLonger * tech.droneCycleReduction) + 5 * RADIUS + Math.max(0, 150 - bullet.length),
classType: "bullet",
+ isDrone: true,
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,
beforeDmg(who) {
- if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle) {
+ if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle && !tech.isForeverDrones) {
const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0)
b.explosion(this.position, max * 0.1 + this.isImproved * 110 + 60 * Math.random()); //makes bullet do explosive damage at end
if (tech.isForeverDrones) {
@@ -3127,6 +3126,7 @@ const b = {
lookFrequency: 120 + Math.floor(23 * Math.random()),
endCycle: simulation.cycle + Math.floor((900 + 110 * Math.random()) * tech.isBulletsLastLonger / tech.droneRadioDamage) + 5 * RADIUS + Math.max(0, 150 - 2 * bullet.length),
classType: "bullet",
+ isDrone: true,
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield //self collide
@@ -3134,7 +3134,6 @@ const b = {
minDmgSpeed: 0,
speedCap: 5 + 2 * Math.random(), //6 is normal
lockedOn: null,
- isFollowMouse: true,
deathCycles: 110 + RADIUS * 5,
isImproved: false,
radioRadius: 0,
@@ -4790,7 +4789,7 @@ const b = {
}
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) {
- b.targetedNail(this.position, 1.5 * tech.fragments * tech.bulletSize)
+ b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn
}
};
@@ -4861,7 +4860,7 @@ const b = {
}
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) {
- b.targetedNail(this.position, 1.5 * tech.fragments * tech.bulletSize)
+ b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn
}
};
@@ -5017,7 +5016,7 @@ const b = {
if (tech.fragments) {
bullet[me].beforeDmg = function() {
if (this.speed > 4) {
- b.targetedNail(this.position, 7 * tech.fragments * tech.bulletSize)
+ b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn
}
}
diff --git a/js/level.js b/js/level.js
index 91be3b9..38f2131 100644
--- a/js/level.js
+++ b/js/level.js
@@ -15,13 +15,13 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true
- // m.setField("time dilation")
- // b.giveGuns("foam")
- // tech.giveTech("quantum foam")
- // tech.giveTech("capacitor bank")
- // tech.giveTech("isotropic radiator")
+ // m.setField("molecular assembler")
+ // b.giveGuns("drones")
+ // tech.giveTech("autonomous navigation")
+ // tech.giveTech("delivery drone")
+ // tech.giveTech("dynamo-bot upgrade")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
- // for (let i = 0; i < 3; i++) tech.giveTech("undefined")
+ // for (let i = 0; i < 9; i++) tech.giveTech("dynamo-bot")
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
// powerUps.research.changeRerolls(100000)
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
diff --git a/js/mob.js b/js/mob.js
index 97fbf9c..296d2f9 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1151,7 +1151,7 @@ const mobs = {
for (let i = 0; i < len; i++) b.spore(this.position)
}
} else if (tech.isExplodeMob) {
- b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 1.5) * (22 + 60 * Math.random())))
+ b.explosion(this.position, Math.min(700, Math.sqrt(this.mass + 6) * (30 + 60 * Math.random())))
} else if (tech.nailsDeathMob) {
b.targetedNail(this.position, tech.nailsDeathMob, 39 + 6 * Math.random())
}
diff --git a/js/player.js b/js/player.js
index 62148a7..9306255 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1957,11 +1957,12 @@ const m = {
// m.fieldMeterColor = "#0c5"
// m.eyeFillColor = m.fieldMeterColor
m.hold = function() {
- if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) {
+ if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 300 && (m.cycle % 2)) {
if (tech.isSporeField) {
if (tech.isSporeWorm) {
- if (m.energy > 0.16) {
- m.energy -= 0.16
+ const drain = 0.16 + (Math.max(bullet.length, 130) - 130) * 0.02
+ if (m.energy > drain) {
+ m.energy -= drain
b.worm({ x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) })
const SPEED = 2 + 1 * Math.random();
Matter.Body.setVelocity(bullet[bullet.length - 1], {
@@ -1970,13 +1971,13 @@ const m = {
});
}
} else {
+ const drain = 0.08 + (Math.max(bullet.length, 130) - 130) * 0.01
for (let i = 0, len = Math.random() * 20; i < len; i++) {
- m.energy -= 0.08
- if (m.energy > 0) {
+ if (m.energy > drain) {
+ m.energy -= drain
b.spore(m.pos)
} else {
- m.energy = 0.001
- break;
+ break
}
}
}
@@ -1987,11 +1988,19 @@ const m = {
m.energy -= 0.04;
b.iceIX(1)
} else if (tech.isDroneRadioactive) {
- m.energy -= 0.8;
- 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)
+ const drain = 0.8 + (Math.max(bullet.length, 50) - 50) * 0.01
+ if (m.energy > drain) {
+ m.energy -= drain
+ 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()
+ //every bullet above 100 adds 0.005 to the energy cost per drone
+ //at 200 bullets the energy cost is 0.45 + 100*0.006 = 1.05
+ const drain = (0.45 + (Math.max(bullet.length, 100) - 100) * 0.006) * tech.droneEnergyReduction
+ if (m.energy > drain) {
+ m.energy -= drain
+ b.drone()
+ }
}
}
@@ -2775,7 +2784,7 @@ const m = {
for (let i = 0, len = body.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(body[i].position, m.fieldPosition)) < m.fieldRadius && !body[i].isNotHoldable) {
- const DRAIN = speed * body[i].mass * 0.000006 // * (1 + m.energy * m.energy) //drain more energy when you have more energy
+ const DRAIN = speed * body[i].mass * 0.000005 // * (1 + m.energy * m.energy) //drain more energy when you have more energy
if (m.energy > DRAIN) {
m.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
diff --git a/js/simulation.js b/js/simulation.js
index 5b36918..8fdcf1b 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -821,6 +821,44 @@ const simulation = {
level.zones = [];
simulation.drawList = [];
+ if (tech.isDronesTravel) {
+ //count drones
+ let count = 0
+ let deliveryCount = 0
+ for (let i = 0; i < bullet.length; ++i) {
+ if (bullet[i].isDrone) {
+ count++
+ if (bullet[i].isImproved) deliveryCount++
+ }
+ }
+ // count *= 2
+ //respawn drones in animation frame
+ let respawnDrones = () => {
+ if (count > 0) {
+ requestAnimationFrame(respawnDrones);
+ if (!simulation.paused && !simulation.isChoosing) {
+ count--
+ const where = { x: level.enter.x + 50, y: level.enter.y - 60 }
+ if (tech.isDroneRadioactive) {
+ b.droneRadioactive({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 100 * (Math.random() - 0.5) }, 0)
+ } else {
+ b.drone({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 120 * (Math.random() - 0.5) }, 0)
+ if (tech.isDroneGrab && deliveryCount > 0) {
+ const who = bullet[bullet.length - 1]
+ who.isImproved = true;
+ const SCALE = 2.25
+ Matter.Body.scale(who, SCALE, SCALE);
+ who.lookFrequency = 30 + Math.floor(11 * Math.random());
+ who.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger
+ deliveryCount--
+ }
+ }
+ }
+ }
+ }
+ requestAnimationFrame(respawnDrones);
+ }
+
function removeAll(array) {
// for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
diff --git a/js/tech.js b/js/tech.js
index bfdeed3..37b91cf 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -211,6 +211,7 @@ const tech = {
},
damageFromTech() {
let dmg = 1 //m.fieldDamage
+ if (tech.isTechDebt) dmg *= 4 - 0.1 * tech.totalCount
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
if (tech.OccamDamage) dmg *= tech.OccamDamage
if (tech.isCloakingDamage) dmg *= 1.35
@@ -3082,6 +3083,26 @@ const tech = {
tech.isPauseEjectTech = false;
}
},
+ {
+ name: "technical debt", // overengineering
+ // description: `increase damage by 300% minus 10% for tech you have learned(${4 - 0.1 * tech.totalCount})`,
+ // description: `increase damage by 300%, but reduce damage
by 10% for tech you have learned`,
+ descriptionFunction() {
+ return `increase damage by 300% minus 10%
for tech you have learned (${Math.floor(100*(4 - 0.1 * tech.totalCount))-100}%)`
+ },
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ allowed() { return true },
+ requires: "",
+ effect() {
+ tech.isTechDebt = true;
+ },
+ remove() {
+ tech.isTechDebt = false;
+ }
+ },
{
name: "abiogenesis",
description: `at the start of a level spawn a 2nd boss
use ${powerUps.orb.research(4)}or add 49% JUNK to the tech pool`,
@@ -5021,7 +5042,7 @@ const tech = {
{
name: "reduced tolerances",
link: `reduced tolerances`,
- description: `increase drones per ${powerUps.orb.ammo()} or energy by 66%
reduce the average drone lifetime by 40%`,
+ description: `increase drones per ${powerUps.orb.ammo()} or energy by 66%
reduce average drone durability by 40%`,
isGunTech: true,
maxCount: 3,
count: 0,
@@ -5089,6 +5110,25 @@ const tech = {
tech.isDroneRespawn = false
}
},
+ {
+ name: "autonomous navigation",
+ description: "drones travel with you through levels
and reset their durability",
+ isGunTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isIceField))
+ },
+ requires: "drones",
+ effect() {
+ tech.isDronesTravel = true
+ },
+ remove() {
+ tech.isDronesTravel = false
+ }
+ },
{
name: "brushless motor",
description: "drones rapidly rush towards their target
increase drone collision damage by 33%",
@@ -5212,9 +5252,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
- return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1
+ return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1 && !tech.isDronesTravel
},
- requires: "drones, not drone repair, anti-shear topology",
+ requires: "drones, not drone repair, anti-shear topology, autonomous navigation",
effect() {
const num = 6
tech.isForeverDrones += num
@@ -6337,7 +6377,6 @@ const tech = {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
-
//fill array of available bots
const notUpgradedBots = []
const num = 2
@@ -9497,4 +9536,6 @@ const tech = {
isRailGun: null,
isGrapple: null,
isImmuneGrapple: null,
+ isDronesTravel: null,
+ isTechDebt: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 2fbf535..555b5cc 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,36 +1,20 @@
******************************************************** NEXT PATCH **************************************************
-JUNK tech - 🐱
+tech: autonomous navigation - drones travel with you through levels and drones reset durability
+tech: technical debt - increase damage by 300%, but reduce damage by 10% for each tech you have
-railgun buffs
- 600% -> 800% more ammo
- more dense (more damage)
- only targets mobs when pressing down
- does a bit of damage to nearby mobs after you fire
- extra damage to mob bullets
+molecular assembler now has a higher bullet spawn cap 200->300
+ but it increases energy cost per spawn above around 150
-pneumatic hammer renamed caliber
- also applies to super balls
- 5% less size increase per stack
-
-pure science and unified field theory have a pause animation to show they are clickable
+fragments are about 15% fewer
+thermal runaway is about 40% bigger and more damage
+plasma torch: extruder uses less energy
+pilot wave uses less energy
bug fixes
******************************************************** TODO ********************************************************
-github bug report - if you reload, the TInker effect is lost, despite it saying it persists through sessions. Please fix.
-
-bug: railgun AoE is randomly killing some mobs when it shouldn't
-
-buff mob death explosions
-
-buff railgun
- make railgun push blocks in the same direction railgun moves
- make block intangible for a sec, like a block throw
-
-buff drone gun / gun tech, but not drones?
-
const ctx = canvas.getContext('2d', {‘willReadFrequently': true});
//deal with game crashes?
@@ -55,13 +39,6 @@ bug: often game puts player position at NaN
very high level for tech, duplication
maybe not about JUNK though
-grappling hook
- give player more control over motion while hanging and retracting
- reduce friction effects so player swing around?
- up down left right push player around?
- scale velocity dampening with distance to grapple?
- make a variable to track rope length?
-
tech that does less damage the more tech you have?
tech.totalCount