autonomous navigation

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

molecular assembler now has a higher bullet spawn cap 200->300
  but it increases energy cost per spawn above around 150

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
This commit is contained in:
landgreen
2022-03-12 05:48:52 -08:00
parent d39e5c784d
commit fc64d2daa4
8 changed files with 134 additions and 70 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -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
}
}

View File

@@ -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")

View File

@@ -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())
}

View File

@@ -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,13 +1988,21 @@ const m = {
m.energy -= 0.04;
b.iceIX(1)
} else if (tech.isDroneRadioactive) {
m.energy -= 0.8;
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;
//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()
}
}
}
if (m.isHolding) {
m.drawHold(m.holdingTarget);
@@ -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

View File

@@ -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]);

View File

@@ -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 <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned(${4 - 0.1 * tech.totalCount})`,
// description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong>, but reduce <strong class='color-d'>damage</strong><br>by <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned`,
descriptionFunction() {
return `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong><br>for <strong class='color-m'>tech</strong> you have learned <em>(${Math.floor(100*(4 - 0.1 * tech.totalCount))-100}%)</em>`
},
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 <strong>boss</strong><br>use ${powerUps.orb.research(4)}or add <strong>49%</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool`,
@@ -5021,7 +5042,7 @@ const tech = {
{
name: "reduced tolerances",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Engineering_tolerance' class="link">reduced tolerances</a>`,
description: `increase <strong>drones</strong> per ${powerUps.orb.ammo()} or <strong class='color-f'>energy</strong> by <strong>66%</strong><br>reduce the average <strong>drone</strong> lifetime by <strong>40%</strong>`,
description: `increase <strong>drones</strong> per ${powerUps.orb.ammo()} or <strong class='color-f'>energy</strong> by <strong>66%</strong><br>reduce average <strong>drone</strong> <strong>durability</strong> by <strong>40%</strong>`,
isGunTech: true,
maxCount: 3,
count: 0,
@@ -5089,6 +5110,25 @@ const tech = {
tech.isDroneRespawn = false
}
},
{
name: "autonomous navigation",
description: "<strong>drones</strong> travel with you through <strong>levels</strong><br>and reset their <strong>durability</strong>",
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: "<strong>drones</strong> rapidly <strong>rush</strong> towards their target<br>increase <strong>drone</strong> collision <strong class='color-d'>damage</strong> by <strong>33%</strong>",
@@ -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
}

View File

@@ -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