robotics
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:
63
js/bullet.js
63
js/bullet.js
@@ -96,11 +96,22 @@ 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
|
||||
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
|
||||
if (tech.crouchAmmoCount && input.down) {
|
||||
@@ -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)
|
||||
|
||||
16
js/level.js
16
js/level.js
@@ -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)
|
||||
|
||||
33
js/player.js
33
js/player.js
@@ -133,11 +133,10 @@ 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() {
|
||||
for (let i = 0; i < 600; i++) { //reset history
|
||||
m.history[i] = {
|
||||
const set = {
|
||||
position: {
|
||||
x: player.position.x,
|
||||
y: player.position.y,
|
||||
@@ -152,6 +151,8 @@ const m = {
|
||||
energy: m.energy,
|
||||
activeGun: b.activeGun
|
||||
}
|
||||
for (let i = 0; i < 600; i++) { //reset history
|
||||
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);
|
||||
|
||||
@@ -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> ${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> ${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> ${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> ${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 = [];
|
||||
|
||||
@@ -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,
|
||||
|
||||
382
js/tech.js
382
js/tech.js
@@ -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 += "⬜" //" " //"□"
|
||||
text += " " //"□" //"☺" //"⬜" //" " //"□"
|
||||
}
|
||||
}
|
||||
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 += "⬜" //" " //"□"
|
||||
text += " " //"□" //"☺" //"⬜" //" " //"□"
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
53
todo.txt
53
todo.txt
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user