tech: electric generator - deflecting mobs generates energy for molecular assembler
tech: homeostasis - for each health below 100 +0.8% defense
tech: compound lens - +77% laser lens damage, +10° lens arc

tech: robotics - 2 random bots, power up choices include a bot tech option
tech: open-source - 3 random bots, 4x bot tech frequency
  renamed from previous robotics tech
slightly buffed all bot upgrades

+9% iceIX damage
catabolism uses energy instead of health if you have mass-energy
optical amplifier laser tech options include laser-bot
rule 90 and rule 30 looks better on more browsers, I hope
This commit is contained in:
landgreen
2022-07-24 12:45:39 -07:00
parent 7a66ea922c
commit cf3ba7d5f2
7 changed files with 443 additions and 180 deletions

View File

@@ -96,11 +96,22 @@ const b = {
outOfAmmo() { //triggers after firing when you have NO ammo outOfAmmo() { //triggers after firing when you have NO ammo
simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-g'>ammo</span><span class='color-symbol'>:</span> 0`); simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-g'>ammo</span><span class='color-symbol'>:</span> 0`);
m.fireCDcycle = m.cycle + 30; //fire cooldown m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth && m.health > 0.01) { if (tech.isAmmoFromHealth) {
tech.extraMaxHealth -= 0.01 //decrease max health const amount = 0.01
if (tech.isEnergyHealth) {
if (m.maxEnergy > amount) {
tech.healMaxEnergyBonus -= amount
m.setMaxEnergy();
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
}
} else {
if (m.health > amount) {
tech.extraMaxHealth -= amount //decrease max health
m.setMaxHealth(); m.setMaxHealth();
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
} }
}
}
}, },
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to
if (tech.crouchAmmoCount && input.down) { if (tech.crouchAmmoCount && input.down) {
@@ -2888,7 +2899,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.023, frictionAir: 0.023,
restitution: 0.9, restitution: 0.9,
dmg: 1.2, //damage done in addition to the damage from momentum dmg: 1.3, //damage done in addition to the damage from momentum
lookFrequency: 14 + Math.floor(8 * Math.random()), lookFrequency: 14 + Math.floor(8 * Math.random()),
endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
classType: "bullet", classType: "bullet",
@@ -4376,7 +4387,7 @@ const b = {
minDmgSpeed: 2, minDmgSpeed: 2,
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20, // lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
lastLookCycle: simulation.cycle + 60 * Math.random(), lastLookCycle: simulation.cycle + 60 * Math.random(),
delay: Math.floor((tech.isNailBotUpgrade ? 20 : 105) * b.fireCDscale), delay: Math.floor((tech.isNailBotUpgrade ? 20 : 110) * b.fireCDscale),
acceleration: 0.005 * (1 + 0.5 * Math.random()), acceleration: 0.005 * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
endCycle: Infinity, endCycle: Infinity,
@@ -4407,7 +4418,7 @@ const b = {
) { ) {
const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position)) const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position))
if (this.isUpgraded) { if (this.isUpgraded) {
const SPEED = 50 const SPEED = 55
b.nail(this.position, Vector.mult(unit, SPEED)) b.nail(this.position, Vector.mult(unit, SPEED))
this.force = Vector.mult(unit, -0.018 * this.mass) this.force = Vector.mult(unit, -0.018 * this.mass)
} else { } else {
@@ -4513,9 +4524,9 @@ const b = {
restitution: 0.6 * (1 + 0.5 * Math.random()), restitution: 0.6 * (1 + 0.5 * Math.random()),
dmg: 0, // 0.14 //damage done in addition to the damage from momentum dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2, minDmgSpeed: 2,
lookFrequency: 60 + Math.floor(17 * Math.random()) - 40 * tech.isFoamBotUpgrade, lookFrequency: 60 + Math.floor(17 * Math.random()) - 45 * tech.isFoamBotUpgrade,
cd: 0, cd: 0,
delay: Math.floor(105 * b.fireCDscale), delay: 20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: 0.005 * (1 + 0.5 * Math.random()), acceleration: 0.005 * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
endCycle: Infinity, endCycle: Infinity,
@@ -4543,7 +4554,7 @@ const b = {
const radius = 6 + 7 * Math.random() const radius = 6 + 7 * Math.random()
const SPEED = 29 - radius * 0.4; //(input.down ? 32 : 20) - radius * 0.7; const SPEED = 29 - radius * 0.4; //(input.down ? 32 : 20) - radius * 0.7;
const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED) const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED)
b.foam(this.position, velocity, radius + 7 * this.isUpgraded) b.foam(this.position, velocity, radius + 7.5 * this.isUpgraded)
break; break;
} }
} }
@@ -4559,7 +4570,7 @@ const b = {
const dir = m.angle; const dir = m.angle;
const RADIUS = (14 + 6 * Math.random()) const RADIUS = (14 + 6 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
isUpgraded: tech.isLaserBotUpgrade, // isUpgraded: tech.isLaserBotUpgrade,
botType: "laser", botType: "laser",
angle: dir, angle: dir,
friction: 0, friction: 0,
@@ -4571,11 +4582,11 @@ const b = {
offPlayer: { x: 0, y: 0, }, offPlayer: { x: 0, y: 0, },
dmg: 0, //damage done in addition to the damage from momentum dmg: 0, //damage done in addition to the damage from momentum
minDmgSpeed: 2, minDmgSpeed: 2,
lookFrequency: 40 + Math.floor(7 * Math.random()) - 10 * tech.isLaserBotUpgrade, lookFrequency: 40 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade,
range: (700 + 450 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()), range: (700 + 500 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4, drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
drain: (0.5 - 0.43 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode, drain: (0.5 - 0.44 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode,
laserDamage: 0.85 + 0.7 * tech.isLaserBotUpgrade, laserDamage: 0.85 + 0.8 * tech.isLaserBotUpgrade,
endCycle: Infinity, endCycle: Infinity,
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -4684,10 +4695,10 @@ const b = {
restitution: 1, restitution: 1,
dmg: 0, dmg: 0,
minDmgSpeed: 0, minDmgSpeed: 0,
lookFrequency: 43 + Math.floor(7 * Math.random()) - 10 * tech.isBoomBotUpgrade, lookFrequency: 43 + Math.floor(7 * Math.random()) - 13 * tech.isBoomBotUpgrade,
acceleration: 0.005 * (1 + 0.5 * Math.random()), acceleration: 0.005 * (1 + 0.5 * Math.random()),
attackAcceleration: 0.012 + 0.005 * tech.isBoomBotUpgrade, attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade,
range: 500 * (1 + 0.1 * Math.random()) + 320 * tech.isBoomBotUpgrade, range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade,
endCycle: Infinity, endCycle: Infinity,
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -4698,7 +4709,7 @@ const b = {
explode: 0, explode: 0,
beforeDmg() { beforeDmg() {
if (this.lockedOn) { if (this.lockedOn) {
const explosionRadius = Math.min(136 + 200 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30) const explosionRadius = Math.min(136 + 230 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30)
if (explosionRadius > 60) { if (explosionRadius > 60) {
this.explode = explosionRadius this.explode = explosionRadius
// //
@@ -4984,7 +4995,7 @@ const b = {
} }
} }
}, },
range: 190 + 120 * tech.isOrbitBotUpgrade, //range is set in bot upgrade too! range: 190 + 130 * tech.isOrbitBotUpgrade, //range is set in bot upgrade too!
orbitalSpeed: 0, orbitalSpeed: 0,
phase: 2 * Math.PI * Math.random(), phase: 2 * Math.PI * Math.random(),
do() { do() {
@@ -4996,8 +5007,8 @@ const b = {
}) })
for (let i = 0; i < q.length; i++) { for (let i = 0; i < q.length; i++) {
if (!q[i].isShielded) { if (!q[i].isShielded) {
mobs.statusStun(q[i], 210) mobs.statusStun(q[i], 210 + 90 * this.isUpgraded)
const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4 : 1) * (tech.isCrit ? 4 : 1) const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4.5 : 1) * (tech.isCrit ? 4 : 1)
q[i].damage(dmg); q[i].damage(dmg);
if (q[i].alive) q[i].foundPlayer(); if (q[i].alive) q[i].foundPlayer();
if (q[i].damageReduction) { if (q[i].damageReduction) {
@@ -6908,7 +6919,6 @@ const b = {
charge: 0, charge: 0,
isStuckOn: false, isStuckOn: false,
angle: 0, angle: 0,
arcRange: 0.78, //1.57,
isInsideArc(angle) { isInsideArc(angle) {
const mod = (a, n) => { const mod = (a, n) => {
return a - Math.floor(a / n) * n return a - Math.floor(a / n) * n
@@ -6916,21 +6926,22 @@ const b = {
let diff = mod(angle - this.angle + Math.PI, 2 * Math.PI) - Math.PI let diff = mod(angle - this.angle + Math.PI, 2 * Math.PI) - Math.PI
return Math.abs(diff) < this.arcRange return Math.abs(diff) < this.arcRange
}, },
arcRange: 0.78, //1.57,
lensDamage: 1, lensDamage: 1,
lensDamageOn: 0, //set in tech
lens() { lens() {
this.stuckOn(); this.stuckOn();
this.angle += 0.02 this.angle += 0.02
if (this.isInsideArc(m.angle)) { if (this.isInsideArc(m.angle)) {
this.lensDamage = 2.5 //150% damage increase this.lensDamage = this.lensDamageOn
ctx.lineWidth = 6 + this.lensDamageOn
} else { } else {
this.lensDamage = 1 this.lensDamage = 1
ctx.lineWidth = 2
} }
const radius = 60
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, radius, this.angle - this.arcRange, this.angle + this.arcRange); ctx.arc(m.pos.x, m.pos.y, 60, this.angle - this.arcRange, this.angle + this.arcRange);
ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)' //tech.laserColor ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)' //tech.laserColor
ctx.lineWidth = (this.lensDamage > 1) ? 10 : 2 //3
ctx.stroke(); ctx.stroke();
// const a = { x: radius * Math.cos(this.angle + this.arcRange), y: radius * Math.sin(this.angle + this.arcRange) } // const a = { x: radius * Math.cos(this.angle + this.arcRange), y: radius * Math.sin(this.angle + this.arcRange) }
// const b = Vector.add(m.pos, a) // const b = Vector.add(m.pos, a)

View File

@@ -24,15 +24,15 @@ const level = {
// powerUps.research.changeRerolls(100) // powerUps.research.changeRerolls(100)
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000 // b.guns[0].ammo = 10000
// m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism // m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.giveTech("siphonaptera") // tech.giveTech("robotics")
// tech.giveTech("fleas") // tech.giveTech("CPT symmetry");
// tech.giveTech("colony") // tech.giveTech("lens");
// tech.giveTech("mycelium manufacturing") // tech.giveTech("robotics")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot") // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// for (let i = 0; i < 1; ++i) tech.giveTech("necrophage") // for (let i = 0; i < 1; ++i) tech.giveTech("electric generator")
// for (let i = 0; i < 1; i++) tech.giveTech("cryodesiccation") // for (let i = 0; i < 9; i++) tech.giveTech("compound lens")
// 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(450, -50, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
// spawn.starter(1900, -500) // spawn.starter(1900, -500)

View File

@@ -133,11 +133,10 @@ const m = {
legLength2: 45, legLength2: 45,
transX: 0, transX: 0,
transY: 0, transY: 0,
history: [], //tracks the last second of player position history: new Array(600), //[], //tracks the last second of player position
rewindCount: 0, //used with CPT rewindCount: 0, //used with CPT
resetHistory() { resetHistory() {
for (let i = 0; i < 600; i++) { //reset history const set = {
m.history[i] = {
position: { position: {
x: player.position.x, x: player.position.x,
y: player.position.y, y: player.position.y,
@@ -152,6 +151,8 @@ const m = {
energy: m.energy, energy: m.energy,
activeGun: b.activeGun activeGun: b.activeGun
} }
for (let i = 0; i < 600; i++) { //reset history
m.history[i] = set
} }
}, },
move() { move() {
@@ -513,6 +514,7 @@ const m = {
let dmg = 1 let dmg = 1
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
// if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5 // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5
if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
if (tech.isZeno) dmg *= 0.15 if (tech.isZeno) dmg *= 0.15
if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.4 if (tech.isHarmMACHO) dmg *= 0.4
@@ -1413,7 +1415,11 @@ const m = {
) { ) {
mob[i].locatePlayer(); mob[i].locatePlayer();
m.pushMass(mob[i]); m.pushMass(mob[i]);
if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 60 if (mob[i].isShielded) {
m.fieldCDcycle = m.cycle + 60
} else if (tech.deflectEnergy && !mob[i].isInvulnerable) {
m.energy += tech.deflectEnergy
}
} }
} }
}, },
@@ -2739,7 +2745,7 @@ const m = {
}, },
{ {
name: "metamaterial cloaking", name: "metamaterial cloaking",
description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:90%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> seconds after <strong class='color-cloaked'>decloaking</strong></span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:92%;'>after <strong class='color-cloaked'>decloaking</strong> <strong>+333%</strong> <strong class='color-d'>damage</strong> for up to <strong>2</strong> s</span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
effect: () => { effect: () => {
m.fieldFire = true; m.fieldFire = true;
m.fieldMeterColor = "#333"; m.fieldMeterColor = "#333";
@@ -2750,8 +2756,9 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100 // m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0 m.fieldDrawRadius = 0
m.isSneakAttack = true; m.isSneakAttack = true;
// m.sneakAttackCharge = 0;
m.sneakAttackCycle = 0; m.sneakAttackCycle = 0;
m.enterCloakCycle = 0 m.enterCloakCycle = 0;
const drawRadius = 800 const drawRadius = 800
m.drawCloak = function() { m.drawCloak = function() {
m.fieldPhase += 0.007 m.fieldPhase += 0.007
@@ -2770,6 +2777,12 @@ const m = {
ctx.clip(); ctx.clip();
} }
m.hold = function() { m.hold = function() {
// if (m.isCloak) {
// if (m.sneakAttackCharge < 120) m.sneakAttackCharge += 0.5
// } else {
// if (m.sneakAttackCharge > 0) m.sneakAttackCharge--
// }
if (m.isHolding) { if (m.isHolding) {
m.drawHold(m.holdingTarget); m.drawHold(m.holdingTarget);
m.holding(); m.holding();
@@ -2806,13 +2819,12 @@ const m = {
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
let isMobsAround = false let isMobsAround = false
const stunRange = m.fieldDrawRadius * 1.5 const stunRange = m.fieldDrawRadius * 1.5
const drain = 0.1 const drain = 0.2
const stunTime = 240
if (m.energy > drain) { if (m.energy > drain) {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) < stunRange && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 && !mob[i].isBadTarget) { if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) < stunRange && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 && !mob[i].isBadTarget) {
isMobsAround = true isMobsAround = true
mobs.statusStun(mob[i], stunTime) mobs.statusStun(mob[i], 180)
} }
} }
if (isMobsAround) { if (isMobsAround) {
@@ -2856,7 +2868,8 @@ const m = {
this.drawFieldMeterCloaking() this.drawFieldMeterCloaking()
//show sneak attack status //show sneak attack status
// if (m.cycle > m.lastKillCycle + 240) { // if (m.cycle > m.lastKillCycle + 240) {
if (m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) { // if (m.sneakAttackCharge > 0) {
if (m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) {
ctx.strokeStyle = "rgba(0,0,0,0.5)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})` ctx.strokeStyle = "rgba(0,0,0,0.5)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI);

View File

@@ -551,15 +551,12 @@ const powerUps = {
let text = "" let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>` if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
let options = []; let options = [];
for (let i = 0; i < b.guns.length; i++) { for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) options.push(i); if (!b.guns[i].have) options.push(i);
} }
let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices) let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices)
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) { function removeOption(index) {
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
if (options[i] === index) { if (options[i] === index) {
@@ -568,14 +565,12 @@ const powerUps = {
} }
} }
} }
//check for guns that were a choice last time and remove them //check for guns that were a choice last time and remove them
for (let i = 0; i < b.guns.length; i++) { for (let i = 0; i < b.guns.length; i++) {
if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display
if (b.guns[i].isRecentlyShown) removeOption(i) if (b.guns[i].isRecentlyShown) removeOption(i)
} }
for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero
if (options.length > 0) { if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) { for (let i = 0; i < totalChoices; i++) {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
@@ -584,6 +579,17 @@ const powerUps = {
removeOption(choose) removeOption(choose)
if (options.length < 1) break if (options.length < 1) break
} }
if (tech.isExtraBotOption) {
const botTech = [] //make an array of bot options
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
}
if (botTech.length > 0) { //pick random bot tech
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
}
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random()) tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">` text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
@@ -704,7 +710,7 @@ const powerUps = {
} }
for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero
if (options.length > 0) { if (options.length > 0 || tech.isExtraBotOption) {
for (let i = 0; i < totalChoices; i++) { for (let i = 0; i < totalChoices; i++) {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choose})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choose].name}</div> ${m.fieldUpgrades[choose].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choose})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choose].name}</div> ${m.fieldUpgrades[choose].description}</div>`
@@ -712,6 +718,17 @@ const powerUps = {
removeOption(choose) removeOption(choose)
if (options.length < 1) break if (options.length < 1) break
} }
if (tech.isExtraBotOption) {
const botTech = [] //make an array of bot options
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
}
if (botTech.length > 0) { //pick random bot tech
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
}
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random()) tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">` text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
@@ -846,9 +863,6 @@ const powerUps = {
tech.tooManyTechChoices = false tech.tooManyTechChoices = false
totalChoices = optionLengthNoDuplicates totalChoices = optionLengthNoDuplicates
} }
//check for tech that were a choice last time and remove them //check for tech that were a choice last time and remove them
if (optionLengthNoDuplicates > totalChoices) { if (optionLengthNoDuplicates > totalChoices) {
// console.log('check for tech that were a choice last time and remove them', optionLengthNoDuplicates, options.length) // console.log('check for tech that were a choice last time and remove them', optionLengthNoDuplicates, options.length)
@@ -904,6 +918,18 @@ const powerUps = {
} }
if (options.length < 1) break if (options.length < 1) break
} }
if (tech.isExtraBotOption) {
const botTech = [] //make an array of bot options
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
}
if (botTech.length > 0) { //pick random bot tech
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span id = "cellular-rule-id${this.id}" style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
}
if (tech.isExtraGunField) { if (tech.isExtraGunField) {
if (Math.random() > 0.5 && b.inventory.length < b.guns.length) { if (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
let gunOptions = []; let gunOptions = [];

View File

@@ -180,7 +180,7 @@ const simulation = {
cyclePaused: 0, cyclePaused: 0,
fallHeight: 6000, //below this y position the player dies fallHeight: 6000, //below this y position the player dies
lastTimeStamp: 0, //tracks time stamps for measuring delta lastTimeStamp: 0, //tracks time stamps for measuring delta
delta: 1000 / 60, //speed of game engine //looks like it has to be 16 to match player input delta: 1000 / 60, //speed of game engine //looks like it has to be 16.6666 to match player input
buttonCD: 0, buttonCD: 0,
isHorizontalFlipped: false, //makes some maps flipped horizontally isHorizontalFlipped: false, //makes some maps flipped horizontally
levelsCleared: 0, levelsCleared: 0,

View File

@@ -252,7 +252,8 @@ const tech = {
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6 if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6
// if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg // if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg
// if (m.isSneakAttack && m.sneakAttackCharge > 0) dmg *= tech.sneakAttackDmg
if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction() if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction()
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
@@ -261,8 +262,8 @@ const tech = {
}, },
isScaleMobsWithDuplication: false, isScaleMobsWithDuplication: false,
maxDuplicationEvent() { maxDuplicationEvent() {
if (tech.is111Duplicate && tech.duplicationChance() > 1.11) { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
tech.is111Duplicate = false tech.is100Duplicate = false
const range = 1300 const range = 1300
tech.isScaleMobsWithDuplication = true tech.isScaleMobsWithDuplication = true
for (let i = 0, len = 9; i < len; i++) { for (let i = 0, len = 9; i < len; i++) {
@@ -308,7 +309,7 @@ const tech = {
}, },
tech: [{ tech: [{
name: "ordnance", name: "ordnance",
description: "</strong>triple</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>", 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>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -324,7 +325,7 @@ const tech = {
powerUps.spawn(m.pos.x, m.pos.y, "gun"); powerUps.spawn(m.pos.x, m.pos.y, "gun");
// this.count-- // this.count--
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 *= 3 if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
} }
}, },
remove() {} remove() {}
@@ -584,15 +585,15 @@ const tech = {
}, },
{ {
name: "catabolism", name: "catabolism",
description: `if you fire while <strong>out</strong> of <strong class='color-ammo'>ammo</strong><br>spawn ${powerUps.orb.ammo(4)} and <strong>1</strong> maximum <strong class='color-h'>health</strong>`, descriptionFunction() { return `if you fire while <strong>out</strong> of <strong class='color-ammo'>ammo</strong><br>spawn ${powerUps.orb.ammo(4)} and <strong>1</strong> maximum ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}` },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isEnergyNoAmmo && !tech.isEnergyHealth return !tech.isEnergyNoAmmo
}, },
requires: "not exciton, mass-energy", requires: "not exciton",
effect: () => { effect: () => {
tech.isAmmoFromHealth = true; tech.isAmmoFromHealth = true;
}, },
@@ -1372,7 +1373,7 @@ const tech = {
{ {
name: "dynamo-bot", name: "dynamo-bot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot</a>`,
description: "a <strong class='color-bot'>bot</strong> <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>when it's near generate <strong>7</strong> <strong class='color-f'>energy</strong> per second", description: "a <strong class='color-bot'>bot</strong> <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>when it's near generate <strong>+7</strong> <strong class='color-f'>energy</strong> per second",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1396,7 +1397,7 @@ const tech = {
{ {
name: "dynamo-bot upgrade", name: "dynamo-bot upgrade",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot upgrade</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot upgrade</a>`,
description: "<strong>convert</strong> your bots to <strong>dynamo-bots</strong><br>when it's near generate <strong>23</strong> <strong class='color-f'>energy</strong> per second", description: "<strong>convert</strong> your bots to <strong>dynamo-bots</strong><br>when it's near generate <strong>+23</strong> <strong class='color-f'>energy</strong> per second",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 3, frequency: 3,
@@ -1451,37 +1452,6 @@ const tech = {
// this.description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>` // this.description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`
} }
}, },
{
name: "robotics",
description: `spawn <strong>2</strong> random <strong>bots</strong><br><strong>quadruple</strong> the <strong class='flicker'>frequency</strong> of finding <strong>bot</strong> <strong class='color-m'>tech</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isBotTech: true,
allowed() {
return b.totalBots() > 1 || build.isExperimentSelection
},
requires: "at least 2 bots",
effect: () => {
b.randomBot()
b.randomBot()
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 4
}
},
remove() {
if (this.count > 0) {
b.removeBot()
b.removeBot()
b.clearPermanentBots();
b.respawnBots();
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 4)
}
}
}
},
{ {
name: "perimeter defense", name: "perimeter defense",
description: "for each permanent <strong class='color-bot'>bot</strong><br><strong>+6%</strong> <strong class='color-defense'>defense</strong>", description: "for each permanent <strong class='color-bot'>bot</strong><br><strong>+6%</strong> <strong class='color-defense'>defense</strong>",
@@ -1578,6 +1548,91 @@ const tech = {
} }
} }
}, },
// {
// name: "robotics",
// description: `spawn <strong>2</strong> random <strong>bots</strong><br><strong>quadruple</strong> the <strong class='flicker'>frequency</strong> of finding <strong>bot</strong> <strong class='color-m'>tech</strong>`,
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// isBotTech: true,
// allowed() {
// return b.totalBots() > 1 || build.isExperimentSelection
// },
// requires: "at least 2 bots",
// effect: () => {
// b.randomBot()
// b.randomBot()
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 4
// }
// },
// remove() {
// if (this.count > 0) {
// b.removeBot()
// b.removeBot()
// b.clearPermanentBots();
// b.respawnBots();
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 4)
// }
// }
// }
// },
{
name: "robotics",
description: `spawn <strong>2</strong> random <strong>bots</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+1</strong> bot <strong>choice</strong>`, //<strong class='color-m'>tech</strong> have an extra <strong>bot</strong> <strong class='color-m'>tech</strong> option
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isBotTech: true,
allowed() {
return b.totalBots() > 1 || build.isExperimentSelection
},
requires: "at least 2 bots",
effect: () => {
tech.isExtraBotOption = true
for (let i = 0; i < 2; i++) b.randomBot()
},
remove() {
if (this.count > 0) {
for (let i = 0; i < 2; i++) b.removeBot()
b.clearPermanentBots();
b.respawnBots();
}
tech.isExtraBotOption = false
}
},
{
name: "open-source", //digital fabricator
description: `spawn <strong>3</strong> random <strong>bots</strong><br><strong>triple</strong> the <strong class='flicker'>frequency</strong> of finding <strong>bot</strong> <strong class='color-m'>tech</strong>`,
maxCount: 1,
count: 0,
frequency: 0,
frequencyDefault: 0,
isBotTech: true,
allowed() {
return tech.isExtraBotOption
},
requires: "robotics",
effect: () => {
for (let i = 0; i < 3; i++) b.randomBot()
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3
}
},
remove() {
if (this.count > 0) {
for (let i = 0; i < 3; i++) b.removeBot()
b.clearPermanentBots();
b.respawnBots();
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 3)
}
}
}
},
{ {
name: "mass driver", name: "mass driver",
description: "<strong>+300%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>", description: "<strong>+300%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>",
@@ -1853,7 +1908,7 @@ const tech = {
}, },
{ {
name: "transistor", name: "transistor",
description: "if <strong class='color-flop'>ON</strong> generate <strong>20</strong> <strong class='color-f'>energy</strong> per second<br>if <strong class='color-flop'>OFF</strong> drain <strong>1</strong> <strong class='color-f'>energy</strong> per second", description: "if <strong class='color-flop'>ON</strong> generate <strong>+20</strong> <strong class='color-f'>energy</strong> per second<br>if <strong class='color-flop'>OFF</strong> drain <strong>-1</strong> <strong class='color-f'>energy</strong> per second",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 4, frequency: 4,
@@ -2138,7 +2193,7 @@ const tech = {
}, },
{ {
name: "piezoelectricity", name: "piezoelectricity",
description: "if you <strong>collide</strong> with a mob<br>generate <strong>2048</strong> <strong class='color-f'>energy</strong>", //<br>reduce <strong class='color-defense'>defense</strong> by <strong>15%</strong> description: "if you <strong>collide</strong> with a mob<br>generate <strong>+2048</strong> <strong class='color-f'>energy</strong>", //<br>reduce <strong class='color-defense'>defense</strong> by <strong>15%</strong>
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2528,7 +2583,7 @@ const tech = {
}, },
{ {
name: "negative feedback", name: "negative feedback",
description: "for each <strong>10</strong> <strong class='color-h'>health</strong> below <strong>100</strong><br><strong>+5%</strong> <strong class='color-d'>damage</strong>", description: `for each <strong class='color-h'>health</strong> below <strong>100</strong><br><strong>+0.5%</strong> <strong class='color-d'>damage</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2544,6 +2599,42 @@ const tech = {
tech.isLowHealthDmg = false; tech.isLowHealthDmg = false;
} }
}, },
{
name: "homeostasis",
description: `for each <strong class='color-h'>health</strong> below <strong>100</strong><br><strong>+0.8%</strong> <strong class='color-defense'>defense</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return (m.health < 0.6 || build.isExperimentSelection) && !tech.isEnergyHealth
},
requires: "health below 60, not mass-energy",
effect() {
tech.isLowHealthDefense = true;
},
remove() {
tech.isLowHealthDefense = false;
}
},
// {
// name: "overshoot", //annoying to code because you'd have to update fire rate too often
// descriptionFunction() { return `for each ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} below <strong>100</strong><br><strong>+2%</strong> <strong><em>fire rate</em></strong>` },
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// allowed() {
// return m.health < 0.5 || build.isExperimentSelection
// },
// requires: "health below 60",
// effect() {
// tech.isLowHealthFireRate = true;
// },
// remove() {
// tech.isLowHealthFireRate = false;
// }
// },
{ {
name: "antiscience", name: "antiscience",
description: "<strong>+90%</strong> <strong class='color-d'>damage</strong><br><strong>11</strong> <strong class='color-h'>health</strong> after picking up a <strong class='color-m'>tech</strong>", description: "<strong>+90%</strong> <strong class='color-d'>damage</strong><br><strong>11</strong> <strong class='color-h'>health</strong> after picking up a <strong class='color-m'>tech</strong>",
@@ -3463,22 +3554,22 @@ const tech = {
}, },
{ {
name: "apomixis", name: "apomixis",
description: `when you reach <strong>111%</strong> <strong class='color-dup'>duplication</strong><br>spawn <strong>11 bosses</strong> with <strong>111%</strong> more <strong>durability</strong>`, description: `when you reach <strong>100%</strong> <strong class='color-dup'>duplication</strong><br>spawn <strong>11 bosses</strong> with <strong>100%</strong> more <strong>durability</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 6, frequency: 6,
frequencyDefault: 6, frequencyDefault: 6,
isNonRefundable: true, isNonRefundable: true,
allowed() { allowed() {
return tech.duplicationChance() > 0.6 return tech.duplicationChance() > 0.5
}, },
requires: "NOT EXPERIMENT MODE, duplication chance above 60%", requires: "NOT EXPERIMENT MODE, duplication chance above 50%",
effect() { effect() {
tech.is111Duplicate = true; tech.is100Duplicate = true;
tech.maxDuplicationEvent() tech.maxDuplicationEvent()
}, },
remove() { remove() {
tech.is111Duplicate = false; tech.is100Duplicate = false;
} }
}, },
{ {
@@ -3624,7 +3715,7 @@ const tech = {
}, },
{ {
name: "reinforcement learning", name: "reinforcement learning",
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current recursive <strong class='color-m'>tech</strong> by <strong>1000%</strong>", description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current <strong class='color-m'>tech</strong> by <strong>1000%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -4211,7 +4302,7 @@ const tech = {
}, },
{ {
name: "thermoelectric effect", name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br>generates <strong>100</strong> <strong class='color-f'>energy</strong>", description: "after <strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br><strong>+100</strong> <strong class='color-f'>energy</strong>",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -5964,7 +6055,7 @@ const tech = {
effect() { effect() {
let techGiven = 0 let techGiven = 0
for (let j = 0; j < 3; j++) { for (let j = 0; j < 3; j++) {
const names = ["lens", "arc length", "laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light"] const names = ["lens", "compound lens", "arc length", "laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"]
//convert names into indexes //convert names into indexes
const options = [] const options = []
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
@@ -6099,9 +6190,9 @@ const tech = {
}, },
{ {
name: "lens", name: "lens",
description: "<strong>+150%</strong> <strong class='color-laser'>laser</strong> gun <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>+90°</strong> arc circular lens", //<span style='font-size: 125%;'>π</span> / 2</strong> description: "<strong>+150%</strong> <strong class='color-laser'>laser</strong> gun <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>90°</strong> arc circular lens", //<span style='font-size: 125%;'>π</span> / 2</strong>
isGunTech: true, isGunTech: true,
maxCount: 3, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
@@ -6111,15 +6202,73 @@ const tech = {
requires: "laser", requires: "laser",
effect() { effect() {
tech.isLaserLens = true tech.isLaserLens = true
b.guns[11].arcRange += 0.78
b.guns[11].chooseFireMethod() b.guns[11].chooseFireMethod()
// if (this.count > 0) b.guns[11].lensDamageOn += 20 * Math.PI / 180
// b.guns[11].arcRange = 0.78
}, },
remove() { remove() {
tech.isLaserLens = false tech.isLaserLens = false
b.guns[11].arcRange = 0
b.guns[11].chooseFireMethod() b.guns[11].chooseFireMethod()
// b.guns[11].lensDamageOn = 2.5 // 100% + 150%
// b.guns[11].arcRange = 0
} }
}, },
{
name: "compound lens",
description: "<strong>+77%</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+10°</strong> lens arc",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isLaserLens
},
requires: "lens",
effect() {
b.guns[11].arcRange += 10 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.77
},
remove() {
b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn
b.guns[11].lensDamageOn = 2.5
}
},
// {
// name: "lens",
// // description: "<strong>+150%</strong> <strong class='color-laser'>laser</strong> gun <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>+90°</strong> arc circular lens", //<span style='font-size: 125%;'>π</span> / 2</strong>
// descriptionFunction() {
// if (this.count) {
// return `<strong>+70%</strong> lens <strong class='color-d'>damage</strong><br><strong>+20°</strong> arc circular lens`
// } else {
// return `<strong>+150%</strong> <strong class='color-laser'>laser</strong> gun <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>90°</strong> arc circular lens`
// }
// },
// isGunTech: true,
// maxCount: 3,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return tech.haveGunCheck("laser")
// },
// requires: "laser",
// effect() {
// tech.isLaserLens = true
// if (this.count) {
// b.guns[11].lensDamageOn += 0.7
// b.guns[11].arcRange += 20 * Math.PI / 180
// } else [
// b.guns[11].lensDamageOn = 2.5 // 100% + 150%
// ]
// b.guns[11].chooseFireMethod()
// },
// remove() {
// tech.isLaserLens = false
// b.guns[11].arcRange = 90 * Math.PI / 180
// b.guns[11].chooseFireMethod()
// }
// },
// { // {
// name: "arc length", // name: "arc length",
// description: "increase the circular arc of your <strong class='color-laser'>laser</strong> <strong>lens</strong><br>by <strong>+<span style='font-size: 125%;'>π</span> / 4</strong>", // description: "increase the circular arc of your <strong class='color-laser'>laser</strong> <strong>lens</strong><br>by <strong>+<span style='font-size: 125%;'>π</span> / 4</strong>",
@@ -6614,26 +6763,6 @@ const tech = {
// tech.isFreezeMobs = false // tech.isFreezeMobs = false
// } // }
// }, // },
{
name: "pair production",
description: "after picking up a <strong>power up</strong><br><strong>+200</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
},
requires: "molecular assembler, pilot wave, standing wave",
effect: () => {
tech.isMassEnergy = true // used in m.grabPowerUp
m.energy += 2
},
remove() {
tech.isMassEnergy = false;
}
},
{ {
name: "bot manufacturing", name: "bot manufacturing",
description: `use ${powerUps.orb.research(2)} to build<br><strong>3</strong> random <strong class='color-bot'>bots</strong>`, description: `use ${powerUps.orb.research(2)} to build<br><strong>3</strong> random <strong class='color-bot'>bots</strong>`,
@@ -6644,9 +6773,8 @@ const tech = {
frequencyDefault: 1, frequencyDefault: 1,
isBotTech: true, isBotTech: true,
isNonRefundable: true, isNonRefundable: true,
// isExperimentHide: true,
allowed() { allowed() {
return powerUps.research.count > 1 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" return powerUps.research.count > 1 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
}, },
requires: "NOT EXPERIMENT MODE, molecular assembler", requires: "NOT EXPERIMENT MODE, molecular assembler",
effect: () => { effect: () => {
@@ -6672,7 +6800,7 @@ const tech = {
isNonRefundable: true, isNonRefundable: true,
// isExperimentHide: true, // isExperimentHide: true,
allowed() { allowed() {
return powerUps.research.count > 2 && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
}, },
requires: "NOT EXPERIMENT MODE, molecular assembler", requires: "NOT EXPERIMENT MODE, molecular assembler",
effect: () => { effect: () => {
@@ -6817,6 +6945,45 @@ const tech = {
// if (this.count > 0) powerUps.research.changeRerolls(1) // if (this.count > 0) powerUps.research.changeRerolls(1)
// } // }
// }, // },
{
name: "pair production",
description: "after picking up a <strong>power up</strong><br><strong>+200</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
},
requires: "molecular assembler, pilot wave, standing wave",
effect: () => {
tech.isMassEnergy = true // used in m.grabPowerUp
m.energy += 2
},
remove() {
tech.isMassEnergy = false;
}
},
{
name: "electric generator",
description: "after <strong>deflecting</strong> mobs<br>molecular assembler generates <strong>+50</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler"
},
requires: "molecular assembler",
effect() {
tech.deflectEnergy += 0.5;
},
remove() {
tech.deflectEnergy = 0;
}
},
{ {
name: "tokamak", name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>", description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>",
@@ -6828,7 +6995,7 @@ const tech = {
allowed() { allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler" return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler"
}, },
requires: "plasma torch or molecular assembler", requires: "plasma torch, molecular assembler",
effect() { effect() {
tech.isTokamak = true; tech.isTokamak = true;
}, },
@@ -6845,9 +7012,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth
}, },
requires: "plasma torch, perfect diamagnetism, pilot wave, not mass-energy", requires: "molecular assembler, plasma torch, perfect diamagnetism, pilot wave, not mass-energy",
effect() { effect() {
tech.isHarmReduce = true tech.isHarmReduce = true
}, },
@@ -7182,7 +7349,8 @@ const tech = {
}, },
{ {
name: "dazzler", name: "dazzler",
description: "after <strong class='color-cloaked'>decloaking</strong> <strong>stun</strong> nearby mobs<br>for <strong>10</strong> <strong class='color-f'>energy</strong>", link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Dazzler_(weapon)' class="link">dazzler</a>`,
description: "after <strong class='color-cloaked'>decloaking</strong> <strong>stun</strong> nearby mobs<br>for <strong>15</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7243,7 +7411,7 @@ const tech = {
} }
}, },
{ {
name: "discrete optimization", name: "combinatorial optimization",
description: "<strong>+35%</strong> <strong class='color-d'>damage</strong><br><strong>35%</strong> <strong><em>fire rate</em></strong>", description: "<strong>+35%</strong> <strong class='color-d'>damage</strong><br><strong>35%</strong> <strong><em>fire rate</em></strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
@@ -9681,7 +9849,7 @@ const tech = {
effect() {}, effect() {},
remove() {}, remove() {},
state: [ state: [
[Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false] [false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false]
], ],
rule(state, a, b, c) { rule(state, a, b, c) {
//30 //30
@@ -9706,27 +9874,29 @@ const tech = {
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
this.state.push(b) this.state.push(b)
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); if (this.count && this.state.length < 150 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
setTimeout(() => { loop() }, 400); setTimeout(() => { loop() }, 300);
} }
} }
setTimeout(() => { loop() }, 400); setTimeout(() => { loop() }, 300);
this.id++ this.id++
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>` return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: -0.5px;font-size: 100%;line-height: normal;font-family: 'Courier New', monospace;">${this.outputText()}</span>`
}, },
outputText() { outputText() {
let text = "" let text = "<pre>"
for (let j = 0; j < this.state.length; j++) { for (let j = 0; j < this.state.length; j++) {
text += "<p style = 'margin-bottom: -11px;'>" // text += "<p style = 'margin-bottom: -12px;'>"
text += "<p style = 'margin-top: -7px;margin-bottom: -7px;'>"
for (let i = 0; i < this.state[j].length; i++) { for (let i = 0; i < this.state[j].length; i++) {
if (this.state[j][i]) { if (this.state[j][i]) {
text += "" //"█" //"■" text += "" //"☻" //"⬛" //"█" //"■"
} else { } else {
text += "" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□" text += " " //"□" //"☺" //"⬜" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
} }
} }
text += "</p>" text += "</p>"
} }
text += "</pre>"
return text return text
}, },
}, },
@@ -9743,7 +9913,7 @@ const tech = {
effect() {}, effect() {},
remove() {}, remove() {},
state: [ state: [
[false, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, true, true, false, false, false, false, Math.random() > 0.8, Math.random() > 0.8, false, false, false, false, false, false, Math.random() > 0.8] [false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false]
], ],
rule(state, a, b, c) { //90 rule(state, a, b, c) { //90
if (state[a] && state[b] && state[c]) return false; // TTT => F if (state[a] && state[b] && state[c]) return false; // TTT => F
@@ -9768,27 +9938,29 @@ const tech = {
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
this.state.push(b) this.state.push(b)
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); if (this.count && this.state.length < 150 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
setTimeout(() => { loop() }, 400); setTimeout(() => { loop() }, 300);
} }
} }
setTimeout(() => { loop() }, 400); setTimeout(() => { loop() }, 300);
this.id++ this.id++
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>` return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: -0.5px;font-size: 100%;line-height: normal;font-family: 'Courier New', monospace;">${this.outputText()}</span>`
}, },
outputText() { outputText() {
let text = "" let text = "<pre>"
for (let j = 0; j < this.state.length; j++) { for (let j = 0; j < this.state.length; j++) {
text += "<p style = 'margin-bottom: -11px;'>" // text += "<p style = 'margin-bottom: -12px;'>"
text += "<p style = 'margin-top: -7px;margin-bottom: -7px;'>"
for (let i = 0; i < this.state[j].length; i++) { for (let i = 0; i < this.state[j].length; i++) {
if (this.state[j][i]) { if (this.state[j][i]) {
text += "" //"█" //"■" text += "" //"☻" //"⬛" //"█" //"■"
} else { } else {
text += "" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□" text += " " //"□" //"☺" //"⬜" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
} }
} }
text += "</p>" text += "</p>"
} }
text += "</pre>"
return text return text
}, },
}, },
@@ -10051,6 +10223,8 @@ const tech = {
squirrelFx: null, squirrelFx: null,
isCrit: null, isCrit: null,
isLowHealthDmg: null, isLowHealthDmg: null,
isLowHealthDefense: null,
isLowHealthFireRate: null,
isFarAwayDmg: null, isFarAwayDmg: null,
isEntanglement: null, isEntanglement: null,
isMassEnergy: null, isMassEnergy: null,
@@ -10216,7 +10390,7 @@ const tech = {
isPauseEjectTech: null, isPauseEjectTech: null,
isShieldPierce: null, isShieldPierce: null,
isDuplicateBoss: null, isDuplicateBoss: null,
is111Duplicate: null, is100Duplicate: null,
isDynamoBotUpgrade: null, isDynamoBotUpgrade: null,
isBlockPowerUps: null, isBlockPowerUps: null,
isDamageAfterKillNoRegen: null, isDamageAfterKillNoRegen: null,
@@ -10257,6 +10431,7 @@ const tech = {
harmonics: null, harmonics: null,
isStandingWaveExpand: null, isStandingWaveExpand: null,
isTokamak: null, isTokamak: null,
deflectEnergy: null,
superBallDelay: null, superBallDelay: null,
isBlockExplode: null, isBlockExplode: null,
isOverHeal: null, isOverHeal: null,
@@ -10353,4 +10528,5 @@ const tech = {
isLaserLens: null, isLaserLens: null,
laserCrit: null, laserCrit: null,
isSporeColony: null, isSporeColony: null,
isExtraBotOption: null
} }

View File

@@ -1,17 +1,54 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
cloaking +damage occurs for 2 seconds after decloaking tech: electric generator - deflecting mobs generates energy for molecular assembler
need to cloak for 4 seconds to get the full 2 seconds of +damage tech: homeostasis - for each health below 100 +0.8% defense
ambush 666% -> 555% damage tech: compound lens - +77% laser lens damage, +10° lens arc
boson composite drains 25% more energy when you move through mobs
nail gun gets 20% more ammo tech: robotics - 2 random bots, power up choices include a bot tech option
harpoons now properly do damage on the frame before they retract tech: open-source - 3 random bots, 4x bot tech frequency
smelting removes 10% more ammo to get another harpoon for railgun renamed from previous robotics tech
grenade fireworks explosive petals are 25% closer together slightly buffed all bot upgrades
+9% iceIX damage
catabolism uses energy instead of health if you have mass-energy
optical amplifier laser tech options include laser-bot
rule 90 and rule 30 looks better on more browsers, I hope
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
store value of last hit health lost
names: patch
tech: after cloaking regen 1/2 of the last hit
spawning a heal power up is annoying because you'd be cloaked, so direct healing?
time limit for effect?
while still under ambush damage?
tech: killing the mob that caused the last hit spawns a heal power up equal to 1/2 of last hit
time limit for effect? 3-4 seconds?
tech: doing damage can recover up to 1/2 of the last hit
spawn a heal equal to 1/2 of last hit
time limit for effect? 3-4 seconds?
tech increase damage by how much health was lost in last hit
+damage = 3x health lost?
if you went from 100 -> 60 health = +40%*3 = 120% damage
negative mass field tech?
too similar to radiative equilibrium
pick between them?
path-finding
build a path-finding map on level load
how to convert vertices into block grid?
check points for map collisions and build grid
is there a path-finding algorithm for vertices, instead of block grid
use for:
mobs,
drones?
bots that can go far from player and return
tech ______ effect that last until you get hit tech ______ effect that last until you get hit
field or bots can check your health every cycle and see if it lower field or bots can check your health every cycle and see if it lower
if it's high update the health check value if it's high update the health check value