power up selection code rewrite

rewrite of the tech,gun,field selection code
  odds of new bugs is pretty high, but the code is shorter and faster, so easier to fix
path integral is no longer a JUNK tech
  lets you choose from every option on next tech
emergence is stackable
  +2 power up choices per stack

tech: integrated circuit - if ON +7 power up choices  if OFF -1

update matter.js engine 0.17.1 -> 0.18.0
  shouldn't change anything
big fixes
This commit is contained in:
landgreen
2022-06-22 07:21:26 -07:00
parent 698c18482b
commit 784c933260
8 changed files with 984 additions and 385 deletions

View File

@@ -20,13 +20,14 @@ const level = {
// m.setField("time dilation")
// b.giveGuns("nail gun")
// b.giveGuns("mine")
// tech.giveTech("needle gun")
// tech.giveTech("stress concentration")
// tech.giveTech("cross disciplinary")
// tech.giveTech("determinism")
// tech.giveTech("pseudoscience")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// tech.giveTech("rivet gun")
// tech.giveTech("needle ice")
// tech.giveTech("flash freeze")
// tech.giveTech("superfluidity")
// for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
// tech.giveTech("decoherence")
// tech.giveTech("brainstorming")
// tech.giveTech("path integral")
// m.maxHealth = 100
// m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -39,9 +40,12 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode
// level.perplex();
// level.testChamber2();
// spawn.cellBossCulture(1900, -500)
// level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// powerUps.research.changeRerolls(100)
// spawn.starter(1900, -500, 300)
// for (let i = 0; i < 50; ++i) spawn.starter(1900, -500)
// spawn.powerUpBoss(1900, -500)
@@ -4058,6 +4062,264 @@ const level = {
}, -2 * Math.PI / 3) //up left
}
},
testChamber2() {
level.setPosToSpawn(0, -50); //lower start
level.exit.y = level.enter.y - 550;
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = level.enter.x;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 2200
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d0d5d5";
color.map = "#444"
spawn.mapRect(0, -1955, 175, 30);
const removeIndex1 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
spawn.mapRect(1225, -1955, 175, 30);
const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
let portal, portal2, portal3
const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4) //laser
spawn.mapRect(340, -2032.5, 20, 25); //laser nose
const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4) //laser
spawn.mapRect(1920, -2557.5, 20, 25); //laser nose
const button = level.button(2100, -2600)
const buttonDoor = level.button(600, -550)
const door = level.door(312, -750, 25, 190, 185)
level.custom = () => {
if (!(m.cycle % 60)) { //so much work to catch blocks caught at the bottom of the vertical portals
let touching = Matter.Query.collides(map[removeIndex1], body)
if (touching.length) {
Matter.Composite.remove(engine.world, touching[0].bodyB);
for (let i = 0, len = body.length; i < len; i++) {
if (body[i].id === touching[0].bodyB.id) {
body.splice(i, 1);
break
}
}
}
touching = Matter.Query.collides(map[removeIndex2], body)
if (touching.length) {
Matter.Composite.remove(engine.world, touching[0].bodyB);
for (let i = 0, len = body.length; i < len; i++) {
if (body[i].id === touching[0].bodyB.id) {
body.splice(i, 1);
break
}
}
}
}
buttonDoor.query();
buttonDoor.draw();
if (buttonDoor.isUp) {
door.isClosing = true
} else {
door.isClosing = false
}
door.openClose();
portal[2].query()
portal[3].query()
portal2[2].query()
portal2[3].query()
portal3[2].query()
portal3[3].query()
if (button.isUp) {
hazard.isOn = false;
hazard2.isOn = false;
} else {
hazard.isOn = true;
hazard2.isOn = true;
}
button.query();
button.draw();
ctx.fillStyle = "#d4f4f4"
ctx.fillRect(-300, -1000, 650, 500)
level.exit.drawAndCheck();
level.enter.draw();
};
level.customTopLayer = () => {
door.draw();
hazard.opticalQuery();
hazard2.opticalQuery();
portal[0].draw();
portal[1].draw();
portal[2].draw();
portal[3].draw();
portal2[0].draw();
portal2[1].draw();
portal2[2].draw();
portal2[3].draw();
portal3[0].draw();
portal3[1].draw();
portal3[2].draw();
portal3[3].draw();
};
powerUps.spawnStartingPowerUps(1875, -3075);
const powerUpPos = shuffle([{ //no debris on this level but 2 random spawn instead
x: -150,
y: -1775
}, {
x: 2400,
y: -2650
}, {
x: -175,
y: -1375
}, {
x: 1325,
y: -150
}]);
powerUps.chooseRandomPowerUp(powerUpPos[0].x, powerUpPos[0].y);
powerUps.chooseRandomPowerUp(powerUpPos[1].x, powerUpPos[1].y);
//outer wall
spawn.mapRect(2500, -3700, 1200, 3800); //right map wall
spawn.mapRect(-1400, -3800, 1100, 3900); //left map wall
spawn.mapRect(-1400, -4800, 5100, 1200); //map ceiling
spawn.mapRect(-1400, 0, 5100, 1200); //floor
//lower entrance /exit
spawn.mapRect(300, -375, 50, 225);
spawn.bodyRect(312, -150, 25, 140);
spawn.mapRect(300, -10, 50, 50);
spawn.mapVertex(1555, 0, "625 0 75 0 200 -100 500 -100"); //entrance ramp
//upper entrance / exit
spawn.mapRect(-400, -1050, 750, 50);
spawn.mapRect(300, -1050, 50, 300);
// spawn.bodyRect(312, -750, 25, 190);
spawn.mapRect(300, -560, 50, 50);
spawn.bodyRect(750, -725, 125, 125);
spawn.mapRect(1150, -1050, 250, 575);
spawn.mapRect(1725, -550, 50, 200); //walls around portal 3
spawn.mapRect(1925, -550, 500, 200);
spawn.mapRect(1750, -390, 200, 40);
spawn.mapRect(-400, -550, 1800, 200);
spawn.mapRect(-200, -1700, 150, 25); //platform above exit room
spawn.mapRect(-200, -1325, 350, 25);
//portal 3 angled
spawn.mapRect(2425, -450, 100, 100);
//portal 1 bottom
spawn.mapRect(2290, -12, 375, 100);
spawn.mapRect(2350, -24, 375, 100);
spawn.mapRect(2410, -36, 375, 100);
//portal 1 top
spawn.mapRect(2290, -3012, 375, 50);
spawn.mapRect(2350, -3024, 375, 50);
spawn.mapRect(2410, -3036, 375, 50);
spawn.mapRect(1400, -3000, 1300, 50); //floor
spawn.mapRect(1750, -3050, 250, 75);
spawn.mapRect(1400, -3625, 50, 200);
spawn.mapRect(350, -3625, 50, 225);
spawn.mapRect(350, -3260, 50, 60);
spawn.mapRect(200, -3250, 1240, 50);
spawn.mapRect(1400, -3260, 50, 310);
spawn.bodyRect(1412, -3425, 25, 165);
spawn.mapRect(-150, -2925, 150, 25);
//portal 2
spawn.mapRect(-300, -2600, 300, 675); //left platform
spawn.mapRect(1400, -2600, 375, 675); //right platform
spawn.mapRect(1925, -2600, 775, 675); //far right platform
spawn.bodyRect(2130, -2660, 50, 50); //button's block
spawn.mapRect(150, -2100, 200, 175);
spawn.mapRect(1050, -2100, 200, 175);
//mobs
spawn.randomMob(1075, -3500, -0.3);
spawn.randomMob(2175, -700, -0.2);
spawn.randomMob(-75, -850, -0.1);
spawn.randomMob(550, -3400, 0);
spawn.randomMob(0, -1175, 0.5);
spawn.randomMob(-75, -1150, 0.5);
spawn.randomMob(1075, -625, 0.5);
spawn.randomMob(800, -3400, -0.3);
spawn.randomMob(1225, -3375, -0.2);
spawn.randomMob(1200, -1125, -0.1);
spawn.randomMob(2050, -950, 0.5);
if (simulation.difficulty > 40) {
spawn.randomMob(2300, -2775, -0.5);
spawn.randomMob(600, -925, -0.5);
spawn.randomMob(1550, -2750, -0.5);
spawn.randomMob(1350, -1150, -0.5);
spawn.randomMob(-75, -1475, 0);
spawn.randomGroup(600, -2600, 0);
}
if (simulation.difficulty > 1) {
if (Math.random() < 0.5) {
spawn.randomLevelBoss(700, -1550);
} else {
spawn.randomLevelBoss(675, -2775); //["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss", "pulsarBoss", "grenadierBoss"]
}
}
powerUps.addResearchToLevel() //needs to run after mobs are spawned
spawn.secondaryBossChance(1925, -1250)
if (simulation.isHorizontalFlipped) { //flip the map horizontally
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
// level.setPosToSpawn(0, -50); //-x // no need since 0
button.min.x = -button.min.x - 126 // flip the button horizontally
button.max.x = -button.max.x + 126 // flip the button horizontally
buttonDoor.min.x = -buttonDoor.min.x - 126 // flip the button horizontally
buttonDoor.max.x = -buttonDoor.max.x + 126 // flip the button horizontally
//this makes the hazard draw, but not collide for reasons I don't understand
//so don't use it, instead just call the hazard differently based on this flip flag
// hazard.min.x = -hazard.min.x - hazard.width //-x-width
// hazard.max.x = -hazard.max.x - hazard.width //-x-width
// hazard2.min.x = -hazard2.min.x - hazard2.width //-x-width
// hazard2.max.x = -hazard2.max.x - hazard2.width //-x-width
portal = level.portal({
x: -2475,
y: -140
}, 2 * Math.PI, { //right
x: -2475,
y: -3140
}, 2 * Math.PI) //right
portal2 = level.portal({
x: -75,
y: -2150
}, -Math.PI / 2, { //up
x: -1325,
y: -2150
}, -Math.PI / 2) //up
portal3 = level.portal({
x: -1850,
y: -585
}, -Math.PI / 2, { //up
x: -2425,
y: -600
}, -1 * Math.PI / 3) //up left
// level.custom = () => { };
// level.customTopLayer = () => {};
} else {
portal = level.portal({
x: 2475,
y: -140
}, Math.PI, { //left
x: 2475,
y: -3140
}, Math.PI) //left
portal2 = level.portal({
x: 75,
y: -2150
}, -Math.PI / 2, { //up
x: 1325,
y: -2150
}, -Math.PI / 2) //up
portal3 = level.portal({
x: 1850,
y: -585
}, -Math.PI / 2, { //up
x: 2425,
y: -600
}, -2 * Math.PI / 3) //up left
}
},
sewers() {
const button1 = level.button(6600, 2675)
@@ -4075,7 +4337,10 @@ const level = {
button1.query();
button1.draw();
ctx.fillStyle = "hsl(175, 15%, 76%)"
ctx.fillRect(9300, 2200, 600, 400)
ctx.fillRect(9100, 2200, 800, 400)
ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
ctx.fillRect(6250, 2025, 700, 650)
ctx.fillRect(8000, 2025, 600, 575)
level.exit.drawAndCheck();
level.enter.draw();
};
@@ -4121,7 +4386,7 @@ const level = {
spawn.bodyRect(1450, -300, 150, 50);
const xPos = shuffle([600, 1250, 2000]);
spawn.mapRect(xPos[0], -200, 400, 100);
spawn.mapRect(xPos[0], -200, 300, 100);
spawn.mapRect(xPos[1], -250, 300, 300);
spawn.mapRect(xPos[2], -150, 300, 200);
@@ -4228,7 +4493,10 @@ const level = {
rotor.rotate();
ctx.fillStyle = "hsl(175, 15%, 76%)"
ctx.fillRect(-9300 - 600, 2200, 600, 400)
ctx.fillRect(-9900, 2200, 800, 400)
ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
ctx.fillRect(-6950, 2025, 700, 650)
ctx.fillRect(-8600, 2025, 600, 575)
level.exit.drawAndCheck();
level.enter.draw();

View File

@@ -3367,7 +3367,7 @@ const m = {
const drain = m.fieldRegen + 0.0004
if (m.energy > drain) {
m.energy -= drain
if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1/4 seconds // and can't regen
if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1 cycle
m.isBodiesAsleep = true;
function sleep(who) {
@@ -3469,7 +3469,7 @@ const m = {
x: velocity.x,
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
});
if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 1/4 seconds
if (m.immuneCycle < m.cycle + 5) m.immuneCycle = m.cycle + 5; //player is immune to damage for 1/4 seconds
// move bots to player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {

View File

@@ -248,6 +248,7 @@ const powerUps = {
} else if (type === "field") {
m.setField(index)
} else if (type === "tech") {
if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
setTimeout(() => { powerUps.lastTechIndex = index }, 10);
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>")`);
tech.giveTech(index)
@@ -270,7 +271,7 @@ const powerUps = {
document.getElementById("choose-grid").style.transitionDuration = "0s";
}, 500);
// if (tech.isExtraChoice) {
// if (tech.extraChoices) {
// document.body.style.overflowY = "scroll";
// document.body.style.overflowX = "hidden";
// }
@@ -304,7 +305,7 @@ const powerUps = {
},
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
if (tech.isCancelTech && Math.random() < 0.94) {
if (tech.isCancelTech && Math.random() < 0.96) {
// powerUps.research.use('tech')
powerUps[type].effect();
return
@@ -330,16 +331,16 @@ const powerUps = {
// 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>`)
// }
if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
for (let i = 0; i < banishLength; i++) {
const index = powerUps.tech.choiceLog.length - i - 1
if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
}
}
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
}
// if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
// const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// for (let i = 0; i < banishLength; i++) {
// const index = powerUps.tech.choiceLog.length - i - 1
// if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
// tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
// }
// }
// simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
// }
}
if (tech.isAnsatz && powerUps.research.count === 0) {
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
@@ -425,14 +426,14 @@ const powerUps = {
powerUps.research.changeRerolls(-1)
}
powerUps.research.currentRerollCount++
if (tech.isBanish && type === 'tech') { // banish researched tech
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
for (let i = 0; i < banishLength; i++) {
const index = powerUps.tech.choiceLog.length - i - 1
if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
}
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
}
// if (tech.isBanish && type === 'tech') { // banish researched tech
// const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// for (let i = 0; i < banishLength; i++) {
// const index = powerUps.tech.choiceLog.length - i - 1
// if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
// }
// simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
// }
if (tech.isResearchReality) {
m.switchWorlds()
simulation.trails()
@@ -572,81 +573,261 @@ const powerUps = {
}
}
},
gun: {
name: "gun",
color: "#26a",
size() {
return 35;
},
effect() {
if (m.alive) {
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
let options = [];
for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) options.push(i);
}
let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices)
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
if (options[i] === index) {
options.splice(i, 1) //remove a previous choice from option pool
return
}
}
}
//check for guns that were a choice last time and remove them
for (let i = 0; i < b.guns.length; i++) {
if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display
if (b.guns[i].isRecentlyShown) removeOption(i)
}
for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero
if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choose})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choose].name}</div> ${b.guns[choose].description}</div>`
b.guns[choose].isRecentlyShown = true
removeOption(choose)
if (options.length < 1) break
}
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
} else if (powerUps.research.count) {
text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
}
if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
}
},
// pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
// let options = [];
// for (let i = 0; i < who.length; i++) {
// if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
// options.push(i);
// }
// }
// //remove repeats from last selection
// const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
// for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
// if (options.length > totalChoices) {
// for (let j = 0, len = options.length; j < len; j++) {
// if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
// options.splice(j, 1) //remove previous choice from option pool
// break
// }
// }
// }
// }
// }
// if (options.length > 0) {
// return options[Math.floor(Math.seededRandom(0, options.length))]
// }
// },
// effectOld() {
// let choice1 = powerUps.gun.pick(b.guns)
// let choice2 = -1
// let choice3 = -1
// if (choice1 > -1) {
// let text = ""
// if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
// text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
// text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
// if (!tech.isDeterminism) {
// choice2 = powerUps.gun.pick(b.guns, choice1)
// if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
// choice3 = powerUps.gun.pick(b.guns, choice1, choice2)
// if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice3})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice3].name}</div> ${b.guns[choice3].description}</div>`
// }
// if (tech.extraChoices) {
// let choice4 = powerUps.gun.pick(b.guns, choice1, choice2, choice3)
// if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice4})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice4].name}</div> ${b.guns[choice4].description}</div>`
// let choice5 = powerUps.gun.pick(b.guns, choice1, choice2, choice3, choice4)
// if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice5})">
// <div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice5].name}</div> ${b.guns[choice5].description}</div>`
// powerUps.gun.choiceLog.push(choice4)
// powerUps.gun.choiceLog.push(choice5)
// }
// powerUps.gun.choiceLog.push(choice1)
// powerUps.gun.choiceLog.push(choice2)
// powerUps.gun.choiceLog.push(choice3)
// // if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
// if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
// tech.junkResearchNumber = Math.floor(5 * Math.random())
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
// } else if (powerUps.research.count) {
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
// }
// if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
// document.getElementById("choose-grid").innerHTML = text
// powerUps.showDraft();
// }
// }
},
field: {
name: "field",
color: "#0cf",
size() {
return 45;
},
pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 1; i < who.length; i++) {
if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
}
//remove repeats from last selection
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break
}
}
}
}
}
if (options.length > 0) {
// return options[Math.floor(Math.random() * options.length)]
return options[Math.floor(Math.seededRandom(0, options.length))]
}
},
choiceLog: [], //records all previous choice options
effect() {
let choice1 = powerUps.field.pick(m.fieldUpgrades)
let choice2 = -1
let choice3 = -1
if (choice1 > -1) {
if (m.alive) {
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>`
powerUps.field.choiceLog.push(choice1)
if (!tech.isDeterminism) {
choice2 = powerUps.field.pick(m.fieldUpgrades, choice1)
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice2].name}</div> ${m.fieldUpgrades[choice2].description}</div>`
choice3 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2)
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice3})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice3].name}</div> ${m.fieldUpgrades[choice3].description}</div>`
powerUps.field.choiceLog.push(choice2)
powerUps.field.choiceLog.push(choice3)
}
if (tech.isExtraChoice) {
let choice4 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3)
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice4].name}</div> ${m.fieldUpgrades[choice4].description}</div>`
let choice5 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice5})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice5].name}</div> ${m.fieldUpgrades[choice5].description}</div>`
powerUps.field.choiceLog.push(choice4)
powerUps.field.choiceLog.push(choice5)
}
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(4 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
} else if (powerUps.research.count) {
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// text += `</span>&nbsp; <span class='research-select'>research</span></div></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
let options = [];
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) options.push(i);
}
let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices)
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
if (options[i] === index) {
options.splice(i, 1) //remove a previous choice from option pool
return
}
}
}
//check for fields that were a choice last time and remove them
for (let i = 0; i < m.fieldUpgrades.length; i++) {
if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display
if (m.fieldUpgrades[i].isRecentlyShown) removeOption(i)
}
for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero
if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choose})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choose].name}</div> ${m.fieldUpgrades[choose].description}</div>`
m.fieldUpgrades[choose].isRecentlyShown = true
removeOption(choose)
if (options.length < 1) break
}
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
} else if (powerUps.research.count) {
text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
}
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
//(${powerUps.research.count})
// text += `<div style = 'color:#fff'>${simulation.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
}
},
// pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
// let options = [];
// for (let i = 1; i < who.length; i++) {
// if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
// }
// //remove repeats from last selection
// const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
// for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
// if (options.length > totalChoices) {
// for (let j = 0, len = options.length; j < len; j++) {
// if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
// options.splice(j, 1) //remove previous choice from option pool
// break
// }
// }
// }
// }
// }
// if (options.length > 0) {
// // return options[Math.floor(Math.random() * options.length)]
// return options[Math.floor(Math.seededRandom(0, options.length))]
// }
// },
// effectOld() {
// let choice1 = powerUps.field.pick(m.fieldUpgrades)
// let choice2 = -1
// let choice3 = -1
// if (choice1 > -1) {
// let text = ""
// if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
// text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
// text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>`
// powerUps.field.choiceLog.push(choice1)
// if (!tech.isDeterminism) {
// choice2 = powerUps.field.pick(m.fieldUpgrades, choice1)
// if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice2].name}</div> ${m.fieldUpgrades[choice2].description}</div>`
// choice3 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2)
// if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice3})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice3].name}</div> ${m.fieldUpgrades[choice3].description}</div>`
// powerUps.field.choiceLog.push(choice2)
// powerUps.field.choiceLog.push(choice3)
// }
// if (tech.extraChoices) {
// let choice4 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3)
// if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice4].name}</div> ${m.fieldUpgrades[choice4].description}</div>`
// let choice5 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
// if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice5})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice5].name}</div> ${m.fieldUpgrades[choice5].description}</div>`
// powerUps.field.choiceLog.push(choice4)
// powerUps.field.choiceLog.push(choice5)
// }
// if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
// tech.junkResearchNumber = Math.floor(4 * Math.random())
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
// } else if (powerUps.research.count) {
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('field')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// // text += `</span>&nbsp; <span class='research-select'>research</span></div></div>`
// text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
// }
// //(${powerUps.research.count})
// // text += `<div style = 'color:#fff'>${simulation.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>`
// document.getElementById("choose-grid").innerHTML = text
// powerUps.showDraft();
// }
// }
},
tech: {
name: "tech",
@@ -654,53 +835,98 @@ const powerUps = {
size() {
return 42;
},
choiceLog: [], //records all previous choice options
lastTotalChoices: 0, //tracks how many tech were available for random selection last time a tech was picked up
// banishLog: [], //records all tech permanently removed from the selection pool
effect() {
if (m.alive) {
function pick(skip1 = null, skip2 = null, skip3 = null, skip4 = null) {
let options = [];
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
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) {
if (tech.tech[i].frequency > 0) optionLengthNoDuplicates++
for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
}
}
// console.log(optionLengthNoDuplicates, options.length)
function removeOption(index) {
for (let i = options.length; i > -1; i--) {
if (index === options[i]) {
options.splice(i, 1) //remove all copies of that option form the options array (some tech are in the options array multiple times because of frequency)
optionLengthNoDuplicates--
}
if (options.length < 1) return;
}
}
//set total choices
let totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
if (optionLengthNoDuplicates < totalChoices + 1) { //if not enough options for all the choices
// console.log('if not enough options for all the choices')
totalChoices = optionLengthNoDuplicates
if (tech.isBanish) { //when you run out of options eject banish
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i, true)
}
simulation.makeTextLog(`decoherence <span class='color-var'>tech</span> ejected`)
simulation.makeTextLog(`options reset`)
}
}
if (tech.tooManyTechChoices) {
tech.tooManyTechChoices = false
totalChoices = optionLengthNoDuplicates
}
//check for tech that were a choice last time and remove them
if (optionLengthNoDuplicates > totalChoices) {
// console.log('check for tech that were a choice last time and remove them', optionLengthNoDuplicates, options.length)
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
}
}
powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.tech.choiceLog.length > totalChoices || powerUps.tech.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break;
}
}
if (optionLengthNoDuplicates > totalChoices) {
if (tech.tech[i].isRecentlyShown) {
// console.log(i)
removeOption(i)
}
} else {
break //you have to repeat choices if there are not enough choices left to display
}
}
}
for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
// powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
// console.log(optionLengthNoDuplicates, options.length)
if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) {
if (options.length < 1) break
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
if (tech.isBanish) {
tech.tech[choose].isBanished = true
if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`)
}
//avoid displaying repeated tech options at the same time
removeOption(choose)
tech.tech[choose].isRecentlyShown = true
if (options.length > 0) {
// const choose = options[Math.floor(Math.random() * options.length)]
const choose = options[Math.floor(Math.seededRandom(0, options.length))]
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
if (tech.tech[choose].isFieldTech) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
<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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isGunTech) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
<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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isLore) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
} else if (tech.tech[choose].isJunk) {
@@ -708,65 +934,28 @@ const powerUps = {
} else {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name}</div> ${tech.tech[choose].description}</div>`
return choose
} else if (tech.isBanish) { //if no tech options available eject banish tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
}
if (options.length < 1) break
}
}
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick()
// console.log(choice1)
let choice2 = null
let choice3 = null
if (choice1 !== null) {
powerUps.tech.choiceLog.push(choice1)
if (!tech.isDeterminism) {
choice2 = pick(choice1)
// if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice2})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice2].name}</div> ${tech.tech[choice2].description}</div>`
choice3 = pick(choice1, choice2)
// if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice3})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice3].name}</div> ${tech.tech[choice3].description}</div>`
powerUps.tech.choiceLog.push(choice2)
powerUps.tech.choiceLog.push(choice3)
}
if (tech.isExtraChoice) {
let choice4 = pick(choice1, choice2, choice3)
// if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice4})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice4].name}</div> ${tech.tech[choice4].description}</div>`
let choice5 = pick(choice1, choice2, choice3, choice4)
// if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice5})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice5].name}</div> ${tech.tech[choice5].description}</div>`
powerUps.tech.choiceLog.push(choice4)
powerUps.tech.choiceLog.push(choice5)
}
// if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
if (tech.isExtraGunField) {
if (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
//bonus gun in tech menu
let choiceGun = powerUps.gun.pick(b.guns)
powerUps.gun.choiceLog.push(choiceGun)
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choiceGun})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choiceGun].name}</div> ${b.guns[choiceGun].description}</div>`
let gunOptions = [];
for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) gunOptions.push(i);
}
const pick = gunOptions[Math.floor(Math.seededRandom(0, gunOptions.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${pick})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[pick].name}</div> ${b.guns[pick].description}</div>`
} else {
//bonus field in tech menu
let choiceField = powerUps.field.pick(m.fieldUpgrades)
powerUps.field.choiceLog.push(choiceField)
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choiceField})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choiceField].name}</div> ${m.fieldUpgrades[choiceField].description}</div>`
let fieldOptions = [];
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) fieldOptions.push(i);
}
const pick = options[Math.floor(Math.seededRandom(0, fieldOptions.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${pick})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[pick].name}</div> ${m.fieldUpgrades[pick].description}</div>`
}
}
if (tech.tooManyTechChoices) {
tech.tooManyTechChoices--
for (let i = 0; i < powerUps.tech.lastTotalChoices; i++) pick()
}
if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
tech.isBrainstormActive = true
let count = 0
requestAnimationFrame(cycle);
function cycle() {
count++
@@ -782,8 +971,8 @@ const powerUps = {
tech.isBrainstormActive = false
}
}
requestAnimationFrame(cycle);
}
//add in research button or pseudoscience button
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
@@ -796,115 +985,160 @@ const powerUps = {
// text += `</span>&nbsp; <span class='research-select'>research</span></div></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
}
// if (tech.isBrainstorm && tech.isBrainstormActive < 4) {
// setTimeout(() => {
// if (simulation.isChoosing) {
// tech.isBrainstormActive++
// powerUps.tech.effect();
// //turn off the normal 500ms delay
// document.getElementById("choose-grid").style.pointerEvents = "auto";
// document.body.style.cursor = "auto";
// document.getElementById("choose-grid").style.transitionDuration = "0s";
// } else {
// tech.isBrainstormActive = 0;
// }
// }, 1000);
// } else {
// tech.isBrainstormActive = 0;
// }
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
}
}
},
gun: {
name: "gun",
color: "#26a",
size() {
return 35;
},
pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 0; i < who.length; i++) {
if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
options.push(i);
}
}
//remove repeats from last selection
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool
break
}
}
}
}
}
if (options.length > 0) {
// console.log(`random: ${Math.seededRandom(0, options.length)}`)
return options[Math.floor(Math.seededRandom(0, options.length))]
// return options[Math.floor(Math.random() * options.length)]
}
},
choiceLog: [], //records all previous choice options
effect() {
let choice1 = powerUps.gun.pick(b.guns)
let choice2 = -1
let choice3 = -1
if (choice1 > -1) {
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
if (!tech.isDeterminism) {
choice2 = powerUps.gun.pick(b.guns, choice1)
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
choice3 = powerUps.gun.pick(b.guns, choice1, choice2)
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice3})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice3].name}</div> ${b.guns[choice3].description}</div>`
}
if (tech.isExtraChoice) {
let choice4 = powerUps.gun.pick(b.guns, choice1, choice2, choice3)
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice4})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice4].name}</div> ${b.guns[choice4].description}</div>`
let choice5 = powerUps.gun.pick(b.guns, choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice5})">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice5].name}</div> ${b.guns[choice5].description}</div>`
powerUps.gun.choiceLog.push(choice4)
powerUps.gun.choiceLog.push(choice5)
}
powerUps.gun.choiceLog.push(choice1)
powerUps.gun.choiceLog.push(choice2)
powerUps.gun.choiceLog.push(choice3)
// if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
// effectOld() {
// if (m.alive) {
// function pick(skip1 = null, skip2 = null, skip3 = null, skip4 = null) {
// let options = [];
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
// for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
// }
// }
// powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
} else if (powerUps.research.count) {
text += `<div class="choose-grid-module" onclick="powerUps.research.use('gun')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
}
if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
}
// const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// if (powerUps.tech.choiceLog.length > totalChoices || powerUps.tech.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
// for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
// if (options.length > totalChoices) {
// for (let j = 0, len = options.length; j < len; j++) {
// if (powerUps.tech.choiceLog[powerUps.tech.length - 1 - i] === options[j]) {
// options.splice(j, 1) //remove previous choice from option pool
// break;
// }
// }
// }
// }
// }
// if (options.length > 0) {
// // const choose = options[Math.floor(Math.random() * options.length)]
// const choose = options[Math.floor(Math.seededRandom(0, options.length))]
// const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
// if (tech.tech[choose].isFieldTech) {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
// } else if (tech.tech[choose].isGunTech) {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><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[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
// } else if (tech.tech[choose].isLore) {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
// } else if (tech.tech[choose].isJunk) {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
// } else {
// text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
// }
// // text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name}</div> ${tech.tech[choose].description}</div>`
// return choose
// } else if (tech.isBanish) { //if no tech options available eject banish tech
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
// }
// }
// }
// let text = ""
// if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
// text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
// let choice1 = pick()
// // console.log(choice1)
// let choice2 = null
// let choice3 = null
// if (choice1 !== null) {
// powerUps.tech.choiceLog.push(choice1)
// if (!tech.isDeterminism) {
// choice2 = pick(choice1)
// // if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice2})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice2].name}</div> ${tech.tech[choice2].description}</div>`
// choice3 = pick(choice1, choice2)
// // if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice3})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice3].name}</div> ${tech.tech[choice3].description}</div>`
// powerUps.tech.choiceLog.push(choice2)
// powerUps.tech.choiceLog.push(choice3)
// }
// if (tech.extraChoices) {
// let choice4 = pick(choice1, choice2, choice3)
// // if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice4})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice4].name}</div> ${tech.tech[choice4].description}</div>`
// let choice5 = pick(choice1, choice2, choice3, choice4)
// // if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice5})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice5].name}</div> ${tech.tech[choice5].description}</div>`
// powerUps.tech.choiceLog.push(choice4)
// powerUps.tech.choiceLog.push(choice5)
// }
// // if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"><div class="circle-grid research"></div> &nbsp; research <span class="research-select">${powerUps.research.count}</span></div></div>`
// if (tech.isExtraGunField) {
// if (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
// //bonus gun in tech menu
// let choiceGun = powerUps.gun.pick(b.guns)
// powerUps.gun.choiceLog.push(choiceGun)
// text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choiceGun})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choiceGun].name}</div> ${b.guns[choiceGun].description}</div>`
// } else {
// //bonus field in tech menu
// let choiceField = powerUps.field.pick(m.fieldUpgrades)
// powerUps.field.choiceLog.push(choiceField)
// text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choiceField})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choiceField].name}</div> ${m.fieldUpgrades[choiceField].description}</div>`
// }
// }
// if (tech.tooManyTechChoices) {
// tech.tooManyTechChoices--
// for (let i = 0; i < powerUps.tech.lastTotalChoices; i++) pick()
// }
// if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
// tech.isBrainstormActive = true
// let count = 0
// requestAnimationFrame(cycle);
// function cycle() {
// count++
// if (count < tech.brainStormDelay * 5 && simulation.isChoosing) {
// if (!(count % tech.brainStormDelay)) {
// powerUps.tech.effect();
// document.getElementById("choose-grid").style.pointerEvents = "auto"; //turn off the normal 500ms delay
// document.body.style.cursor = "auto";
// document.getElementById("choose-grid").style.transitionDuration = "0s";
// }
// requestAnimationFrame(cycle);
// } else {
// tech.isBrainstormActive = false
// }
// }
// }
// //add in research button or pseudoscience button
// if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
// tech.junkResearchNumber = Math.floor(5 * Math.random())
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
// text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div>`
// } else if (powerUps.research.count) {
// text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"> <span style="position:relative;">`
// for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px;opacity:0.8; border: 1px #fff solid;"></div>`
// // text += `</span>&nbsp; <span class='research-select'>research</span></div></div>`
// text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
// }
// document.getElementById("choose-grid").innerHTML = text
// powerUps.showDraft();
// }
// }
// }
},
onPickUp(who) {
powerUps.research.currentRerollCount = 0
if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
if (tech.isTechDamage && who.name === "tech") m.damage(0.11 + 0.11 * tech.isEnergyHealth)
if (tech.isMassEnergy) m.energy += 2;
if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.6) {
if (tech.isLaserMine && input.down) {
@@ -1027,10 +1261,8 @@ const powerUps = {
for (let i = 0; i < 3; i++) powerUps.spawnRandomPowerUp(x, y);
}
},
ejectTech(choose = 'random') {
if (!simulation.isChoosing)
ejectTech(choose = 'random', isOverride = false) {
if (!simulation.isChoosing || isOverride) {
//find which tech you have
if (choose === 'random') {
const have = []
@@ -1063,22 +1295,23 @@ const powerUps = {
return false
}
} else if (tech.tech[choose].count) {
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
powerUp[powerUp.length - 1].isDuplicated = true
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
tech.tech[choose].count = 0;
tech.tech[choose].isLost = true;
simulation.updateTechHUD();
m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
return true
} else {
return false
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
tech.tech[choose].count = 0;
tech.tech[choose].isLost = true;
simulation.updateTechHUD();
m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
return true
} else {
return false
}
},
pauseEjectTech(index) {

View File

@@ -105,7 +105,7 @@ const simulation = {
simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) {
simulation.cycle++;
// m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast (it's times 0.5 because when they move too fast it's a blur)
// m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast this is just gonna run for each method call since it needs some tweaking
simulation.gravity();
Engine.update(engine, simulation.delta);
// level.custom();

View File

@@ -1,7 +1,7 @@
//main object for spawning things in a level
const spawn = {
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
// other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
// other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss, mineBoss //these need a particular level to work so they are not included in the random pool
randomBossList: [
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
@@ -3576,7 +3576,7 @@ const spawn = {
ctx.setLineDash([]);
}
},
sprayBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
sprayBoss(x, y, radius = 40, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
@@ -3588,7 +3588,7 @@ const spawn = {
me.frictionAir = 0;
me.restitution = 1
spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.0022 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
@@ -3630,8 +3630,8 @@ const spawn = {
if (this.speed < 0.01) {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1));
} else {
if (Math.abs(this.velocity.y) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
if (Math.abs(this.velocity.y) < 10) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.05 });
if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.05, y: this.velocity.y });
}
}
me.burstFire = function() {
@@ -4816,8 +4816,8 @@ const spawn = {
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
me.onDeath = function() {
if (simulation.difficulty > 11) { //explode AoE
const radius = 100 + simulation.difficulty + 60 * Math.random()
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0004 * radius * simulation.dmgScale);
const radius = 100 + 0.5 * simulation.difficulty + 50 * Math.random()
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0003 * radius * simulation.dmgScale);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,

View File

@@ -4,6 +4,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) {
tech.tech[i].count = 0
tech.tech[i].isLost = false
tech.tech[i].isBanished = false
tech.tech[i].remove();
if (tech.tech[i].isJunk) {
tech.tech[i].frequency = 0
@@ -224,7 +225,7 @@ const tech = {
damageFromTech() {
let dmg = 1 //m.fieldDamage
if (tech.isDeathSkipTime) dmg *= 1.67
if (tech.isNoDraftPause) dmg *= 1.4
if (tech.isNoDraftPause) dmg *= 1.34
if (tech.isCloakingDamage) dmg *= 1.35
if (tech.isTechDamage) dmg *= 1.9
if (tech.isMaxEnergyTech) dmg *= 1.5
@@ -1794,6 +1795,24 @@ const tech = {
tech.isFlipFlopDamage = false;
}
},
{
name: "integrated circuit",
description: "if <strong class='color-flop'>ON</strong> <strong>+7</strong> power up <strong>choices</strong><br>if <strong class='color-flop'>OFF</strong> <strong>-1</strong> power up <strong>choices</strong>",
maxCount: 1,
count: 0,
frequency: 4,
frequencyDefault: 4,
allowed() {
return (tech.isFlipFlop || tech.isRelay) && !tech.isDeterminism
},
requires: "ON/OFF tech not determinism",
effect() {
tech.isFlipFlopChoices = true //do you have this tech
},
remove() {
tech.isFlipFlopChoices = false
}
},
{
name: "transistor",
description: "if <strong class='color-flop'>ON</strong> generate <strong>20</strong> <strong class='color-f'>energy</strong> per second<br>if <strong class='color-flop'>OFF</strong> drain <strong>1</strong> <strong class='color-f'>energy</strong> per second",
@@ -2107,7 +2126,7 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isTechDamage && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
},
requires: "not Zeno, ergodicity, piezoelectricity, CPT, antiscience, mutualism",
effect: () => {
@@ -2494,10 +2513,8 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isEnergyHealth
},
requires: "not mass-energy",
allowed() { return true },
requires: "",
effect() {
tech.isTechDamage = true;
},
@@ -2776,7 +2793,7 @@ const tech = {
{
name: "Ψ(t) collapse",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Wave_function_collapse' class="link">Ψ(t) collapse</a>`,
description: `after you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong><br>spawn ${powerUps.orb.research(14)}`,
description: `after you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong><br>spawn ${powerUps.orb.research(17)}`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -2785,7 +2802,7 @@ const tech = {
return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch
},
requires: "not many-worlds, non-unitary, pseudoscience",
bonusResearch: 14,
bonusResearch: 17,
effect() {
tech.isResearchReality = true;
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false);
@@ -2958,8 +2975,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>5</strong> <strong>choices</strong><br><strong>+5%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 1,
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>+4%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9,
count: 0,
frequency: 1,
frequencyDefault: 1,
@@ -2968,21 +2985,41 @@ const tech = {
},
requires: "not determinism",
effect: () => {
tech.isExtraChoice = true;
this.refundAmount += tech.addJunkTechToPool(0.05)
tech.extraChoices += 2;
this.refundAmount += tech.addJunkTechToPool(0.04)
},
refundAmount: 0,
remove() {
tech.isExtraChoice = false;
tech.extraChoices = 0;
if (this.count > 0 && this.refundAmount > 0) {
tech.removeJunkTechFromPool(this.refundAmount)
this.refundAmount = 0
}
}
},
{
name: "path integral",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Path_integral_formulation' class="link">path integral</a>`,
description: "your next <strong class='color-m'>tech</strong> choice<br>presents every possible <strong>option</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
// isJunk: true,
allowed() { return true },
requires: "",
effect() {
tech.tooManyTechChoices = 1
// for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
},
remove() {
tech.tooManyTechChoices = 0
}
},
{
name: "determinism",
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have only<br> <strong>1 choice</strong> for <strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong>",
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong><br>only <strong>1 choice</strong> for <strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2990,9 +3027,9 @@ const tech = {
isBadRandomOption: true,
isNonRefundable: true,
allowed() {
return !tech.isExtraChoice && !tech.isExtraGunField
return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices
},
requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary",
requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary, integrated circuit",
effect: () => {
tech.isDeterminism = true;
//if you change the number spawned also change it in Born rule
@@ -3019,7 +3056,7 @@ const tech = {
},
{
name: "superdeterminism",
description: `spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have <strong>no cancel</strong><br>and ${powerUps.orb.research(1)}, no longer <strong>spawn</strong>`,
description: `spawn <strong>5</strong> <strong class='color-m'>tech</strong><br>you have <strong>no cancel</strong> and ${powerUps.orb.research(1)}, no longer <strong>spawn</strong>`,
maxCount: 1,
count: 0,
frequency: 4,
@@ -3106,7 +3143,7 @@ const tech = {
{
name: "eternalism",
// description: `increase <strong class='color-d'>damage</strong> by <strong>60%</strong>, but <strong>time</strong> doesn't <strong>pause</strong><br>while choosing a choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>`, //${powerUps.orb.heal()} or
description: "<strong>+40%</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em>(time can be dilated)</em>",
description: "<strong>+34%</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em>(time can be dilated)</em>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3253,7 +3290,7 @@ const tech = {
{
name: "options exchange",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>94%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>96%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3564,7 +3601,7 @@ const tech = {
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
requires: "NOT EXPERIMENT MODE, some duplication, not super determinism",
requires: "NOT EXPERIMENT MODE, some duplication, not superdeterminism",
effect: () => {
powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2`)
@@ -3602,7 +3639,7 @@ const tech = {
// text = ``
// let num = 3
// if (tech.isExtraChoice) num = 5
// if (tech.extraChoices) num = 5
// if (tech.isDeterminism) num = 1
// for (let i = 0; i < num; i++) {
// const index = powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - i - 1]
@@ -3627,7 +3664,7 @@ const tech = {
// effect: () => {
// powerUps.research.changeRerolls(-2)
// let num = 3
// if (tech.isExtraChoice) num = 5
// if (tech.extraChoices) num = 5
// if (tech.isDeterminism) num = 1
// for (let i = 0; i < num; i++) {
// const index = powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - i - 1]
@@ -9570,7 +9607,7 @@ const tech = {
remove() {}
},
// {
// name: "JUNKie", //just crashes the game
// name: "JUNKie", //just crashes the game
// description: "all junk",
// maxCount: 1,
// count: 0,
@@ -9591,27 +9628,6 @@ const tech = {
// tech.tooManyTechChoices = 0
// }
// },
{
name: "path integral",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Path_integral_formulation' class="link">path integral</a>`,
// description: "your next <strong>3</strong> <strong class='color-m'>tech</strong> choices<br>present almost every possible <strong>option</strong>",
description: "your next <strong class='color-m'>tech</strong> choice<br>presents almost every possible <strong>option</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
tech.tooManyTechChoices = 1
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
},
remove() {
tech.tooManyTechChoices = 0
}
},
{
name: "rule 30",
maxCount: 1,
@@ -9625,7 +9641,7 @@ const tech = {
effect() {},
remove() {},
state: [
[false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
[Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false]
],
rule(state, a, b, c) {
//30
@@ -9640,25 +9656,68 @@ const tech = {
},
id: 0,
descriptionFunction() {
if (this.id === 0 && Math.random() < 0.5) {
// for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
this.name = "rule 90"
this.link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(this.name).replace(/'/g, '%27')}&title=Special:Search' class="link">${this.name}</a>`
// console.log(this.name)
this.state[0] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
this.rule = function(state, a, b, c) {
if (state[a] && state[b] && state[c]) return false; // TTT => F
if (state[a] && state[b] && !state[c]) return true; // TTF => T
if (state[a] && !state[b] && state[c]) return false; //TFT => F
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
if (!state[a] && state[b] && state[c]) return true; //FTT => T
if (!state[a] && state[b] && !state[c]) return false; //FTF => F
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
const loop = () => {
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
let b = []; //produce next row
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
}
b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
this.state.push(b)
if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
setTimeout(() => { loop() }, 400);
}
}
setTimeout(() => { loop() }, 400);
this.id++
return `<span id = "cellular-rule-id${this.id}" style = "letter-spacing: 0px;font-size: 50%;line-height: normal;">${this.outputText()}</span>`
},
outputText() {
let text = ""
for (let j = 0; j < this.state.length; j++) {
text += "<p style = 'margin-bottom: -11px;'>"
for (let i = 0; i < this.state[j].length; i++) {
if (this.state[j][i]) {
text += "⬛" //"█" //"■"
} else {
text += "⬜" //"&nbsp;&nbsp;&nbsp;&nbsp;" //"□"
}
}
text += "</p>"
}
return text
},
},
{
name: "rule 90",
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {},
remove() {},
state: [
[false, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, true, true, false, false, false, false, Math.random() > 0.8, Math.random() > 0.8, false, false, false, false, false, false, Math.random() > 0.8]
],
rule(state, a, b, c) { //90
if (state[a] && state[b] && state[c]) return false; // TTT => F
if (state[a] && state[b] && !state[c]) return true; // TTF => T
if (state[a] && !state[b] && state[c]) return false; //TFT => F
if (state[a] && !state[b] && !state[c]) return true; //TFF => T
if (!state[a] && state[b] && state[c]) return true; //FTT => T
if (!state[a] && state[b] && !state[c]) return false; //FTF => F
if (!state[a] && !state[b] && state[c]) return true; //FFT => T
if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
},
id: 90,
descriptionFunction() {
// this.link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(this.name).replace(/'/g, '%27')}&title=Special:Search' class="link">${this.name}</a>`
const loop = () => {
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
let b = []; //produce next row
@@ -9955,7 +10014,7 @@ const tech = {
isFarAwayDmg: null,
isEntanglement: null,
isMassEnergy: null,
isExtraChoice: null,
extraChoices: null,
laserBotCount: null,
dynamoBotCount: null,
nailBotCount: null,
@@ -10134,6 +10193,7 @@ const tech = {
// isFlipFlopLevelReset: null,
isFlipFlopDamage: null,
isFlipFlopEnergy: null,
isFlipFlopChoices: null,
isRelay: null,
relayIce: null,
isMetaAnalysis: null,