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,10 +96,21 @@ const b = {
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`);
m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth && m.health > 0.01) {
tech.extraMaxHealth -= 0.01 //decrease max health
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");
if (tech.isAmmoFromHealth) {
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();
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
@@ -2888,7 +2899,7 @@ const b = {
friction: 0,
frictionAir: 0.023,
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()),
endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
classType: "bullet",
@@ -4376,7 +4387,7 @@ const b = {
minDmgSpeed: 2,
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
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()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
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))
if (this.isUpgraded) {
const SPEED = 50
const SPEED = 55
b.nail(this.position, Vector.mult(unit, SPEED))
this.force = Vector.mult(unit, -0.018 * this.mass)
} else {
@@ -4513,9 +4524,9 @@ const b = {
restitution: 0.6 * (1 + 0.5 * Math.random()),
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 60 + Math.floor(17 * Math.random()) - 40 * tech.isFoamBotUpgrade,
lookFrequency: 60 + Math.floor(17 * Math.random()) - 45 * tech.isFoamBotUpgrade,
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()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(),
endCycle: Infinity,
@@ -4543,7 +4554,7 @@ const b = {
const radius = 6 + 7 * Math.random()
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)
b.foam(this.position, velocity, radius + 7 * this.isUpgraded)
b.foam(this.position, velocity, radius + 7.5 * this.isUpgraded)
break;
}
}
@@ -4559,7 +4570,7 @@ const b = {
const dir = m.angle;
const RADIUS = (14 + 6 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
isUpgraded: tech.isLaserBotUpgrade,
// isUpgraded: tech.isLaserBotUpgrade,
botType: "laser",
angle: dir,
friction: 0,
@@ -4571,11 +4582,11 @@ const b = {
offPlayer: { x: 0, y: 0, },
dmg: 0, //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 40 + Math.floor(7 * Math.random()) - 10 * tech.isLaserBotUpgrade,
range: (700 + 450 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
lookFrequency: 40 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade,
range: (700 + 500 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
drain: (0.5 - 0.43 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode,
laserDamage: 0.85 + 0.7 * tech.isLaserBotUpgrade,
drain: (0.5 - 0.44 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode,
laserDamage: 0.85 + 0.8 * tech.isLaserBotUpgrade,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
@@ -4684,10 +4695,10 @@ const b = {
restitution: 1,
dmg: 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()),
attackAcceleration: 0.012 + 0.005 * tech.isBoomBotUpgrade,
range: 500 * (1 + 0.1 * Math.random()) + 320 * tech.isBoomBotUpgrade,
attackAcceleration: 0.012 + 0.006 * tech.isBoomBotUpgrade,
range: 500 * (1 + 0.1 * Math.random()) + 350 * tech.isBoomBotUpgrade,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
@@ -4698,7 +4709,7 @@ const b = {
explode: 0,
beforeDmg() {
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) {
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,
phase: 2 * Math.PI * Math.random(),
do() {
@@ -4996,8 +5007,8 @@ const b = {
})
for (let i = 0; i < q.length; i++) {
if (!q[i].isShielded) {
mobs.statusStun(q[i], 210)
const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4 : 1) * (tech.isCrit ? 4 : 1)
mobs.statusStun(q[i], 210 + 90 * this.isUpgraded)
const dmg = 0.4 * m.dmgScale * (this.isUpgraded ? 4.5 : 1) * (tech.isCrit ? 4 : 1)
q[i].damage(dmg);
if (q[i].alive) q[i].foundPlayer();
if (q[i].damageReduction) {
@@ -6908,7 +6919,6 @@ const b = {
charge: 0,
isStuckOn: false,
angle: 0,
arcRange: 0.78, //1.57,
isInsideArc(angle) {
const mod = (a, 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
return Math.abs(diff) < this.arcRange
},
arcRange: 0.78, //1.57,
lensDamage: 1,
lensDamageOn: 0, //set in tech
lens() {
this.stuckOn();
this.angle += 0.02
if (this.isInsideArc(m.angle)) {
this.lensDamage = 2.5 //150% damage increase
this.lensDamage = this.lensDamageOn
ctx.lineWidth = 6 + this.lensDamageOn
} else {
this.lensDamage = 1
ctx.lineWidth = 2
}
const radius = 60
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.lineWidth = (this.lensDamage > 1) ? 10 : 2 //3
ctx.stroke();
// 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)

View File

@@ -24,15 +24,15 @@ const level = {
// powerUps.research.changeRerolls(100)
// tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000
// m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism
// 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
// tech.giveTech("siphonaptera")
// tech.giveTech("fleas")
// tech.giveTech("colony")
// tech.giveTech("mycelium manufacturing")
// m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole
// 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("robotics")
// tech.giveTech("CPT symmetry");
// tech.giveTech("lens");
// tech.giveTech("robotics")
// 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("cryodesiccation")
// for (let i = 0; i < 1; ++i) tech.giveTech("electric generator")
// 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, "research");
// spawn.starter(1900, -500)

View File

@@ -133,25 +133,26 @@ const m = {
legLength2: 45,
transX: 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
resetHistory() {
const set = {
position: {
x: player.position.x,
y: player.position.y,
},
velocity: {
x: player.velocity.x,
y: player.velocity.y
},
yOff: m.yOff,
angle: m.angle,
health: m.health,
energy: m.energy,
activeGun: b.activeGun
}
for (let i = 0; i < 600; i++) { //reset history
m.history[i] = {
position: {
x: player.position.x,
y: player.position.y,
},
velocity: {
x: player.velocity.x,
y: player.velocity.y
},
yOff: m.yOff,
angle: m.angle,
health: m.health,
energy: m.energy,
activeGun: b.activeGun
}
m.history[i] = set
}
},
move() {
@@ -513,6 +514,7 @@ const m = {
let dmg = 1
dmg *= m.fieldHarmReduction
// 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.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.4
@@ -1413,7 +1415,11 @@ const m = {
) {
mob[i].locatePlayer();
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",
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: () => {
m.fieldFire = true;
m.fieldMeterColor = "#333";
@@ -2750,8 +2756,9 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0
m.isSneakAttack = true;
// m.sneakAttackCharge = 0;
m.sneakAttackCycle = 0;
m.enterCloakCycle = 0
m.enterCloakCycle = 0;
const drawRadius = 800
m.drawCloak = function() {
m.fieldPhase += 0.007
@@ -2770,6 +2777,12 @@ const m = {
ctx.clip();
}
m.hold = function() {
// if (m.isCloak) {
// if (m.sneakAttackCharge < 120) m.sneakAttackCharge += 0.5
// } else {
// if (m.sneakAttackCharge > 0) m.sneakAttackCharge--
// }
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2806,13 +2819,12 @@ const m = {
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
let isMobsAround = false
const stunRange = m.fieldDrawRadius * 1.5
const drain = 0.1
const stunTime = 240
const drain = 0.2
if (m.energy > drain) {
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) {
isMobsAround = true
mobs.statusStun(mob[i], stunTime)
mobs.statusStun(mob[i], 180)
}
}
if (isMobsAround) {
@@ -2856,7 +2868,8 @@ const m = {
this.drawFieldMeterCloaking()
//show sneak attack status
// 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.beginPath();
ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI);

View File

@@ -551,15 +551,12 @@ const powerUps = {
let text = ""
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>`
let options = [];
for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) options.push(i);
}
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
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
if (options[i] === index) {
@@ -568,14 +565,12 @@ const powerUps = {
}
}
}
//check for guns that were a choice last time and remove them
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 (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
if (options.length > 0) {
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
@@ -584,6 +579,17 @@ const powerUps = {
removeOption(choose)
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) {
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;">`
@@ -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
if (options.length > 0) {
if (options.length > 0 || tech.isExtraBotOption) {
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
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)
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) {
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;">`
@@ -846,9 +863,6 @@ const powerUps = {
tech.tooManyTechChoices = false
totalChoices = optionLengthNoDuplicates
}
//check for tech that were a choice last time and remove them
if (optionLengthNoDuplicates > totalChoices) {
// 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 (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 (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
let gunOptions = [];

View File

@@ -180,7 +180,7 @@ const simulation = {
cyclePaused: 0,
fallHeight: 6000, //below this y position the player dies
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,
isHorizontalFlipped: false, //makes some maps flipped horizontally
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.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6
// 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()
return dmg * tech.slowFire * tech.aimDamage
},
@@ -261,8 +262,8 @@ const tech = {
},
isScaleMobsWithDuplication: false,
maxDuplicationEvent() {
if (tech.is111Duplicate && tech.duplicationChance() > 1.11) {
tech.is111Duplicate = false
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
tech.is100Duplicate = false
const range = 1300
tech.isScaleMobsWithDuplication = true
for (let i = 0, len = 9; i < len; i++) {
@@ -308,7 +309,7 @@ const tech = {
},
tech: [{
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,
count: 0,
frequency: 1,
@@ -324,7 +325,7 @@ const tech = {
powerUps.spawn(m.pos.x, m.pos.y, "gun");
// this.count--
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() {}
@@ -584,15 +585,15 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isEnergyNoAmmo && !tech.isEnergyHealth
return !tech.isEnergyNoAmmo
},
requires: "not exciton, mass-energy",
requires: "not exciton",
effect: () => {
tech.isAmmoFromHealth = true;
},
@@ -1372,7 +1373,7 @@ const tech = {
{
name: "dynamo-bot",
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,
count: 0,
frequency: 1,
@@ -1396,7 +1397,7 @@ const tech = {
{
name: "dynamo-bot upgrade",
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,
count: 0,
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>`
}
},
{
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",
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",
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",
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,
count: 0,
frequency: 4,
@@ -2138,7 +2193,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
@@ -2528,7 +2583,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
@@ -2544,6 +2599,42 @@ const tech = {
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",
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",
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,
count: 0,
frequency: 6,
frequencyDefault: 6,
isNonRefundable: true,
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() {
tech.is111Duplicate = true;
tech.is100Duplicate = true;
tech.maxDuplicationEvent()
},
remove() {
tech.is111Duplicate = false;
tech.is100Duplicate = false;
}
},
{
@@ -3624,7 +3715,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
@@ -4211,7 +4302,7 @@ const tech = {
},
{
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,
maxCount: 9,
count: 0,
@@ -5964,7 +6055,7 @@ const tech = {
effect() {
let techGiven = 0
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
const options = []
for (let i = 0; i < names.length; i++) {
@@ -6099,9 +6190,9 @@ const tech = {
},
{
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,
maxCount: 3,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
@@ -6111,15 +6202,73 @@ const tech = {
requires: "laser",
effect() {
tech.isLaserLens = true
b.guns[11].arcRange += 0.78
b.guns[11].chooseFireMethod()
// if (this.count > 0) b.guns[11].lensDamageOn += 20 * Math.PI / 180
// b.guns[11].arcRange = 0.78
},
remove() {
tech.isLaserLens = false
b.guns[11].arcRange = 0
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",
// 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
// }
// },
{
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",
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,
isBotTech: true,
isNonRefundable: true,
// isExperimentHide: true,
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",
effect: () => {
@@ -6672,7 +6800,7 @@ const tech = {
isNonRefundable: true,
// isExperimentHide: true,
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",
effect: () => {
@@ -6817,6 +6945,45 @@ const tech = {
// 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",
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() {
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() {
tech.isTokamak = true;
},
@@ -6845,9 +7012,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
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() {
tech.isHarmReduce = true
},
@@ -7182,7 +7349,8 @@ const tech = {
},
{
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,
maxCount: 1,
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>",
isFieldTech: true,
maxCount: 1,
@@ -9681,7 +9849,7 @@ const tech = {
effect() {},
remove() {},
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) {
//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
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 (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");
setTimeout(() => { loop() }, 400);
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() }, 300);
}
}
setTimeout(() => { loop() }, 400);
setTimeout(() => { loop() }, 300);
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() {
let text = ""
let text = "<pre>"
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++) {
if (this.state[j][i]) {
text += "" //"█" //"■"
text += "" //"☻" //"⬛" //"█" //"■"
} else {
text += "" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
text += " " //"□" //"☺" //"⬜" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
}
}
text += "</p>"
}
text += "</pre>"
return text
},
},
@@ -9743,7 +9913,7 @@ const tech = {
effect() {},
remove() {},
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
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
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 (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");
setTimeout(() => { loop() }, 400);
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() }, 300);
}
}
setTimeout(() => { loop() }, 400);
setTimeout(() => { loop() }, 300);
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() {
let text = ""
let text = "<pre>"
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++) {
if (this.state[j][i]) {
text += "" //"█" //"■"
text += "" //"☻" //"⬛" //"█" //"■"
} else {
text += "" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
text += " " //"□" //"☺" //"⬜" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
}
}
text += "</p>"
}
text += "</pre>"
return text
},
},
@@ -10051,6 +10223,8 @@ const tech = {
squirrelFx: null,
isCrit: null,
isLowHealthDmg: null,
isLowHealthDefense: null,
isLowHealthFireRate: null,
isFarAwayDmg: null,
isEntanglement: null,
isMassEnergy: null,
@@ -10216,7 +10390,7 @@ const tech = {
isPauseEjectTech: null,
isShieldPierce: null,
isDuplicateBoss: null,
is111Duplicate: null,
is100Duplicate: null,
isDynamoBotUpgrade: null,
isBlockPowerUps: null,
isDamageAfterKillNoRegen: null,
@@ -10257,6 +10431,7 @@ const tech = {
harmonics: null,
isStandingWaveExpand: null,
isTokamak: null,
deflectEnergy: null,
superBallDelay: null,
isBlockExplode: null,
isOverHeal: null,
@@ -10353,4 +10528,5 @@ const tech = {
isLaserLens: null,
laserCrit: null,
isSporeColony: null,
isExtraBotOption: null
}

View File

@@ -1,17 +1,54 @@
******************************************************** NEXT PATCH **************************************************
cloaking +damage occurs for 2 seconds after decloaking
need to cloak for 4 seconds to get the full 2 seconds of +damage
ambush 666% -> 555% damage
boson composite drains 25% more energy when you move through mobs
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
nail gun gets 20% more ammo
harpoons now properly do damage on the frame before they retract
smelting removes 10% more ammo to get another harpoon for railgun
grenade fireworks explosive petals are 25% closer together
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
*********************************************************** 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
field or bots can check your health every cycle and see if it lower
if it's high update the health check value