JUNK % and pause sort

new tech are sorted to the top of the tech list
  pause menu tech list matches the tech list in game
JUNK tech icons are properly displayed in pause
Sort interface works with enter key
bug fix: you can no longer pause or enter testing in experiment selection on text input
pressing P in power up selection menu brings up the pause menu
  so you can see your tech and stats
blocks stuck in vertical portals have a bit of randomness added to their velocity to help them escape

JUNK tech chance is a raw percent chance to display a random JUNK
  it was previously a specific JUNK tech directly added to the pool
  this might cause bugs
JUNK tech: beforeunload - asks if you want to cancel if you exit game, if you cancel gain 25% damage, but there is a 25% chance to exit anyways
JUNK tech: what the block? - trying to throw a block, throws you instead
reinforcement learning converted into a JUNK tech
JUNK DNA - scale damage by 100->200% of JUNK pool tech percent
dark patterns 33->22% JUNK
replication 33->22% JUNK

overcharge 66->88 max energy
residual dipolar coupling 6->8 coupling per cancel
futures exchange 4.7->5% duplication per cancel
hyperpolarization reduces polarization time by 1->1.25 seconds
reel +75->100 energy

updated physics engine to matter.js 0.19 (from 0.18)
This commit is contained in:
landgreen
2024-03-11 20:19:37 -07:00
parent 64f2a9f081
commit 64c81cd802
8 changed files with 389 additions and 213 deletions

View File

