pigeonhole principle

tech: junk DNA - +53% spore/worm/flea damage per JUNK tech you have, +50% JUNK added to tech pool
tech: pigeonhole principle - +31% damage for each gun you have, while a chosen gun is active
  chosen gun cycles each level
  syncs well with generalist

heuristics 30->25% fire rate, and now spawns a gun
arsenal gives 13->22% damage per gun, but no longer counts your current gun
active cooling gives 18->28% fire rate per gun, but no longer counts your current gun
supply chain adds 4% JUNK
dead reckoning 36->50% damage
alternator harpoon 60->80% energy cost reduction
quickly releasing the fire button retracts harpoon early

JUNK tech - circular symmetry - ship gets 200% damage, ship only faces forward but you can rotate the universe

several bug fixes
  coupling for molecular assembler 5->8 energy per second
    but also fixed a bug where coupling was giving 10x regen
This commit is contained in:
landgreen
2022-10-23 19:07:07 -07:00
parent 3a9cc28b76
commit de6d910aca
9 changed files with 314 additions and 128 deletions

View File

@@ -284,7 +284,7 @@ const b = {
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
if (m.fieldMode === 6) b.fireCDscale *= 0.75 if (m.fieldMode === 6) b.fireCDscale *= 0.75
if (tech.isFastTime) b.fireCDscale *= 0.5 if (tech.isFastTime) b.fireCDscale *= 0.5
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, b.inventory.length) if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, Math.max(0, b.inventory.length - 1))
if (tech.isFireMoveLock) b.fireCDscale *= 0.55 if (tech.isFireMoveLock) b.fireCDscale *= 0.55
}, },
fireAttributes(dir, rotate = true) { fireAttributes(dir, rotate = true) {
@@ -1441,7 +1441,7 @@ const b = {
minDmgSpeed: 4, minDmgSpeed: 4,
lookFrequency: Math.floor(7 + Math.random() * 3), lookFrequency: Math.floor(7 + Math.random() * 3),
density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
drain: tech.isRailEnergy ? 0.002 : 0.006, drain: tech.isRailEnergy ? 0.001 : 0.006,
beforeDmg(who) { beforeDmg(who) {
if (tech.isShieldPierce && who.isShielded) { //disable shields if (tech.isShieldPierce && who.isShielded) { //disable shields
who.isShielded = false who.isShielded = false
@@ -1697,7 +1697,7 @@ const b = {
friction: 1, friction: 1,
frictionAir: 0.4, frictionAir: 0.4,
thrustMag: 0.1, thrustMag: 0.1,
drain: tech.isRailEnergy ? 0.002 : 0.006, drain: tech.isRailEnergy ? 0.001 : 0.006,
turnRate: isReturn ? 0.1 : 0.03, //0.015 turnRate: isReturn ? 0.1 : 0.03, //0.015
drawStringControlMagnitude: 3000 + 5000 * Math.random(), drawStringControlMagnitude: 3000 + 5000 * Math.random(),
drawStringFlip: (Math.round(Math.random()) ? 1 : -1), drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
@@ -1862,7 +1862,7 @@ const b = {
this.cycle++ this.cycle++
if (isReturn || target) { if (isReturn || target) {
if (isReturn) { if (isReturn) {
if (this.cycle > totalCycles || m.energy < 0.05) { //return to player if (this.cycle > totalCycles || m.energy < 0.05 || !input.fire) { //return to player
this.do = this.returnToPlayer 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) if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
Matter.Sleeping.set(this, false) Matter.Sleeping.set(this, false)
@@ -2698,7 +2698,7 @@ const b = {
thrust: (tech.isSporeFollow ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)), thrust: (tech.isSporeFollow ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)),
wormSize: wormSize, wormSize: wormSize,
wormTail: 1 + Math.max(4, Math.min(wormSize - 2 * tech.wormSize, 30)), wormTail: 1 + Math.max(4, Math.min(wormSize - 2 * tech.wormSize, 30)),
dmg: (tech.isMutualism ? 8 : 3.2) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm dmg: (tech.isMutualism ? 8 : 3.2) * wormSize * (tech.isJunkDNA ? 1 + 0.53 * tech.junkCount : 1), //bonus damage from tech.isMutualism //2.5 is extra damage as worm
lookFrequency: 100 + Math.floor(37 * Math.random()), lookFrequency: 100 + Math.floor(37 * Math.random()),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -2814,7 +2814,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isSporeFollow ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)), thrust: (tech.isSporeFollow ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism dmg: (tech.isMutualism ? 16.8 : 7) * (tech.isJunkDNA ? 1 + 0.53 * tech.junkCount : 1), //bonus damage from tech.isMutualism
lookFrequency: 100 + Math.floor(117 * Math.random()), lookFrequency: 100 + Math.floor(117 * Math.random()),
classType: "bullet", classType: "bullet",
isSpore: true, isSpore: true,
@@ -3031,7 +3031,7 @@ const b = {
cd: simulation.cycle + 10, cd: simulation.cycle + 10,
dmg: 0, //radius * (tech.isMutualism ? 2.5 : 1), dmg: 0, //radius * (tech.isMutualism ? 2.5 : 1),
setDamage() { //dmg is set to zero after doing damage once, and set back to normal after jumping setDamage() { //dmg is set to zero after doing damage once, and set back to normal after jumping
this.dmg = radius * (tech.isMutualism ? 2.5 : 1) //damage done in addition to the damage from momentum //spores do 7 dmg, worms do 18 this.dmg = radius * (tech.isMutualism ? 2.5 : 1) * (tech.isJunkDNA ? 1 + 0.53 * tech.junkCount : 1) //damage done in addition to the damage from momentum //spores do 7 dmg, worms do 18
}, },
beforeDmg(who) { beforeDmg(who) {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), 10 + 10 * Math.random())); //push away from target Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), 10 + 10 * Math.random())); //push away from target
@@ -6777,7 +6777,7 @@ const b = {
charge: 0, charge: 0,
railDo() { railDo() {
if (this.charge > 0) { if (this.charge > 0) {
const DRAIN = (tech.isRailEnergy ? 0.0005 : 0.002) const DRAIN = (tech.isRailEnergy ? 0.00025 : 0.002)
//exit railgun charging without firing //exit railgun charging without firing
if (m.energy < DRAIN) { if (m.energy < DRAIN) {
// m.energy += 0.025 + this.charge * 22 * this.drain // m.energy += 0.025 + this.charge * 22 * this.drain
@@ -7051,7 +7051,7 @@ const b = {
} }
} }
if (input.down && m.onGround) { if (input.down && m.onGround) {
b.harpoon(where, null, m.angle, harpoonSize, true, 1.5 * totalCycles, (input.down && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true) b.harpoon(where, null, m.angle, harpoonSize, true, 1.5 * totalCycles, (input.down && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true) {
} else { } else {
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles) b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
} }

View File

@@ -28,19 +28,20 @@ const level = {
// m.setField("time dilation") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave // m.setField("time dilation") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave
// simulation.molecularMode = 2 // simulation.molecularMode = 2
// m.damage(0.1); // m.damage(0.1);
// b.giveGuns("missiles") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 10000 // b.guns[9].ammo = 10000
// tech.giveTech("ship")
// tech.giveTech("arsenal") // for (let i = 0; i < 1; ++i) tech.giveTech("junk DNA")
// for (let i = 0; i < 1; ++i) tech.giveTech("compound lens")
// tech.giveTech("dye laser") // tech.giveTech("dye laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("CPT symmetry") // for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook")
// for (let i = 0; i < 5; i++) tech.giveTech("laser-bot") // for (let i = 0; i < 5; i++) tech.giveTech("laser-bot")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// canvas.requestPointerLock()
// level.testing(); // level.testing();
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500) // spawn.starter(1900, -500)
@@ -94,6 +95,14 @@ const level = {
m.resetHistory(); m.resetHistory();
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
//used for generalist and pigeonhole principle
tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle) {
b.inventoryGun = tech.buffedGun;
simulation.switchGun();
}
if (tech.isForeverDrones) { if (tech.isForeverDrones) {
if (tech.isDroneRadioactive) { if (tech.isDroneRadioactive) {
for (let i = 0; i < tech.isForeverDrones * 0.25; i++) { for (let i = 0; i < tech.isForeverDrones * 0.25; i++) {
@@ -111,11 +120,6 @@ const level = {
tech.healMaxEnergyBonus += 0.1 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51) tech.healMaxEnergyBonus += 0.1 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51)
m.setMaxEnergy(); m.setMaxEnergy();
} }
if (tech.isGunCycle) {
b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
simulation.switchGun();
}
if (tech.isSwitchReality && powerUps.research.count > 0) { if (tech.isSwitchReality && powerUps.research.count > 0) {
powerUps.research.changeRerolls(-1); powerUps.research.changeRerolls(-1);
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`); simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
@@ -162,7 +166,7 @@ const level = {
if (m.plasmaBall) m.plasmaBall.reset() if (m.plasmaBall) m.plasmaBall.reset()
if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) { if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) {
const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1 const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
powerUps.spawn(flip * localSettings.entanglement.position.x, localSettings.entanglement.position.y, "entanglement", false); powerUps.directSpawn(flip * localSettings.entanglement.position.x, localSettings.entanglement.position.y, "entanglement", false);
} }
}, },
trainingText(say) { trainingText(say) {

View File

@@ -362,6 +362,7 @@ const m = {
tech.cancelCount = 0; tech.cancelCount = 0;
tech.extraMaxHealth = 0; tech.extraMaxHealth = 0;
tech.totalCount = 0; tech.totalCount = 0;
tech.countJunkTech();
const randomBotCount = b.totalBots() const randomBotCount = b.totalBots()
b.zeroBotCount() b.zeroBotCount()
//remove all bullets, respawn bots //remove all bullets, respawn bots
@@ -1066,7 +1067,8 @@ const m = {
} else { } else {
m.fieldRegen = 0.001 //6 energy per second m.fieldRegen = 0.001 //6 energy per second
} }
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.008333 * m.coupling if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.00133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
if (tech.isTimeCrystals) { if (tech.isTimeCrystals) {
m.fieldRegen *= 3 m.fieldRegen *= 3
} else if (tech.isGroundState) { } else if (tech.isGroundState) {
@@ -1589,7 +1591,7 @@ const m = {
case 3: //negative mass case 3: //negative mass
return `<strong>+${((1-0.73 ** couple)*100).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>` return `<strong>+${((1-0.73 ** couple)*100).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>`
case 4: //assembler case 4: //assembler
return `generate <strong>${(5*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second` return `generate <strong>${(8*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma case 5: //plasma
return `<strong>+${(15*couple).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>` return `<strong>+${(15*couple).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation case 6: //time dilation

View File

@@ -332,7 +332,7 @@ const powerUps = {
}, },
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) { if (isCanceled) {
if (tech.isCancelTech && Math.random() < 0.88) { if (tech.isCancelTech && Math.random() < 0.85) {
// powerUps.research.use('tech') // powerUps.research.use('tech')
powerUps[type].effect(); powerUps[type].effect();
return return
@@ -356,7 +356,7 @@ const powerUps = {
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false); powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
} }
} }
if (tech.isCancelCouple) powerUps.coupling.spawnDelay(5) if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 5)
// if (tech.isCancelTech && Math.random() < 0.3) { // if (tech.isCancelTech && Math.random() < 0.3) {
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false); // powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false);
// simulation.makeTextLog(`<strong>options exchange</strong>: returns 1 <strong class='color-m'>tech</strong>`) // simulation.makeTextLog(`<strong>options exchange</strong>: returns 1 <strong class='color-m'>tech</strong>`)
@@ -401,20 +401,20 @@ const powerUps = {
effect() { effect() {
m.couplingChange(0.1) m.couplingChange(0.1)
}, },
spawnDelay(num) { // spawnDelay(num) {
let count = num // let count = num
let respawnDrones = () => { // let respawnDrones = () => {
if (count > 0) { // if (count > 0) {
requestAnimationFrame(respawnDrones); // requestAnimationFrame(respawnDrones);
if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2) // if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2)
count-- // count--
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) } // const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
powerUps.spawn(where.x, where.y, "coupling"); // powerUps.spawn(where.x, where.y, "coupling");
} // }
} // }
} // }
requestAnimationFrame(respawnDrones); // requestAnimationFrame(respawnDrones);
} // }
}, },
boost: { boost: {
name: "boost", name: "boost",
@@ -1149,8 +1149,8 @@ const powerUps = {
let count = num let count = num
let cycle = () => { let cycle = () => {
if (count > 0) { if (count > 0) {
requestAnimationFrame(cycle); if (m.alive) requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing && m.alive) { //&& !(simulation.cycle % 2) if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2)
count-- count--
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) } const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
powerUps.spawn(where.x, where.y, type); powerUps.spawn(where.x, where.y, type);

View File

@@ -531,6 +531,15 @@ const simulation = {
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX; simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY; simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
}, },
cameraNoLook() {
ctx.save();
ctx.translate(canvas.width2, canvas.height2); //center
// ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered
ctx.translate(-canvas.width2 + m.transX, -canvas.height2 + m.transY); //translate
//calculate in game mouse position by undoing the zoom and translations
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
},
restoreCamera() { restoreCamera() {
ctx.restore(); ctx.restore();
}, },

View File

@@ -31,6 +31,7 @@ const tech = {
// tech.addLoreTechToPool(); // tech.addLoreTechToPool();
tech.extraMaxHealth = 0; tech.extraMaxHealth = 0;
tech.totalCount = 0; tech.totalCount = 0;
tech.junkCount = 0 //tech.countJunkTech();
simulation.updateTechHUD(); simulation.updateTechHUD();
}, },
removeTech(index = 'random') { removeTech(index = 'random') {
@@ -61,6 +62,7 @@ const tech = {
tech.tech[index].remove(); tech.tech[index].remove();
tech.tech[index].count = 0; tech.tech[index].count = 0;
tech.totalCount -= totalRemoved tech.totalCount -= totalRemoved
tech.countJunkTech();
simulation.updateTechHUD(); simulation.updateTechHUD();
tech.tech[index].isLost = true tech.tech[index].isLost = true
simulation.updateTechHUD(); simulation.updateTechHUD();
@@ -90,7 +92,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) countNonJunk += tech.tech[i].frequency if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) countNonJunk += tech.tech[i].frequency
} }
const num = percent * countNonJunk //scale number added const num = Math.ceil(percent * countNonJunk) //scale number added
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ //add random array options to tech pool for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ //add random array options to tech pool
simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`) simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`)
return num return num
@@ -154,9 +156,17 @@ const tech = {
tech.tech[index].effect(); //give specific tech tech.tech[index].effect(); //give specific tech
tech.tech[index].count++ tech.tech[index].count++
tech.totalCount++ //used in power up randomization tech.totalCount++ //used in power up randomization
tech.countJunkTech();
simulation.updateTechHUD(); simulation.updateTechHUD();
} }
}, },
junkCount: 0,
countJunkTech() {
tech.junkCount = 0
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && tech.tech[i].isJunk) tech.junkCount++
}
},
// setTechoNonRefundable(name) { // setTechoNonRefundable(name) {
// for (let i = 0; i < tech.tech.length; i++) { // for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech.name === name) { // if (tech.tech.name === name) {
@@ -210,6 +220,7 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() { damageFromTech() {
let dmg = tech.damage //m.fieldDamage let dmg = tech.damage //m.fieldDamage
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.33 * m.coupling) if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.33 * m.coupling)
@@ -218,7 +229,7 @@ const tech = {
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555 if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
if (tech.isDamageForGuns) dmg *= 1 + 0.13 * b.inventory.length if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1)
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25 if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35;
if (tech.isRerollDamage) dmg *= 1 + 0.038 * powerUps.research.count if (tech.isRerollDamage) dmg *= 1 + 0.038 * powerUps.research.count
@@ -288,7 +299,7 @@ const tech = {
}, },
tech: [{ tech: [{
name: "ordnance", name: "ordnance",
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong> and <strong>+5%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool", description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong> and <strong>+7%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -302,7 +313,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2 if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
} }
this.refundAmount += tech.addJunkTechToPool(0.05) this.refundAmount += tech.addJunkTechToPool(0.07)
}, },
refundAmount: 0, refundAmount: 0,
remove() { remove() {
@@ -315,7 +326,7 @@ const tech = {
{ {
name: "ad hoc", name: "ad hoc",
descriptionFunction() { descriptionFunction() {
return `spawn a ${powerUps.orb.heal()}, ${powerUps.orb.research(1)}, <strong class='color-f'>field</strong>, ${powerUps.orb.ammo(1)}, or <strong class='color-m'>tech</strong><br>for each of your <strong class='color-g'>guns</strong>` return `spawn a ${powerUps.orb.heal()}, ${powerUps.orb.research(1)}, ${powerUps.orb.ammo(1)}, <strong class='color-f'>field</strong>, <strong class='color-g'>gun</strong>, or <strong class='color-m'>tech</strong><br>for each of your <strong class='color-g'>guns</strong>`
}, },
maxCount: 1, //random power up maxCount: 1, //random power up
count: 0, count: 0,
@@ -325,10 +336,12 @@ const tech = {
allowed() { allowed() {
return b.inventory.length > 1 return b.inventory.length > 1
}, },
requires: "NOT EXPERIMENT MODE, at least 2 guns", requires: "at least 2 guns",
effect() { effect() {
for (let i = 0; i < b.inventory.length; i++) { for (let i = 0; i < b.inventory.length; i++) {
if (Math.random() < 1 / 5) { if (Math.random() < 1 / 6) {
powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
} else if (Math.random() < 1 / 5) {
powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "tech"); powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "tech");
} else if (Math.random() < 1 / 4) { } else if (Math.random() < 1 / 4) {
powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "field"); powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "field");
@@ -354,9 +367,9 @@ const tech = {
allowed() { allowed() {
return b.inventory.length > 1 return b.inventory.length > 1
}, },
requires: "NOT EXPERIMENT MODE, at least 2 guns", requires: "at least 2 guns",
effect() { effect() {
for (let i = b.inventory.length - 1; i > -1; i--) { for (let i = b.inventory.length - 1; i > -1; i--) { //backwards because some tech can remove or add guns
const gunTechPool = [] //find gun tech for this gun const gunTechPool = [] //find gun tech for this gun
for (let j = 0, len = tech.tech.length; j < len; j++) { for (let j = 0, len = tech.tech.length; j < len; j++) {
// console.log(j, tech.tech[j].isGunTech, tech.tech[j].allowed(), !tech.tech[j].isJunk, !tech.tech[j].isBadRandomOption, tech.tech[j].count < tech.tech[j].maxCount) // console.log(j, tech.tech[j].isGunTech, tech.tech[j].allowed(), !tech.tech[j].isJunk, !tech.tech[j].isBadRandomOption, tech.tech[j].count < tech.tech[j].maxCount)
@@ -382,13 +395,13 @@ const tech = {
}, },
{ {
name: "arsenal", name: "arsenal",
descriptionFunction() { return `<strong>+13%</strong> <strong class='color-d'>damage</strong> per <strong class='color-g'>gun</strong> <em>(${(13 * b.inventory.length).toFixed(0)}%)</em>` }, descriptionFunction() { return `<strong>+22%</strong> <strong class='color-d'>damage</strong> per unequipped <strong class='color-g'>gun</strong> <em>(${(22 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)</em>` },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed: () => true, allowed: () => b.inventory.length > 1,
requires: "", requires: "at least 2 guns",
effect() { effect() {
tech.isDamageForGuns = true; tech.isDamageForGuns = true;
}, },
@@ -398,13 +411,13 @@ const tech = {
}, },
{ {
name: "active cooling", name: "active cooling",
descriptionFunction() { return `<strong>+18%</strong> <em>fire rate</em> per <strong class='color-g'>gun</strong> <em>(${(18 * b.inventory.length).toFixed(0)}%)</em>` }, descriptionFunction() { return `<strong>+28%</strong> <em>fire rate</em> per unequipped <strong class='color-g'>gun</strong> <em>(${(28 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)</em>` }, //<br>but not including your equipped <strong class='color-g'>gun</strong>` },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed: () => true, allowed: () => b.inventory.length > 1,
requires: "", requires: "at least 2 guns",
effect() { effect() {
tech.isFireRateForGuns = true; tech.isFireRateForGuns = true;
b.setFireCD(); b.setFireCD();
@@ -414,6 +427,67 @@ const tech = {
b.setFireCD(); b.setFireCD();
} }
}, },
{
name: "pigeonhole principle",
descriptionFunction() {
var info = ""
if (this.count > 0 && Number.isInteger(tech.buffedGun) && b.inventory.length) {
var gun = b.guns[b.inventory[tech.buffedGun]].name
var info = `<br>this level: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`
}
// return `
// a <strong class='color-g'>gun</strong> is <strong>chosen</strong> to be improved each <strong>level</strong>
// <br><strong>+${(31*b.inventory.length).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for ${gun}
// <br><strong class='color-d'>damage</strong> scales by 31% per unequipped <strong class='color-g'>gun</strong>`
return `
a new <strong class='color-g'>gun</strong> is <strong>chosen</strong> to be improved each <strong>level</strong>
<br><strong>+31%</strong> <strong class='color-d'>damage</strong> per <strong class='color-g'>gun</strong> for the <strong>chosen</strong> <strong class='color-g'>gun</strong>${info}`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return b.inventory.length > 1
},
requires: "at least 2 guns",
effect() {
tech.isGunChoice = true
//switches gun on new level
//generalist uses the same chosen gun so they match
},
remove() {
tech.isGunChoice = false;
}
},
{
name: "generalist",
description: "spawn <strong>7</strong> <strong class='color-g'>guns</strong>, but you can't <strong>switch</strong> <strong class='color-g'>guns</strong><br>your equipped <strong class='color-g'>gun</strong> cycles after each level",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
return b.inventory.length < b.guns.length - 5 && b.inventory.length > 1
},
requires: "at least 2 guns, at least 5 unclaimed guns",
effect() {
tech.isGunCycle = true;
for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
},
remove() {
if (!this.count) tech.isGunCycle = false; // only set to false if you don't have this tech
// if (tech.isGunCycle) {
// for (let i = 0; i < 8; i++) {
// if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun
// }
// tech.isGunCycle = false;
// }
}
},
{ {
name: "first derivative", name: "first derivative",
descriptionFunction() { return `while your <strong>first</strong> <strong class='color-g'>gun</strong> is equipped<br><strong>+15%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-g'>gun</strong> <em>(${(100*(1-0.85 ** b.inventory.length)).toFixed(0)}%)</em>` }, descriptionFunction() { return `while your <strong>first</strong> <strong class='color-g'>gun</strong> is equipped<br><strong>+15%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-g'>gun</strong> <em>(${(100*(1-0.85 ** b.inventory.length)).toFixed(0)}%)</em>` },
@@ -449,37 +523,9 @@ const tech = {
tech.isOneGun = false; tech.isOneGun = false;
} }
}, },
{
name: "generalist",
description: "spawn <strong>7</strong> <strong class='color-g'>guns</strong>, but you can't <strong>switch</strong> <strong class='color-g'>guns</strong><br><strong class='color-g'>guns</strong> cycle automatically with each new level",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
return b.inventory.length < b.guns.length - 5 && b.inventory.length > 1 //(tech.isDamageForGuns || tech.isFireRateForGuns) &&
},
requires: "at least 2 guns, at least 5 unclaimed guns",
effect() {
tech.isGunCycle = true;
for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
},
remove() {
if (!this.count) tech.isGunCycle = false; // only set to false if you don't have this tech
// if (tech.isGunCycle) {
// for (let i = 0; i < 8; i++) {
// if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun
// }
// tech.isGunCycle = false;
// }
}
},
{ {
name: "supply chain", name: "supply chain",
junk: 0.05, descriptionFunction() { return `double your current <strong class='color-ammo'>ammo</strong><br><strong>+4%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool` },
descriptionFunction() { return `for each <strong class='color-g'>gun</strong> in your inventory<br>double its <strong class='color-ammo'>ammo</strong>` },
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -491,7 +537,7 @@ const tech = {
if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo) if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo)
} }
simulation.makeGunHUD(); simulation.makeGunHUD();
// this.refundAmount += tech.addJunkTechToPool(this.junk) this.refundAmount += tech.addJunkTechToPool(0.04)
}, },
refundAmount: 0, refundAmount: 0,
remove() { remove() {
@@ -501,10 +547,10 @@ const tech = {
} }
} }
simulation.makeGunHUD(); simulation.makeGunHUD();
// if (this.count > 0 && this.refundAmount > 0) { if (this.count > 0 && this.refundAmount > 0) {
// tech.removeJunkTechFromPool(this.refundAmount) tech.removeJunkTechFromPool(this.refundAmount)
// this.refundAmount = 0 this.refundAmount = 0
// } }
} }
}, },
{ {
@@ -622,7 +668,7 @@ const tech = {
}, },
{ {
name: "dead reckoning", name: "dead reckoning",
description: "if your <strong>speed</strong> is 0<br><strong>+36%</strong> <strong class='color-d'>damage</strong>", description: "if your <strong>speed</strong> is 0<br><strong>+50%</strong> <strong class='color-d'>damage</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -630,7 +676,7 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.restDamage += 0.36 tech.restDamage += 0.5
}, },
remove() { remove() {
tech.restDamage = 1; tech.restDamage = 1;
@@ -811,7 +857,7 @@ const tech = {
}, },
{ {
name: "heuristics", name: "heuristics",
description: "<strong>+30%</strong> <strong><em>fire rate</em></strong>", description: "<strong>+25%</strong> <strong><em>fire rate</em></strong><br>spawn a <strong class='color-g'>gun</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -819,8 +865,9 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.fireRate *= 0.7 tech.fireRate *= 0.75
b.setFireCD(); b.setFireCD();
powerUps.spawn(m.pos.x, m.pos.y, "gun");
}, },
remove() { remove() {
tech.fireRate = 1; tech.fireRate = 1;
@@ -2871,7 +2918,7 @@ const tech = {
isNonRefundable: true, isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
allowed() { return true }, allowed() { return true },
requires: "NOT EXPERIMENT MODE", requires: "",
effect() { effect() {
for (let i = 0; i < 13; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal"); for (let i = 0; i < 13; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
@@ -3251,7 +3298,7 @@ const tech = {
allowed() { allowed() {
return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices
}, },
requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary, integrated circuit", requires: "not emergence, cross disciplinary, integrated circuit",
effect() { effect() {
tech.isDeterminism = true; tech.isDeterminism = true;
//if you change the number spawned also change it in Born rule //if you change the number spawned also change it in Born rule
@@ -3327,8 +3374,8 @@ const tech = {
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { return true }, allowed() { return tech.junkCount > 0 },
requires: "", requires: "some JUNK tech",
effect() { effect() {
tech.isMetaAnalysis = true tech.isMetaAnalysis = true
}, },
@@ -3611,7 +3658,7 @@ const tech = {
{ {
name: "options exchange", name: "options exchange",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>88%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`, description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>85%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3700,7 +3747,7 @@ const tech = {
}, },
{ {
name: "metastability", name: "metastability",
description: "<strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong>", description: "<strong>+12%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -4773,9 +4820,11 @@ const tech = {
}, },
remove() { remove() {
tech.infiniteWaveAmmo = 1 tech.infiniteWaveAmmo = 1
if (this.count > 1 && b.guns[3].savedAmmo !== undefined) {
b.guns[3].ammo = b.guns[3].savedAmmo b.guns[3].ammo = b.guns[3].savedAmmo
simulation.updateGunHUD(); simulation.updateGunHUD();
} }
}
}, },
{ {
name: "phonon", //longitudinal //gravitational wave? name: "phonon", //longitudinal //gravitational wave?
@@ -4858,7 +4907,7 @@ const tech = {
}, },
{ {
name: "sympathetic resonance", name: "sympathetic resonance",
description: "after a <strong>mob</strong> gets vibrated by a <strong>phonon</strong><br>a new <strong>resonance wave</strong> expands from their location", description: "after a <strong>mob</strong> gets vibrated by a <strong>phonon</strong><br>a new <strong>resonance wave</strong> expands",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5538,6 +5587,57 @@ const tech = {
tech.isSporeFollow = false tech.isSporeFollow = false
} }
}, },
{
name: "junk DNA",
descriptionFunction() { return `<strong>+53%</strong> ${b.guns[6].nameString()} <strong class='color-d'>damage</strong> per <strong class='color-j'>JUNK</strong><strong class='color-m'>tech</strong> <em>(${(53*tech.junkCount).toFixed(0)}%)</em><br><strong>+50%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool` },
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 0) || tech.isSporeWorm || tech.isSporeFlea
},
requires: "spores",
effect() {
tech.isJunkDNA = true
this.refundAmount += tech.addJunkTechToPool(0.5)
},
refundAmount: 0,
remove() {
tech.isJunkDNA = false
if (this.count > 0 && this.refundAmount > 0) {
tech.removeJunkTechFromPool(this.refundAmount)
this.refundAmount = 0
}
}
},
// {
// name: "junk DNA",
// //increase damage by 10% for each JUNK tech percent in the tech pool, remove all JUNK tech,
// descriptionFunction() { return `<strong>+50%</strong> ${b.guns[6].nameString()} <strong class='color-d'>damage</strong><br><strong>+15%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool` },
// isGunTech: true,
// maxCount: 1,
// count: 0,
// frequency: 3,
// frequencyDefault: 3,
// allowed() {
// return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 0) || tech.isSporeWorm || tech.isSporeFlea
// },
// requires: "spores",
// effect() {
// tech.isSporeWorm = true
// this.refundAmount += tech.addJunkTechToPool(0.15)
// },
// refundAmount: 0,
// remove() {
// tech.isSporeWorm = false
// if (this.count > 0 && this.refundAmount > 0) {
// tech.removeJunkTechFromPool(this.refundAmount)
// this.refundAmount = 0
// }
// }
// },
{ {
name: "mutualism", name: "mutualism",
descriptionFunction() { return `<strong>+150%</strong> ${b.guns[6].nameString()} <strong class='color-d'>damage</strong><br>${b.guns[6].nameString('s')} borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>` }, descriptionFunction() { return `<strong>+150%</strong> ${b.guns[6].nameString()} <strong class='color-d'>damage</strong><br>${b.guns[6].nameString('s')} borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>` },
@@ -5603,8 +5703,8 @@ const tech = {
isGunTech: true, isGunTech: true,
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 3, frequency: 2,
frequencyDefault: 3, frequencyDefault: 2,
allowed() { allowed() {
return tech.isSporeWorm || tech.isSporeFlea return tech.isSporeWorm || tech.isSporeFlea
}, },
@@ -6159,7 +6259,7 @@ const tech = {
}, },
{ {
name: "alternator", name: "alternator",
description: "<strong>+60%</strong> <strong>harpoon</strong> <strong class='color-f'>energy</strong> efficiency", description: "<strong>+80%</strong> <strong>harpoon</strong> <strong class='color-f'>energy</strong> efficiency",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8184,7 +8284,9 @@ const tech = {
isJunk: true, isJunk: true,
allowed: () => true, allowed: () => true,
requires: "", requires: "",
effect() {}, effect() {
if (Math.random() < 0.1) tech.damage *= 7.77
},
remove() {} remove() {}
}, },
{ {
@@ -9899,6 +10001,38 @@ const tech = {
effect() { effect() {
m.shipMode() m.shipMode()
level.difficultyDecrease(simulation.difficultyMode) level.difficultyDecrease(simulation.difficultyMode)
//unlock relativistic rotation
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].name === "relativistic rotation") tech.tech[i].frequency = 10
}
},
remove() {}
},
{
name: "circular symmetry",
description: "turning the ship rotates the universe instead<br><strong>+200%</strong> <strong class='color-d'>damage</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return m.isShipMode },
requires: "",
effect() {
tech.damage *= 2
m.look = () => {
// const scale = 0;
m.transSmoothX = canvas.width2 - m.pos.x // - (simulation.mouse.x - canvas.width2) * scale;
m.transSmoothY = canvas.height2 - m.pos.y // - (simulation.mouse.y - canvas.height2) * scale;
m.transX += (m.transSmoothX - m.transX) * m.lookSmoothing;
m.transY += (m.transSmoothY - m.transY) * m.lookSmoothing;
ctx.restore();
ctx.save();
ctx.translate(canvas.width2, canvas.height2); //center
ctx.rotate(-m.angle)
ctx.translate(-canvas.width2, -canvas.height2); //center
}
}, },
remove() {} remove() {}
}, },
@@ -10799,5 +10933,8 @@ const tech = {
isBoostPowerUps: null, isBoostPowerUps: null,
isBoostReplaceAmmo: null, isBoostReplaceAmmo: null,
isFlipFlopCoupling: null, isFlipFlopCoupling: null,
infiniteWaveAmmo: null infiniteWaveAmmo: null,
isJunkDNA: null,
buffedGun: 0,
isGunChoice: null,
} }

View File

@@ -1,3 +1,4 @@
// https://ncase.me/sight-and-light/
// redblobgames.com/articles/visibility // redblobgames.com/articles/visibility
// https://github.com/Silverwolf90/2d-visibility/tree/master/src // https://github.com/Silverwolf90/2d-visibility/tree/master/src
// could apply to explosions, neutron bomb, player LOS // could apply to explosions, neutron bomb, player LOS

View File

@@ -557,6 +557,11 @@ summary {
color: hsl(218, 100%, 58%); color: hsl(218, 100%, 58%);
} }
.highlight {
border-radius: 6px;
background-color: #ff0;
padding: 3px;
}
/* colors for pause, selection and experiment */ /* colors for pause, selection and experiment */
/* #text-log { /* #text-log {

View File

@@ -1,25 +1,62 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
entanglement - your death leaves a power up for next run
renamed entanglement
also stores your gun and field
improved graphics for incompatible tech
tech: junk DNA - +53% spore/worm/flea damage per JUNK tech you have, +50% JUNK added to tech pool
tech: pigeonhole principle - +31% damage for each gun you have, while a chosen gun is active
chosen gun cycles each level
syncs well with generalist
heuristics 30->25% fire rate, and now spawns a gun
arsenal gives 13->22% damage per gun, but no longer counts your current gun
active cooling gives 18->28% fire rate per gun, but no longer counts your current gun
supply chain adds 4% JUNK
dead reckoning 36->50% damage
alternator harpoon 60->80% energy cost reduction
quickly releasing the fire button retracts harpoon early
JUNK tech - circular symmetry - ship gets 200% damage, ship only faces forward but you can rotate the universe
several bug fixes
coupling for molecular assembler 5->8 energy per second
but also fixed a bug where coupling was giving 10x regen
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
lock mouse to the window until you press escape
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
canvas.requestPointerLock()
exitPointerLock
toggle off and on when:
you die and start a game
when choosing?
If this doesn't work it could at least be a fun JUNK tech
run canvas direct pixel editing while game is paused
just update once every second?
if it uses too much processing have a setting to toggle it off
this might help get players to spend more time relaxing on the power up selection
increase the click delay?
try again - line of sight https://ncase.me/sight-and-light/
for tech power ups no tech options are displayed until you research once
or display only JUNK until you research once
increase the number of options after each research
tech increase max energy and energy to 5000, but you can no longer regen energy through any process tech increase max energy and energy to 5000, but you can no longer regen energy through any process
it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing
add some css based visual effects for opening up a tech,gun,field add some css based visual effects for opening up a tech,gun,field
make freeze and __ not cause death at health health, but just 600% extra damage for that bullet make freeze and __ not cause death at 50% health, but just 600% extra damage for that bullet
new mob attibute - phosphorescence - mobs fire lasers for a few seconds after being hit with lasers new mob status effect - phosphorescence - mobs fire lasers for a few seconds after being hit with lasers
make a new coupling effect for perfect diamagnetism or standing wave make a new coupling effect for perfect diamagnetism or standing wave
make a faster smaller version of cell boss that also has map collisions
laserMines need a copy of laser-bot method laserMines need a copy of laser-bot method
this is a very rare bug, so not a priority this is a very rare bug, so not a priority
@@ -53,13 +90,6 @@ JUNK tech description that changes similar to cards in inscription
that changes based on mouse position that changes based on mouse position
can you tell if mouse is over card? can you tell if mouse is over card?
tech that encourages gun swapping
a field tech: molecular assembler, pilot wave, negative mass?
something similar to applied science, but also spawn a gun?
a bonus for each time a mob dies with a different active gun each level
+damage on that level
ammo, heals, research?
tech - buff MACHO range, effect, move speed? tech - buff MACHO range, effect, move speed?
while you are inside MACHO it will damage mobs? while you are inside MACHO it will damage mobs?
@@ -1021,7 +1051,6 @@ possible names for tech
Gödel's incompleteness Gödel's incompleteness
quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields) quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields)
counterfactual - something false counterfactual - something false
Pigeonhole principle - if there are several things that are matched up
regression to the mean regression to the mean
phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston 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. 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.
@@ -1043,7 +1072,6 @@ possible names for tech
https://en.wikipedia.org/wiki/High-entropy_alloys https://en.wikipedia.org/wiki/High-entropy_alloys
https://en.wikipedia.org/wiki/Refractory_metals https://en.wikipedia.org/wiki/Refractory_metals
https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves
entanglement
prion quine - self replicating protein prion quine - self replicating protein
Unitarity - https://en.wikipedia.org/wiki/Unitarity_(physics) - all probabilities add up to 1, calculations work the same forward and backwards in time Unitarity - https://en.wikipedia.org/wiki/Unitarity_(physics) - all probabilities add up to 1, calculations work the same forward and backwards in time
this is violated by expansion of the universe this is violated by expansion of the universe