another combo
tech: collimator - add 1 laser beam and align your diverging beams to be parallel requires diffraction grating added secret pilot wave combo to make blocks rewrote combo test algorithm to be more forgiving with pattern matching also extended combos test to arrow keys, not just WASD cache 17->15x ammo metamaterial cloaking 0.3->0.4x damage reduction while cloaked boson composite drains more energy when passing through mobs scales with difficulty subway level has 6->4 (5 on hard difficulty) stations subway gives 1/3->1/5 interest per station bug fixes Higgs skin removal fixed diaphragm skin removal fixed
This commit is contained in:
BIN
img/collimator.webp
Normal file
BIN
img/collimator.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
26
js/bullet.js
26
js/bullet.js
@@ -7370,6 +7370,8 @@ const b = {
|
||||
};
|
||||
}
|
||||
|
||||
} else if (tech.beamCollimator) {
|
||||
this.fire = this.fireSplitCollimator
|
||||
} else if (tech.beamSplitter) {
|
||||
this.fire = this.fireSplit
|
||||
} else if (tech.historyLaser) {
|
||||
@@ -7395,6 +7397,7 @@ const b = {
|
||||
}, tech.laserDamage / b.fireCDscale * this.lensDamage);
|
||||
}
|
||||
},
|
||||
|
||||
firePulse() { },
|
||||
fireSplit() {
|
||||
const drain = tech.laserDrain / b.fireCDscale
|
||||
@@ -7418,6 +7421,29 @@ const b = {
|
||||
}
|
||||
}
|
||||
},
|
||||
fireSplitCollimator() {
|
||||
const drain = tech.laserDrain / b.fireCDscale
|
||||
if (m.energy < drain) {
|
||||
m.fireCDcycle = m.cycle + 100; // cool down if out of energy
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle
|
||||
m.energy -= drain
|
||||
const freq = 0.037
|
||||
const len = tech.beamSplitter + 1
|
||||
const phase = 2 * Math.PI / len
|
||||
for (let i = 0; i < len; i++) {
|
||||
if (Math.sin(m.cycle * freq + phase * (i) + Math.PI / 2) > 0 || !(m.cycle % 3)) ctx.globalAlpha = 0.35
|
||||
|
||||
const whereSweep = m.angle + (m.crouch ? 0.4 : 1) * (Math.sin(m.cycle * freq + phase * (i)))
|
||||
const where = { x: m.pos.x + 30 * Math.cos(whereSweep), y: m.pos.y + 30 * Math.sin(whereSweep) }
|
||||
b.laser(where, {
|
||||
x: where.x + 5000 * Math.cos(m.angle),
|
||||
y: where.y + 5000 * Math.sin(m.angle)
|
||||
}, tech.laserDamage / b.fireCDscale * this.lensDamage);
|
||||
ctx.globalAlpha = 1
|
||||
}
|
||||
}
|
||||
},
|
||||
fireWideBeam() {
|
||||
const drain = tech.laserDrain / b.fireCDscale
|
||||
if (m.energy < drain) {
|
||||
|
||||
@@ -1176,6 +1176,7 @@ function openExperimentMenu() {
|
||||
document.body.style.overflowX = "hidden";
|
||||
document.getElementById("info").style.display = 'none'
|
||||
build.reset();
|
||||
|
||||
}
|
||||
|
||||
//record settings so they can be reproduced in the experimental menu
|
||||
|
||||
18
js/level.js
18
js/level.js
@@ -33,7 +33,7 @@ const level = {
|
||||
// tech.tech[297].frequency = 100
|
||||
// tech.addJunkTechToPool(0.5)
|
||||
// m.couplingChange(10)
|
||||
// m.setField("wormhole") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.setField("pilot wave") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
|
||||
// m.energy = 0
|
||||
// powerUps.research.count = 3
|
||||
// tech.isHookWire = true
|
||||
@@ -50,8 +50,8 @@ const level = {
|
||||
// requestAnimationFrame(() => { tech.giveTech("non-renewables") });
|
||||
// tech.giveTech("dark matter")
|
||||
// tech.addJunkTechToPool(0.5)
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("demineralization")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("remineralization")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("paradigm shift")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("Higgs mechanism")
|
||||
// m.skin.egg();
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("many-worlds")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("quasiparticles") });
|
||||
@@ -67,7 +67,7 @@ const level = {
|
||||
|
||||
|
||||
// for (let i = 0; i < 10; ++i) spawn.starter(1900, -500)
|
||||
// for (let i = 0; i < 1; i++) spawn.mantisBoss(1900, -500)
|
||||
// for (let i = 0; i < 1; i++) spawn.softBoss(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "entanglement");
|
||||
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "gun");
|
||||
// for (let i = 0; i < 100; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
|
||||
@@ -175,7 +175,8 @@ const level = {
|
||||
let rate = tech.interestRate
|
||||
if (level.onLevel < level.levels.length - 1) {//make sure it's not on the lore level which has an undefined name
|
||||
const levelName = level.levels[level.onLevel]
|
||||
if (levelName === "final" || levelName === "subway") rate *= 1 / 3
|
||||
if (levelName === "final") rate *= 1 / 3
|
||||
if (levelName === "subway") rate *= 1 / 5
|
||||
}
|
||||
|
||||
let ammoSum = 0
|
||||
@@ -2754,6 +2755,11 @@ const level = {
|
||||
Composite.add(engine.world, cons[cons.length - 1]);
|
||||
}
|
||||
},
|
||||
// softBody(x, y, angle = 0, isAttached = true, len = 15, radius = 20, stiffness = 1, damping = 1) {
|
||||
// https://github.com/liabru/matter-js/blob/master/examples/softBody.js
|
||||
// https://brm.io/matter-js/docs/classes/Composites.html
|
||||
// https://codepen.io/Shokeen/pen/EmOLJO?editors=0010
|
||||
// },
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
@@ -3534,7 +3540,7 @@ const level = {
|
||||
const stationList = [] //use to randomize station order
|
||||
for (let i = 1, totalNumberOfStations = 10; i < totalNumberOfStations; ++i) stationList.push(i) //!!!! update station number when you add a new station
|
||||
stationList.sort(() => Math.random() - 0.5);
|
||||
stationList.splice(0, 3); //remove some stations to keep it to 4 stations
|
||||
stationList.splice(0, simulation.difficultyMode > 4 ? 4 : 5); //remove some stations to keep it to 4 stations
|
||||
stationList.unshift(0) //add index zero to the front of the array
|
||||
|
||||
let isExitOpen = false
|
||||
|
||||
@@ -1088,7 +1088,7 @@ const lore = {
|
||||
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
lore.anand.text("How ever it thinks it can learn, and I think we showed it that nonviolence is an option,")
|
||||
lore.anand.text("How ever it thinks, it can learn, and I think we showed it that violence isn't the only option,")
|
||||
}, 1000);
|
||||
},
|
||||
() => {
|
||||
|
||||
106
js/player.js
106
js/player.js
@@ -3647,6 +3647,7 @@ const m = {
|
||||
m.fieldUpgrades[index].effect();
|
||||
simulation.inGameConsole(`<div class="circle-grid field"></div> <span class='color-var'>m</span>.setField("<strong class='color-text'>${m.fieldUpgrades[m.fieldMode].name}</strong>")<br>input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>MouseRight</span>"]`);
|
||||
if (m.fieldMode === 4) simulation.inGameConsole(`simulation<span class='color-symbol'>.</span>molecularMode <span class='color-symbol'>=</span> ${m.fieldUpgrades[4].modeText()} <em style="float: right;font-family: monospace;font-size: 1rem;color: #055;">↓↘→↓↙←↑↑↓</em>`);
|
||||
if (m.fieldMode === 8) simulation.inGameConsole(`Composite<span class='color-symbol'>.</span>add<span class='color-symbol'>(</span>engine.world<span class='color-symbol'>,</span> block<span class='color-symbol'>)</span> <em style ="float: right; font-family: monospace;font-size:1rem;color:#055;">//↓↓→↘↓↙←↓↓</em>`);
|
||||
},
|
||||
fieldEvent: null,
|
||||
fieldUpgrades: [
|
||||
@@ -4209,43 +4210,23 @@ const m = {
|
||||
setDescription() {
|
||||
return `use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br><strong>12</strong> <strong class='color-f'>energy</strong> per second <em style ="float: right; font-family: monospace;font-size:1rem;color:#fff;">↓↘→↓↙←↑↑↓</em>`
|
||||
},
|
||||
keyLog: [],
|
||||
keyLog: [null, null, null, null, null, null, null],
|
||||
effect: () => {
|
||||
//store event function so it can be found and removed in m.setField()
|
||||
m.fieldEvent = function (event) {
|
||||
m.fieldUpgrades[4].keyLog.push(event.code)
|
||||
|
||||
|
||||
// Helper function to compare arrays
|
||||
function arraysEqual(arr1, arr2) {
|
||||
if (arr1.length !== arr2.length) return false;
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] !== arr2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const pattern = [input.key.down, input.key.right, input.key.down, input.key.left, input.key.up, input.key.up, input.key.down]
|
||||
//check if the newest key press is correct
|
||||
if (event.code !== pattern[m.fieldUpgrades[4].keyLog.length - 1]) {
|
||||
m.fieldUpgrades[4].keyLog = [] //pattern is wrong, reset log
|
||||
} else if (arraysEqual(m.fieldUpgrades[4].keyLog, pattern)) { //pattern is complete
|
||||
m.fieldUpgrades[4].keyLog.shift() //remove first element
|
||||
m.fieldUpgrades[4].keyLog.push(event.code) //add new key to end
|
||||
const patternA = ["ArrowDown", "ArrowRight", "ArrowDown", "ArrowLeft", "ArrowUp", "ArrowUp", "ArrowDown"]
|
||||
const patternB = [input.key.down, input.key.right, input.key.down, input.key.left, input.key.up, input.key.up, input.key.down]
|
||||
const arraysEqual = (a, b) => a.length === b.length && a.every((val, i) => val === b[i]);
|
||||
if (arraysEqual(m.fieldUpgrades[4].keyLog, patternA) || arraysEqual(m.fieldUpgrades[4].keyLog, patternB)) {
|
||||
//cycle to next molecular mode
|
||||
m.fieldUpgrades[4].keyLog = []
|
||||
const energy = m.energy //save current energy
|
||||
if (simulation.molecularMode < 3) {
|
||||
simulation.molecularMode++
|
||||
} else {
|
||||
simulation.molecularMode = 0
|
||||
}
|
||||
// m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field, skip field emitter
|
||||
simulation.molecularMode = simulation.molecularMode < 3 ? simulation.molecularMode + 1 : 0
|
||||
m.fieldUpgrades[4].description = m.fieldUpgrades[4].setDescription()
|
||||
m.energy = energy //return to current energy
|
||||
|
||||
const name = `${simulation.molecularMode === 0 ? "<em class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<em>missiles" : simulation.molecularMode === 2 ? "<em class='color-s'>ice IX" : "<em>drones"}</em>`
|
||||
simulation.inGameConsole(`simulation<span class='color-symbol'>.</span>molecularMode <span class='color-symbol'>=</span> ${simulation.molecularMode} // ${name} <em style="float: right;font-family: monospace;font-size: 1rem;color: #055;">↓↘→↓↙←↑↑↓</em>`);
|
||||
}
|
||||
// console.log(m.fieldUpgrades[4].keyLog)
|
||||
// console.log(event.code, m.fieldUpgrades[4].keyLog)
|
||||
}
|
||||
window.addEventListener("keydown", m.fieldEvent);
|
||||
|
||||
@@ -5019,7 +5000,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "metamaterial cloaking",
|
||||
description: `<strong>0.3x</strong> <strong class='color-defense'>damage taken</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>4.5x</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br><strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `<strong>0.4x</strong> <strong class='color-defense'>damage taken</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>4.5x</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br><strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.fieldMeterColor = "#333";
|
||||
@@ -5070,7 +5051,7 @@ const m = {
|
||||
if (!m.isCloak) { //&& m.energy > drain + 0.03
|
||||
// m.energy -= drain
|
||||
m.isCloak = true //enter cloak
|
||||
m.fieldHarmReduction = 0.3;
|
||||
m.fieldHarmReduction = 0.4;
|
||||
m.enterCloakCycle = m.cycle
|
||||
if (tech.isCloakHealLastHit && m.lastHit > 0) {
|
||||
const heal = Math.min(0.75 * m.lastHit, m.energy)
|
||||
@@ -5151,8 +5132,8 @@ const m = {
|
||||
if (inPlayer.length > 0) {
|
||||
for (let i = 0; i < inPlayer.length; i++) {
|
||||
if (m.energy > 0) {
|
||||
if (!inPlayer[i].isUnblockable) m.energy -= 0.003;
|
||||
if (inPlayer[i].shield) m.energy -= 0.011;
|
||||
if (!inPlayer[i].isUnblockable) m.energy -= 0.004 + 0.0005 * simulation.difficultyMode;
|
||||
if (inPlayer[i].shield) m.energy -= 0.015 + 0.001 * simulation.difficultyMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5180,8 +5161,65 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "pilot wave",
|
||||
description: `use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><div class="circle-grid tech"></div>, <div class="circle-grid gun"></div>, and <div class="circle-grid field"></div> have <strong>+3</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><em style ="float: right; font-family: monospace;font-size:1rem;color:#fff;">↓↓→↘↓↙←↓↓</em><br><div class="circle-grid tech"></div>, <div class="circle-grid gun"></div>, and <div class="circle-grid field"></div> have <strong>+3</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
keyLog: [null, null, null, null, null, null, null],
|
||||
effect: () => {
|
||||
//store event function so it can be found and removed in m.setField()
|
||||
m.fieldEvent = function (event) {
|
||||
m.fieldUpgrades[4].keyLog.shift() //remove first element
|
||||
m.fieldUpgrades[4].keyLog.push(event.code) //add new key to end
|
||||
const patternA = ["ArrowDown", "ArrowDown", "ArrowRight", "ArrowDown", "ArrowLeft", "ArrowDown", "ArrowDown"]
|
||||
const patternB = [input.key.down, input.key.down, input.key.right, input.key.down, input.key.left, input.key.down, input.key.down]
|
||||
const arraysEqual = (a, b) => a.length === b.length && a.every((val, i) => val === b[i]);
|
||||
const where = {
|
||||
x: m.pos.x,
|
||||
y: m.pos.y - 75
|
||||
}
|
||||
if (
|
||||
(arraysEqual(m.fieldUpgrades[4].keyLog, patternA) || arraysEqual(m.fieldUpgrades[4].keyLog, patternB))
|
||||
&& !Matter.Query.point(map, where).length
|
||||
) {
|
||||
//remove old blocks
|
||||
// for (let i = 0; i < body.length; i++) {
|
||||
// if (body[i].isPilotWave) {
|
||||
// Matter.Composite.remove(engine.world, body[i]);
|
||||
// body.splice(i, 1);
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
|
||||
//spawn a block
|
||||
const radius = 25 + Math.floor(15 * Math.random())
|
||||
// body[body.length] = Matter.Bodies.polygon(simulation.mouseInGame.x, simulation.mouseInGame.y, 4, radius, {
|
||||
body[body.length] = Matter.Bodies.polygon(where.x, where.y, 4 + Math.floor(4 * Math.random()), radius, {
|
||||
friction: 0.05,
|
||||
frictionAir: 0.001,
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||
},
|
||||
classType: "body",
|
||||
isPilotWave: true,
|
||||
});
|
||||
const block = body[body.length - 1]
|
||||
//mess with the block shape (this code is horrible)
|
||||
Composite.add(engine.world, block); //add to world
|
||||
const r1 = radius * (0.85 + 0.6 * Math.random())
|
||||
const r2 = radius * (0.85 + 0.6 * Math.random())
|
||||
let angle = Math.PI / 4
|
||||
const vertices = []
|
||||
for (let i = 0, len = block.vertices.length; i < len; i++) {
|
||||
angle += 2 * Math.PI / len + 0.06 * Math.random()
|
||||
vertices.push({ x: block.position.x + r1 * Math.cos(angle), y: block.position.y + r2 * Math.sin(angle) })
|
||||
}
|
||||
Matter.Body.setVertices(block, vertices)
|
||||
/* <em style ="float: right; font-family: monospace;font-size:1rem;color:#fff;">↓↘→↓↙←↑↑↓</em> */
|
||||
simulation.inGameConsole(`Composite<span class='color-symbol'>.</span>add<span class='color-symbol'>(</span>engine.world<span class='color-symbol'>,</span> block<span class='color-symbol'>)</span> <em style ="float: right; font-family: monospace;font-size:1rem;color:#fff;">//↓↓→↘↓↙←↓↓</em>`);
|
||||
}
|
||||
}
|
||||
window.addEventListener("keydown", m.fieldEvent);
|
||||
|
||||
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
|
||||
|
||||
61
js/tech.js
61
js/tech.js
@@ -406,12 +406,13 @@ const tech = {
|
||||
m.skin.strokeGap();
|
||||
},
|
||||
remove() {
|
||||
tech.isFireMoveLock = false
|
||||
if (tech.isFireMoveLock) {
|
||||
tech.isFireMoveLock = false
|
||||
b.setFireCD();
|
||||
b.setFireMethod();
|
||||
if (this.count) m.resetSkin();
|
||||
m.resetSkin();
|
||||
}
|
||||
tech.isFireMoveLock = false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -480,7 +481,10 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.isDilate = false
|
||||
if (this.count) m.resetSkin();
|
||||
if (this.count) {
|
||||
m.resetSkin();
|
||||
if (tech.isDiaphragm) m.skin.dilate2()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -490,7 +494,7 @@ const tech = {
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
isSkin: true,
|
||||
// isSkin: true,
|
||||
allowed() {
|
||||
return tech.isDilate
|
||||
},
|
||||
@@ -502,7 +506,10 @@ const tech = {
|
||||
},
|
||||
remove() {
|
||||
tech.isDiaphragm = false
|
||||
if (this.count) m.resetSkin();
|
||||
if (this.count) {
|
||||
m.resetSkin();
|
||||
if (tech.isDilate) m.skin.dilate()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1063,7 +1070,7 @@ const tech = {
|
||||
{
|
||||
name: "cache",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Cache_(computing)' class="link">cache</a>`,
|
||||
description: `<strong>17x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo()}, but<br>you can't <strong>store</strong> additional <strong class='color-ammo'>ammo</strong>`,
|
||||
description: `<strong>15x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo()}, but<br>you can't <strong>store</strong> additional <strong class='color-ammo'>ammo</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1073,7 +1080,7 @@ const tech = {
|
||||
},
|
||||
requires: "not non-renewables",
|
||||
effect() {
|
||||
tech.ammoCap = 17;
|
||||
tech.ammoCap = 15;
|
||||
powerUps.ammo.effect()
|
||||
},
|
||||
remove() {
|
||||
@@ -7372,7 +7379,7 @@ const tech = {
|
||||
requestAnimationFrame(() => {
|
||||
let techGiven = 0
|
||||
for (let j = 0; j < 3; j++) {
|
||||
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"]
|
||||
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", "collimator"]
|
||||
//convert names into indexes
|
||||
const options = []
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
@@ -7514,7 +7521,7 @@ const tech = {
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade || tech.isLaserField) && !tech.isWideLaser && !tech.isPulseLaser && !tech.historyLaser
|
||||
},
|
||||
requires: "laser, not diffuse beam, pulse, or slow light",
|
||||
requires: "laser, not diffuse beam, pulse, slow light",
|
||||
effect() {
|
||||
tech.laserReflections += 2;
|
||||
},
|
||||
@@ -7533,7 +7540,7 @@ const tech = {
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && !tech.isWideLaser && !tech.historyLaser
|
||||
},
|
||||
requires: "laser gun, diffuse beam, or slow light",
|
||||
requires: "laser gun, not diffuse beam, slow light",
|
||||
effect() {
|
||||
tech.beamSplitter++
|
||||
b.guns[11].chooseFireMethod()
|
||||
@@ -7545,6 +7552,29 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "collimator",
|
||||
description: `<strong>+1</strong> <strong class='color-laser'>laser</strong> beam<br>align your diverging <strong class='color-laser'>laser</strong> beams to be <strong>parallel</strong>`,
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && !tech.isWideLaser && !tech.historyLaser && tech.beamSplitter > 0 && !tech.isPulseLaser
|
||||
},
|
||||
requires: "laser gun, diffraction, not diffuse beam, slow light, pulse",
|
||||
effect() {
|
||||
tech.beamSplitter++
|
||||
tech.beamCollimator = true
|
||||
b.guns[11].chooseFireMethod()
|
||||
},
|
||||
remove() {
|
||||
tech.beamCollimator = false
|
||||
if (tech.beamSplitter > 0) tech.beamSplitter--
|
||||
b.guns[11].chooseFireMethod()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "diffuse beam",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Diffuser_(optics)' class="link">diffuse beam</a>`,
|
||||
@@ -7607,7 +7637,7 @@ const tech = {
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && !tech.beamSplitter && !tech.isWideLaser
|
||||
},
|
||||
requires: "laser gun, diffraction grating, diffuse beam",
|
||||
requires: "laser gun, not diffraction grating, diffuse beam",
|
||||
effect() {
|
||||
tech.historyLaser++
|
||||
b.guns[11].chooseFireMethod()
|
||||
@@ -7657,8 +7687,8 @@ const tech = {
|
||||
effect() {
|
||||
tech.laserDrain *= 0.75
|
||||
tech.laserDamage *= 1.25
|
||||
tech.laserColor = "rgb(0, 11, 255)"
|
||||
tech.laserColorAlpha = "rgba(0, 11, 255,0.5)"
|
||||
tech.laserColor = "rgb(0, 40, 255)"
|
||||
tech.laserColorAlpha = "rgba(0, 40, 255,0.5)"
|
||||
},
|
||||
remove() {
|
||||
tech.laserDrain = 0.003;
|
||||
@@ -7701,9 +7731,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDrain === 0.003 && !tech.isStuckOn
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDrain === 0.003 && !tech.isStuckOn && !tech.beamCollimator
|
||||
},
|
||||
requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier",
|
||||
requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier, collimator",
|
||||
effect() {
|
||||
tech.isPulseLaser = true;
|
||||
b.guns[11].chooseFireMethod()
|
||||
@@ -12319,4 +12349,5 @@ const tech = {
|
||||
isDemineralize: null,
|
||||
mineralDamage: null,
|
||||
negativeMassCost: null,
|
||||
beamCollimator: null,
|
||||
}
|
||||
@@ -9,6 +9,7 @@ body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
cursor: auto;
|
||||
background-color: #f00;
|
||||
/* filter: grayscale(1); */
|
||||
/* transition: background-color 0.2s ease-in-out; */
|
||||
}
|
||||
|
||||
37
todo.txt
37
todo.txt
@@ -1,17 +1,22 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
mantisBoss flashes for a second before it drops invulnerability
|
||||
removed parasitism - it's too similar to invulnerability tech
|
||||
invariant no longer drains energy while wormhole time is paused
|
||||
added 1 research cost
|
||||
added secret combo to change molecular assembler mode
|
||||
tech: collimator - add 1 laser beam and align your diverging beams to be parallel
|
||||
requires diffraction grating
|
||||
|
||||
added secret pilot wave combo to make blocks
|
||||
rewrote combo test algorithm to be more forgiving with pattern matching
|
||||
also extended combos test to arrow keys, not just WASD
|
||||
|
||||
cache 17->15x ammo
|
||||
metamaterial cloaking 0.3->0.4x damage reduction while cloaked
|
||||
boson composite drains more energy when passing through mobs
|
||||
scales with difficulty
|
||||
subway level has 6->4 (5 on hard difficulty) stations
|
||||
subway gives 1/3->1/5 interest per station
|
||||
|
||||
bug fixes
|
||||
issue with constraint: "mob death heals mobs"
|
||||
mob health was becoming NaN, this was infecting other values like player energy
|
||||
entering a seed in settings wasn't giving the same results as a randomly generated seeds
|
||||
also removed some random code that was using seeded shuffle, but didn't need to
|
||||
converted it to non seeded random shuffle with .sort(() => Math.random() - 0.5);
|
||||
Higgs skin removal fixed
|
||||
diaphragm skin removal fixed
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
@@ -19,9 +24,10 @@ player can become crouched while not touching the ground if they exit the ground
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
soft body boss?
|
||||
search softBody(x, y, angle = 0, isAttached = true, len = 15, radius = 20, stiffness = 1, damping = 1) {
|
||||
|
||||
use ←↑→↓↖↗↘↙ combos to allow fields to have special actions
|
||||
!!should this be wasd, arrows, or both?
|
||||
how to limit spam?
|
||||
on cooldown
|
||||
timer or once per level
|
||||
@@ -40,8 +46,7 @@ use ←↑→↓↖↗↘↙ combos to allow fields to have special actions
|
||||
plasma torch
|
||||
time dilation
|
||||
metamaterial cloaking
|
||||
pilot wave
|
||||
spawn blocks
|
||||
pilot wave - done
|
||||
wormhole
|
||||
shoot out all the blocks that were sucked in this level (maybe cap at like 10?, cap with energy spent to fire)
|
||||
are block sizes stored properly? because they shrink before they get eaten...
|
||||
@@ -52,6 +57,12 @@ use ←↑→↓↖↗↘↙ combos to allow fields to have special actions
|
||||
fire from player (and draw a wormhole looking graphic)
|
||||
grappling hook
|
||||
|
||||
new level idea: large map sized blocks that can't be destroyed that the player walks on as a part of the level
|
||||
eventually the blocks fall
|
||||
after fall level progresses to a phase 2 to clean up the blocks or leave them
|
||||
should bosses be killed by falling blocks??
|
||||
how to avoid the large block vibrating/dancing on tiny block issue
|
||||
|
||||
new level idea: escort mission
|
||||
player has to stay near something that moves slowly through the level
|
||||
maybe only a zone around the escort is safe
|
||||
|
||||
Reference in New Issue
Block a user