isotropic radiator

"pressure wave" renamed "phonon"
  tech packet length removed
  most wave beam tech is now compatible with phonon

wave beam tech: isotropic radiator - phonon has shorter range but expands in every direction

drone tech: torque bursts - teleport towards targets and do 30% more collision damage

irradiated drones do 33% more damage, 33% less collisions damage
   5% more ammo, 30% less range, don't lose duration on collisions

pseudoscience only gets 3 free rerolls per tech
This commit is contained in:
landgreen
2021-07-15 06:14:56 -07:00
parent 95adf9fa06
commit f590cfc99e
11 changed files with 324 additions and 296 deletions

View File

@@ -2039,8 +2039,8 @@ const b = {
friction: 0.05,
frictionAir: 0,
restitution: 1,
dmg: 0.24, //damage done in addition to the damage from momentum
lookFrequency: 80 + Math.floor(23 * Math.random()),
dmg: 0.24 + 0.12 * tech.isDroneTeleport, //damage done in addition to the damage from momentum
lookFrequency: 70 + Math.floor(17 * Math.random()),
endCycle: simulation.cycle + Math.floor((950 + 420 * Math.random()) * tech.isBulletsLastLonger * tech.droneCycleReduction) + 140 + RADIUS * 5,
classType: "bullet",
collisionFilter: {
@@ -2110,11 +2110,24 @@ const b = {
}
}
}
//blink towards mobs
if (tech.isDroneTeleport && this.lockedOn) {
const sub = Vector.sub(this.lockedOn.position, this.position);
const distMag = Vector.magnitude(sub);
const unit = Vector.normalise(sub)
Matter.Body.setVelocity(this, Vector.mult(unit, Math.max(20, this.speed * 1.5)));
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
Matter.Body.translate(this, Vector.mult(unit, Math.min(350, distMag - this.lockedOn.radius + 10)));
ctx.lineTo(this.position.x, this.position.y);
ctx.lineWidth = RADIUS * 2;
ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.stroke();
}
//power ups
if (!this.isImproved && !simulation.isChoosing && !tech.isExtraMaxEnergy) {
if (this.lockedOn) {
//grab, but don't lock onto nearby power up
for (let i = 0, len = powerUp.length; i < len; ++i) {
for (let i = 0, len = powerUp.length; i < len; ++i) { //grab, but don't lock onto nearby power up
if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
@@ -2223,8 +2236,8 @@ const b = {
inertia: Infinity,
friction: 0,
frictionAir: 0,
restitution: 0.8 + 0.199 * Math.random(),
dmg: 0.24, //damage done in addition to the damage from momentum
restitution: 0.4 + 0.199 * Math.random(),
dmg: 0, //0.24 damage done in addition to the damage from momentum and radiation
lookFrequency: 120 + Math.floor(23 * Math.random()),
endCycle: simulation.cycle + Math.floor((900 + 120 * Math.random()) * tech.isBulletsLastLonger / tech.droneRadioDamage) + 140 + RADIUS * 5,
classType: "bullet",
@@ -2239,7 +2252,7 @@ const b = {
deathCycles: 110 + RADIUS * 5,
isImproved: false,
radioRadius: 0,
maxRadioRadius: 355 + Math.floor(150 * Math.random()),
maxRadioRadius: 300 + Math.floor(100 * Math.random()),
beforeDmg(who) {
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20) //move away from target after hitting
Matter.Body.setVelocity(this, {
@@ -2247,10 +2260,10 @@ const b = {
y: unit.y
});
this.lockedOn = null
if (this.endCycle > simulation.cycle + this.deathCycles) {
this.endCycle -= 60
if (simulation.cycle + this.deathCycles > this.endCycle) this.endCycle = simulation.cycle + this.deathCycles
}
// if (this.endCycle > simulation.cycle + this.deathCycles) {
// this.endCycle -= 60
// if (simulation.cycle + this.deathCycles > this.endCycle) this.endCycle = simulation.cycle + this.deathCycles
// }
},
onEnd() {
if (tech.isDroneRespawn) {
@@ -2280,7 +2293,7 @@ const b = {
//aoe damage to mobs
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.radioRadius + mob[i].radius) {
let dmg = b.dmgScale * 0.06 * tech.droneRadioDamage //neutron bombs dmg = 0.09
let dmg = b.dmgScale * 0.1 * tech.droneRadioDamage //neutron bombs dmg = 0.09
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.25 //reduce damage if a wall is in the way
if (mob[i].shield) dmg *= 3 // to make up for the /5 that shields normally take
mob[i].damage(dmg);
@@ -2695,12 +2708,7 @@ const b = {
}
for (let i = 0, len = totalPermanentBots - totalTechToConvert; i < len; i++) tech.tech[index].effect(); //also convert any permanent bots that didn't come from a tech
//in experiment mode set the unselect color for bot tech that was converted
if (build.isExperimentSelection) {
}
// if (build.isExperimentSelection) { }
},
clearPermanentBots() {
for (let i = 0; i < bullet.length; i++) {
@@ -3991,7 +3999,10 @@ const b = {
propagationRate: 20,
waves: [], //used in longitudinal mode
chooseFireMethod() { //set in simulation.startGame
if (tech.isLongitudinal) {
if (tech.is360Longitudinal) {
this.fire = this.fire360Longitudinal
this.do = this.do360Longitudinal
} else if (tech.isLongitudinal) {
this.fire = this.fireLongitudinal
this.do = this.doLongitudinal
} else {
@@ -4000,10 +4011,94 @@ const b = {
}
},
do() {},
doLongitudinal() {
ctx.strokeStyle = "rgba(0,0,0,0.2)" //"000";
ctx.lineWidth = 2
do360Longitudinal() {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
const end = 75 * Math.sqrt(tech.isBulletsLastLonger) * tech.waveBeamSpeed / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) {
//draw wave
ctx.moveTo(this.waves[i].position.x + this.waves[i].radius, this.waves[i].position.y)
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI);
// collisions
if (!m.isBodiesAsleep) {
for (let j = 0, len = mob.length; j < len; j++) {
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position))
const r = mob[j].radius + 30
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
//make them shake around
if (!mob[j].isBadTarget) {
mob[j].force.x += 0.01 * (Math.random() - 0.5) * mob[j].mass
mob[j].force.y += 0.01 * (Math.random() - 0.5) * mob[j].mass
}
if (!mob[j].isShielded) {
Matter.Body.setVelocity(mob[j], { //friction
x: mob[j].velocity.x * 0.93,
y: mob[j].velocity.y * 0.93
});
//draw vibes
let vertices = mob[j].vertices;
const vibe = 50 + mob[j].radius * 0.15
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
}
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
//damage
mob[j].locatePlayer();
mob[j].damage(damage / Math.sqrt(mob[j].radius));
}
}
}
for (let j = 0, len = body.length; j < len; j++) {
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position))
const r = 20
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
//make them shake around
body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass
body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity
//draw vibes
let vertices = body[j].vertices;
const vibe = 25
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
}
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
}
}
this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move
}
// if (this.waves[i].radius > end) this.waves.splice(i, 1) //end
if (this.waves[i].radius > end) {
this.waves[i].expanding = -1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
} else if (this.waves[i].radius < 25) {
this.waves[i].expanding = 1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
}
}
ctx.stroke();
},
fire360Longitudinal() {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 3 : 8) * b.fireCDscale); // cool down
this.waves.push({
position: { x: m.pos.x, y: m.pos.y, },
radius: 25,
reflection: tech.waveReflections,
expanding: true
})
},
doLongitudinal() {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
const end = 125 * tech.isBulletsLastLonger * tech.waveBeamSpeed / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
const damage = 2 * b.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) {
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
@@ -4018,23 +4113,25 @@ const b = {
for (let j = 0; j < hits.length; j++) {
const who = hits[j].body
//make them shake around
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
Matter.Body.setVelocity(who, { //friction
x: who.velocity.x * 0.95,
y: who.velocity.y * 0.95
});
let vertices = who.vertices;
const vibe = 50 + who.radius * 0.15
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
for (let j = 1; j < vertices.length; j++) {
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
if (!who.isBadTarget) {
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
}
if (!who.isShielded) {
Matter.Body.setVelocity(who, { //friction
x: who.velocity.x * 0.95,
y: who.velocity.y * 0.95
});
let vertices = who.vertices;
const vibe = 50 + who.radius * 0.15
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
for (let j = 1; j < vertices.length; j++) {
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
}
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
who.locatePlayer();
who.damage(damage / Math.sqrt(who.radius));
}
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
const damage = 1.9 * b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage / Math.sqrt(who.radius) //damage is lower for large radius mobs, since they feel the waves longer
who.locatePlayer();
who.damage(damage);
}
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
@@ -4052,11 +4149,19 @@ const b = {
}
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
}
ctx.stroke(); //draw vibes
// ctx.stroke(); //draw vibes
this.waves[i].radius += tech.waveBeamSpeed * 2 //expand / move
this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move
}
if (this.waves[i].radius > end) {
this.waves[i].expanding = -1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
} else if (this.waves[i].radius < 25) {
this.waves[i].expanding = 1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
}
if (this.waves[i].radius > 1800 * tech.isBulletsLastLonger) this.waves.splice(i, 1) //end
}
ctx.stroke();
},
@@ -4072,7 +4177,9 @@ const b = {
unit1: { x: Math.cos(m.angle - halfArc), y: Math.sin(m.angle - halfArc) }, //used for collision
unit2: { x: Math.cos(m.angle + halfArc), y: Math.sin(m.angle + halfArc) }, //used for collision
arc: halfArc * 2,
radius: 25
radius: 25,
reflection: tech.waveReflections,
expanding: 1
})
},
doTransverse() {
@@ -4082,7 +4189,7 @@ const b = {
}
},
fireTransverse() {
totalCycles = Math.floor(4.3 * tech.wavePacketLength * tech.waveReflections * tech.isBulletsLastLonger)
totalCycles = Math.floor(4.3 * 35 * tech.waveReflections * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5))
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 25 * Math.cos(m.angle), m.pos.y + 25 * Math.sin(m.angle), 5, 4, {
angle: m.angle,
@@ -4091,7 +4198,7 @@ const b = {
inertia: Infinity,
frictionAir: 0,
slow: 0,
amplitude: (m.crouch ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * tech.wavePacketFrequency), //
amplitude: (m.crouch ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * 0.088), //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
minDmgSpeed: 0,
dmg: b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage, //also control damage when you divide by mob.mass
classType: "bullet",
@@ -4176,7 +4283,7 @@ const b = {
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
//fire a packet of bullets then delay for a while
this.wavePacketCycle++
if (this.wavePacketCycle > tech.wavePacketLength) {
if (this.wavePacketCycle > 35) {
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
this.wavePacketCycle = 0;
}

View File

@@ -176,6 +176,7 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
console.log(dmg)
if (tech.isCrit && mob[k].isStunned) dmg *= 4
mob[k].foundPlayer();
mob[k].damage(dmg);

View File

@@ -257,7 +257,7 @@ const build = {
}
}
//show in game console with scroll bar?
// text +=``
@@ -434,7 +434,6 @@ const build = {
for (let i = 0, len = b.guns.length; i < len; i++) {
text += `<div id = "gun-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[i].name}</div> ${b.guns[i].description}</div>`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode)) {
if (tech.tech[i].allowed()) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
@@ -457,7 +456,6 @@ const build = {
document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
//add tooltips
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (document.getElementById(`tech-${i}`)) {
@@ -470,9 +468,7 @@ const build = {
simulation.startGame(true); //starts game, but pauses it
build.isExperimentSelection = true;
simulation.paused = true;
m.setField(0)
b.inventory = []; //removes guns and ammo
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].count = 0;
@@ -481,7 +477,6 @@ const build = {
}
b.activeGun = null;
simulation.makeGunHUD();
tech.setupAllTech();
build.populateGrid();
document.getElementById("field-0").classList.add("build-field-selected");
@@ -490,14 +485,12 @@ const build = {
shareURL(isCustom = false) {
let url = "https://landgreen.github.io/sidescroller/index.html?"
let count = 0;
for (let i = 0; i < b.inventory.length; i++) {
if (b.guns[b.inventory[i]].have) {
url += `&gun${count}=${encodeURIComponent(b.guns[b.inventory[i]].name.trim())}`
count++
}
}
count = 0;
for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < tech.tech[i].count; j++) {
@@ -516,7 +509,6 @@ const build = {
}
console.log('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
console.log(url)
navigator.clipboard.writeText(url).then(function() {
/* clipboard successfully set */
if (isCustom) {

View File

@@ -15,13 +15,15 @@ const level = {
// level.difficultyIncrease(30)
// simulation.isHorizontalFlipped = true
// m.setField("wormhole")
// b.giveGuns("shotgun")
// tech.isShotgunRecoil = true
// tech.isShotgunReversed = true
// tech.giveTech("supertemporal")
// tech.giveTech("free-electron laser")
// b.giveGuns("drones")
// tech.giveTech("torque bursts")
// b.giveGuns("wave beam")
// tech.giveTech("phonon")
// tech.giveTech("bound state")
// tech.giveTech("bound state")
// tech.giveTech("bound state")
// tech.giveTech("isotropic radiator")
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
// tech.giveTech("decoherence")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
level.intro(); //starting level
@@ -2252,14 +2254,14 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.starter(1900, -500, 200) //big boy
// spawn.pulseShooter(1900, -500)
spawn.shieldingBoss(1900, -500)
// spawn.pulsarBoss(1900, -500)
// spawn.shieldingBoss(1900, -500)
// spawn.grenadierBoss(1900, -500)
// spawn.shieldingBoss(1900, -500)
// spawn.historyBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.hopper(1600, -500)
// spawn.focuser(1600, -500)
// spawn.laserTargetingBoss(1700, -120)
// spawn.bomberBoss(1400, -500)
// spawn.hopBoss(1800, -120)
@@ -2267,7 +2269,7 @@ const level = {
// spawn.orbitalBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.shieldingBoss(1600, -500)
// spawn.laser(1200, -500)
spawn.grenadier(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "grenadier")
@@ -2621,7 +2623,7 @@ const level = {
// localSettings.levelsClearedLastGame = 20
if (level.levelsCleared === 0) {
powerUps.spawn(2500, -50, "research", false);
// powerUps.spawn(2500, -50, "research", false);
powerUps.spawn(1900, -50, "heal", false);
powerUps.spawn(2050, -50, "heal", false);
if (localSettings.levelsClearedLastGame < 6) {

View File

@@ -1830,7 +1830,7 @@ const m = {
m.energy -= 0.04;
b.iceIX(1)
} else if (tech.isDroneRadioactive) {
m.energy -= 1.5; //almost 5x drain of normal drones
m.energy -= 0.9;
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25)
} else {
m.energy -= 0.45 * tech.droneEnergyReduction;

View File

@@ -262,12 +262,14 @@ const powerUps = {
}
}
},
currentRerollCount: 0,
use(type) { //runs when you actually research a list of selections, type can be field, gun, or tech
if (tech.isJunkResearch) {
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.addJunkTechToPool(tech.junkResearchNumber)
} else {
powerUps.research.changeRerolls(-1)
}
powerUps.research.currentRerollCount++
// simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
// <br>${powerUps.research.count}`)
if (tech.isBanish && type === 'tech') { // banish researched tech
@@ -447,8 +449,8 @@ const powerUps = {
powerUps.field.choiceLog.push(choice2)
powerUps.field.choiceLog.push(choice3)
if (tech.isJunkResearch) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(4 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
@@ -461,8 +463,6 @@ const powerUps = {
// text += `<div style = 'color:#fff'>${simulation.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {
powerUps.giveRandomAmmo()
}
}
},
@@ -566,7 +566,7 @@ const powerUps = {
powerUps.tech.choiceLog.push(choice3)
// if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
if (tech.isJunkResearch) {
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
@@ -579,19 +579,16 @@ const powerUps = {
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {
if (tech.isBanish) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
// simulation.makeTextLog(`No <strong class='color-m'>tech</strong> left<br>erased <strong class='color-m'>tech</strong> have been recovered`)
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`)
// powerUps.spawn(m.pos.x, m.pos.y, "tech");
powerUps.endDraft("tech");
} else {
powerUps.giveRandomAmmo()
} else if (tech.isBanish) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
// simulation.makeTextLog(`No <strong class='color-m'>tech</strong> left<br>erased <strong class='color-m'>tech</strong> have been recovered`)
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`)
// powerUps.spawn(m.pos.x, m.pos.y, "tech");
powerUps.endDraft("tech");
}
}
}
},
@@ -658,7 +655,7 @@ const powerUps = {
powerUps.gun.choiceLog.push(choice3)
// if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
if (tech.isJunkResearch) {
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;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
@@ -673,12 +670,11 @@ const powerUps = {
if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {
powerUps.giveRandomAmmo()
}
}
},
onPickUp(who) {
powerUps.research.currentRerollCount = 0
if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
if (tech.isMassEnergy) m.energy += 2;
if (tech.isMineDrop) {
@@ -700,15 +696,15 @@ const powerUps = {
}
}
},
giveRandomAmmo() {
const ammoTarget = Math.floor(Math.random() * (b.guns.length));
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6);
if (ammo !== Infinity) {
b.guns[ammoTarget].ammo += ammo;
simulation.updateGunHUD();
simulation.makeTextLog(`${b.guns[ammoTarget].name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammo}`);
}
},
// giveRandomAmmo() {
// const ammoTarget = Math.floor(Math.random() * (b.guns.length));
// const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6);
// if (ammo !== Infinity) {
// b.guns[ammoTarget].ammo += ammo;
// simulation.updateGunHUD();
// simulation.makeTextLog(`${b.guns[ammoTarget].name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammo}`);
// }
// },
spawnRandomPowerUp(x, y) { //mostly used after mob dies, doesn't always return a power up
if ((Math.random() * Math.random() - 0.3 > Math.sqrt(m.health) && !tech.isEnergyHealth) || Math.random() < 0.04) { //spawn heal chance is higher at low health
powerUps.spawn(x, y, "heal");

View File

@@ -332,14 +332,14 @@ const simulation = {
}
},
nextGun() {
if (b.inventory.length > 0 && !tech.isGunCycle) {
if (b.inventory.length > 1 && !tech.isGunCycle) {
b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
simulation.switchGun();
}
},
previousGun() {
if (b.inventory.length > 0 && !tech.isGunCycle) {
if (b.inventory.length > 1 && !tech.isGunCycle) {
b.inventoryGun--;
if (b.inventoryGun < 0) b.inventoryGun = b.inventory.length - 1;
simulation.switchGun();

View File

@@ -306,16 +306,16 @@ const spawn = {
function loop() {
if (!simulation.paused) {
count++
if (count < 600) {
if (count < 660) {
if (count === 1) simulation.makeTextLog(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
if (!(count % 60)) simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${(count/60- Math.random()).toFixed(3)}`);
} else if (count === 600) {
if (!(count % 60)) simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${((count/60- Math.random())*0.1 ).toFixed(3)}`);
} else if (count === 660) {
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> 1 <em>//analysis complete</em>`);
} else if (count === 720) {
} else if (count === 780) {
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}`)
} else if (count === 900) {
} else if (count === 1020) {
simulation.makeTextLog(`World.clear(engine.world) <em>//simulation successful</em>`);
} else if (count === 1140) {
} else if (count === 1260) {
// tech.isImmortal = false;
// m.death()
// m.alive = false;
@@ -1709,7 +1709,7 @@ const spawn = {
if (targetDist < r + 16) {
targetDist = r + 10;
//charge at player
const forceMag = this.accelMag * 30 * this.mass;
const forceMag = this.accelMag * 40 * this.mass;
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
this.force.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(angle);
@@ -1906,7 +1906,7 @@ const spawn = {
me.fireCycle = 0
me.fireTarget = { x: 0, y: 0 }
me.pulseRadius = Math.min(500, 230 + simulation.difficulty * 3)
me.fireDelay = Math.max(60, 140 - simulation.difficulty * 2)
me.fireDelay = Math.max(60, 150 - simulation.difficulty * 2)
me.isFiring = false
Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
@@ -2999,20 +2999,21 @@ const spawn = {
};
},
grenadierBoss(x, y, radius = 95) {
mobs.spawn(x, y, 6, radius, "rgb(255,50,160)");
mobs.spawn(x, y, 6, radius, "rgb(215,80,190)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.00008 * simulation.accelScale;
me.accelMag = 0.0001 * simulation.accelScale;
me.fireFreq = Math.floor(360 * simulation.CDScale)
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.02;
me.frictionAir = 0.035;
me.memory = 420;
me.repulsionRange = 1200000; //squared
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 25, 1);
spawn.spawnOrbitals(me, radius + 75, 1);
Matter.Body.setDensity(me, 0.002 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 50, 1);
spawn.spawnOrbitals(me, radius + 125, 1);
spawn.spawnOrbitals(me, radius + 200, 1);
Matter.Body.setDensity(me, 0.004 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() { //helps collisions functions work better after vertex have been changed
for (let i = 0; i < 6; i++) {
spawn.grenade(this.position.x, this.position.y, 2, 4, 75 * simulation.CDScale);
@@ -3050,110 +3051,8 @@ const spawn = {
this.attraction();
};
},
// grenadierBoss(x, y, radius = 110) {
// mobs.spawn(x, y, 3, radius, "rgb(255,50,160)"); //rgb(255,100,200)
// let me = mob[mob.length - 1];
// me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
// me.isVerticesChange = true
// me.isBoss = true;
// me.frictionStatic = 0;
// me.friction = 0;
// me.memory = 180 //140;
// me.fireFreq = 0.02;
// me.noseLength = 0;
// me.fireAngle = 0;
// me.accelMag = 0.005 * simulation.accelScale;
// me.frictionAir = 0.05;
// me.lookTorque = 0.000006 * (Math.random() > 0.5 ? -1 : 1);
// me.fireDir = {
// x: 0,
// y: 0
// };
// Matter.Body.setDensity(me, 0.008 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// setTimeout(() => {
// spawn.spawnOrbitals(me, radius + 25, 1);
// spawn.spawnOrbitals(me, radius + 75, 1);
// }, 100); //have to wait a sec so the tether constraint doesn't attach to an orbital
// me.onDeath = function() { //helps collisions functions work better after vertex have been changed
// for (let i = 0; i < 6; i++) {
// spawn.grenade(this.position.x, this.position.y, 2, 4, 75 * simulation.CDScale);
// const who = mob[mob.length - 1]
// who.collisionFilter.category = 0
// who.collisionFilter.mask = 0
// const speed = 4 * simulation.accelScale;
// const angle = 2 * Math.PI * i / 6
// Matter.Body.setVelocity(who, {
// x: this.velocity.x + speed * Math.cos(angle),
// y: this.velocity.y + speed * Math.sin(angle)
// });
// }
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// }
// // me.onDamage = function() {
// // spawn.grenade(this.position.x, this.position.y, 2, 4, 120 * simulation.CDScale);
// // const who = mob[mob.length - 1]
// // who.collisionFilter.category = 0
// // who.collisionFilter.mask = 0
// // const velocity = Vector.mult(Vector.normalise(Vector.sub(player.position, who.position)), 3)
// // Matter.Body.setVelocity(who, {
// // x: this.velocity.x + velocity.x,
// // y: this.velocity.y + velocity.y
// // });
// // };
// me.do = function() {
// this.seePlayerByLookingAt();
// this.checkStatus();
// if (!m.isBodiesAsleep) {
// const setNoseShape = () => {
// const mag = this.radius + this.radius * this.noseLength;
// this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag;
// this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag;
// };
// //throw a mob/bullet at player
// if (this.seePlayer.recall) {
// //set direction to turn to fire
// if (!(simulation.cycle % this.seePlayerFreq)) {
// this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
// // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
// }
// //rotate towards fireAngle
// const angle = this.angle + Math.PI / 2;
// // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
// //rotate towards fireAngle
// const dot = Vector.dot({
// x: Math.cos(angle),
// y: Math.sin(angle)
// }, this.fireDir)
// const threshold = 0.03;
// if (dot > threshold) {
// this.torque += 0.000004 * this.inertia;
// } else if (dot < -threshold) {
// this.torque -= 0.000004 * this.inertia;
// } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) {
// //fire
// spawn.grenade(this.vertices[1].x, this.vertices[1].y);
// const v = 7 * simulation.accelScale;
// Matter.Body.setVelocity(mob[mob.length - 1], {
// x: this.velocity.x + this.fireDir.x * v + Math.random(),
// y: this.velocity.y + this.fireDir.y * v + Math.random()
// });
// this.noseLength = 0;
// // recoil
// this.force.x -= 0.002 * this.fireDir.x * this.mass;
// this.force.y -= 0.002 * this.fireDir.y * this.mass;
// }
// if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
// setNoseShape();
// } else if (this.noseLength > 0.1) {
// this.noseLength -= this.fireFreq / 2;
// setNoseShape();
// }
// }
// };
// },
grenadier(x, y, radius = 35 + Math.ceil(Math.random() * 20)) {
mobs.spawn(x, y, 3, radius, "rgba(255,50,160,1)"); //rgb(255,100,200)
mobs.spawn(x, y, 3, radius, "rgb(215,80,190)"); //rgb(255,100,200)
let me = mob[mob.length - 1];
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
@@ -3231,7 +3130,7 @@ const spawn = {
};
},
grenade(x, y, radius = 2, sides = 4, lifeSpan = 90 + Math.ceil(60 / simulation.accelScale)) {
mobs.spawn(x, y, sides, radius, "rgb(255,0,0)");
mobs.spawn(x, y, sides, radius, "rgb(215,0,190)"); //rgb(215,80,190)
let me = mob[mob.length - 1];
me.stroke = "transparent";
me.onHit = function() {
@@ -3258,7 +3157,7 @@ const spawn = {
x: this.position.x,
y: this.position.y,
radius: this.pulseRadius,
color: "rgba(255,0,100,0.6)",
color: "rgba(255,0,220,0.3)",
time: simulation.drawTime
});
};
@@ -3269,7 +3168,7 @@ const spawn = {
this.timeLimit();
ctx.beginPath(); //draw explosion outline
ctx.arc(this.position.x, this.position.y, this.pulseRadius * (1.01 - this.timeLeft / this.lifeSpan), 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
ctx.fillStyle = "rgba(255,0,100,0.06)";
ctx.fillStyle = "rgba(255,0,220,0.05)";
ctx.fill();
};
},

View File

@@ -647,7 +647,7 @@
},
{
name: "microstates",
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> active <strong>projectiles</strong>",
maxCount: 1,
count: 0,
frequency: 2,
@@ -665,7 +665,7 @@
},
{
name: "anti-shear topology",
description: "some <strong>bullets</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drones, spores, missiles, foam, wave, neutron</em>",
description: "some <strong>projectiles</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drones, spores, missiles, foam, wave, neutron</em>",
// isGunTech: true,
maxCount: 3,
count: 0,
@@ -2802,7 +2802,7 @@
},
{
name: "pseudoscience",
description: "<strong>rerolling</strong> choices no longer costs <strong class='color-r'>research</strong><br>instead it adds <strong>0-4</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool",
description: "<span style = 'font-size:94%;'>when <strong>selecting</strong> a power up, <strong class='color-r'>research</strong> <strong>3</strong> times</span><br>for <strong>free</strong>, but add <strong>0-3</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3883,28 +3883,9 @@
tech.bulletSize = 1;
}
},
{
name: "bound state",
description: "instead of dissipating normally<br>wave packets <strong>reflect</strong> backwards <strong>2</strong> times",
isGunTech: true,
maxCount: 3,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
},
requires: "wave beam",
effect() {
tech.waveReflections += 2
},
remove() {
tech.waveReflections = 1
}
},
{
name: "phase velocity",
description: "wave beam <strong>propagates</strong> faster through solids<br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
description: "wave beam <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -3913,7 +3894,7 @@
allowed() {
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
},
requires: "wave beam",
requires: "wave beam, not phonon",
effect() {
tech.isPhaseVelocity = true;
},
@@ -3922,27 +3903,22 @@
}
},
{
name: "packet length",
description: "wave packet <strong>length</strong> and <strong>duration</strong><br>is increased by <strong>50%</strong>", // description: "holding fire allows the <strong>wave beam</strong> to emits a second <strong>packet</strong><br>at zero ammo cost",
name: "bound state",
description: "wave packets <strong>reflect</strong> backwards <strong>2</strong> times<br><strong>range</strong> is reduced by <strong>25%</strong>",
isGunTech: true,
maxCount: 3,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("wave beam") && !tech.isLongitudinal
return tech.haveGunCheck("wave beam")
},
requires: "wave beam",
effect() {
const scale = 1.5 - 0.025 * this.count
tech.wavePacketLength *= scale
tech.wavePacketFrequency /= scale
tech.waveLengthRange *= Math.sqrt(scale)
tech.waveReflections += 2
},
remove() {
tech.wavePacketFrequency = 0.088 //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
tech.wavePacketLength = 35 //32.7 //31.3 //28.8 //36 //how many wave packets are released // double this to emit 2 packets
tech.waveLengthRange = 130;
tech.waveReflections = 1
}
},
{
@@ -3968,7 +3944,7 @@
},
{
name: "propagation",
description: "wave packet propagation <strong>speed</strong> is <strong>25%</strong> slower<br>wave <strong class='color-d'>damage</strong> is increased by <strong>50%</strong>",
description: "wave packet propagation <strong>speed</strong> is <strong>20%</strong> slower<br>wave <strong class='color-d'>damage</strong> is increased by <strong>50%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -3979,26 +3955,26 @@
},
requires: "wave beam",
effect() {
tech.waveBeamSpeed *= 0.75;
tech.waveBeamDamage += 1.3 * 0.5
tech.waveBeamSpeed *= 0.8;
tech.waveBeamDamage += 1.5 * 0.5 //this sets base wave beam damage, not used by arcs or circles
},
remove() {
tech.waveBeamSpeed = 10;
tech.waveBeamDamage = 1.5 //this sets base wave beam damage
tech.waveBeamDamage = 1.5 //this sets base wave beam damage, not used by arcs or circles
}
},
{
name: "pressure wave", //longitudinal //gravitational wave?
description: "wave beam emits low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through solids",
name: "phonon", //longitudinal //gravitational wave?
description: "wave beam emits low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through <strong>solids</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 4,
frequencyDefault: 4,
allowed() {
return tech.haveGunCheck("wave beam") && !tech.isPhaseVelocity && tech.waveLengthRange === 130 && tech.waveReflections === 1
return tech.haveGunCheck("wave beam") && !tech.isPhaseVelocity
},
requires: "wave beam, not phase velocity, packet length, bound state",
requires: "wave beam, not phase velocity ",
effect() {
tech.isLongitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -4026,6 +4002,37 @@
tech.isLongitudinal = false;
}
},
{
name: "isotropic radiator",
description: "<strong>wave beam</strong> expands in <strong>all</strong> directions<br><span style = 'font-size:90%;'><strong>range</strong> reduced <strong>40%</strong> and <strong class='color-d'>damage</strong> increased <strong>50%</strong></span>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 4,
frequencyDefault: 4,
allowed() {
return tech.isLongitudinal
},
requires: "phonon",
effect() {
tech.is360Longitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "wave beam") {
b.guns[i].chooseFireMethod()
break
}
}
},
remove() {
tech.is360Longitudinal = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "wave beam") {
b.guns[i].chooseFireMethod()
break
}
}
}
},
{
name: "cruise missile",
description: "<strong>missiles</strong> travel <strong>63%</strong> slower,<br>but have a <strong>50%</strong> larger <strong class='color-e'>explosive</strong> payload",
@@ -4432,24 +4439,42 @@
}
},
{
name: "irradiated drones",
description: "<strong class='color-p'>irradiate</strong> the space around your <strong>drones</strong><br>reduce <strong class='color-g'>ammo</strong>/<strong class='color-f'>efficiency</strong> by <strong>80%</strong>",
//<br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>
name: "torque bursts",
description: "<strong>drones</strong> rapidly <strong>rush</strong> towards their target<br>increase <strong>drone</strong> collision <strong class='color-d'>damage</strong> by <strong>33%</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.droneCycleReduction === 1 && !tech.isIncendiary && (tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)))
return tech.haveGunCheck("drones") && !tech.isDroneRadioactive
},
requires: "drone gun",
effect() {
tech.isDroneTeleport = true
},
remove() {
tech.isDroneTeleport = false
}
},
{
name: "irradiated drones",
description: "<strong class='color-p'>irradiate</strong> the space around your <strong>drones</strong><br>reduce <strong class='color-g'>ammo</strong>/<strong class='color-f'>efficiency</strong> by <strong>75%</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.droneCycleReduction === 1 && !tech.isIncendiary && !tech.isDroneTeleport && (tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)))
},
requires: "drone gun, not reduced tolerances or incendiary",
effect() {
tech.isDroneRadioactive = true
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "drones") {
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.2
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.2)
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.25
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.25)
}
}
},
@@ -4459,7 +4484,7 @@
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "drones") {
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
b.guns[i].ammo = b.guns[i].ammo * 5
b.guns[i].ammo = b.guns[i].ammo * 4
}
}
}
@@ -4583,7 +4608,7 @@
},
{
name: "electrostatic induction",
description: "<strong>foam</strong> bullets are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
description: "<strong>foam</strong> bubbles are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5173,7 +5198,7 @@
m.energy = 0.01;
b.randomBot()
b.randomBot()
// b.randomBot()
b.randomBot()
},
remove() {}
},
@@ -5726,7 +5751,7 @@
},
{
name: "traversable geodesics",
description: "your <strong>bullets</strong> can traverse <strong class='color-worm'>wormholes</strong><br>spawn 2 <strong class='color-g'>guns</strong> and <strong class='color-g'>ammo</strong>",
description: "your <strong>projectiles</strong> can traverse <strong class='color-worm'>wormholes</strong><br>spawn 2 <strong class='color-g'>guns</strong> and <strong class='color-g'>ammo</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -6299,13 +6324,16 @@
if (
tech.tech[i].count < tech.tech[i].maxCount &&
tech.tech[i].allowed() &&
!tech.tech[i].isJunk
!tech.tech[i].isJunk &&
!tech.tech.isLore
) {
for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
options.push(i);
}
}
const index = options[Math.floor(Math.random() * options.length)]
tech.tech[index].frequency = 100
if (options.length) {
const index = options[Math.floor(Math.random() * options.length)]
tech.tech[index].frequency = 100
}
},
remove() {}
},
@@ -7445,10 +7473,8 @@
isMobBlockFling: null,
blockingIce: null,
isPhaseVelocity: null,
wavePacketLength: null,
waveBeamSpeed: null,
wavePacketAmplitude: null,
waveLengthRange: null,
isCollisionRealitySwitch: null,
iceIXOnDeath: null,
wimpCount: null,
@@ -7473,10 +7499,12 @@
laserColor: null,
laserColorAlpha: null,
isLongitudinal: null,
is360Longitudinal: null,
isShotgunReversed: null,
wormDuplicate: null,
isCloakingDamage: null,
harmonicEnergy: null,
isFieldHarmReduction: null,
isFastTime: null
isFastTime: null,
isDroneTeleport: null
}