diff --git a/js/bullet.js b/js/bullet.js
index dd63469..ae671f7 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1688,7 +1688,7 @@ const b = {
});
Composite.add(engine.world, bullet[me]); //add bullet to world
},
- harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true) {
+ harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
const me = bullet.length;
const returnRadius = 100 * Math.sqrt(harpoonSize)
bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -40 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 50 * harpoonSize, y: -3 * harpoonSize, index: 3, isInternal: false }, { x: 30 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }], {
@@ -1696,7 +1696,7 @@ const b = {
angle: angle,
friction: 1,
frictionAir: 0.4,
- thrustMag: 0.1,
+ // thrustMag: 0.1,
drain: tech.isRailEnergy ? 0.001 : 0.006,
turnRate: isReturn ? 0.1 : 0.03, //0.015
drawStringControlMagnitude: 3000 + 5000 * Math.random(),
@@ -1808,7 +1808,7 @@ const b = {
if (m.energy < 0.05) {
m.fireCDcycle = m.cycle + 120; //fire cooldown
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
- m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
+ m.fireCDcycle = m.cycle + 25 * b.fireCDscale //lower cd to 25 if it is above 25
}
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.0001 : 0.0002))
@@ -1828,7 +1828,7 @@ const b = {
if (m.energy > this.drain) m.energy -= this.drain
const sub = Vector.sub(this.position, m.pos)
const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
- const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
+ const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * thrust * this.mass)
this.force.x -= returnForce.x
this.force.y -= returnForce.y
this.grabPowerUp()
@@ -1850,7 +1850,7 @@ const b = {
Matter.Body.setPosition(powerUp[i], this.vertices[2])
powerUp[i].collisionFilter.category = 0
powerUp[i].collisionFilter.mask = 0
- this.thrustMag *= 0.6
+ thrust *= 0.6
this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
break //just pull 1 power up if possible
}
@@ -1887,16 +1887,16 @@ const b = {
Matter.Body.rotate(this, -this.turnRate);
}
}
- this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
- this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
+ this.force.x += thrust * this.mass * Math.cos(this.angle);
+ this.force.y += thrust * this.mass * Math.sin(this.angle);
}
this.draw()
},
});
if (!isReturn && !target) {
Matter.Body.setVelocity(bullet[me], {
- x: m.Vx / 2 + 60 * Math.cos(bullet[me].angle),
- y: m.Vy / 2 + 60 * Math.sin(bullet[me].angle)
+ x: m.Vx / 2 + 600 * thrust * Math.cos(bullet[me].angle),
+ y: m.Vy / 2 + 600 * thrust * Math.sin(bullet[me].angle)
});
bullet[me].frictionAir = 0.002
bullet[me].do = function() {
@@ -6790,7 +6790,7 @@ const b = {
}
//fire
if ((!input.fire && this.charge > 0.6)) {
- tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
+ // tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
const where = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
@@ -6800,25 +6800,27 @@ const b = {
target: null
}
//push away blocks and mobs
- const range = 1200 * this.charge
+ const range = 600 + 500 * this.charge
for (let i = 0, len = mob.length; i < len; ++i) { //push away mobs when firing
- const SUB = Vector.sub(mob[i].position, m.pos)
- const DISTANCE = Vector.magnitude(SUB)
- if (DISTANCE < range + mob[i].radius) {
- const DEPTH = 100 + Math.min(range - DISTANCE + mob[i].radius, 1500)
- const FORCE = Vector.mult(Vector.normalise(SUB), 0.0015 * Math.sqrt(DEPTH) * mob[i].mass)
- mob[i].force.x += FORCE.x;
- mob[i].force.y += FORCE.y;
+ if (!mob[i].isUnblockable) {
+ const SUB = Vector.sub(mob[i].position, m.pos)
+ const DISTANCE = Vector.magnitude(SUB)
+ if (DISTANCE < range + mob[i].radius) {
+ const DEPTH = 100 + Math.min(range - DISTANCE + mob[i].radius, 1500)
+ const FORCE = Vector.mult(Vector.normalise(SUB), 0.0015 * Math.sqrt(DEPTH) * mob[i].mass)
+ mob[i].force.x += FORCE.x;
+ mob[i].force.y += FORCE.y;
- let dmg = m.dmgScale * (mob[i].isDropPowerUp ? 0.1 : 0.4)
- simulation.drawList.push({ //add dmg to draw queue
- x: mob[i].position.x,
- y: mob[i].position.y,
- radius: Math.log(dmg + 1.1) * 40 * mob[i].damageReduction + 3,
- color: 'rgba(100, 0, 200, 0.2)',
- time: 15
- });
- mob[i].damage(dmg);
+ let dmg = m.dmgScale * (mob[i].isDropPowerUp ? 350 : 1100) * tech.harpoonDensity * this.charge
+ simulation.drawList.push({ //add dmg to draw queue
+ x: mob[i].position.x,
+ y: mob[i].position.y,
+ radius: Math.log(dmg + 1.1) * 40 * mob[i].damageReduction + 3,
+ color: 'rgba(100, 0, 200, 0.4)',
+ time: 15
+ });
+ mob[i].damage(dmg);
+ }
}
}
for (let i = 0, len = body.length; i < len; ++i) { //push away blocks when firing
@@ -6841,13 +6843,26 @@ const b = {
powerUp[i].force.y += FORCE.y - powerUp[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
}
}
+ //draw little dots near the edge of range
+ for (let i = 0, len = 10 + 25 * this.charge; i < len; i++) {
+ const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random())
+ const where = Vector.add(m.pos, Vector.mult(unit, range * (0.6 + 0.3 * Math.random())))
+ simulation.drawList.push({
+ x: where.x,
+ y: where.y,
+ radius: 5 + 12 * Math.random(),
+ color: "rgba(100, 0, 200, 0.1)",
+ time: Math.floor(5 + 35 * Math.random())
+ });
+ }
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.03 : 0.06)
player.force.x -= recoil.x
player.force.y -= recoil.y
- tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
+ // tech.harpoonDensity = 0.0065 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
+ const thrust = 0.15 * (this.charge)
if (tech.extraHarpoons) {
let targetCount = 0
const SPREAD = 0.06 + 0.05 * (!input.down)
@@ -6861,7 +6876,7 @@ const b = {
if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target
// if (this.ammo > -1) {
// this.ammo--
- b.harpoon(where, input.down ? null : mob[i], angle, harpoonSize, false) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
+ b.harpoon(where, input.down ? null : mob[i], angle, harpoonSize, false, 35, false, thrust) //harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
angle += SPREAD
targetCount++
if (targetCount > tech.extraHarpoons) break
@@ -6873,14 +6888,10 @@ const b = {
if (targetCount < tech.extraHarpoons + 1) {
const num = tech.extraHarpoons + 1 - targetCount
for (let i = 0; i < num; i++) {
- // if (this.ammo > -1) {
- // this.ammo--
- b.harpoon(where, null, angle, harpoonSize, false)
+ b.harpoon(where, null, angle, harpoonSize, false, 35, false, thrust)
angle += SPREAD
- // }
}
}
- // this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
} else {
//look for closest mob in player's LoS
@@ -6895,7 +6906,7 @@ const b = {
}
}
}
- b.harpoon(where, input.down ? null : closest.target, m.angle, harpoonSize, false)
+ b.harpoon(where, closest.target, m.angle, harpoonSize, false, 35, false, thrust)
}
this.charge = 0;
@@ -6909,13 +6920,18 @@ const b = {
player.force.y = 0
}
m.fireCDcycle = m.cycle + 10 //can't fire until mouse is released
- const previousCharge = this.charge
- //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
- let smoothRate = tech.isCapacitor ? 0.85 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
- if (input.down) smoothRate *= 0.995
+ // const previousCharge = this.charge
- this.charge = this.charge * smoothRate + 1 - smoothRate
+ //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
+ // let smoothRate = tech.isCapacitor ? 0.85 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
+ const rate = Math.sqrt(b.fireCDscale) * tech.railChargeRate * (tech.isCapacitor ? 0.6 : 1) * (input.down ? 0.8 : 1)
+ let smoothRate = Math.min(0.998, 0.94 + 0.05 * rate)
+
+
+ this.charge = 1 - smoothRate + this.charge * smoothRate
if (m.energy > DRAIN) m.energy -= DRAIN
+
+ // console.log((this.charge).toFixed(2))
// m.energy += (this.charge - previousCharge) * ((tech.isRailEnergy ? 0.5 : -0.3)) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
//draw magnetic field
@@ -6936,9 +6952,11 @@ const b = {
X, Y)
}
ctx.fillStyle = `rgba(50,0,100,0.05)`;
+ const magSize = 8 * this.charge * tech.railChargeRate ** 3
+ const arcSize = 6 * this.charge * tech.railChargeRate ** 3
for (let i = 3; i < 7; i++) {
- const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
- const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
+ const MAG = magSize * i * i * (0.93 + 0.07 * Math.random())
+ const ARC = arcSize * i * i * (0.93 + 0.07 * Math.random())
ctx.beginPath();
magField(MAG, ARC)
magField(MAG, -ARC)
@@ -6990,13 +7008,13 @@ const b = {
}
//look for closest mob in player's LoS
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1)
- const totalCycles = 5 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
+ const totalCycles = 6 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
if (tech.extraHarpoons && !input.down) { //multiple harpoons
const SPREAD = 0.1
let angle = m.angle - SPREAD * tech.extraHarpoons / 2;
const dir = { x: Math.cos(angle), y: Math.sin(angle) }; //make a vector for the player's direction of length 1; used in dot product
- const range = 450 * (tech.isFilament ? 1 + 0.006 * Math.min(110, this.ammo) : 1)
+ const range = 450 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1)
let targetCount = 0
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
@@ -7036,9 +7054,8 @@ const b = {
}
this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
- m.fireCDcycle = m.cycle + 90 // cool down
- } else {
- //single harpoon
+ m.fireCDcycle = m.cycle + 90 // cool down is set when harpoon bullet returns to player
+ } else { //input.down makes a single harpoon with longer range
const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
@@ -7055,7 +7072,7 @@ const b = {
} else {
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
}
- m.fireCDcycle = m.cycle + 45 // cool down
+ m.fireCDcycle = m.cycle + 45 // cool down is set when harpoon bullet returns to player
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
}
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
diff --git a/js/engine.js b/js/engine.js
index 6fdcd87..5944323 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -154,7 +154,7 @@ function collisionChecks(event) {
m.damage(dmg); //normal damage
}
- if (tech.isCollisionRealitySwitch) {
+ if (tech.isCollisionRealitySwitch && m.alive) {
m.switchWorlds()
simulation.trails()
simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
diff --git a/js/index.js b/js/index.js
index 5b915d9..070d780 100644
--- a/js/index.js
+++ b/js/index.js
@@ -963,7 +963,7 @@ window.addEventListener("keyup", function(event) {
});
window.addEventListener("keydown", function(event) {
- console.log(event.code)
+ // console.log(event.code)
switch (event.code) {
case input.key.right:
case "ArrowRight":
diff --git a/js/level.js b/js/level.js
index dbc96db..13e26b6 100644
--- a/js/level.js
+++ b/js/level.js
@@ -18,30 +18,31 @@ const level = {
// simulation.enableConstructMode() //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
- // level.difficultyIncrease(2 * 4) //30 is near max on hard //60 is near max on why
+ // level.difficultyIncrease(15 * 4) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
- // powerUps.research.changeRerolls(50)
+ // powerUps.research.changeRerolls(1000)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
- // m.setField("time dilation") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave
+ // m.setField("plasma torch") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
- // b.guns[9].ammo = 10000
- // tech.giveTech("startle response")
- // for (let i = 0; i < 1; ++i) tech.giveTech("junk DNA")
+ // b.guns[0].ammo = 10000
+ // tech.giveTech("plasma ball")
// tech.giveTech("dye laser")
- // for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook")
- // for (let i = 0; i < 5; i++) tech.giveTech("laser-bot")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("railgun")
+ // for (let i = 0; i < 3; ++i) tech.giveTech("Bitter electromagnet")
+ // for (let i = 0; i < 1; i++) tech.giveTech("capacitor bank")
+ // for (let i = 0; i < 9; i++) tech.giveTech("heuristics")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.testing();
- // spawn.starter(1900, -500, 200)
+ // spawn.shooter(1900, -500, 200)
// spawn.starter(1900, -500)
// spawn.timeBoss(2538, -950)
// for (let i = 0; i < 5; ++i) spawn.sniper(1000 + 5000 * Math.random(), -500 + 300 * Math.random())
@@ -66,7 +67,7 @@ const level = {
// level.null()
// localSettings.isHuman = true
// tech.isNoDraftPause = false //disable pause
- // mobs.mobDeaths = 200
+ // mobs.mobDeaths = 200 //to prevent pacifist mode
// for (let i = 0; i < 13; i++) level.nextLevel(); //jump to final boss
// lore.unlockTesting();
@@ -101,6 +102,11 @@ const level = {
b.inventoryGun = tech.buffedGun;
simulation.switchGun();
}
+ if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) {
+ var gun = b.guns[b.inventory[tech.buffedGun]].name
+ simulation.makeTextLog(`pigeonhole principle: +${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for ${gun}`, 600);
+ }
+
if (tech.isForeverDrones) {
if (tech.isDroneRadioactive) {
@@ -119,8 +125,7 @@ const level = {
tech.healMaxEnergyBonus += 0.1 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51)
m.setMaxEnergy();
}
- if (tech.isSwitchReality && powerUps.research.count > 0) {
- powerUps.research.changeRerolls(-1);
+ if (tech.isSwitchReality) {
simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
m.switchWorlds()
simulation.trails()
@@ -162,7 +167,8 @@ const level = {
if (tech.isSpawnExitTech) {
for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit
}
- if (m.plasmaBall) m.plasmaBall.reset()
+ // if (m.plasmaBall) m.plasmaBall.reset()
+ if (m.plasmaBall) m.plasmaBall.fire()
if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) {
const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
powerUps.directSpawn(flip * localSettings.entanglement.position.x, localSettings.entanglement.position.y, "entanglement", false);
diff --git a/js/mob.js b/js/mob.js
index 4759662..f460689 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -342,12 +342,6 @@ const mobs = {
this.seePlayer.position.y = player.position.y;
}
},
- // alwaysSeePlayerIfRemember() {
- // if (!m.isCloak && this.seePlayer.recall) {
- // this.seePlayer.position.x = player.position.x;
- // this.seePlayer.position.y = player.position.y;
- // }
- // },
seePlayerByHistory(depth = 30) { //depth max 60? limit of history
if (!(simulation.cycle % this.seePlayerFreq)) {
if (Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && !m.isCloak) {
@@ -1255,12 +1249,12 @@ const mobs = {
}
if (tech.isBotSpawnerReset) {
for (let i = 0, len = bullet.length; i < len; i++) {
- if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 840 //14 seconds
+ if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 780 //13 seconds
}
}
if (Math.random() < tech.botSpawner) {
b.randomBot(this.position, false)
- bullet[bullet.length - 1].endCycle = simulation.cycle + 840 //14 seconds
+ bullet[bullet.length - 1].endCycle = simulation.cycle + 780 //13 seconds
this.leaveBody = false; // no body since it turned into the bot
}
if (tech.isAddRemoveMaxHealth) {
diff --git a/js/player.js b/js/player.js
index 68bdf16..ff4a49b 100644
--- a/js/player.js
+++ b/js/player.js
@@ -2385,11 +2385,15 @@ const m = {
if (this.circleRadius < this.radiusLimit) this.reset()
},
reset() {
+ // console.log(this.circleRadius)
const scale = 1 / m.plasmaBall.circleRadius
Matter.Body.scale(m.plasmaBall, scale, scale); //grow
+ // console.log(this.circleRadius)
+ // this.circleRadius = 0
this.alpha = 0.7
this.isOn = false
this.isPopping = false
+ // this.isAttached = true;
},
do() {
if (this.isOn) {
diff --git a/js/spawn.js b/js/spawn.js
index 097af74..80af8ce 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -297,7 +297,7 @@ const spawn = {
me.showHealthBar = false;
me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body
- me.chaseSpeed = 1.2 + 2 * Math.random()
+ me.chaseSpeed = 1.2 + 2.3 * Math.random()
me.awake = function() {
//chase player
@@ -394,6 +394,9 @@ const spawn = {
this.pushAway();
this.mode[this.totalModes].enter() //enter new mode
this.totalModes++
+ //spawn 6 mobs
+ me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; //fire a bullet from each vertex
+ for (let i = 0; i < 6; i++) me.spawnMobs(i)
}
ctx.beginPath(); //draw invulnerable
let vertices = this.vertices;
@@ -408,12 +411,21 @@ const spawn = {
}
}
me.damageReductionDecay = function() { //slowly make the boss take more damage over time //damageReduction resets with each invulnerability phase
- if (!(me.cycle % 60) && this.lastDamageCycle + 240 > this.cycle) this.damageReduction *= 1.015 //only decay once a second //only decay if the player has done damage in the last 4 seconds
+ if (!(me.cycle % 60) && this.lastDamageCycle + 240 > this.cycle) this.damageReduction *= 1.017 //only decay once a second //only decay if the player has done damage in the last 4 seconds
+ }
+ me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]
+ me.spawnMobs = function(index = 0) {
+ const vertex = me.vertices[index]
+ const unit = Vector.normalise(Vector.sub(me.position, vertex))
+ const where = Vector.add(vertex, Vector.mult(unit, -30))
+ spawn[me.mobType](where.x + 50 * (Math.random() - 0.5), where.y + 50 * (Math.random() - 0.5));
+ const velocity = Vector.mult(Vector.perp(unit), -10) //give the mob a rotational velocity as if they were attached to a vertex
+ Matter.Body.setVelocity(mob[mob.length - 1], { x: me.velocity.x + velocity.x, y: me.velocity.y + velocity.y });
}
me.maxMobs = 400
me.mode = [{
name: "boulders",
- spawnRate: 120 - 6 * simulation.difficultyMode,
+ spawnRate: 170 - 6 * simulation.difficultyMode,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
me.boulder(me.position.x, me.position.y + 250)
@@ -423,19 +435,20 @@ const spawn = {
exit() {},
}, {
name: "mobs",
- whoSpawn: spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)],
- spawnRate: 240 - 20 * simulation.difficultyMode,
+ // whoSpawn: spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)],
+ spawnRate: 280 - 20 * simulation.difficultyMode,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
me.torque += 0.000015 * me.inertia; //spin
const index = Math.floor((me.cycle % (this.spawnRate * 6)) / this.spawnRate) //int from 0 to 5
- if (index === 0) this.whoSpawn = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; //fire a bullet from each vertex
- const vertex = me.vertices[index]
- const unit = Vector.normalise(Vector.sub(me.position, vertex))
- const where = Vector.add(vertex, Vector.mult(unit, -30))
- spawn[this.whoSpawn](where.x + 50 * (Math.random() - 0.5), where.y + 50 * (Math.random() - 0.5));
- const velocity = Vector.mult(Vector.perp(unit), -18) //give the mob a rotational velocity as if they were attached to a vertex
- Matter.Body.setVelocity(mob[mob.length - 1], { x: me.velocity.x + velocity.x, y: me.velocity.y + velocity.y });
+ if (index === 0) me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; //fire a bullet from each vertex
+ me.spawnMobs(index)
+ // const vertex = me.vertices[index]
+ // const unit = Vector.normalise(Vector.sub(me.position, vertex))
+ // const where = Vector.add(vertex, Vector.mult(unit, -30))
+ // spawn[me.mobType](where.x + 50 * (Math.random() - 0.5), where.y + 50 * (Math.random() - 0.5));
+ // const velocity = Vector.mult(Vector.perp(unit), -18) //give the mob a rotational velocity as if they were attached to a vertex
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: me.velocity.x + velocity.x, y: me.velocity.y + velocity.y });
}
},
enter() {},
@@ -443,7 +456,7 @@ const spawn = {
},
{
name: "hoppers",
- spawnRate: 420 - 16 * simulation.difficultyMode,
+ spawnRate: 480 - 16 * simulation.difficultyMode,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
me.torque += 0.00002 * me.inertia; //spin
@@ -457,6 +470,10 @@ const spawn = {
y: me.velocity.y + velocity.y
});
}
+ let where = { x: 600 - Math.random() * 100, y: -225 }
+ if (simulation.isHorizontalFlipped) where.x = -600 + Math.random() * 100
+ spawn.hopBullet(where.x, where.y, 13 + Math.ceil(Math.random() * 8)); //hopBullet(x, y, radius = 10 + Math.ceil(Math.random() * 8))
+ Matter.Body.setDensity(mob[mob.length - 1], 0.002); //normal is 0.001
}
},
enter() {},
@@ -464,7 +481,7 @@ const spawn = {
},
{
name: "seekers",
- spawnRate: 60 - 3 * simulation.difficultyMode,
+ spawnRate: 100 - 3 * simulation.difficultyMode,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) { //spawn seeker
const index = Math.floor((me.cycle % 360) / 60)
@@ -482,7 +499,7 @@ const spawn = {
{
name: "mines",
bombCycle: 0,
- bombInterval: 34 - 2 * simulation.difficultyMode,
+ bombInterval: 55 - 2 * simulation.difficultyMode,
do() {
const yOff = 120
this.bombCycle++
@@ -544,7 +561,7 @@ const spawn = {
},
{
name: "orbiters",
- spawnRate: 30 - 2 * simulation.difficultyMode,
+ spawnRate: 42 - 2 * simulation.difficultyMode,
do() {
if (!(me.cycle % this.spawnRate) && mob.length < me.maxMobs) {
const speed = (0.01 + 0.0005 * simulation.difficultyMode) * ((Math.random() < 0.5) ? 0.85 : -1.15)
@@ -602,7 +619,7 @@ const spawn = {
{
name: "black hole",
eventHorizon: 0,
- eventHorizonRadius: 2200,
+ eventHorizonRadius: 2100,
eventHorizonCycle: 0,
do() {
this.eventHorizonCycle++
@@ -690,10 +707,10 @@ const spawn = {
for (let i = 0; i < this.totalModes; i++) this.mode[i].do()
}
// this.cycle++;
- // this.mode[0].do()
+ // this.mode[4].do()
// this.mode[7].do()
};
- me.spawnRate = 4800 - 30 * simulation.difficultyMode * simulation.difficultyMode
+ me.spawnRate = 5800 - 30 * simulation.difficultyMode * simulation.difficultyMode
me.spawnBoss = function() { //if the fight lasts too long start spawning bosses
if (!(me.cycle % this.spawnRate) && this.health < 1) {
this.spawnRate = Math.max(300, this.spawnRate - 10 * simulation.difficultyMode * simulation.difficultyMode) //reduce the timer each time a boss spawns
@@ -816,7 +833,7 @@ const spawn = {
}
};
}
- me.lasers = function(where, angle, dmg = 0.13 * simulation.dmgScale) {
+ me.lasers = function(where, angle, dmg = 0.1 * simulation.dmgScale) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
@@ -1752,7 +1769,7 @@ const spawn = {
me.seeAtDistance2 = 1400000;
me.cellMassMax = 70
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body | cat.map
- Matter.Body.setDensity(me, 0.0002 + 0.00001 * simulation.difficulty) // normal density is 0.001
+ Matter.Body.setDensity(me, 0.0001 + 0.00002 * simulation.difficulty) // normal density is 0.001
me.damageReduction = 0.17 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); //me.damageReductionGoal
const k = 642 //k=r^2/m
@@ -2542,13 +2559,13 @@ const spawn = {
mobs.spawn(x, y, 6, radius, "transparent");
let me = mob[mob.length - 1];
me.stroke = "transparent"; //used for drawSneaker
- me.eventHorizon = radius * 23; //required for blackhole
+ me.eventHorizon = radius * 27; //required for blackhole
me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon
- me.accelMag = 0.0001 * simulation.accelScale;
+ me.accelMag = 0.00012 * simulation.accelScale;
me.frictionAir = 0.025;
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
me.memory = Infinity;
- Matter.Body.setDensity(me, 0.008); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
me.do = function() {
//keep it slow, to stop issues from explosion knock backs
if (this.speed > 5) {
@@ -2675,11 +2692,11 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = 1100; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon
- me.accelMag = 0.00003 * simulation.accelScale;
+ me.accelMag = 0.00004 * simulation.accelScale;
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
// me.frictionAir = 0.005;
me.memory = 1600;
- Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.04); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() {
//applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
diff --git a/js/tech.js b/js/tech.js
index 32723e2..7b2709e 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -430,16 +430,11 @@ const tech = {
{
name: "pigeonhole principle",
descriptionFunction() {
- var info = ""
+ let info = ""
if (this.count > 0 && Number.isInteger(tech.buffedGun) && b.inventory.length) {
- var gun = b.guns[b.inventory[tech.buffedGun]].name
- var info = `
this level: +${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for ${gun}`
+ let gun = b.guns[b.inventory[tech.buffedGun]].name
+ info = `
this level: +${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for ${gun}`
}
-
- // return `
- // a gun is chosen to be improved each level
- //
+${(31*b.inventory.length).toFixed(0)}% damage for ${gun}
- //
damage scales by 31% per unequipped gun`
return `
a new gun is chosen to be improved each level
+31% damage per gun for the chosen gun${info}`
@@ -574,7 +569,7 @@ const tech = {
{
name: "cache",
link: `cache`,
- description: `${powerUps.orb.ammo()} give 1600% more ammo, but
you can't store any more ammo than that`,
+ description: `${powerUps.orb.ammo()} give 1500% more ammo, but
you can't store any more ammo than that`,
// ammo powerups always max out your gun,
// but the maximum ammo ti limited
// description: `${powerUps.orb.ammo()} give 13x more ammo, but
you can't store any more ammo than that`,
@@ -587,7 +582,7 @@ const tech = {
},
requires: "not non-renewables",
effect() {
- tech.ammoCap = 16;
+ tech.ammoCap = 15;
powerUps.ammo.effect()
},
remove() {
@@ -1049,7 +1044,7 @@ const tech = {
},
{
name: "anticorrelation",
- description: "+100% damage
after not using your gun or field for 2 seconds",
+ description: "if your gun or field are unused for 2 seconds
+100% damage",
maxCount: 1,
count: 0,
frequency: 1,
@@ -1068,7 +1063,7 @@ const tech = {
{
name: "scrap bots",
link: `scrap bots`,
- description: "after mobs die you have a +33% chance
to build scrap bots that operate for 14 seconds",
+ description: "after mobs die you have a +33% chance
to build scrap bots that operate for 13 seconds",
maxCount: 3,
count: 0,
frequency: 1,
@@ -1088,7 +1083,7 @@ const tech = {
{
name: "scrap refit",
link: `scrap refit`,
- description: "after mobs die
reset scrap bots to 14 seconds of operation",
+ description: "after mobs die
reset scrap bots to 13 seconds of operation",
maxCount: 1,
count: 0,
frequency: 3,
@@ -3036,7 +3031,7 @@ const tech = {
{
name: "many-worlds",
// description: "each level is an alternate reality, where you
find a tech at the start of each level",
- description: `on each new level use ${powerUps.orb.research(1)} to enter an
alternate reality and spawn a tech power up`,
+ description: `on each new level enter an
alternate reality and spawn a tech power up`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3243,7 +3238,8 @@ const tech = {
},
{
name: "emergence",
- description: "tech, fields, and guns have +2 choices
+3% JUNK to tech pool",
+ description: "tech, fields, and guns have +1 choice
+8% damage",
+ // description: "tech, fields, and guns have +2 choices
+3% JUNK to tech pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -3252,16 +3248,18 @@ const tech = {
return !tech.isDeterminism
},
requires: "not determinism",
+ damage: 1.08,
effect() {
- tech.extraChoices += 2;
- this.refundAmount += tech.addJunkTechToPool(0.03)
+ tech.extraChoices += 1;
+ tech.damage *= this.damage
+ // this.refundAmount += tech.addJunkTechToPool(0.03)
},
refundAmount: 0,
remove() {
tech.extraChoices = 0;
- if (this.count > 0 && this.refundAmount > 0) {
- tech.removeJunkTechFromPool(this.refundAmount)
- this.refundAmount = 0
+ if (this.count > 0) {
+ tech.damage /= this.damage
+ // if (this.refundAmount > 0) tech.removeJunkTechFromPool(this.refundAmount)
}
}
},
@@ -4825,7 +4823,7 @@ const tech = {
},
remove() {
tech.infiniteWaveAmmo = 1
- if (this.count > 1 && b.guns[3].savedAmmo !== undefined) {
+ if (this.count > 0 && b.guns[3].savedAmmo !== undefined) {
b.guns[3].ammo = b.guns[3].savedAmmo
simulation.updateGunHUD();
}
@@ -6188,9 +6186,31 @@ const tech = {
tech.isCapacitor = false;
}
},
+ {
+ name: "Bitter electromagnet",
+ descriptionFunction() { return `railgun charges +33% slower
+100% harpoon density and damage` },
+ isGunTech: true,
+ maxCount: 3,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("harpoon") && tech.isRailGun
+ },
+ requires: "harpoon, railgun",
+ effect() {
+ tech.railChargeRate *= 1.06
+ tech.harpoonDensity += 0.0065
+ },
+ remove() {
+ tech.railChargeRate = 0.97;
+ tech.harpoonDensity = 0.0065
+ }
+ },
{
name: "railgun",
- description: `+50% harpoon density, but they don't retract
+900% harpoon ammo per ${powerUps.orb.ammo(1)}`,
+ description: `harpoons can't retract, hold fire to charge
+50% harpoon density and damage`,
+ // description: `+900% harpoon ammo, but it can't retract
+50% harpoon density and damage`,
isGunTech: true,
maxCount: 1,
count: 0,
@@ -6414,7 +6434,6 @@ const tech = {
},
remove() {
tech.isHarpoonPowerUp = false
- tech.harpoonDensity = 0.004
}
},
{
@@ -8260,6 +8279,39 @@ const tech = {
},
remove() {}
},
+ {
+ name: "random",
+ link: `random`,
+ delay: 333,
+ descriptionFunction() {
+ const delay = 333
+ const loop = () => {
+ if ((simulation.isChoosing) && m.alive && !build.isExperimentSelection) {
+ const dmg = Math.floor(33 * Math.random()) * 0.01
+ this.text = `+${(dmg*100).toFixed(0).padStart(2, '0')}% damage`
+ this.damage = 1 + dmg
+ if (document.getElementById(`damage-JUNK-id${this.id}`)) document.getElementById(`damage-JUNK-id${this.id}`).innerHTML = this.text
+ setTimeout(() => { loop() }, delay);
+ }
+ }
+ setTimeout(() => { loop() }, delay);
+ this.id++
+ return `${this.text}`
+ },
+ maxCount: 3,
+ count: 0,
+ frequency: 1,
+ isJunk: true,
+ allowed() { return !build.isExperimentSelection },
+ requires: "NOT EXPERIMENT MODE",
+ damage: 0,
+ effect() {
+ tech.damage *= this.damage
+ },
+ remove() {
+ if (this.count > 0) tech.damage /= this.damage
+ }
+ },
{
name: "boost",
maxCount: 1,
@@ -8267,9 +8319,7 @@ const tech = {
frequency: 0,
isJunk: true,
isNonRefundable: true,
- allowed() {
- return !build.isExperimentSelection
- },
+ allowed() { return !build.isExperimentSelection },
requires: "NOT EXPERIMENT MODE",
effect() {
powerUps.spawnDelay("boost", this.spawnCount)
@@ -8306,7 +8356,7 @@ const tech = {
allowed: () => true,
requires: "",
effect() {
- if (Math.random() < 0.1) tech.damage *= 7.77
+ if (Math.random() < 0.1) tech.damage *= 8.77
},
remove() {}
},
@@ -10066,7 +10116,7 @@ const tech = {
allowed() { return m.isShipMode },
requires: "",
effect() {
- tech.damage *= 2
+ tech.damage *= 3
m.look = () => {
// const scale = 0;
@@ -10984,4 +11034,5 @@ const tech = {
isJunkDNA: null,
buffedGun: 0,
isGunChoice: null,
+ railChargeRate: null,
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 3fd4bb9..652a4bf 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,20 +1,93 @@
******************************************************** NEXT PATCH **************************************************
+harpoon
+ default fire rate is 10% higher
+ default harpoon range 15% higher
+railgun
+ tech: Bitter electromagnet - 33% slower charge time for railgun, 100% more density and damage
+ area effect damage is increased 20%, scales with bitter electromagnet and total charge
+ charging longer increases harpoon velocity/damage by up to 30%
+ contributions to charge time are more uniform between:
+ crouching, fire rate, Bitter electromagnet, and capacitor bank
+ auto aims no longer disabled on crouch
-plasma-bot does 15% more damage, but costs 2 research
-fault tolerance 4->5 forever drones, but costs 2 research
-surfactant 2->3 foam bots, but costs 2 research
-missile-bot costs 1 research
-shaped charge 4->3 research cost
-renormalization 40->44% chance to refund research
-exciton 18->16% chance to spawn
-ground state 50->40% reduced energy regen
-Bayesian statistics 3.8->3% damage per research, and spawns 3 research
+emergence 2->1 extra choice, and +8% damage, and no added JUNK anymore
+cache 16->15x ammo
+many-worlds 1->0 research to enter an alternate reality on each new level
-JUNK tech: startle response - if mobs are near boost damage, and lock mouse until you press escape
+finalBoss
+ health decays a bit faster
+ spawns 6 mobs at each health threshold
+ spawns from the different modes are reduced
+ boss laser damage is 25% reduced
+ hoppers spawn from the slime tunnel
+
+JUNKtech: random - gives random +damage
+
+bug fixes
*********************************************************** TODO *****************************************************
+tech: zombie - sporangium infect mobs, making them fight for you
+ infected mobs get a status debuff. when they die they return as zombie mob type
+ zombie mobs run code similar to drones
+ they inherit color, sides, radius from host
+
+
+tech: sporangium that grow little trees
+ the trees have an area of effect damage for about 6-10 seconds
+ maybe something similar to radioactive drones, but maybe a few smaller shapes
+
+new bot type that makes phonon waves
+ name: phono-bot?
+ each bot has to generate it themselves, can't run code in gun.do
+ synergy with 2 resonance tech
+ not isotropic? I think no
+ synergy with bound? phase velocity, amplitude, propagation
+
+harpoon tech that makes auto aim work much better
+
+tech - super balls gain 20 seconds of time and are reset to original launch speed after hitting a mob
+
+railgun
+ magnetic pinch: harpoon does damage to nearby mobs
+ draw charge graphic on harpoon
+ use same code as the damage when fire effect
+
+hookBoss fires a hook that pulls player towards it
+ hook does a bit of damage
+ player targeted unless cloaking
+ also add effect to finalBoss
+
+
+finalBoss
+ add synergies between modes:
+ new modes:
+ rotating quadrant immunity shield, can't take damage from that quadrant
+ maybe also attack player near that quadrant
+ but how to tell the angle of incoming damage
+ maybe a physics body like the shield but it only covers 1/3 of mob?
+ falling object warps to ceiling after hitting floor
+ doesn't end, player needs to kill it
+ slowly grows?
+ slow effect zones
+ random placement or place over player or both!
+ draw white dot and an outline of area of effect
+ expanding circle stroke, freeze effect triggers when stroke circle hits fill circle
+ after 1-2 seconds freeze player if in the zone
+ also freeze mobs
+ effect that makes player have to be close to boss
+ hook that tries to yank the player into hitting finalBoss
+ does damage
+ pulls player into center
+ counter with wormhole, negative mass
+ player targeted unless cloaking
+
+
+mob status effect - emit - mobs fire lasers for a few seconds
+ tech: phosphorescence - mobs emit after being hit with laser beams
+
run canvas direct pixel editing while game is paused
+ (I tried it an it really hits performance hard)
just update once every second?
if it uses too much processing have a setting to toggle it off
this might help get players to spend more time relaxing on the power up selection
@@ -41,8 +114,6 @@ it would be nice if there was incentive to go slow when choosing tech so n-gon i
make freeze and __ not cause death at 50% health, but just 600% extra damage for that bullet
-new mob status effect - phosphorescence - mobs fire lasers for a few seconds after being hit with lasers
-
make a new coupling effect for perfect diamagnetism or standing wave
make a faster smaller version of cell boss that also has map collisions
@@ -50,32 +121,6 @@ make a faster smaller version of cell boss that also has map collisions
laserMines need a copy of laser-bot method
this is a very rare bug, so not a priority
-finalBoss
- add synergies between modes:
- black hole can pull in bullets
- laser can hurt bullets? maybe bad idea
- old mode changes
- mine color needs to be move vibrant
- hoppers can hop out of the slime and the door on the sides
- new modes:
- rotating quadrant immunity shield, can't take damage from that quadrant
- maybe also attack player near that quadrant
- falling object warps to ceiling after hitting floor
- doesn't end, player needs to kill it
- slowly grows?
- slow effect zones
- random placement or place over player or both!
- draw white dot and an outline of area of effect
- expanding circle stroke, freeze effect triggers when stroke circle hits fill circle
- after 1-2 seconds freeze player if in the zone
- also freeze mobs
- effect that makes player have to be close to boss
- hook that tries to yank the player into hitting finalBoss
- does damage
- pulls player into center
- counter with wormhole, negative mass
- player targeted unless cloaking
-
JUNK tech description that changes similar to cards in inscription
that changes based on mouse position
can you tell if mouse is over card?
@@ -1059,8 +1104,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
+ https://en.wikipedia.org/wiki/High-entropy_alloys high yield strength and low ductility, high temp resistance
+ https://en.wikipedia.org/wiki/Refractory_metals hard, high temp resistance
https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves
prion quine - self replicating protein
Unitarity - https://en.wikipedia.org/wiki/Unitarity_(physics) - all probabilities add up to 1, calculations work the same forward and backwards in time