@@ -1519,7 +1519,7 @@ const b = {
if (this.pickUpTarget) {
if (tech.isReel && this.blockDist > 150) {
// console.log(0.0003 * Math.min(this.blockDist, 1000))
m.energy += 0.0009 * Math.min(this.blockDist, 800) //max 0.352 energy
m.energy += 0.00113 * Math.min(this.blockDist, 800) //max 0.352 energy
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,

View File

@@ -129,6 +129,19 @@ function vertexCollision(v1, v1End, domains) { //= [map, body, [playerBody, pla
return best
}
// prompts to reload and exit for JUNK tech named "beforeunload"
function beforeUnloadEventListener(event) {
event.preventDefault();
if (tech.isExitPrompt) {
tech.damage *= 1.25
simulation.makeTextLog(`damage <span class='color-symbol'>*=</span> ${1.25}`)
if (Math.random() < 0.25) {
removeEventListener('beforeunload', beforeUnloadEventListener);
}
}
}
// addEventListener('beforeunload', beforeUnloadEventListener);
//collision groups
// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield | cat.phased
@@ -425,6 +438,7 @@ const build = {
pauseGrid() {
build.generatePauseLeft() //makes the left side of the pause menu with the tech
build.generatePauseRight() //makes the right side of the pause menu with the tech
// build.sortTech('') //sorts tech into the order the player got them using tech.tech[i].cycle = m.cycle
document.getElementById("tech").style.display = "none"
document.getElementById("guns").style.display = "none"
document.getElementById("field").style.display = "none"
@@ -436,15 +450,6 @@ const build = {
simulation.lastLogTime = m.cycle //hide in game console
},
generatePauseLeft() {
//used for junk estimation
let junkCount = 0
let totalCount = 1 //start at one to avoid NaN issues
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
totalCount += tech.tech[i].frequency
if (tech.tech[i].isJunk) junkCount += tech.tech[i].frequency
}
}
//left side
let botText = ""
if (tech.nailBotCount) botText += `<br>nail-bots: ${tech.nailBotCount}`
@@ -487,7 +492,7 @@ ${botText}
<span style="float: right;">mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})</span>
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<span style="float: right;">velocity: (${player.velocity.x.toFixed(3)}, ${player.velocity.y.toFixed(3)})</span>
${junkCount ? `<br><strong class='color-junk'>JUNK</strong>: ${(junkCount / totalCount * 100).toFixed(1)}% ` : ""}
${tech.junkChance ? `<br><strong class='color-junk'>JUNK</strong>: ${(100 * tech.junkChance).toFixed(1)}% ` : ""}
<br>
<br>level: ${level.levelsCleared} ${level.levels[level.onLevel]} (${level.difficultyText()})
<br>mobs: ${spawn.pickList[0]}, ${spawn.pickList[0]}
@@ -542,14 +547,6 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
el.innerHTML = text
},
generatePauseRight() {
//right side
// <input onclick="" type="checkbox" id="sort-damage" name="sort-damage" style="width:1em; height:1em;">
// <label for="sort-damage" title="sort tech by damage"><strong class='color-d'>damage</strong></label>
// <input onclick="build.sortTech('guntech')" type="checkbox" id="sort-guntech" name="sort-guntech" style="width:1em; height:1em;">
// <label for="sort-guntech" title="sort guntech"> <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></label>
// <button onclick="build.sortTech('bot')" class='sort-button'><strong class='color-bot'>bot</strong></button>
let text = `<div class="sort">
<button onclick="build.sortTech('damage')" class='sort-button'><strong class='color-d'>damage</strong></button>
<button onclick="build.sortTech('guntech')" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
@@ -560,38 +557,13 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
<input type="search" id="sort-input" style="width: 8em;font-size: 0.6em;color:#000;" placeholder="sort by"/>
<button onclick="build.sortTech('input')" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>`;
// const style = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : ''
const ejectClass = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'pause-eject' : ''
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
// const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
// if (tech.tech[i].isNonRefundable) {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// } else if (tech.tech[i].isFieldTech) {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title">
// <span style="position:relative;">
// <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
// <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
// </span>
// &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// } else if (tech.tech[i].isGunTech) {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title">
// <span style="position:relative;">
// <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
// <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
// </span>
// &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// } else if (tech.tech[i].isLore) {
// text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[i].name} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// } else {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// }
const style = (localSettings.isHideImages || tech.tech[i].isJunk || tech.tech[i].isLore) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"`
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isNonRefundable) {
text += `<div class="pause-grid-module" id ="${i}-pause-tech" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div></div>`
// } else if (tech.tech[i].isLore) {
// text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[i].name} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isFieldTech) {
text += `<div id="${i}-pause-tech" class="pause-grid-module card-background ${ejectClass}" onclick="powerUps.pauseEjectTech(${i})" ${style}>`
text += build.fieldTechText(i) + "</div>"
@@ -601,6 +573,9 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
} else if (tech.tech[i].isSkin) {
text += `<div id="${i}-pause-tech" class="pause-grid-module card-background ${ejectClass}" onclick="powerUps.pauseEjectTech(${i})" ${style}>`
text += build.skinTechText(i) + "</div>"
} else if (tech.tech[i].isJunk) {
text += `<div id="${i}-pause-tech" class="pause-grid-module card-background ${ejectClass}" onclick="powerUps.pauseEjectTech(${i})" ${style}>`
text += build.junkTechText(i) + "</div>"
} else {
text += `<div id="${i}-pause-tech" class="pause-grid-module card-background ${ejectClass}" onclick="powerUps.pauseEjectTech(${i})" ${style}>`
text += build.techText(i) + "</div>"
@@ -612,6 +587,17 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
const el = document.getElementById("pause-grid-right")
el.style.display = "grid"
el.innerHTML = text
//add event listener for pressing enter key when in sort
function pressEnterSort(event) {
if (event.key === 'Enter') {
requestAnimationFrame(() => { document.getElementById("sort-input").focus(); });
// event.preventDefault(); // Prevent the default action to avoid form submission or any other default action
build.sortTech('input')
}
}
document.getElementById("sort-input").addEventListener('keydown', pressEnterSort);
requestAnimationFrame(() => { document.getElementById("sort-input").focus(); });
},
sortTech(find, isExperiment = false) {
const sortKeyword = (a, b) => {
@@ -621,6 +607,16 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
if (!aHasKeyword && bHasKeyword) return 1;
return 0;
}
// if (find === '') {
// tech.tech.sort((a, b) => { //sorts tech into the order the player got them using tech.tech[i].cycle = m.cycle
// console.log(a.cycle, b.cycle)
// if (a.cycle === undefined && b.cycle !== undefined) return -1;
// if (a.cycle !== undefined && b.cycle === undefined) return 1;
// if (a.cycle === undefined && b.cycle === undefined) return 0;
// if (a.cycle !== b.cycle) return a.cycle - b.cycle;
// });
// } else
if (find === 'guntech') {
tech.tech.sort((a, b) => {
if (a.isGunTech && b.isGunTech) {
@@ -704,6 +700,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
build.generatePauseRight() //makes the right side of the pause menu with the tech
}
document.getElementById("sort-input").value = find; //make the sorted string display in the keyword search input field
simulation.updateTechHUD();
},
unPauseGrid() {
document.getElementById("guns").style.display = "inline"
@@ -961,10 +958,17 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
}
}
document.getElementById("experiment-grid").innerHTML = text
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count)
// document.getElementById("tech-" + i).classList.add("build-tech-selected")
// }
//add event listener for pressing enter key when in sort
function pressEnterSort(event) {
if (event.key === 'Enter') {
// event.preventDefault(); // Prevent the default action to avoid form submission or any other default action
build.sortTech('input', true)
}
}
document.getElementById("sort-input").addEventListener('keydown', pressEnterSort);
document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
@@ -1348,12 +1352,15 @@ window.addEventListener("keydown", function (event) {
simulation.previousGun();
break
case input.key.pause:
if (!simulation.isChoosing && input.isPauseKeyReady && m.alive) {
if (input.isPauseKeyReady && m.alive && !build.isExperimentSelection) {
input.isPauseKeyReady = false
setTimeout(function () {
input.isPauseKeyReady = true
}, 300);
if (simulation.paused) {
setTimeout(function () { input.isPauseKeyReady = true }, 300);
if (simulation.isChoosing) {
build.pauseGrid()
} else if (simulation.paused) {
build.unPauseGrid()
simulation.paused = false;
// level.levelAnnounce();
@@ -1404,7 +1411,7 @@ window.addEventListener("keydown", function (event) {
}
break
case input.key.testing:
if (m.alive && localSettings.loreCount > 0 && !simulation.paused) {
if (m.alive && localSettings.loreCount > 0 && !simulation.paused && !build.isExperimentSelection) {
if (simulation.difficultyMode > 4) {
simulation.makeTextLog("<em>testing mode disabled for this difficulty</em>");
break

View File

@@ -33,26 +33,25 @@ const level = {
// m.energy = 0
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("drones") //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("mine") //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("laser") //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[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("Higgs mechanism") });
// for (let i = 0; i < 1; ++i) tech.giveTech("flame test")
// for (let i = 0; i < 1; ++i) tech.giveTech("dazzler")
// for (let i = 0; i < 1; ++i) tech.giveTech("mass production")
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) tech.giveTech("orbital-bot") });
// requestAnimationFrame(() => { tech.giveTech("eternalism") });
// for (let i = 0; i < 1; ++i) tech.giveTech("beforeunload")
// for (let i = 0; i < 1; ++i) tech.giveTech("Sleipnir")
// for (let i = 0; i < 1; ++i) tech.giveTech("dark patterns")
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("paradigm shift") });
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
// m.skin.hexagon();
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
// m.lastKillCycle = m.cycle
// for (let i = 0; i < 1; ++i) tech.giveTech("swarf")
// for (let i = 0; i < 1; ++i) tech.giveTech("what the block?")
// for (let i = 0; i < 1; ++i) tech.giveTech("unified field theory")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
// level.testing();
// level.testChamber();
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
@@ -75,7 +74,7 @@ const level = {
// simulation.isAutoZoom = false; //look in close
// simulation.zoomScale *= 0.5;
// simulation.setZoom();
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 10; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "boost");
// for (let i = 0; i < 20; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "heal");
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
@@ -1570,7 +1569,6 @@ const level = {
}
}
}
// if (body.length) {
for (let i = 0, len = body.length; i < len; i++) {
if (body[i] !== m.holdingTarget) {
// body[i].bounds.max.x - body[i].bounds.min.x < 100 && body[i].bounds.max.y - body[i].bounds.min.y < 100
@@ -1591,17 +1589,20 @@ const level = {
}
//rotate velocity
let mag
if (this.portalPair.angle !== 0 && this.portalPair.angle !== Math.PI) { //portal that fires the player up
if (this.portalPair.angle !== 0 && this.portalPair.angle !== Math.PI) { //portal that fires up
mag = Math.max(10, Math.min(50, body[i].velocity.y * 0.8)) + 11
let v = Vector.mult(this.portalPair.unit, mag)
//rotate the velocity vector of blocks fired directly up to keep them from getting stuck endlessly in vertical portals
Matter.Body.setVelocity(body[i], Vector.rotate(v, 0.5 * (Math.random() - 0.5)));
} else {
mag = Math.max(6, Math.min(50, Vector.magnitude(body[i].velocity)))
}
let v = Vector.mult(this.portalPair.unit, mag)
Matter.Body.setVelocity(body[i], v);
}
}
}
}
// }
//remove block if touching
// if (body.length) {

View File

@@ -362,10 +362,10 @@ const m = {
// tech.removeLoreTechFromPool();
// tech.addLoreTechToPool();
// tech.removeJunkTechFromPool();
tech.junkChance = 0;
tech.duplication = 0;
tech.extraMaxHealth = 0;
tech.totalCount = 0;
tech.countJunkTech();
const randomBotCount = b.totalBots()
b.zeroBotCount()
//remove all bullets, respawn bots
@@ -547,7 +547,6 @@ const m = {
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
},
defaultFPSCycle: 0, //tracks when to return to normal fps
immuneCycle: 0, //used in engine
lastCalculatedDamage: 0, //used to decided if damage bar needs to be redrawn (in simulation.checks)
@@ -2329,7 +2328,8 @@ const m = {
m.isHolding = false
}
},
throwBlock() {
throwBlock() { },
throwBlockDefault() {
if (m.holdingTarget) {
if (input.field) {
if (m.energy > 0.001) {
@@ -2478,6 +2478,116 @@ const m = {
m.isHolding = false
}
},
throwSelf() {
if (m.holdingTarget) {
if (input.field) {
if (m.energy > 0.001) {
if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle
if (tech.isCapacitor && m.throwCharge < 4) m.throwCharge = 4
m.throwCharge += 0.5 / m.holdingTarget.mass / b.fireCDscale
if (m.throwCharge < 6) m.energy -= 0.001 / b.fireCDscale; // m.throwCharge caps at 5
//trajectory path prediction
//draw charge
const x = m.pos.x + 15 * Math.cos(m.angle);
const y = m.pos.y + 15 * Math.sin(m.angle);
const len = m.holdingTarget.vertices.length - 1;
const edge = m.throwCharge * m.throwCharge * m.throwCharge;
const grd = ctx.createRadialGradient(x, y, edge, x, y, edge + 5);
grd.addColorStop(0, "rgba(255,50,150,0.3)");
grd.addColorStop(1, "transparent");
ctx.fillStyle = grd;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(m.holdingTarget.vertices[len].x, m.holdingTarget.vertices[len].y);
ctx.lineTo(m.holdingTarget.vertices[0].x, m.holdingTarget.vertices[0].y);
ctx.fill();
for (let i = 0; i < len; i++) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(m.holdingTarget.vertices[i].x, m.holdingTarget.vertices[i].y);
ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y);
ctx.fill();
}
//trajectory prediction
const cycles = 30
const charge = Math.min(m.throwCharge / 5, 1)
const speed = (tech.isPrinter ? 15 + 80 * charge * Math.min(0.85, 0.8 / Math.pow(m.holdingTarget.mass, 0.1)) : 80 * charge * Math.min(0.85, 0.8 / Math.pow(m.holdingTarget.mass, 0.25)))
const v = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
ctx.beginPath()
for (let i = 1, len = 10; i < len + 1; i++) {
const time = cycles * i / len
ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + 0.34 * time * time)
}
ctx.strokeStyle = "rgba(68, 68, 68, 0.15)" //color.map
ctx.lineWidth = 2
ctx.stroke()
} else {
m.drop()
}
} else if (m.throwCharge > 0) { //Matter.Query.region(mob, player.bounds)
if (m.holdingTarget.isPrinted) m.holdingTarget.isPrinted = undefined
//throw the body
m.fieldCDcycle = m.cycle + 20;
m.fireCDcycle = m.cycle + 20;
m.isHolding = false;
//bullet-like collisions
m.holdingTarget.collisionFilter.category = cat.bullet
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
if (tech.isBlockRestitution) {
m.holdingTarget.restitution = 0.999 //extra bouncy
m.holdingTarget.friction = m.holdingTarget.frictionStatic = m.holdingTarget.frictionAir = 0.001
}
//check every second to see if player is away from thrown body, and make solid
const solid = function (that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
// if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
if (dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
that.collisionFilter.category = cat.body; //make solid
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {
setTimeout(solid, 40, that);
}
};
setTimeout(solid, 200, m.holdingTarget);
const charge = Math.min(m.throwCharge / 5, 1)
//***** scale throw speed with the first number, 80 *****
// let speed = 80 * charge * Math.min(0.85, 0.8 / Math.pow(m.holdingTarget.mass, 0.25));
let speed = (tech.isPrinter ? 15 + 80 * charge * Math.min(0.85, 0.8 / Math.pow(m.holdingTarget.mass, 0.1)) : 80 * charge * Math.min(0.85, 0.8 / Math.pow(m.holdingTarget.mass, 0.25)))
m.throwCharge = 0;
m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds
Matter.Body.setVelocity(m.holdingTarget, {
x: Math.cos(m.angle) * speed / (m.crouch ? 30 : 10) * Math.sqrt(m.holdingTarget.mass),
y: player.velocity.y - Math.sin(m.angle) * speed / 30 * Math.sqrt(m.holdingTarget.mass)
});
Matter.Body.setVelocity(player, {
x: player.velocity.x - player.velocity.x * 0.5 + Math.cos(m.angle) * speed,
y: player.velocity.y - player.velocity.y * 0.5 + Math.sin(m.angle) * speed
});
m.definePlayerMass() //return to normal player mass
if (tech.isAddBlockMass) {
const expand = function (that, massLimit) {
if (that.mass < massLimit) {
const scale = 1.04;
Matter.Body.scale(that, scale, scale);
setTimeout(expand, 20, that, massLimit);
}
};
expand(m.holdingTarget, Math.min(20, m.holdingTarget.mass * 3))
}
}
} else {
m.isHolding = false
}
},
drawField() {
if (m.holdingTarget) {
ctx.fillStyle = "rgba(110,170,200," + (m.energy * (0.05 + 0.05 * Math.random())) + ")";

View File

@@ -326,7 +326,7 @@ const powerUps = {
return
}
if (tech.isCancelDuplication) {
tech.duplication += 0.047
tech.duplication += 0.05
tech.maxDuplicationEvent()
simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.043}`)
simulation.circleFlare(0.043);
@@ -344,7 +344,7 @@ const powerUps = {
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
}
}
if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 6)
if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 8)
// if (tech.isCancelTech && Math.random() < 0.3) {
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false);
// simulation.makeTextLog(`<strong>options exchange</strong>: returns 1 <strong class='color-m'>tech</strong>`)
@@ -958,9 +958,6 @@ const powerUps = {
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
}
if (botTech.length > 0) { //pick random bot tech
// const choose = botTech[Math.floor(Math.random() * botTech.length)];
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
@@ -1024,9 +1021,6 @@ const powerUps = {
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
}
if (botTech.length > 0) { //pick random bot tech
// const choose = botTech[Math.floor(Math.random() * botTech.length)];
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"> <span style = "font-size: 150%;font-family: 'Courier New', monospace;">⭓▸●■</span> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
const choose = botTech[Math.floor(Math.random() * botTech.length)];
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
@@ -1051,14 +1045,10 @@ const powerUps = {
effect() {
if (m.alive) {
// powerUps.animatePowerUpGrab('hsla(246, 100%, 77%,0.5)')
let junkCount = 0 //used for junk estimation
let totalCount = 0 //used for junk estimation
let options = []; //generate all options
optionLengthNoDuplicates = 0
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
totalCount += tech.tech[i].frequency
if (tech.tech[i].isJunk) junkCount += tech.tech[i].frequency
if (tech.tech[i].frequency > 0) optionLengthNoDuplicates++
for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
}
@@ -1111,7 +1101,14 @@ const powerUps = {
}
removeOption(choose) //move from future options pool to avoid repeats on this selection
tech.tech[choose].isRecentlyShown = true //this flag prevents this option from being shown the next time you pick up a tech power up
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
if (Math.random() < tech.junkChance) { // choose is set to a random JUNK tech
const list = []
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isJunk) list.push(i)
}
chooseJUNK = list[Math.floor(Math.random() * list.length)]
text += powerUps.junkTechText(chooseJUNK, `powerUps.choose('tech',${chooseJUNK})`)
} else {
if (tech.tech[choose].isFieldTech) {
text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`)
} else if (tech.tech[choose].isGunTech) {
@@ -1125,6 +1122,7 @@ const powerUps = {
}
if (options.length < 1) break
}
}
if (tech.isExtraBotOption) {
const botTech = [] //make an array of bot options
for (let i = 0, len = tech.tech.length; i < len; i++) {

View File

@@ -418,6 +418,15 @@ const simulation = {
simulation.boldActiveGunHUD();
},
updateTechHUD() {
// tech.tech.sort((a, b) => {
// console.log(a.cycle, b.cycle)
// if (a.cycle === undefined && b.cycle !== undefined) return -1;
// if (a.cycle !== undefined && b.cycle === undefined) return 1;
// if (a.cycle === undefined && b.cycle === undefined) return 0;
// if (a.cycle !== b.cycle) return a.cycle - b.cycle;
// });
let text = ""
for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
if (tech.tech[i].isLost) {

View File

@@ -29,9 +29,9 @@ const tech = {
// tech.removeJunkTechFromPool();
// tech.removeLoreTechFromPool();
// tech.addLoreTechToPool();
tech.junkChance = 0;
tech.extraMaxHealth = 0;
tech.totalCount = 0;
tech.junkCount = 0 //tech.countJunkTech();
simulation.updateTechHUD();
simulation.updateGunHUD();
},
@@ -63,7 +63,6 @@ const tech = {
tech.tech[index].remove();
tech.tech[index].count = 0;
tech.totalCount -= totalRemoved
tech.countJunkTech();
simulation.updateTechHUD();
tech.tech[index].isLost = true
simulation.updateTechHUD();
@@ -82,36 +81,41 @@ const tech = {
// if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1)
// }
// },
junkChance: 0,
addJunkTechToPool(percent) { //percent is number between 0-1
tech.junkPoolPercent += percent
tech.junkChance += (1 - tech.junkChance) * percent
return percent
//make an array for possible junk tech to add
let options = [];
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].isJunk) options.push(i);
}
if (options.length) {
let countNonJunk = 0 // count total non junk tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) countNonJunk += tech.tech[i].frequency
}
const num = Math.ceil(percent * countNonJunk) //scale number added
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ //add random array options to tech pool
simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`)
return num
} else {
return 0
}
// let options = [];
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].isJunk) options.push(i);
// }
// if (options.length) {
// let countNonJunk = 0 // count total non junk tech
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) countNonJunk += tech.tech[i].frequency
// }
// const num = Math.ceil(percent * countNonJunk) //scale number added
// for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ //add random array options to tech pool
// simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`)
// return num
// } else {
// return 0
// }
},
removeJunkTechFromPool(num = 1) {
for (let j = 0; j < num; j++) {
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isJunk && tech.tech[i].frequency > 0 && tech.tech[i].count < tech.tech[i].maxCount) {
tech.tech[i].frequency--
break
removeJunkTechFromPool(percent) {
// for (let j = 0; j < num; j++) {
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech[i].isJunk && tech.tech[i].frequency > 0 && tech.tech[i].count < tech.tech[i].maxCount) {
// tech.tech[i].frequency--
// break
// }
// }
// }
if (percent > 0) {
tech.junkChance = (tech.junkChance - percent) / (1 - percent)
if (tech.junkChance < 0.001 || tech.junkChance === undefined) tech.junkChance = 0
}
}
}
tech.junkPoolPercent = 0
},
giveRandomJUNK() {
const list = []
@@ -123,6 +127,10 @@ const tech = {
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${name}</span>")<em>`);
},
giveTech(index = 'random') {
// if (Math.random() < tech.junkChance) {
// tech.giveRandomJUNK();
// return
// }
if (index === 'random') {
let options = [];
for (let i = 0; i < tech.tech.length; i++) {
@@ -157,27 +165,20 @@ const tech = {
if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false //stops the bug where you can't gets stacks of tech you take with decoherence, I think
tech.tech[index].effect(); //give specific tech
tech.tech[index].count++
// tech.tech[index].cycle = m.cycle
console.log(tech.tech[index].cycle)
tech.totalCount++ //used in power up randomization
tech.countJunkTech();
//move new tech to the top of the tech list
if (index > 0) {
// Remove the element from the array
const [item] = tech.tech.splice(index, 1);
// Add the element to the front of the array
tech.tech.unshift(item);
}
simulation.updateTechHUD();
}
},
junkPoolPercent: 0,
junkCount: 0,
countJunkTech() {
tech.junkCount = 0
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && tech.tech[i].isJunk) tech.junkCount++
}
},
// setTechoNonRefundable(name) {
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech.name === name) {
// tech.tech[i].isNonRefundable = true;
// return
// }
// }
// },
setCheating() {
if (!simulation.isCheating) {
simulation.isCheating = true;
@@ -261,7 +262,7 @@ const tech = {
if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3;
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.defense()) // if (!simulation.paused) m.lastHit = 0
if (tech.isLowHealthDmg) dmg *= 1 + 0.7 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))
if (tech.isJunkDNA) dmg *= 1 + tech.junkPoolPercent
if (tech.isJunkDNA) dmg *= 1 + 2 * tech.junkChance
return dmg
},
duplicationChance() {
@@ -536,7 +537,9 @@ const tech = {
name: "depolarization",
descriptionFunction() {
// return `<strong>+300%</strong> <strong class='color-d'>damage</strong> or <strong>-50%</strong> <strong class='color-d'>damage</strong><br>if a mob has <strong>died</strong> in the last <strong>5 seconds</strong>`
return `<span style = 'font-size:88%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> if <strong>no</strong> mobs <strong>died</strong> in the last <strong>${(tech.isDamageCooldownTime / 60).toFixed(0)} seconds</strong><br><strong>-55%</strong> <strong class='color-d'>damage</strong> if a mob <strong>died</strong> in the last <strong>${(tech.isDamageCooldownTime / 60).toFixed(0)} seconds</strong></span > `
// return `<span style = 'font-size:88%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> if <strong>no</strong> mobs <strong>died</strong> in the last <strong>${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds</strong><br><strong>-55%</strong> <strong class='color-d'>damage</strong> if a mob <strong>died</strong> in the last <strong>${(tech.isDamageCooldownTime / 60).toFixed(0)} seconds</strong></span> `
// return `<span style = 'font-size:90%;'><strong>-55%</strong> <strong class='color-d'>damage</strong> if a mob <strong>died</strong> in the last <strong>${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds</strong><br>otherwise do <strong>+333%</strong> <strong class='color-d'>damage</strong></span>`
return `<span style = 'font-size:95%;'><strong>-55%</strong> <strong class='color-d'>damage</strong> for <strong>${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds</strong> after a mob <strong>dies</strong><br><strong>+333%</strong> <strong class='color-d'>damage</strong> otherwise</span>`
},
maxCount: 1,
count: 0,
@@ -559,7 +562,7 @@ const tech = {
{
name: "hyperpolarization",
descriptionFunction() {
return `the <strong class= 'color-d'> damage</strong> from <strong> depolarization</strong> <br>resets <strong>1 second</strong> sooner after a mob has <strong>died</strong>`
return `the <strong class= 'color-d'> damage</strong> from <strong> depolarization</strong> <br>resets <strong>1.25 seconds</strong> sooner after a mob <strong>dies</strong>`
},
maxCount: 3,
count: 0,
@@ -570,7 +573,7 @@ const tech = {
},
requires: "depolarization",
effect() {
tech.isDamageCooldownTime -= 60
tech.isDamageCooldownTime -= 75
},
remove() {
tech.isDamageCooldownTime = 240
@@ -661,7 +664,7 @@ const tech = {
},
{
name: "ordnance",
description: "<strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong> and <strong>+7%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
description: "<strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong> and <strong>+6%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 1,
count: 0,
frequency: 1,
@@ -675,7 +678,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
}
this.refundAmount += tech.addJunkTechToPool(0.07)
this.refundAmount += tech.addJunkTechToPool(0.06)
},
refundAmount: 0,
remove() {
@@ -2915,7 +2918,7 @@ const tech = {
},
{
name: "overcharge",
description: "<strong>+66</strong> maximum <strong class='color-f'>energy</strong><br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
description: "<strong>+88</strong> maximum <strong class='color-f'>energy</strong><br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -3942,7 +3945,7 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.junkCount > 0
return tech.junkChance > 0
},
requires: "some JUNK tech",
effect() {
@@ -3954,7 +3957,7 @@ const tech = {
},
{
name: "dark patterns",
description: "<strong>+22%</strong> <strong class='color-d'>damage</strong><br><strong>+22%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
description: "<strong>+22%</strong> <strong class='color-d'>damage</strong><br><strong>+11%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -3966,7 +3969,7 @@ const tech = {
damage: 1.22,
effect() {
tech.damage *= this.damage
this.refundAmount += tech.addJunkTechToPool(0.22)
this.refundAmount += tech.addJunkTechToPool(0.11)
},
refundAmount: 0,
remove() {
@@ -3979,29 +3982,21 @@ const tech = {
{
name: "junk DNA",
descriptionFunction() {
// return ` <strong>+100%</strong> ${b.guns[6].nameString()} <strong class='color-d'>damage</strong> per <strong class='color-junk'>JUNK</strong><strong class='color-m'>tech</strong> <em>(${(100 * tech.junkCount).toFixed(0)}%)</em><br><strong>+33%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool`
return `<strong class='color-d'>damage</strong> scales with <strong class='color-junk'>JUNK</strong> <strong class='color-m'>tech</strong> pool percent`
return `increase <strong class='color-d'>damage</strong> by twice the<br><strong class='color-junk'>JUNK</strong> <strong class='color-m'>tech</strong> pool percent <em>(${(200 * tech.junkChance).toFixed(0)}%)</em>`
},
// isGunTech: true,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.junkPoolPercent > 0
return tech.junkChance > 0
},
requires: "JUNK in tech pool",
effect() {
tech.isJunkDNA = true
// this.refundAmount += tech.addJunkTechToPool(0.20)
},
// refundAmount: 0,
remove() {
tech.isJunkDNA = false
// if (this.count > 0 && this.refundAmount > 0) {
// tech.removeJunkTechFromPool(this.refundAmount)
// this.refundAmount = 0
// }
}
},
{
@@ -4246,7 +4241,7 @@ const tech = {
name: "residual dipolar coupling",
descriptionFunction() {
// return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns ${powerUps.orb.coupling(5)}that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `clicking <strong class='color-cancel'>cancel</strong> spawns ${powerUps.orb.coupling(6)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
return `clicking <strong class='color-cancel'>cancel</strong> spawns ${powerUps.orb.coupling(8)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
maxCount: 1,
count: 0,
@@ -4304,7 +4299,7 @@ const tech = {
},
{
name: "futures exchange",
description: "clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+4.7%</strong> power up <strong class='color-dup'>duplication</strong> chance",
description: "clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
// descriptionFunction() {
// return `clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+${4.9 - 0.15*simulation.difficultyMode}%</strong> power up <strong class='color-dup'>duplication</strong> chance`
// },
@@ -4327,7 +4322,7 @@ const tech = {
},
{
name: "replication",
description: "<strong>+10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+33%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
description: "<strong>+10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+22%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -4339,8 +4334,8 @@ const tech = {
effect() {
tech.duplicateChance += 0.1
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
this.refundAmount += tech.addJunkTechToPool(0.33)
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.1);
this.refundAmount += tech.addJunkTechToPool(0.22)
},
refundAmount: 0,
remove() {
@@ -4677,30 +4672,6 @@ const tech = {
},
remove() { }
},
{
name: "reinforcement learning",
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current <strong class='color-m'>tech</strong> by <strong>1000%</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.totalCount > 9
},
requires: "at least 10 tech",
effect() {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) tech.tech[i].frequency *= 10
}
},
remove() {
if (this.count) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0 && tech.tech[i].frequency > 1) tech.tech[i].frequency /= 10
}
}
}
},
// {
// name: "backward induction",
// descriptionFunction() {
@@ -6230,10 +6201,7 @@ const tech = {
requires: "mines",
effect() {
tech.isMineDrop = true;
if (tech.isMineDrop) b.mine(m.pos, {
x: 0,
y: 0
}, 0)
if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0)
this.refundAmount += tech.addJunkTechToPool(0.30)
},
refundAmount: 0,
@@ -9057,7 +9025,7 @@ const tech = {
},
{
name: "reel",
description: "<strong>+400%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong><br>up to <strong>+75</strong> <strong class='color-f'>energy</strong> after reeling in <strong class='color-block'>blocks</strong>",
description: "<strong>+400%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong><br>up to <strong>+100</strong> <strong class='color-f'>energy</strong> after reeling in <strong class='color-block'>blocks</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -9549,6 +9517,30 @@ const tech = {
},
remove() { }
},
{
name: "reinforcement learning",
description: "<strong>+1000%</strong> <strong class='flicker'>frequency</strong> of finding copies of current <strong class='color-m'>tech</strong><br>",
maxCount: 1,
count: 0,
frequency: 1,
isJunk: true,
allowed() {
return tech.totalCount > 9
},
requires: "at least 10 tech",
effect() {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) tech.tech[i].frequency *= 10
}
},
remove() {
if (this.count) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0 && tech.tech[i].frequency > 1) tech.tech[i].frequency /= 10
}
}
}
},
{
name: "startle response",
description: `if a threat is nearby, activate a ${powerUps.orb.boost(1)}<br>and lock your mouse until you press escape`,
@@ -10228,6 +10220,25 @@ const tech = {
},
remove() { }
},
{
name: "what the block?",
description: "throwing a <strong class='color-block'>block</strong> throws <strong>you</strong> instead",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() {
return m.fieldMode !== 8 && m.fieldMode !== 9 && !tech.isTokamak
},
requires: "not pilot wave, tokamak, wormhole",
effect() {
},
remove() {
m.throwBlock = m.throwBlockDefault
}
},
{
name: "spinor",
description: "the direction you aim is determined by your position",
@@ -10599,9 +10610,7 @@ const tech = {
},
requires: "",
effect() {
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].isJunk) tech.tech[i].frequency = 0
}
tech.junkChance = 0;
},
remove() { }
},
@@ -11592,6 +11601,26 @@ const tech = {
},
remove() { }
},
{
name: "beforeunload",
description: "<strong>75%</strong> of the time when you attempt to <strong>exit</strong> n-gon<br>you are prompted to <strong>cancel</strong> or continue.<br>Each time you <strong>cancel</strong> gain <strong>+25%</strong> <strong class='color-d'>damage</strong>.",
maxCount: 1,
count: 0,
frequency: 1,
isJunk: true,
allowed() {
return tech.totalCount > 9
},
requires: "at least 10 tech",
effect() {
tech.isExitPrompt = true
addEventListener('beforeunload', beforeUnloadEventListener);
},
remove() {
tech.isExitPrompt = false
if (this.count > 0) removeEventListener('beforeunload', beforeUnloadEventListener);
}
},
{
name: "planetesimals",
description: `play <strong>planetesimals</strong> <em style = 'font-size:80%;'>(an asteroids-like game)</em><br>clear <strong>levels</strong> in <strong>planetesimals</strong> to spawn <strong class='color-m'>tech</strong><br>if you <strong style="color:red;">die</strong> in <strong>planetesimals</strong> you <strong style="color:red;">die</strong> in <strong>n-gon</strong>`,
@@ -12189,4 +12218,5 @@ const tech = {
isDamageCooldown: null,
isDamageCooldownTime: null,
isPowerUpDamage: null,
isExitPrompt: null,
}

View File

@@ -1,19 +1,41 @@
******************************************************** NEXT PATCH **************************************************
laserLayerBoss - sends lasers to player's location
snakes bosses - after you kill a tail piece the rest of the tails lose 5% life
this makes targeting any part of the tail a viable strategy
new tech are sorted to the top of the tech list
pause menu tech list matches the tech list in game
JUNK tech icons are properly displayed in pause
Sort interface works with enter key
bug fix: you can no longer pause or enter testing in experiment selection on text input
pressing P in power up selection menu brings up the pause menu
so you can see your tech and stats
blocks stuck in vertical portals have a bit of randomness added to their velocity to help them escape
accretion disk - 5% damage for every power up on this level
requires accretion
unified field theory has buttons to cycle field forwards or backwards when paused
iceIX range and damage increased 15%
electric tech in labs level is finally nerfed
drains energy, but doesn't do damage
pushes player away
JUNK tech chance is a raw percent chance to display a random JUNK
it was previously a specific JUNK tech directly added to the pool
this might cause bugs
JUNK tech: beforeunload - asks if you want to cancel if you exit game, if you cancel gain 25% damage, but there is a 25% chance to exit anyways
JUNK tech: what the block? - trying to throw a block, throws you instead
reinforcement learning converted into a JUNK tech
JUNK DNA - scale damage by 100->200% of JUNK pool tech percent
dark patterns 33->22% JUNK
replication 33->22% JUNK
overcharge 66->88 max energy
residual dipolar coupling 6->8 coupling per cancel
futures exchange 4.7->5% duplication per cancel
hyperpolarization reduces polarization time by 1->1.25 seconds
reel +75->100 energy
updated physics engine to matter.js 0.19 (from 0.18)
*********************************************************** TODO *****************************************************
List of ways to break the game
CPT + high energy regen
research->bot fabrication-> ersatz bots -> various bot upgrades
duplication 100%
electronegativity and high energy?
boss - tracks the position, velocity, angle of power ups, blocks, and bullets it fires
reactor only?
will rewind time
@@ -32,7 +54,7 @@ button/switch input ideas from Cocoon game
draw field effect
make it still functional without the field button
tech: - getting a new gun also gives you 2 random tech for that gun
tech - getting a new gun also gives you 2 random tech for that gun
or a field?
can these guntech tech be converted into a player choice?
@@ -149,6 +171,7 @@ super-bot: fires super balls
tech: after a needle hits a mobs
the needle splits into 3 needles?
reset your fire CD?
fire again for zero ammo
2x damage for each consecutive mob hit?
mob non-combat behaviors, like Rain World
@@ -277,9 +300,6 @@ Tech:when relay switch/flip flop is on, turn ammo powerups into boosts, when rel
or toggle other power ups
health/ammo
JUNK: what the golf?
trying to throw a block throws you instead
complete blowSuckBoss... or don't
tech: laser reflections increase damage
@@ -1136,6 +1156,7 @@ possible names for tech
Unruh effect - accelerating makes heat/thermal particles
configuration space - holds the position of everything
stressenergy tensor
radioisotope thermoelectric generator -
******************************************************** CARS IMAGES ********************************************************