diff --git a/js/bullet.js b/js/bullet.js
index 8d04cbc..8d5bd5d 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1926,7 +1926,7 @@ const b = {
if (tech.isMissileBig) {
size *= 1.55
if (tech.isMissileBiggest) {
- size *= 2
+ size *= 1.55
}
}
@@ -2015,7 +2015,7 @@ const b = {
ctx.fill();
},
});
- const thrust = 0.0066 * bullet[me].mass * (tech.isMissileBig ? (tech.isMissileBiggest ? 0.15 : 0.7) : 1);
+ const thrust = 0.0066 * bullet[me].mass * (tech.isMissileBig ? (tech.isMissileBiggest ? 0.3 : 0.7) : 1);
Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle)
@@ -5463,16 +5463,40 @@ const b = {
player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps
}
+ const spray = (num) => {
+ const side = 22
+ for (let i = 0; i < num; i++) {
+ const me = bullet.length;
+ const dir = m.angle + (Math.random() - 0.5) * spread
+ bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
+ Composite.add(engine.world, bullet[me]); //add bullet to world
+ const SPEED = 52 + Math.random() * 8
+ Matter.Body.setVelocity(bullet[me], {
+ x: SPEED * Math.cos(dir),
+ y: SPEED * Math.sin(dir)
+ });
+ bullet[me].endCycle = simulation.cycle + 40 * tech.isBulletsLastLonger
+ bullet[me].minDmgSpeed = 15
+ if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0015)
+ // bullet[me].restitution = 0.4
+ bullet[me].frictionAir = 0.034;
+ bullet[me].do = function() {
+ const scale = 1 - 0.034 / tech.isBulletsLastLonger
+ Matter.Body.scale(this, scale, scale);
+ };
+ }
+ }
+
b.muzzleFlash(35);
if (tech.isRivets) {
const me = bullet.length;
// const dir = m.angle + 0.02 * (Math.random() - 0.5)
- bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60 * tech.bulletSize, 27 * tech.bulletSize, b.fireAttributes(m.angle));
+ bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 56 * tech.bulletSize, 25 * tech.bulletSize, b.fireAttributes(m.angle));
- Matter.Body.setDensity(bullet[me], 0.007 * (tech.isShotgunReversed ? 1.6 : 1));
+ Matter.Body.setDensity(bullet[me], 0.005 * (tech.isShotgunReversed ? 1.5 : 1));
Composite.add(engine.world, bullet[me]); //add bullet to world
- const SPEED = (input.down ? 50 : 37)
+ const SPEED = (input.down ? 50 : 43)
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
@@ -5480,7 +5504,7 @@ const b = {
if (tech.isIncendiary) {
bullet[me].endCycle = simulation.cycle + 60
bullet[me].onEnd = function() {
- b.explosion(this.position, 300 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
+ b.explosion(this.position, 360 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -5490,10 +5514,10 @@ const b = {
}
bullet[me].minDmgSpeed = 7
// bullet[me].restitution = 0.4
- bullet[me].frictionAir = 0.006;
+ bullet[me].frictionAir = 0.004;
bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75)
bullet[me].do = function() {
- this.force.y += this.mass * 0.0022
+ this.force.y += this.mass * 0.002
if (this.speed > 6) { //rotates bullet to face current velocity?
const facing = { x: Math.cos(this.angle), y: Math.sin(this.angle) }
if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) {
@@ -5512,9 +5536,11 @@ const b = {
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn
}
+ if (tech.isIncendiary) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
if (tech.isCritKill) b.crit(who, this)
}
}
+ spray(12); //fires normal shotgun bullets
} else if (tech.isIncendiary) {
spread *= 0.15
const END = Math.floor(input.down ? 10 : 7);
@@ -5534,7 +5560,7 @@ const b = {
y: speed * Math.sin(dirOff)
});
bullet[me].onEnd = function() {
- b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.5 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
+ b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.4 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
}
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -5546,7 +5572,7 @@ const b = {
}
} else if (tech.isNailShot) {
spread *= 0.65
- const dmg = 2 * (tech.isShotgunReversed ? 1.6 : 1)
+ const dmg = 2 * (tech.isShotgunReversed ? 1.5 : 1)
if (input.down) {
for (let i = 0; i < 17; i++) {
speed = 38 + 15 * Math.random()
@@ -5576,47 +5602,49 @@ const b = {
}
} else if (tech.isSporeFlea) {
const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) }
- const number = 4 * (tech.isShotgunReversed ? 1.6 : 1)
+ const number = 2 * (tech.isShotgunReversed ? 1.5 : 1)
for (let i = 0; i < number; i++) {
const angle = m.angle + 0.2 * (Math.random() - 0.5)
- const speed = (input.down ? 33 : 20) * (1 + 0.1 * Math.random())
+ const speed = (input.down ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random()))
b.flea(where, { x: speed * Math.cos(angle), y: speed * Math.sin(angle) })
bullet[bullet.length - 1].setDamage()
}
+ spray(10); //fires normal shotgun bullets
} else if (tech.isSporeWorm) {
const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) }
const spread = (input.down ? 0.02 : 0.07)
- const number = 4 * (tech.isShotgunReversed ? 1.6 : 1)
+ const number = 3 * (tech.isShotgunReversed ? 1.5 : 1)
let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) {
b.worm(where)
- const SPEED = (8 + 10 * input.down) * (1 + 0.15 * Math.random())
+ const SPEED = (30 + 10 * input.down) * (1 + 0.2 * Math.random())
Matter.Body.setVelocity(bullet[bullet.length - 1], {
x: player.velocity.x * 0.5 + SPEED * Math.cos(angle),
y: player.velocity.y * 0.5 + SPEED * Math.sin(angle)
});
angle += spread
}
+ spray(7); //fires normal shotgun bullets
} else if (tech.isIceShot) {
const spread = (input.down ? 0.7 : 1.2)
- for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) {
- // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
- b.iceIX(25 + 20 * Math.random(), m.angle + spread * (Math.random() - 0.5))
+ for (let i = 0, len = 10 * (tech.isShotgunReversed ? 1.5 : 1); i < len; i++) {
+ b.iceIX(23 + 10 * Math.random(), m.angle + spread * (Math.random() - 0.5))
}
+ spray(10); //fires normal shotgun bullets
} else if (tech.isFoamShot) {
const spread = (input.down ? 0.15 : 0.4)
const where = {
x: m.pos.x + 25 * Math.cos(m.angle),
y: m.pos.y + 25 * Math.sin(m.angle)
}
- const number = 16 * (tech.isShotgunReversed ? 1.6 : 1)
+ const number = 16 * (tech.isShotgunReversed ? 1.5 : 1)
for (let i = 0; i < number; i++) {
- const SPEED = 11 + 4 * Math.random();
+ const SPEED = 13 + 4 * Math.random();
const angle = m.angle + spread * (Math.random() - 0.5)
b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 8 + 7 * Math.random())
}
} else if (tech.isNeedles) {
- const number = 9 * (tech.isShotgunReversed ? 1.6 : 1)
+ const number = 9 * (tech.isShotgunReversed ? 1.5 : 1)
const spread = (input.down ? 0.03 : 0.05)
let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) {
@@ -5624,27 +5652,7 @@ const b = {
angle += spread
}
} else {
- const side = 22
- for (let i = 0; i < 17; i++) {
- const me = bullet.length;
- const dir = m.angle + (Math.random() - 0.5) * spread
- bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
- Composite.add(engine.world, bullet[me]); //add bullet to world
- const SPEED = 52 + Math.random() * 8
- Matter.Body.setVelocity(bullet[me], {
- x: SPEED * Math.cos(dir),
- y: SPEED * Math.sin(dir)
- });
- bullet[me].endCycle = simulation.cycle + 40 * tech.isBulletsLastLonger
- bullet[me].minDmgSpeed = 15
- if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0016)
- // bullet[me].restitution = 0.4
- bullet[me].frictionAir = 0.034;
- bullet[me].do = function() {
- const scale = 1 - 0.034 / tech.isBulletsLastLonger
- Matter.Body.scale(this, scale, scale);
- };
- }
+ spray(16); //fires normal shotgun bullets
}
}
}, {
diff --git a/js/engine.js b/js/engine.js
index 399ce79..3a0e8c4 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -208,7 +208,6 @@ function collisionChecks(event) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) {
if (tech.blockDmg) { //electricity
- // console.log("hi")
Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y });
if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) {
mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12
diff --git a/js/index.js b/js/index.js
index 52c9f9e..e00e897 100644
--- a/js/index.js
+++ b/js/index.js
@@ -431,7 +431,7 @@ ${simulation.isCheating ? "
lore disabled": ""}
//update tech text //disable not allowed tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
const techID = document.getElementById("tech-" + i)
- if (!tech.tech[i].isExperimentHide && !tech.tech[i].isNonRefundable && (!tech.tech[i].isJunk || tech.tech[i].isExperimentalMode || localSettings.isJunkExperiment)) {
+ if (!tech.tech[i].isExperimentHide && !tech.tech[i].isNonRefundable && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) {
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
//
@@ -460,8 +460,6 @@ ${simulation.isCheating ? "
lore disabled": ""}
`
} else if (tech.tech[i].isJunk) {
techID.innerHTML = ` ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}`
- } else if (tech.tech[i].isExperimentalMode) {
- techID.innerHTML = `${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}`
} else {
techID.innerHTML = ` ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}`
}
@@ -531,11 +529,9 @@ ${simulation.isCheating ? "
lore disabled": ""}
text += ` ${build.nameLink(b.guns[i].name)}
${b.guns[i].description}
`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
- if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //&& (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode)) {
- if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
- if (tech.tech[i].isExperimentalMode) {
- text += `${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
`
- } else if (tech.tech[i].isJunk) {
+ if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //&& (!tech.tech[i].isNonRefundable)) {
+ if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
+ if (tech.tech[i].isJunk) {
text += ` ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
`
} else {
text += ` ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
`
@@ -668,13 +664,7 @@ ${simulation.isCheating ? "
lore disabled": ""}
build.hasExperimentalMode = false
if (!simulation.isCheating) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
- if (tech.tech[i].count > 0) {
- if (tech.tech[i].isExperimentalMode) {
- build.hasExperimentalMode = true
- } else if (!tech.tech[i].isLore) {
- simulation.isCheating = true;
- }
- }
+ if (tech.tech[i].count > 0 && !tech.tech[i].isLore) simulation.isCheating = true;
}
if (b.inventory.length !== 0 || m.fieldMode !== 0) simulation.isCheating = true;
}
diff --git a/js/level.js b/js/level.js
index 6672ef0..61b4b3f 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,7 +16,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
- // level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
+ // level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
@@ -24,9 +24,11 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.setField("metamaterial cloaking") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
- // 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
+ // b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 1000000
- // tech.giveTech("1st ionization energy")
+ // tech.giveTech("rivet gun")
+ // tech.isFoamShot = true
+ // tech.isIncendiary = true
// for (let i = 0; i < 1; ++i) tech.giveTech("field coupling")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// m.damage(0.1);
@@ -36,10 +38,10 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.starter(1900, -500, 200)
- // spawn.beetleBoss(1900, -400)
- // spawn.shooter(1900, -500)
- // for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
+ // spawn.ghoster(2538, -1950)
+ // for (let i = 0; i < 15; ++i) spawn.shooter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// level.testing();
+ // spawn.blowSuckBoss(1900, -500)
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
@@ -114,7 +116,6 @@ const level = {
spawn.WIMP()
for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
}
- for (let i = 0; i < tech.wimpExperiment; i++) spawn.WIMP()
// if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) {
if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) {
tech.isFlipFlopOn = true
@@ -2809,6 +2810,17 @@ const level = {
spawn.mapRect(5300, -275, 50, 175);
spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175);
+ spawn.mapRect(-950, -3250, 850, 1750);
+ //roof
+ spawn.mapRect(-175, -2975, 300, 1425);
+ spawn.mapRect(75, -2650, 325, 1150);
+ spawn.mapRect(375, -2225, 250, 650);
+ spawn.mapRect(4075, -2125, 700, 800);
+ spawn.mapRect(4450, -2950, 675, 1550);
+ spawn.mapRect(4875, -3625, 725, 2225);
+ spawn.mapRect(5525, -4350, 1725, 2925);
+ spawn.mapRect(7200, -5125, 300, 3900);
+
//???
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
@@ -10926,9 +10938,6 @@ const level = {
simulation.fallHeight = -1000;
simulation.setZoom(1800);
templePlayer.startAnim = -1;
- for (let i = 0; i < tech.wimpCount + tech.wimpExperiment; i++) {
- addWIMP();
- }
templePlayer.drawExit = false;
}
},
diff --git a/js/mob.js b/js/mob.js
index d5148e3..ab66ec0 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -899,7 +899,7 @@ const mobs = {
//accelerate towards the searchTarget
if (!this.seePlayer.recall) {
const newTarget = function(that) {
- if (Math.random() < 0.0005) {
+ if (Math.random() < 0.0007) {
that.searchTarget = player.position; //chance to target player
} else {
//target random body
@@ -1246,18 +1246,6 @@ const mobs = {
}
}
}
- if (tech.removeMaxHealthOnKill) {
- const amount = 0.002
- if (tech.isEnergyHealth) {
- if (m.maxEnergy > amount) {
- tech.healMaxEnergyBonus -= amount
- m.setMaxEnergy();
- }
- } else if (m.maxHealth > amount) {
- tech.extraMaxHealth -= amount //decrease max health
- m.setMaxHealth();
- }
- }
if (tech.cloakDuplication && !this.isBoss) {
tech.cloakDuplication -= 0.02
powerUps.setDupChance(); //needed after adjusting duplication chance
diff --git a/js/player.js b/js/player.js
index 7db4cb1..d81de84 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1571,24 +1571,24 @@ const m = {
case 0: //field emitter
return `gain the effects of all fields`
case 1: //standing wave
- return `deflecting condenses +${Math.ceil(couple)} ice IX`
+ return `deflecting condenses +${couple.toFixed(1)} ice IX`
case 2: //perfect diamagnetism
- return `deflecting condenses +${Math.ceil(couple)} ice IX`
+ return `deflecting condenses +${couple.toFixed(1)} ice IX`
// return `invulnerable +${2*couple} seconds post collision`
case 3: //negative mass
return `+${((1-0.73 ** couple)*100).toFixed(1)}% defense`
case 4: //assembler
- return `generate ${6*couple} energy per second`
+ return `generate ${(6*couple).toFixed(0)} energy per second`
case 5: //plasma
- return `+${15*couple} damage`
+ return `+${(15*couple).toFixed(0)}% damage`
case 6: //time dilation
- return `+${25*couple}% longer stopped time` //movement, jumping, and
+ return `+${(25*couple).toFixed(0)}% longer stopped time` //movement, jumping, and
case 7: //cloaking
- return `+${33*couple}% ambush damage`
+ return `+${(33*couple).toFixed(0)}% ambush damage`
case 8: //pilot wave
- return `+${40*couple}% block collision damage`
+ return `+${(40*couple).toFixed(0)}% block collision damage`
case 9: //wormhole
- return `after eating blocks +${20*couple} energy`
+ return `after eating blocks +${(20*couple).toFixed(0)} energy`
}
},
couplingChange() {
diff --git a/js/powerup.js b/js/powerup.js
index 57e32d9..5552c04 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -333,7 +333,7 @@ const powerUps = {
},
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
- if (tech.isCancelTech && Math.random() < 0.9) {
+ if (tech.isCancelTech && Math.random() < 0.88) {
// powerUps.research.use('tech')
powerUps[type].effect();
return
@@ -414,8 +414,8 @@ const powerUps = {
return 11;
},
endCycle: 0,
- duration: 600,
- damage: 1.5,
+ duration: null, //set by "tech: band gap"
+ damage: null, //set by "tech: band gap"
effect() {
powerUps.boost.endCycle = m.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - m.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
},
@@ -912,7 +912,7 @@ const powerUps = {
}
function removeOption(index) {
- for (let i = options.length; i > -1; i--) {
+ for (let i = options.length - 1; i > -1; i--) {
if (index === options[i]) {
options.splice(i, 1) //remove all copies of that option form the options array (some tech are in the options array multiple times because of frequency)
optionLengthNoDuplicates--
@@ -1272,9 +1272,11 @@ const powerUps = {
}
if (tech.isCouplingPowerUps && Math.random() < 0.17) {
powerUps.spawn(x, y, "coupling");
+ return;
}
- if (tech.isBoostPowerUps && Math.random() < 0.17) {
+ if (tech.isBoostPowerUps && Math.random() < 0.18) {
powerUps.spawn(x, y, "boost");
+ return;
}
// if (Math.random() < 0.01) {
// powerUps.spawn(x, y, "research");
diff --git a/js/simulation.js b/js/simulation.js
index d2427b2..77554cf 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -1458,21 +1458,22 @@ const simulation = {
const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
-
- if (e.button === 2) {
+ console.log(e.button)
+ if (e.button === 1) {
if (level.isProcedural) {
- simulation.outputMapString(`spawn.randomMob(x+${x}, y+${y}, 0);`);
+ simulation.outputMapString(`spawn.randomMob(x+${x}, y+${y}, 0);\n`);
} else {
- simulation.outputMapString(`spawn.randomMob(${x}, ${y}, 0);`);
+ simulation.outputMapString(`spawn.randomMob(${x}, ${y}, 0);\n`);
}
} else if (e.button === 4) {
simulation.outputMapString(`${Math.floor(simulation.constructMouseDownPosition.x)}, ${Math.floor(simulation.constructMouseDownPosition.y)}`);
} else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive
- if (e.button === 1) { //add map
+
+ if (e.button === 0) { //add map
if (level.isProcedural) {
- simulation.outputMapString(`spawn.mapRect(x+${x}, y+${y}, ${dx}, ${dy});`);
+ simulation.outputMapString(`spawn.mapRect(x+${x}, y+${y}, ${dx}, ${dy});\n`);
} else {
- simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`);
+ simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
}
//see map in world
@@ -1484,11 +1485,11 @@ const simulation = {
Composite.add(engine.world, map[len]); //add to world
simulation.draw.setPaths() //update map graphics
- } else if (e.button === 3) { //add body
+ } else if (e.button === 2) { //add body
if (level.isProcedural) {
- simulation.outputMapString(`spawn.bodyRect(x+${x}, y+${y}, ${dx}, ${dy});`);
+ simulation.outputMapString(`spawn.bodyRect(x+${x}, y+${y}, ${dx}, ${dy});\n`);
} else {
- simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`);
+ simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});\n`);
}
//see map in world
@@ -1513,6 +1514,7 @@ const simulation = {
}
});
+ //undo last element added after you press z
document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) {
if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level
diff --git a/js/spawn.js b/js/spawn.js
index 081a24d..4814e70 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -5,8 +5,8 @@ const spawn = {
randomBossList: [
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
- "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss",
- "dragonFlyBoss", "beetleBoss"
+ "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
+ "timeSkipBoss", "dragonFlyBoss", "beetleBoss"
],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -142,7 +142,7 @@ const spawn = {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
- if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
+ if (tech.isDuplicateBoss && Math.random() < tech.duplicationChance()) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
@@ -158,7 +158,7 @@ const spawn = {
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
}
}
- if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
+ if (tech.isDuplicateBoss && Math.random() < tech.duplicationChance()) {
for (let i = 0; i < num; ++i) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
@@ -296,7 +296,7 @@ const spawn = {
me.showHealthBar = false;
me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body
- me.chaseSpeed = 1 + 2 * Math.random()
+ me.chaseSpeed = 1.2 + 2 * Math.random()
me.awake = function() {
//chase player
@@ -4104,8 +4104,8 @@ const spawn = {
if (this.phaseCycle > -1) {
Matter.Body.rotate(this, 0.02)
for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex
- spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 6, 4);
- const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -17)
+ spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 5, 4);
+ const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -15)
Matter.Body.setVelocity(mob[mob.length - 1], {
x: velocity.x,
y: velocity.y
@@ -5013,13 +5013,13 @@ const spawn = {
}, 2000); //add in a delay in case the level gets flipped left right
me.isBoss = true;
- Matter.Body.setDensity(me, 0.01 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.01 + 0.0004 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
me.memory = 240;
- me.fireFreq = 0.025;
+ me.fireFreq = 0.009 + 0.0004 * Math.min(40, simulation.difficulty); //bigger number means more shots per second
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.005 * simulation.accelScale;
@@ -5066,16 +5066,14 @@ const spawn = {
//fire
for (let i = 0, len = 2 + 0.07 * simulation.difficulty; i < len; i++) {
spawn.bullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 25));
- const v = 15;
- Matter.Body.setVelocity(mob[mob.length - 1], {
- x: this.velocity.x + this.fireDir.x * v + 7 * Math.random(),
- y: this.velocity.y + this.fireDir.y * v + 7 * Math.random()
- });
+ const spread = Vector.rotate({
+ x: Math.sqrt(len) + 4,
+ y: 0
+ }, 2 * Math.PI * Math.random())
+ const dir = Vector.add(Vector.mult(this.fireDir, 15), spread)
+ Matter.Body.setVelocity(mob[mob.length - 1], dir);
}
this.noseLength = 0;
- // recoil
- this.force.x -= 0.005 * this.fireDir.x * this.mass;
- this.force.y -= 0.005 * this.fireDir.y * this.mass;
}
if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
setNoseShape();
@@ -5421,6 +5419,163 @@ const spawn = {
}
};
},
+ // blowSuckBoss(x, y, radius = 80) {
+ // mobs.spawn(x, y, 10, radius, "transparent");
+ // let me = mob[mob.length - 1];
+ // me.isBoss = true;
+ // Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ // me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+
+ // me.fireFreq = Math.floor(60 * simulation.CDScale)
+ // me.seePlayerFreq = 15
+ // me.seeAtDistance2 = 300000;
+ // me.accelMag = 0.0003 * simulation.accelScale;
+ // if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
+ // // Matter.Body.setDensity(me, 0.001); //normal is 0.001 //makes effective life much lower
+ // me.stroke = "transparent"; //used for drawGhost
+ // me.alpha = 1; //used in drawGhost
+ // me.canTouchPlayer = false; //used in drawGhost
+ // me.isBadTarget = true;
+ // // me.leaveBody = false;
+ // me.collisionFilter.mask = cat.bullet //| cat.body
+ // me.showHealthBar = false;
+ // me.memory = 480;
+ // me.onDeath = function() {
+ // powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ // };
+ // me.onDamage = function() {};
+ // me.suck = function() {
+ // for (let i = 0; i < mob.length; i++) {
+ // if (mob[i].isBlowSuckBullet) {
+ // const unit = Vector.normalise(Vector.sub(this.position, mob[i].position))
+ // const mag = Vector.mult(unit, 0.0008 * mob[i].mass)
+ // mob[i].force.x += mag.x
+ // mob[i].force.y += mag.y
+ // }
+ // }
+ // }
+ // me.do = function() {
+ // //cap max speed
+ // if (this.speed > 8) {
+ // Matter.Body.setVelocity(this, {
+ // x: this.velocity.x * 0.8,
+ // y: this.velocity.y * 0.8
+ // });
+ // }
+ // this.seePlayerCheckByDistance();
+ // this.checkStatus();
+ // this.attraction();
+ // this.search();
+ // //draw
+ // if (this.distanceToPlayer2() < this.seeAtDistance2) {
+ // if (this.alpha < 1) this.alpha += 0.005 * simulation.CDScale; //near player go solid
+ // } else {
+ // if (this.alpha > 0) this.alpha -= 0.05; ///away from player, hide
+ // }
+ // if (this.alpha > 0) {
+ // if (this.alpha > 0.8 && this.seePlayer.recall) {
+ // this.healthBar();
+ // if (!this.canTouchPlayer) {
+ // this.canTouchPlayer = true;
+ // this.isBadTarget = false;
+ // this.collisionFilter.mask = cat.player | cat.bullet
+ // }
+ // }
+ // //draw body
+ // ctx.beginPath();
+ // const vertices = this.vertices;
+ // ctx.moveTo(vertices[0].x, vertices[0].y);
+ // for (let j = 1, len = vertices.length; j < len; ++j) {
+ // ctx.lineTo(vertices[j].x, vertices[j].y);
+ // }
+ // ctx.lineTo(vertices[0].x, vertices[0].y);
+ // ctx.lineWidth = 1;
+ // ctx.fillStyle = `rgba(255,255,255,${this.alpha * this.alpha})`;
+ // ctx.fill();
+
+
+ // this.suck();
+ // if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) {
+ // this.suckCount = 0;
+ // Matter.Body.setAngularVelocity(this, 0.11)
+ // //fire a bullet from each vertex
+ // for (let i = 0, len = this.vertices.length; i < len; i++) {
+ // spawn.bounceBullet(this.vertices[i].x, this.vertices[i].y, 8)
+ // //give the bullet a rotational velocity as if they were attached to a vertex
+ // const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -16)
+ // const who = mob[mob.length - 1]
+ // who.isBlowSuckBullet = true
+ // Matter.Body.setVelocity(who, {
+ // x: this.velocity.x + velocity.x,
+ // y: this.velocity.y + velocity.y
+ // });
+ // }
+ // }
+
+
+ // } else if (this.canTouchPlayer) {
+ // this.canTouchPlayer = false;
+ // this.isBadTarget = true;
+ // this.collisionFilter.mask = cat.bullet; //can't touch player or walls
+ // }
+ // };
+ // },
+ // blowSuckBoss(x, y, radius = 80, isSpawnBossPowerUp = true) {
+ // mobs.spawn(x, y, 10, radius, "transparent"); //rgb(60,60,85)
+ // let me = mob[mob.length - 1];
+ // me.isBoss = true;
+ // Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ // me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+
+ // me.accelMag = 0.0001 * simulation.accelScale;
+ // me.fireFreq = Math.floor(180 * simulation.CDScale)
+ // me.frictionStatic = 0;
+ // me.friction = 0;
+ // me.frictionAir = 0.005;
+ // me.memory = 420;
+ // me.repulsionRange = 1000000; //squared
+ // // spawn.shield(me, x, y, 1);
+ // // spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
+
+ // me.onDeath = function() {
+ // if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ // };
+ // me.onDamage = function() {};
+ // me.suck = function() {
+ // for (let i = 0; i < mob.length; i++) {
+ // if (mob[i].isBlowSuckBullet) {
+ // const unit = Vector.normalise(Vector.sub(this.position, mob[i].position))
+ // const mag = Vector.mult(unit, 0.0008 * mob[i].mass)
+ // mob[i].force.x += mag.x
+ // mob[i].force.y += mag.y
+ // }
+ // }
+ // }
+ // me.do = function() {
+ // this.seePlayerCheck();
+ // this.checkStatus();
+ // this.attraction();
+ // // this.repulsion();
+ // this.suck();
+
+ // if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) {
+ // this.suckCount = 0;
+ // Matter.Body.setAngularVelocity(this, 0.11)
+ // //fire a bullet from each vertex
+ // for (let i = 0, len = this.vertices.length; i < len; i++) {
+ // spawn.bounceBullet(this.vertices[i].x, this.vertices[i].y, 8)
+ // //give the bullet a rotational velocity as if they were attached to a vertex
+ // const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -16)
+ // const who = mob[mob.length - 1]
+ // who.isBlowSuckBullet = true
+ // Matter.Body.setVelocity(who, {
+ // x: this.velocity.x + velocity.x,
+ // y: this.velocity.y + velocity.y
+ // });
+ // }
+ // }
+ // };
+ // },
grenadierBoss(x, y, radius = 95) {
mobs.spawn(x, y, 6, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1];
@@ -6192,7 +6347,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1];
me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body
- me.damageReduction = 0.021
+ me.damageReduction = 0.024
Matter.Body.setDensity(me, 0.0001); //normal is 0.001
// me.accelMag = 0.0007 * simulation.accelScale;
diff --git a/js/tech.js b/js/tech.js
index b88ea79..29260a1 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -2227,7 +2227,7 @@ const tech = {
name: "1st ionization energy",
link: `1st ionization energy`,
description: `after you collect ${powerUps.orb.heal()}
+10 maximum energy`,
- description: `convert ${powerUps.orb.heal()} into
give +10 maximum energy`,
+ description: `convert current and future ${powerUps.orb.heal()} into
give +10 maximum energy`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -3240,7 +3240,8 @@ const tech = {
},
{
name: "abiogenesis",
- description: `at the start of a level spawn a 2nd boss
use ${powerUps.orb.research(4)}or add 49% JUNK to the tech pool`,
+ description: `use ${powerUps.orb.research(4)} (or 49% JUNK to the tech pool if you can't) to add a 2nd boss to each level`,
+ description: `as a level begins spawn a 2nd boss using ${powerUps.orb.research(4)}
(+49% JUNK to the tech pool if you can't pay)`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -3297,7 +3298,7 @@ const tech = {
{
name: "exciton",
descriptionFunction() {
- return `after mobs die they have a 17% chance to
spawn ${powerUps.orb.boost(1)} that give +${powerUps.boost.damage*100}% damage for ${(powerUps.boost.duration/60).toFixed(0)} seconds`
+ return `after mobs die they have a 18% chance to
spawn ${powerUps.orb.boost(1)} that give +${(powerUps.boost.damage*100).toFixed(0)}% damage for ${(powerUps.boost.duration/60).toFixed(0)} seconds`
},
maxCount: 1,
count: 0,
@@ -3314,6 +3315,29 @@ const tech = {
tech.isBoostPowerUps = false
}
},
+ {
+ name: "band gap",
+ descriptionFunction() {
+ return `${powerUps.orb.boost(1)} give +77% damage
but their duration is reduced by 1 second`
+ },
+ maxCount: 9,
+ count: 1,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.isBoostPowerUps || tech.isBoostReplaceAmmo
+ },
+ requires: "exciton, quasiparticles",
+ effect() {
+ powerUps.boost.duration -= 60
+ powerUps.boost.damage += 0.77
+ },
+ remove() {
+ powerUps.boost.duration = 600
+ powerUps.boost.damage = 1.25
+ }
+ },
+
{
name: "eternalism",
description: "+34% damage
time can't be paused (time can be dilated)",
@@ -3463,7 +3487,7 @@ const tech = {
maxCount: 1,
count: 0,
frequency: 1,
- frequencyDefault: 1,
+ frequencyDefault: 100,
allowed() {
return true
},
@@ -3474,11 +3498,14 @@ const tech = {
simulation.makeTextLog(`m.coupling += ${(this.value).toFixed(1)}`);
m.coupling += this.value
m.couplingChange()
+ this.maxCount = 0
},
remove() {
if (this.count) {
m.coupling -= this.value
m.couplingChange()
+ } else {
+ this.maxCount = 1
}
tech.isCouplingNoHit = false
}
@@ -3506,7 +3533,7 @@ const tech = {
{
name: "options exchange",
link: `options exchange`,
- description: `clicking × for a field, tech, or gun has a 90%
chance to randomize choices and not cancel`,
+ description: `clicking × for a field, tech, or gun has a 88%
chance to randomize choices and not cancel`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3542,7 +3569,7 @@ const tech = {
},
{
name: "futures exchange",
- description: "clicking × to cancel a field, tech, or gun
+4.5% power up duplication chance",
+ description: "clicking × to cancel a field, tech, or gun
gives +4.5% power up duplication chance",
maxCount: 1,
count: 0,
frequency: 1,
@@ -4034,7 +4061,7 @@ const tech = {
frequencyDefault: 2,
allowed() {
// return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines"))
- return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
+ return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles)
},
//
requires: "nail gun, not rotary cannon, rivets, or needles",
@@ -4298,7 +4325,7 @@ const tech = {
{
name: "Noether violation",
link: `Noether violation`,
- description: "+60% shotgun damage
shotgun recoil is reversed",
+ description: "+50% shotgun damage
shotgun recoil is reversed",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4318,7 +4345,7 @@ const tech = {
{
name: "nail-shot",
link: `nail-shot`,
- description: "shotgun fires 17 nails",
+ description: "shotgun drives a long clip of nails",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4338,7 +4365,7 @@ const tech = {
{
name: "foam-shot",
link: `foam-shot`,
- description: "shotgun sprays 15 sticky foam bubbles",
+ description: "shotgun sprays sticky foam bubbles",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4358,7 +4385,7 @@ const tech = {
{
name: "ice-shot",
link: `ice-shot`,
- description: "shotgun grows 15 freezing ice IX crystals",
+ description: "shotgun grows freezing ice IX crystals",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4756,7 +4783,7 @@ const tech = {
},
{
name: "cruise missile",
- description: "+100% missile explosive damage, radius
–50% missiles speed",
+ description: "+100% missile explosive damage, radius
–50% missile speed",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4765,7 +4792,7 @@ const tech = {
allowed() {
return (tech.haveGunCheck("missiles") && tech.missileFireCD === 45) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount
},
- requires: "missiles",
+ requires: "missiles, not launch system",
effect() {
tech.isMissileBig = true
},
@@ -4775,7 +4802,7 @@ const tech = {
},
{
name: "ICBM",
- description: "+100% missile explosive damage, radius
–66% missiles speed",
+ description: "+75% missile explosive damage, radius
–50% missile speed",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4803,7 +4830,7 @@ const tech = {
allowed() {
return tech.haveGunCheck("missiles") && !tech.isMissileBig
},
- requires: "missiles",
+ requires: "missiles, not cruise missile",
ammoBonus: 1.2,
effect() {
tech.missileFireCD = 10
@@ -4976,7 +5003,7 @@ const tech = {
}
},
{
- name: "controlled explosion",
+ name: "shaped charge",
description: `use ${powerUps.orb.research(4)} to dynamically reduce
all explosions to prevent health loss`,
isGunTech: true,
maxCount: 1,
@@ -5959,9 +5986,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple
+ return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple && !tech.isBoostReplaceAmmo
},
- requires: "harpoon, not UHMWPE, induction furnace, grappling hook",
+ requires: "harpoon, not UHMWPE, induction furnace, grappling hook, quasiparticles",
ammoBonus: 9,
effect() {
tech.isRailGun = true;
@@ -6179,6 +6206,35 @@ const tech = {
tech.harpoonDensity = 0.004
}
},
+ {
+ name: "quasiparticles",
+ descriptionFunction() {
+ return `convert current and future ${powerUps.orb.ammo(1)} into ${powerUps.orb.boost(1)} which
give +${(powerUps.boost.damage*100).toFixed(0)}% damage for ${(powerUps.boost.duration/60).toFixed(0)} seconds`
+ },
+ isGunTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("laser") || (tech.haveGunCheck("harpoon") && !tech.isRailGun)
+ },
+ requires: "harpoon, laser, not railgun",
+ effect() {
+ tech.isBoostReplaceAmmo = true
+ for (let i = powerUp.length - 1; i > -1; i--) {
+ if (powerUp[i].name === "ammo") {
+ powerUps.spawn(powerUp[i].position.x + 50 * (Math.random() - 0.5), powerUp[i].position.y + 50 * (Math.random() - 0.5), "boost");
+ Matter.Composite.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1);
+ }
+ }
+
+ },
+ remove() {
+ tech.isBoostReplaceAmmo = false
+ }
+ },
{
name: "optical amplifier",
description: "gain 3 random laser guntech
laser only turns off if you have no energy",
@@ -6195,7 +6251,7 @@ const tech = {
effect() {
let techGiven = 0
for (let j = 0; j < 3; j++) {
- const names = ["lens", "compound lens", "arc length", "infrared diode", "free-electron laser", "dye laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"]
+ const names = ["quasiparticles", "lens", "compound lens", "arc length", "infrared diode", "free-electron laser", "dye 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++) {
@@ -6241,27 +6297,6 @@ const tech = {
tech.isStuckOn = false
}
},
- {
- name: "quasiparticles",
- descriptionFunction() {
- return `replace all ${powerUps.orb.ammo(1)} spawns with ${powerUps.orb.boost(1)} which give
+${powerUps.boost.damage*100}% damage for ${(powerUps.boost.duration/60).toFixed(0)} seconds`
- },
- isGunTech: true,
- maxCount: 1,
- count: 0,
- frequency: 2,
- frequencyDefault: 2,
- allowed() {
- return tech.haveGunCheck("laser")
- },
- requires: "laser, not pulse",
- effect() {
- tech.isBoostReplaceAmmo = true
- },
- remove() {
- tech.isBoostReplaceAmmo = false
- }
- },
{
name: "relativistic momentum",
description: "lasers push mobs and blocks",
@@ -7812,207 +7847,153 @@ const tech = {
//************************************************** experimental
//************************************************** modes
//**************************************************
- {
- name: "-ship-",
- description: "experiment: fly around with no legs
aim with the keyboard",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isNonRefundable: true,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
- },
- requires: "",
- effect() {
- m.shipMode()
- },
- remove() {}
- },
- {
- name: "-quantum leap-",
- description: "experiment: every 20 seconds
become an alternate version of yourself",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- interval: undefined,
- effect() {
- this.interval = setInterval(() => {
- if (!build.isExperimentSelection) {
- m.switchWorlds()
- simulation.trails()
- }
- }, 20000); //every 20 seconds
+ // {
+ // name: "-ship-",
+ // description: "experiment: fly around with no legs
aim with the keyboard",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isNonRefundable: true,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
+ // },
+ // requires: "",
+ // effect() {
+ // m.shipMode()
+ // },
+ // remove() {}
+ // },
+ // {
+ // name: "-quantum leap-",
+ // description: "experiment: every 20 seconds
become an alternate version of yourself",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection
+ // },
+ // requires: "",
+ // interval: undefined,
+ // effect() {
+ // this.interval = setInterval(() => {
+ // if (!build.isExperimentSelection) {
+ // m.switchWorlds()
+ // simulation.trails()
+ // }
+ // }, 20000); //every 20 seconds
+
+ // },
+ // remove() {
+ // if (this.count > 0) clearTimeout(this.interval);
+ // }
+ // },
+ // {
+ // name: "-shields-",
+ // description: "experiment: every 5 seconds
all mobs gain a shield",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection
+ // },
+ // requires: "",
+ // effect() {
+ // this.interval = setInterval(() => {
+ // if (!build.isExperimentSelection) {
+ // for (let i = 0; i < mob.length; i++) {
+ // if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
+ // }
+ // }
+ // }, 5000); //every 5 seconds
+ // },
+ // interval: undefined,
+ // remove() {
+ // if (this.count > 0) clearTimeout(this.interval);
+ // }
+ // },
+ // {
+ // name: "-Fourier analysis-",
+ // description: "experiment: your aiming is random",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection && !m.isShipMode
+ // },
+ // requires: "not ship",
+ // effect() {
+ // m.look = () => {
+ // m.angle = 2 * Math.sin(m.cycle * 0.0133) + Math.sin(m.cycle * 0.013) + 0.5 * Math.sin(m.cycle * 0.031) + 0.33 * Math.sin(m.cycle * 0.03)
+ // const scale = 0.8;
+ // m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
+ // m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
+ // m.transX += (m.transSmoothX - m.transX) * 0.07;
+ // m.transY += (m.transSmoothY - m.transY) * 0.07;
+ // }
+ // },
+ // remove() {
+ // if (this.count > 0) m.look = m.lookDefault()
+ // }
+ // },
+ // {
+ // name: "-panopticon-",
+ // description: "experiment: mobs can always see you",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection
+ // },
+ // requires: "",
+ // effect() {
+ // this.interval = setInterval(() => {
+ // if (!build.isExperimentSelection) {
+ // for (let i = 0; i < mob.length; i++) {
+ // if (!mob[i].shield && mob[i].isDropPowerUp) {
+ // mob[i].locatePlayer()
+ // mob[i].seePlayer.yes = true;
+ // }
+ // }
+ // }
+ // }, 1000); //every 1 seconds
+ // },
+ // interval: undefined,
+ // remove() {
+ // if (this.count > 0) clearTimeout(this.interval);
+ // }
+ // },
+ // {
+ // name: "-decomposers-",
+ // description: "experiment: after they die
mobs leave behind spawns",
+ // maxCount: 1,
+ // count: 0,
+ // frequency: 0,
+ // isBadRandomOption: true,
+ // isExperimentalMode: true,
+ // allowed() {
+ // return build.isExperimentSelection
+ // },
+ // requires: "",
+ // effect() {
+ // tech.deathSpawns = 0.2
+ // },
+ // remove() {
+ // tech.deathSpawns = 0
+ // }
+ // },
+
+
- },
- remove() {
- if (this.count > 0) clearTimeout(this.interval);
- }
- },
- {
- name: "-shields-",
- description: "experiment: every 5 seconds
all mobs gain a shield",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- this.interval = setInterval(() => {
- if (!build.isExperimentSelection) {
- for (let i = 0; i < mob.length; i++) {
- if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
- }
- }
- }, 5000); //every 5 seconds
- },
- interval: undefined,
- remove() {
- if (this.count > 0) clearTimeout(this.interval);
- }
- },
- {
- name: "-Fourier analysis-",
- description: "experiment: your aiming is random",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection && !m.isShipMode
- },
- requires: "not ship",
- effect() {
- m.look = () => {
- m.angle = 2 * Math.sin(m.cycle * 0.0133) + Math.sin(m.cycle * 0.013) + 0.5 * Math.sin(m.cycle * 0.031) + 0.33 * Math.sin(m.cycle * 0.03)
- const scale = 0.8;
- m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
- m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
- m.transX += (m.transSmoothX - m.transX) * 0.07;
- m.transY += (m.transSmoothY - m.transY) * 0.07;
- }
- },
- remove() {
- if (this.count > 0) m.look = m.lookDefault()
- }
- },
- {
- name: "-panopticon-",
- description: "experiment: mobs can always see you",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- this.interval = setInterval(() => {
- if (!build.isExperimentSelection) {
- for (let i = 0; i < mob.length; i++) {
- if (!mob[i].shield && mob[i].isDropPowerUp) {
- mob[i].locatePlayer()
- mob[i].seePlayer.yes = true;
- }
- }
- }
- }, 1000); //every 1 seconds
- },
- interval: undefined,
- remove() {
- if (this.count > 0) clearTimeout(this.interval);
- }
- },
- {
- name: "-decomposers-",
- description: "experiment: after they die
mobs leave behind spawns",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- tech.deathSpawns = 0.2
- },
- remove() {
- tech.deathSpawns = 0
- }
- },
- {
- name: "-WIMP-",
- description: "experiment: harmful particles slowly chase you",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- tech.wimpExperiment = 5
- },
- remove() {
- tech.wimpExperiment = 0
- }
- },
- {
- name: "-symbiosis-",
- description: "experiment: if you kill a mob
lose 0.2 max health",
- maxCount: 1,
- count: 0,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- tech.removeMaxHealthOnKill = 0.002
- },
- remove() {
- tech.removeMaxHealthOnKill = 0
- }
- },
- {
- name: "-parthenocarpy-",
- description: "experiment: spawn about 50% more mobs",
- maxCount: 1,
- count: 1,
- frequency: 0,
- isBadRandomOption: true,
- isExperimentalMode: true,
- allowed() {
- return build.isExperimentSelection
- },
- requires: "",
- effect() {
- tech.isMoreMobs = true
- },
- remove() {
- tech.isMoreMobs = false
- }
- },
//**************************************************
//************************************************** JUNK
//************************************************** tech
@@ -10629,12 +10610,10 @@ const tech = {
isHarpoonPowerUp: null,
harpoonDensity: null,
isAddRemoveMaxHealth: null,
- removeMaxHealthOnKill: null,
isSpawnExitTech: null,
cloakDuplication: null,
extruderRange: null,
isForeverDrones: null,
- isMoreMobs: null,
nailRecoil: null,
baseJumpForce: null,
baseFx: null,
diff --git a/todo.txt b/todo.txt
index bd5c991..88050d7 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,21 +1,41 @@
******************************************************** NEXT PATCH **************************************************
-tech: virtual particles - mobs have a chance to spawn coupling power ups
- old tech virtual particles renamed vacuum fluctuation
+some shotgun ammo tech upgrades will continue to fire some original recipe shotgun bullets
+ rivets, fleas, worms, iceIX
+tech: band gap - boosts give more damage but it lasts for 1 less second
-tech: exciton - mobs have a chance to spawn a boost
- boosts are a power up that increases your damage for 10 seconds
- old tech exciton renamed non-renewables
-laser tech: quasiparticles - replace all ammo with boosts
+WIMPs are 10% faster
+controlled explosion renamed shaped charge
-added +20px to grid elements to prevent text spillover
bug fixes
+ construction mode works better with my buttons
+ to unlock run this and press T to enter testing mode
+ simulation.enableConstructMode() //used to build maps in testing mode
+removed -experiment- tech because it's function was reproduced by "tech - tinker"
*********************************************************** TODO *****************************************************
+complete blowSuckBoss... or don't
+
+tech: laser reflections increase damage
+
+JUNK tech different effects based on night or day
+ use system time
+
+buffing your deflecting for 1 second after pressing the field button
+ 2 second cooldown on the effect to prevent spamming it
+ buff: giving energy or doing damage makes sense
+ maybe this could be a rework for bremstralung
+
+replace field descriptions with a function call so they can have dynamic text
+ add in dynamic coupling text as a 4th line
+
+Boss that shoots out a ring of bullets, then after a few seconds it gravitates the bullets back
+
+JUNK: Placebo: double the power up spawn rate but make half of them do nothing
+
coupling
- pause menu +defense on coupling description goes above 100%
put coupling description as 4th line on field description
raw text no function call
no need for coupling description in power ups, pause
@@ -27,15 +47,8 @@ coupling tech
tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use
some fields aren't used much (that's ok?)
-tech: increase the effect of boosts, but shorten the duration?
-
tech give laser mines more lasers (3->4? 5?)
-buffing your deflecting for 1 second after pressing the field button sounds cool
- 2 second cooldown on the effect to prevent spamming it
- buff: giving energy or doing damage makes sense
- maybe this could be a rework for bremstralung
-
rewindBoss: after hitting 1/5 damage thresholds the boss rewinds back in time to where it was a few seconds ago
track it's data like player history
@@ -913,6 +926,8 @@ possible names for tech
lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown.
p-zombie
p-hacking JUNK tech
+ https://en.wikipedia.org/wiki/High-entropy_alloys
+ https://en.wikipedia.org/wiki/Refractory_metals
plot script: