Bitter electromagnet
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
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
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
This commit is contained in:
85
js/bullet.js
85
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,8 +6800,9 @@ 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
|
||||
if (!mob[i].isUnblockable) {
|
||||
const SUB = Vector.sub(mob[i].position, m.pos)
|
||||
const DISTANCE = Vector.magnitude(SUB)
|
||||
if (DISTANCE < range + mob[i].radius) {
|
||||
@@ -6810,17 +6811,18 @@ const b = {
|
||||
mob[i].force.x += FORCE.x;
|
||||
mob[i].force.y += FORCE.y;
|
||||
|
||||
let dmg = m.dmgScale * (mob[i].isDropPowerUp ? 0.1 : 0.4)
|
||||
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.2)',
|
||||
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
|
||||
const SUB = Vector.sub(body[i].position, m.pos)
|
||||
const DISTANCE = Vector.magnitude(SUB)
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <span class='color-symbol'>=</span> ${Math.random()}`);
|
||||
|
||||
@@ -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":
|
||||
|
||||
32
js/level.js
32
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: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`, 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 <span class='color-symbol'>=</span> ${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);
|
||||
|
||||
10
js/mob.js
10
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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
69
js/spawn.js
69
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)
|
||||
|
||||
107
js/tech.js
107
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 = `<br>this level: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`
|
||||
let gun = b.guns[b.inventory[tech.buffedGun]].name
|
||||
info = `<br>this level: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`
|
||||
}
|
||||
|
||||
// return `
|
||||
// a <strong class='color-g'>gun</strong> is <strong>chosen</strong> to be improved each <strong>level</strong>
|
||||
// <br><strong>+${(31*b.inventory.length).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for ${gun}
|
||||
// <br><strong class='color-d'>damage</strong> scales by 31% per unequipped <strong class='color-g'>gun</strong>`
|
||||
return `
|
||||
a new <strong class='color-g'>gun</strong> is <strong>chosen</strong> to be improved each <strong>level</strong>
|
||||
<br><strong>+31%</strong> <strong class='color-d'>damage</strong> per <strong class='color-g'>gun</strong> for the <strong>chosen</strong> <strong class='color-g'>gun</strong>${info}`
|
||||
@@ -574,7 +569,7 @@ const tech = {
|
||||
{
|
||||
name: "cache",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Cache_(computing)' class="link">cache</a>`,
|
||||
description: `${powerUps.orb.ammo()} give <strong>1600%</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
|
||||
description: `${powerUps.orb.ammo()} give <strong>1500%</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
|
||||
// ammo powerups always max out your gun,
|
||||
// but the maximum ammo ti limited
|
||||
// description: `${powerUps.orb.ammo()} give <strong>13x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> 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: "<strong>+100%</strong> <strong class='color-d'>damage</strong><br>after not using your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>+100%</strong> <strong class='color-d'>damage</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1068,7 +1063,7 @@ const tech = {
|
||||
{
|
||||
name: "scrap bots",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap bots</a>`,
|
||||
description: "after mobs <strong>die</strong> you have a <strong>+33%</strong> chance<br>to build scrap <strong class='color-bot'>bots</strong> that operate for <strong>14</strong> seconds",
|
||||
description: "after mobs <strong>die</strong> you have a <strong>+33%</strong> chance<br>to build scrap <strong class='color-bot'>bots</strong> that operate for <strong>13</strong> seconds",
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1088,7 +1083,7 @@ const tech = {
|
||||
{
|
||||
name: "scrap refit",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Scrap' class="link">scrap refit</a>`,
|
||||
description: "after mobs <strong>die</strong><br>reset scrap <strong class='color-bot'>bots</strong> to <strong>14</strong> seconds of operation",
|
||||
description: "after mobs <strong>die</strong><br>reset scrap <strong class='color-bot'>bots</strong> to <strong>13</strong> seconds of operation",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 3,
|
||||
@@ -3036,7 +3031,7 @@ const tech = {
|
||||
{
|
||||
name: "many-worlds",
|
||||
// description: "each <strong>level</strong> is an <strong class='alt'>alternate reality</strong>, where you<br>find a <strong class='color-m'>tech</strong> at the start of each level",
|
||||
description: `on each new <strong>level</strong> use ${powerUps.orb.research(1)} to enter an<br><strong class='alt'>alternate reality</strong> and spawn a <strong class='color-m'>tech</strong> power up`,
|
||||
description: `on each new <strong>level</strong> enter an<br><strong class='alt'>alternate reality</strong> and spawn a <strong class='color-m'>tech</strong> power up`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3243,7 +3238,8 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "emergence",
|
||||
description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choices</strong><br><strong>+3%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
|
||||
description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+1</strong> <strong>choice</strong><br><strong>+8%</strong> <strong class='color-d'>damage</strong>",
|
||||
// description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choices</strong><br><strong>+3%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> 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 `<strong>railgun</strong> charges <strong>+33%</strong> slower<br><strong>+100%</strong> <strong>harpoon</strong> density and <strong class='color-d'>damage</strong>` },
|
||||
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: `<strong>+50%</strong> <strong>harpoon</strong> density, but they don't <strong>retract</strong><br><strong>+900%</strong> harpoon <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`,
|
||||
description: `<strong>harpoons</strong> can't <strong>retract</strong>, hold fire to charge<br><strong>+50%</strong> <strong>harpoon</strong> density and <strong class='color-d'>damage</strong>`,
|
||||
// description: `<strong>+900%</strong> <strong>harpoon</strong> <strong class='color-ammo'>ammo</strong>, but it can't <strong>retract</strong><br><strong>+50%</strong> <strong>harpoon</strong> density and <strong class='color-d'>damage</strong>`,
|
||||
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: `<a target="_blank" href='https://en.wikipedia.org/wiki/Special:Random' class="link">random</a>`,
|
||||
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 = `<strong style = "font-family: 'Courier New', monospace;">+${(dmg*100).toFixed(0).padStart(2, '0')}%</strong> <strong class='color-d'>damage</strong>`
|
||||
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 `<span id = "damage-JUNK-id${this.id}">${this.text}</span>`
|
||||
},
|
||||
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,
|
||||
}
|
||||
125
todo.txt
125
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
|
||||
|
||||
Reference in New Issue
Block a user