level - reactor
new level: reactor - midBoss fight it's not well balanced yet Let me know if there are any impossible gun combinations for new players the training button at the start screen now cycles colors effect shows if you haven't cleared the first training level, and you haven't done at least a few normal runs standing wave expansion tech is 40% larger and gives 25% deflecting efficiency ammonium nitrate gives 30 -> 27% damage and range heuristics gives 30 -> 33% fire rate wormhole invariant tech drains energy much slower while time is paused bug fixes null level now longer progresses level.onLevel
This commit is contained in:
@@ -81,11 +81,9 @@
|
||||
<text x="10" y="33">experiment</text>
|
||||
</g>
|
||||
</svg>
|
||||
<svg class="SVG-button" id="training-button" width="120" height="45" style="border: 2px #333 solid;" onclick="simulation.startGame(false, true)">
|
||||
<g stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Arial, sans-serif">
|
||||
<!-- <animate attributeName="fill" values="#f00;#dd0;#0f0;#0ff;#66f;#0ff;#0f0;#dd0;#f77" dur="4s" repeatCount="indefinite" /> -->
|
||||
<text x="10" y="33" class="lore">training</text>
|
||||
</g>
|
||||
<svg class="SVG-button" id="training-button" width="120" height="45" style="border: 2px #333 solid;" stroke='none' fill='#333' font-size="30px" font-family="Arial, sans-serif" onclick="simulation.startGame(false, true)">
|
||||
<!-- <animate attributeName="fill" values="#f55;#cc5;#5c5;#5dd;#66f;#5dd;#5c5;#cc5;#f55" dur="4s" repeatCount="indefinite" /> -->
|
||||
<text x="10" y="33">training</text>
|
||||
</svg>
|
||||
<div id='info'>
|
||||
<div id="settings">
|
||||
|
||||
40
js/index.js
40
js/index.js
@@ -132,6 +132,25 @@ window.addEventListener('load', () => {
|
||||
if (property === "level") document.getElementById("starting-level").value = Math.max(Number(set[property]) - 1, 0)
|
||||
if (property === "noPower") document.getElementById("no-power-ups").checked = Number(set[property])
|
||||
}
|
||||
} else if (localSettings.isTrainingNotAttempted && localSettings.runCount < 30) { //make training button more obvious for new players
|
||||
// document.getElementById("training-button").style.border = "0px #333 solid";
|
||||
// document.getElementById("training-button").style.fill = "rgb(0, 150, 235)" //"#fff";
|
||||
// document.getElementById("training-button").style.background = "rgb(0, 200, 255)";
|
||||
|
||||
//css classes not working for some reason
|
||||
// document.getElementById("training-button").classList.add('lore-text');
|
||||
|
||||
let myanim = document.createElementNS("http://www.w3.org/2000/svg", 'animate');
|
||||
myanim.setAttribute("id", "myAnimation");
|
||||
myanim.setAttribute("attributeType", "XML");
|
||||
myanim.setAttribute("attributeName", "fill");
|
||||
// myanim.setAttribute("values", "#f55;#cc5;#5c5;#5dd;#66f;#5dd;#5c5;#cc5;#f55"); //rainbow
|
||||
myanim.setAttribute("values", "#5dd;#66f;#5dd");
|
||||
// myanim.setAttribute("values", "#333;rgb(0, 170, 255);#333");
|
||||
myanim.setAttribute("dur", "3s");
|
||||
myanim.setAttribute("repeatCount", "indefinite");
|
||||
document.getElementById("training-button").appendChild(myanim);
|
||||
document.getElementById("myAnimation").beginElement();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -252,25 +271,25 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
||||
text += `<div class="pause-grid-module" id ="pause-field"><div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>`
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) {
|
||||
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||
if (tech.tech[i].isFieldTech) {
|
||||
text += `<div class="pause-grid-module"><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>
|
||||
${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
${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"><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>
|
||||
${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
${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> ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> ${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"><div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> ${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].isLost) {
|
||||
text += `<div class="pause-grid-module" style="text-decoration: line-through;"><div class="grid-title">${tech.tech[i].link}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
@@ -355,7 +374,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
||||
if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode || (localSettings.isJunkExperiment && tech.tech[i].isJunk))) {
|
||||
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
|
||||
// console.log(tech.tech[i].name, isAllowed, tech.tech[i].count, tech.haveGunCheck("nail gun"))
|
||||
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||
|
||||
// <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div>
|
||||
if (tech.tech[i].isFieldTech) {
|
||||
@@ -367,7 +386,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
||||
<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>
|
||||
${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
|
||||
${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
|
||||
</div>`
|
||||
// <div class="circle-grid gun" style="position:absolute; top:-3px; left:-3px; opacity:1; height: 33px; width:33px;"></div>
|
||||
// <div class="circle-grid tech" style="position:absolute; top:5px; left:5px;opacity:1;height: 20px; width:20px;border: #fff solid 2px;"></div>
|
||||
@@ -380,15 +399,15 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
||||
<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>
|
||||
${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
|
||||
${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
|
||||
</div>`
|
||||
} else
|
||||
if (tech.tech[i].isJunk) {
|
||||
techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> ${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
|
||||
techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
|
||||
} else if (tech.tech[i].isExperimentalMode) {
|
||||
techID.innerHTML = `<div class="grid-title">${tech.tech[i].name}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
|
||||
} else {
|
||||
techID.innerHTML = `<div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[i].link} ${isCount}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
|
||||
techID.innerHTML = `<div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
|
||||
}
|
||||
//deselect selected tech options if you don't have the tech any more // for example: when bot techs are converted after a bot upgrade tech is taken
|
||||
if (tech.tech[i].count === 0 && techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected");
|
||||
@@ -1161,6 +1180,7 @@ if (localSettings) {
|
||||
difficultyMode: '2',
|
||||
fpsCapDefault: 'max',
|
||||
runCount: 0,
|
||||
isTrainingNotAttempted: true,
|
||||
levelsClearedLastGame: 0,
|
||||
loreCount: 0,
|
||||
isHuman: false,
|
||||
|
||||
165
js/level.js
165
js/level.js
@@ -7,7 +7,8 @@ const level = {
|
||||
defaultZoom: 1400,
|
||||
onLevel: -1,
|
||||
levelsCleared: 0,
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"], //see level.populateLevels: (intro, ... , reservoir, ... , gauntlet, final) added later
|
||||
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"],
|
||||
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"],
|
||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
|
||||
levels: [],
|
||||
@@ -15,23 +16,23 @@ const level = {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// localSettings.levelsClearedLastGame = 10
|
||||
// level.difficultyIncrease(1) //30 is near max on hard //60 is near max on why
|
||||
// spawn.setSpawnList();spawn.setSpawnList();
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("harpoon")
|
||||
// for (let i = 0; i < 9; i++) tech.giveTech("slow light")
|
||||
// tech.giveTech("grenade production")
|
||||
// m.setField("standing wave")
|
||||
// b.giveGuns("laser")
|
||||
// for (let i = 0; i < 100; i++) tech.giveTech("slow light")
|
||||
// tech.giveTech("expansion")
|
||||
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
|
||||
// tech.giveTech("charmed baryons")
|
||||
// tech.giveTech("tinsellated flagella")
|
||||
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
|
||||
// tech.giveTech("antiscience")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
|
||||
// tech.giveTech("nail-bot")
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
|
||||
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
|
||||
// tech.tech[297].frequency = 100
|
||||
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.pavilion();
|
||||
// level.reactor();
|
||||
// level.testing(); //not in rotation, used for testing
|
||||
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); }
|
||||
@@ -41,7 +42,7 @@ const level = {
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
|
||||
// lore.techCount = 3
|
||||
// simulation.isCheating = false //true;
|
||||
// localSettings.loreCount = 0; //this sets what conversation is heard
|
||||
// localSettings.loreCount = 2; //this sets what conversation is heard
|
||||
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
|
||||
// level.null()
|
||||
@@ -127,29 +128,29 @@ const level = {
|
||||
b.dmgScale = 1; //damage done by player decreases each level
|
||||
simulation.accelScale = 1 //mob acceleration increases each level
|
||||
simulation.CDScale = 1 //mob CD time decreases each level
|
||||
simulation.dmgScale = 0.41 * simulation.difficulty //damage done by mobs increases each level
|
||||
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
|
||||
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
|
||||
},
|
||||
difficultyIncrease(num = 1) {
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty++
|
||||
b.dmgScale *= 0.914; //damage done by player decreases each level
|
||||
b.dmgScale *= 0.917; //damage done by player decreases each level
|
||||
if (simulation.accelScale < 6) simulation.accelScale *= 1.025 //mob acceleration increases each level
|
||||
if (simulation.CDScale > 0.15) simulation.CDScale *= 0.965 //mob CD time decreases each level
|
||||
}
|
||||
simulation.dmgScale = 0.39 * simulation.difficulty //damage done by mobs scales with total levels
|
||||
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs scales with total levels
|
||||
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
|
||||
// console.log(`CD = ${simulation.CDScale}`)
|
||||
},
|
||||
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
|
||||
for (let i = 0; i < num; i++) {
|
||||
simulation.difficulty--
|
||||
b.dmgScale /= 0.914; //damage done by player decreases each level
|
||||
b.dmgScale /= 0.917; //damage done by player decreases each level
|
||||
if (simulation.accelScale > 1) simulation.accelScale /= 1.025 //mob acceleration increases each level
|
||||
if (simulation.CDScale < 1) simulation.CDScale /= 0.965 //mob CD time decreases each level
|
||||
}
|
||||
if (simulation.difficulty < 1) simulation.difficulty = 0;
|
||||
simulation.dmgScale = 0.39 * simulation.difficulty //damage done by mobs scales with total levels
|
||||
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs scales with total levels
|
||||
if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1;
|
||||
simulation.healScale = 1 / (1 + simulation.difficulty * 0.055)
|
||||
},
|
||||
@@ -235,6 +236,7 @@ const level = {
|
||||
level.levels = shuffle(level.levels); //shuffles order of maps
|
||||
}
|
||||
level.levels.splice(Math.floor(level.levels.length * (0.4 + 0.6 * Math.random())), 0, "reservoir"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(level.levels.length * (0.4 + 0.6 * Math.random())), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(0, 2); //remove 2 levels from the start of the array
|
||||
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
|
||||
level.levels.unshift("intro"); //add level to the start of the randomized levels list
|
||||
@@ -2364,6 +2366,8 @@ const level = {
|
||||
},
|
||||
null() {
|
||||
level.levels.pop(); //remove lore level from rotation
|
||||
level.onLevel--
|
||||
console.log(level.onLevel, level.levels)
|
||||
//start a conversation based on the number of conversations seen
|
||||
if (localSettings.loreCount < lore.conversation.length && !simulation.isCheating) {
|
||||
lore.testSpeechAPI() //see if speech is working
|
||||
@@ -2588,6 +2592,116 @@ const level = {
|
||||
// spawn.suckerBoss(2900, -500)
|
||||
// spawn.randomMob(1600, -500)
|
||||
},
|
||||
reactor() {
|
||||
level.setPosToSpawn(-50, -800); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 3000;
|
||||
level.exit.y = -35;
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
|
||||
level.defaultZoom = 2000
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#d0d5df" //"#d8dadf";
|
||||
// powerUps.spawnStartingPowerUps(1475, -1175);
|
||||
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||
spawn.mapRect(-1525, -2825, 1250, 3925);
|
||||
spawn.mapRect(-400, -2025, 625, 925);
|
||||
spawn.mapRect(-400, -750, 625, 1200);
|
||||
|
||||
spawn.mapRect(-425, 0, 4200, 1100);
|
||||
spawn.mapRect(175, -1250, 50, 300);
|
||||
spawn.mapRect(-475, -2825, 4250, 1025);
|
||||
// spawn.mapRect(1200, -1300, 600, 800);
|
||||
const a = 400 //side length
|
||||
const c = 100 //corner offset
|
||||
spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off
|
||||
|
||||
//exit
|
||||
spawn.mapRect(3300, -2825, 1125, 3925);
|
||||
spawn.mapRect(2750, -2150, 1025, 1775);
|
||||
spawn.mapRect(2750, -475, 50, 300);
|
||||
|
||||
|
||||
|
||||
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
|
||||
// spawn.randomSmallMob(1300, -70);
|
||||
// spawn.randomMob(2650, -975, 0.8);
|
||||
// const doorIn = level.door(187, -450, 25, 250, 2) //x, y, width, height, distance, speed = 1
|
||||
// doorIn.isClosing = false
|
||||
// level.custom = () => {
|
||||
// level.exit.drawAndCheck();
|
||||
// // if (mob.length > 0) {
|
||||
// // doorIn.isClosing = true
|
||||
// // } else {
|
||||
// // doorIn.isClosing = false
|
||||
// // }
|
||||
// doorIn.isClosing = !(mob.length > 0)
|
||||
// doorIn.openClose();
|
||||
|
||||
const doorIn = level.door(187, -950, 25, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
||||
const doorOut = level.door(2762, -175, 25, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
||||
doorOut.isClosing = true
|
||||
let isDoorsLocked = false
|
||||
let isFightOver = false
|
||||
let isSpawnedBoss = false
|
||||
|
||||
level.custom = () => {
|
||||
if (isDoorsLocked) {
|
||||
if (!isFightOver && !(simulation.cycle % 120)) { //once a second
|
||||
let isFoundBoss = false
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (mob[i].isBoss) {
|
||||
isFoundBoss = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isFoundBoss) {
|
||||
isFightOver = true
|
||||
doorIn.isClosing = false
|
||||
doorOut.isClosing = false
|
||||
powerUps.spawnBossPowerUp(2900, -100)
|
||||
for (let i = 0; i < 3; ++i) powerUps.spawn(2900 + 30 * i, -300, "ammo");
|
||||
}
|
||||
}
|
||||
|
||||
// if (mob.length > 0) {
|
||||
// doorIn.isClosing = true
|
||||
// doorOut.isClosing = true
|
||||
// } else if (!isFightOver) {
|
||||
// isFightOver = true
|
||||
// doorIn.isClosing = false
|
||||
// doorOut.isClosing = false
|
||||
// powerUps.spawnBossPowerUp(2900, -200)
|
||||
// }
|
||||
if (player.position.x < 0) { //if player gets trapped inside starting room open up again
|
||||
isDoorsLocked = false
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
} else if (player.position.x > 225) {
|
||||
isDoorsLocked = true
|
||||
doorIn.isClosing = true
|
||||
doorOut.isClosing = true
|
||||
if (!isSpawnedBoss) {
|
||||
isSpawnedBoss = true
|
||||
for (let i = 0, len = simulation.difficulty / 20; i < len; ++i) spawn.bounceBoss(1487 + 300 * i, -1525, 80, false);
|
||||
}
|
||||
}
|
||||
|
||||
doorIn.openClose();
|
||||
doorOut.openClose();
|
||||
level.enter.draw();
|
||||
level.exit.drawAndCheck();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
// if (isDoorsLocked) {
|
||||
// ctx.fillStyle = "#333"
|
||||
// ctx.fillRect(2800, -375, 500, 375);
|
||||
// }
|
||||
doorIn.draw();
|
||||
doorOut.draw();
|
||||
};
|
||||
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
template() {
|
||||
level.custom = () => {
|
||||
level.exit.drawAndCheck();
|
||||
@@ -3309,12 +3423,7 @@ const level = {
|
||||
vanish.push(level.vanish(-350, -225, 150, 225))
|
||||
vanish.push(level.vanish(-350, -450, 150, 223))
|
||||
spawn.mapRect(2475, -1800, 250, 2300);
|
||||
// vanish.push(level.vanish(1300, -375, 150, 225))
|
||||
// vanish.push(level.vanish(1300, -450, 150, 223))
|
||||
// spawn.mapRect(1200, -375, 250, 50);
|
||||
|
||||
// spawn.mapRect(1200, -375, 250, 225);
|
||||
// spawn.mapRect(1200, -375, 175, 25);
|
||||
spawn.mapRect(1200, -750, 100, 450);
|
||||
spawn.mapRect(1200, -375, 250, 75);
|
||||
powerUps.spawnStartingPowerUps(550, -100);
|
||||
@@ -3322,11 +3431,6 @@ const level = {
|
||||
spawn.mapRect(175, -25, 750, 50);
|
||||
spawn.bodyRect(1350, -175, 150, 175, 0.5);
|
||||
spawn.bodyRect(1350, -600, 125, 225, 0.2);
|
||||
//entrance
|
||||
// vanish.push(level.vanish(-300, -500, 100, 25))
|
||||
// vanish.push(level.vanish(-450, -200, 100, 25))
|
||||
// spawn.bodyRect(-450, -175, 100, 175, 0.7);
|
||||
// spawn.bodyRect(-250, -550, 50, 50, 0.7);
|
||||
|
||||
//middle floor
|
||||
spawn.bodyRect(215, -1175, 100, 100, 0.3);
|
||||
@@ -5428,7 +5532,6 @@ const level = {
|
||||
ctx.fillRect(3650, -110, 1000, 170);
|
||||
ctx.fillRect(4865, -55, 100, 55);
|
||||
level.exit.drawAndCheck();
|
||||
|
||||
level.enter.draw();
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
@@ -7378,8 +7481,6 @@ const level = {
|
||||
|
||||
level.custom = () => {
|
||||
boost1.query();
|
||||
level.exit.drawAndCheck()
|
||||
|
||||
buttonGreen.query()
|
||||
buttonYellow.query()
|
||||
buttonRed.query()
|
||||
@@ -7521,6 +7622,7 @@ const level = {
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
ctx.fillRect(3500, 675, 600, 450)
|
||||
level.enter.draw()
|
||||
level.exit.drawAndCheck()
|
||||
}
|
||||
|
||||
level.customTopLayer = () => {
|
||||
@@ -8864,6 +8966,11 @@ const level = {
|
||||
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
|
||||
},
|
||||
crouch() { //learn to crouch
|
||||
if (localSettings.isTrainingNotAttempted) { //after making it to the second training level
|
||||
localSettings.isTrainingNotAttempted = false // this makes the training button less obvious at the start screen
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
|
||||
m.addHealth(Infinity)
|
||||
level.setPosToSpawn(75, -100); //normal spawn
|
||||
spawn.mapRect(25, -60, 100, 20); //small platform for player
|
||||
|
||||
12
js/mob.js
12
js/mob.js
@@ -1154,7 +1154,17 @@ const mobs = {
|
||||
}
|
||||
if (tech.isBotSpawnerReset) {
|
||||
for (let i = 0, len = bullet.length; i < len; i++) {
|
||||
if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 840 //14 seconds
|
||||
if (bullet[i].botType && bullet[i].endCycle !== Infinity) {
|
||||
bullet[i].endCycle = simulation.cycle + 840 //14 seconds
|
||||
// //draw a flash on top of bot
|
||||
// ctx.beginPath();
|
||||
// const v = bullet[i].vertices;
|
||||
// ctx.moveTo(v[0].x, v[0].y);
|
||||
// for (let i = 1; i < v.length; ++i) ctx.lineTo(v[i].x, v[i].y);
|
||||
// ctx.lineTo(v[0].x, v[0].y);
|
||||
// ctx.fillStyle = "#fff"
|
||||
// ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Math.random() < tech.botSpawner) {
|
||||
|
||||
@@ -1604,10 +1604,10 @@ const m = {
|
||||
if (tech.isStandingWaveExpand) {
|
||||
if (input.field) {
|
||||
// const oldHarmonicRadius = m.harmonicRadius
|
||||
m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5
|
||||
m.harmonicRadius = 0.99 * m.harmonicRadius + 0.01 * 4
|
||||
// m.energy -= 0.1 * (m.harmonicRadius - oldHarmonicRadius)
|
||||
} else {
|
||||
m.harmonicRadius = 0.995 * m.harmonicRadius + 0.005
|
||||
m.harmonicRadius = 0.994 * m.harmonicRadius + 0.006
|
||||
}
|
||||
}
|
||||
m.harmonicShield()
|
||||
@@ -3064,7 +3064,7 @@ const m = {
|
||||
|
||||
if (input.field) {
|
||||
if (tech.isWormHolePause) {
|
||||
const drain = m.fieldRegen + 0.0007
|
||||
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
|
||||
|
||||
@@ -397,8 +397,7 @@ const powerUps = {
|
||||
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
|
||||
for (let i = 0; i < banishLength; i++) {
|
||||
const index = powerUps.tech.choiceLog.length - i - 1
|
||||
// console.log(index, powerUps.tech.choiceLog[index], tech.tech[powerUps.tech.choiceLog[index]].name)
|
||||
if (powerUps.tech.choiceLog[index] !== undefined) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
|
||||
if (powerUps.tech.choiceLog[index] !== undefined || powerUps.tech.choiceLog[index] !== null) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
|
||||
}
|
||||
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
|
||||
}
|
||||
@@ -470,7 +469,7 @@ const powerUps = {
|
||||
}
|
||||
|
||||
if (tech.healGiveMaxEnergy) {
|
||||
tech.healMaxEnergyBonus += 0.07
|
||||
tech.healMaxEnergyBonus += 0.08
|
||||
m.setMaxEnergy();
|
||||
}
|
||||
},
|
||||
@@ -580,11 +579,14 @@ const powerUps = {
|
||||
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</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> ${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> ${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> ${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)
|
||||
@@ -594,9 +596,6 @@ const powerUps = {
|
||||
powerUps.field.choiceLog.push(choice4)
|
||||
powerUps.field.choiceLog.push(choice5)
|
||||
}
|
||||
powerUps.field.choiceLog.push(choice1)
|
||||
powerUps.field.choiceLog.push(choice2)
|
||||
powerUps.field.choiceLog.push(choice3)
|
||||
|
||||
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
tech.junkResearchNumber = Math.floor(4 * Math.random())
|
||||
@@ -627,7 +626,7 @@ const powerUps = {
|
||||
// banishLog: [], //records all tech permanently removed from the selection pool
|
||||
effect() {
|
||||
if (m.alive) {
|
||||
function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
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) {
|
||||
@@ -685,14 +684,17 @@ const powerUps = {
|
||||
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
|
||||
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
|
||||
let choice1 = pick()
|
||||
let choice2 = -1
|
||||
let choice3 = -1
|
||||
if (choice1 > -1) {
|
||||
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> ${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> ${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)
|
||||
@@ -702,9 +704,6 @@ const powerUps = {
|
||||
powerUps.tech.choiceLog.push(choice4)
|
||||
powerUps.tech.choiceLog.push(choice5)
|
||||
}
|
||||
powerUps.tech.choiceLog.push(choice1)
|
||||
powerUps.tech.choiceLog.push(choice2)
|
||||
powerUps.tech.choiceLog.push(choice3)
|
||||
// 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> research <span class="research-select">${powerUps.research.count}</span></div></div>`
|
||||
|
||||
if (tech.isExtraGunField) {
|
||||
@@ -857,8 +856,6 @@ const powerUps = {
|
||||
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> <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div>`
|
||||
}
|
||||
// console.log(powerUps.gun.choiceLog)
|
||||
// console.log(choice1, choice2, choice3)
|
||||
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();
|
||||
|
||||
112
js/spawn.js
112
js/spawn.js
@@ -1197,7 +1197,7 @@ const spawn = {
|
||||
} else if (!m.isCloak) {
|
||||
me.foundPlayer();
|
||||
}
|
||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0.22 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isInvulnerable = true
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.damageReduction = 0
|
||||
@@ -1276,7 +1276,7 @@ const spawn = {
|
||||
me.foundPlayer();
|
||||
}
|
||||
|
||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0.22 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
// me.isInvulnerable = true
|
||||
// me.startingDamageReduction = me.damageReduction
|
||||
// me.damageReduction = 0
|
||||
@@ -2030,7 +2030,7 @@ const spawn = {
|
||||
this.cons2.length = 100 + 1.5 * this.radius;
|
||||
|
||||
this.isInvulnerable = false
|
||||
this.invulnerabilityCountDown = 60 + Math.max(0, 70 - simulation.difficulty * 0.5)
|
||||
this.invulnerabilityCountDown = 70 + Math.max(0, 70 - simulation.difficulty * 0.5)
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
for (let i = 0; i < this.babyList.length; i++) {
|
||||
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction
|
||||
@@ -2044,7 +2044,7 @@ const spawn = {
|
||||
this.cons2.length = -200;
|
||||
|
||||
this.isInvulnerable = false
|
||||
this.invulnerabilityCountDown = 60 + Math.max(0, 70 - simulation.difficulty)
|
||||
this.invulnerabilityCountDown = 70 + Math.max(0, 70 - simulation.difficulty)
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
for (let i = 0; i < this.babyList.length; i++) {
|
||||
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction
|
||||
@@ -3518,6 +3518,110 @@ const spawn = {
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
},
|
||||
bounceBoss(x, y, radius = 80, isSpawnBossPOwerUp = true) {
|
||||
mobs.spawn(x, y, 0, radius, "rgb(255,255,255)") // "rgb(201,202,225)");
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.rotate(me, 2 * Math.PI * Math.random());
|
||||
me.isBoss = true;
|
||||
Matter.Body.setDensity(me, 0.003); //normal is 0.001
|
||||
me.inertia = Infinity;
|
||||
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.frictionAir = 0.01
|
||||
me.restitution = 1
|
||||
me.friction = 0
|
||||
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map | cat.mob
|
||||
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
|
||||
me.seePlayer.recall = 1;
|
||||
// spawn.shield(me, x, y, 1);
|
||||
me.onDamage = function() {
|
||||
if (this.health < this.nextHealthThreshold) {
|
||||
this.health = this.nextHealthThreshold - 0.01
|
||||
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
|
||||
this.fireCount = 60 + simulation.difficulty * 1.5
|
||||
this.isInvulnerable = true
|
||||
this.damageReduction = 0
|
||||
}
|
||||
};
|
||||
if (isSpawnBossPOwerUp) me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) };
|
||||
me.cycle = 0
|
||||
me.nextHealthThreshold = 0.75
|
||||
me.fireCount = 0
|
||||
// console.log(me.mass) //100
|
||||
me.do = function() {
|
||||
if (this.isInvulnerable) {
|
||||
this.fireCount--
|
||||
if (this.fireCount < 0) {
|
||||
this.isInvulnerable = false
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
}
|
||||
|
||||
if (this.mass > 10) Matter.Body.scale(this, 0.99, 0.99);
|
||||
|
||||
// for (let i = 0; i < 1; i++) {
|
||||
const velocity = Vector.rotate(Vector.mult(Vector.normalise(this.velocity), -10 - 10 * Math.random()), 1 * (Math.random() - 0.5))
|
||||
spawn.bounceBullet(this.position.x, this.position.y, velocity)
|
||||
// }
|
||||
//draw invulnerable
|
||||
ctx.beginPath();
|
||||
let vertices = this.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 20;
|
||||
ctx.strokeStyle = "rgba(255,255,255,0.7)";
|
||||
ctx.stroke();
|
||||
} else if (this.mass < 100) {
|
||||
Matter.Body.scale(this, 1.01, 1.01); //grow back to normal size
|
||||
}
|
||||
|
||||
this.checkStatus();
|
||||
//horizontal attraction
|
||||
// const xMag = 0.0005
|
||||
// if (player.position.x > this.position.x + 200) {
|
||||
// this.force.x += xMag * this.mass;
|
||||
// } else if (player.position.x < this.position.x - 200) {
|
||||
// this.force.x -= xMag * this.mass;
|
||||
// }
|
||||
|
||||
//maintain speed //faster in the vertical to help avoid repeating patterns
|
||||
if (Math.abs(this.velocity.y) < 15) {
|
||||
Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.05 });
|
||||
}
|
||||
if (Math.abs(this.velocity.x) < 11) {
|
||||
Matter.Body.setVelocity(this, { x: this.velocity.x * 1.05, y: this.velocity.y });
|
||||
}
|
||||
};
|
||||
},
|
||||
bounceBullet(x, y, velocity = { x: 0, y: 0 }, radius = 10, sides = 6) {
|
||||
//bullets
|
||||
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.stroke = "transparent";
|
||||
Matter.Body.setDensity(me, 0.00003); //normal is 0.001
|
||||
me.timeLeft = 360 + Math.floor(180 * Math.random())
|
||||
me.inertia = Infinity;
|
||||
me.damageReduction = 1
|
||||
me.frictionAir = 0
|
||||
me.friction = 0
|
||||
me.restitution = 1
|
||||
me.collisionFilter.category = cat.mobBullet;
|
||||
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map | cat.mob
|
||||
|
||||
me.leaveBody = false;
|
||||
me.isDropPowerUp = false;
|
||||
me.isBadTarget = true;
|
||||
me.isMobBullet = true;
|
||||
me.showHealthBar = false;
|
||||
me.onHit = function() {
|
||||
this.explode(this.mass * 20);
|
||||
};
|
||||
me.do = function() {
|
||||
this.timeLimit();
|
||||
};
|
||||
Matter.Body.setVelocity(me, velocity);
|
||||
},
|
||||
slashBoss(x, y, radius = 80) {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(201,202,225)");
|
||||
let me = mob[mob.length - 1];
|
||||
|
||||
30
js/tech.js
30
js/tech.js
@@ -795,7 +795,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "heuristics",
|
||||
description: "<strong>30%</strong> decreased <strong><em>delay</em></strong> after firing",
|
||||
description: "<strong>33%</strong> decreased <strong><em>delay</em></strong> after firing",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -803,7 +803,7 @@ const tech = {
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.fireRate *= 0.7
|
||||
tech.fireRate *= 0.67
|
||||
b.setFireCD();
|
||||
},
|
||||
remove() {
|
||||
@@ -4671,7 +4671,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "ammonium nitrate",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>30%</strong>",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>27%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>27%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -4682,7 +4682,7 @@ const tech = {
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
tech.explosiveRadius += 0.3;
|
||||
tech.explosiveRadius += 0.27;
|
||||
},
|
||||
remove() {
|
||||
tech.explosiveRadius = 1;
|
||||
@@ -5955,7 +5955,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "spherical harmonics",
|
||||
description: "<strong>standing wave</strong> oscillates in a 3rd dimension<br>increasing <strong>deflecting</strong> efficiency by <strong>40%</strong>",
|
||||
description: "<strong>standing wave</strong> oscillates in a 3rd dimension<br>increase <strong>deflecting</strong> efficiency by <strong>40%</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -5967,18 +5967,18 @@ const tech = {
|
||||
requires: "standing wave",
|
||||
effect() {
|
||||
tech.harmonics++
|
||||
m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2))
|
||||
m.fieldShieldingScale = (tech.isStandingWaveExpand ? 1.1 : 1.3) * Math.pow(0.6, (tech.harmonics - 2))
|
||||
m.harmonicShield = m.harmonicAtomic
|
||||
},
|
||||
remove() {
|
||||
tech.harmonics = 2
|
||||
m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2))
|
||||
m.fieldShieldingScale = (tech.isStandingWaveExpand ? 1.1 : 1.3) * Math.pow(0.6, (tech.harmonics - 2))
|
||||
m.harmonicShield = m.harmonic3Phase
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "expansion",
|
||||
description: "using <strong>standing wave</strong> field<br>temporarily <strong>expands</strong> its <strong>radius</strong>",
|
||||
description: "using <strong>standing wave</strong> field <strong>expands</strong> its <strong>radius</strong><br>increase <strong>deflecting</strong> efficiency by <strong>25%</strong>",
|
||||
// description: "use <strong class='color-f'>energy</strong> to <strong>expand</strong> <strong>standing wave</strong><br>the field slowly <strong>contracts</strong> when not used",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
@@ -5991,9 +5991,11 @@ const tech = {
|
||||
requires: "standing wave",
|
||||
effect() {
|
||||
tech.isStandingWaveExpand = true
|
||||
m.fieldShieldingScale = (tech.isStandingWaveExpand ? 1.1 : 1.3) * Math.pow(0.6, (tech.harmonics - 2))
|
||||
},
|
||||
remove() {
|
||||
tech.isStandingWaveExpand = false
|
||||
m.fieldShieldingScale = (tech.isStandingWaveExpand ? 1.1 : 1.3) * Math.pow(0.6, (tech.harmonics - 2))
|
||||
m.harmonicRadius = 1
|
||||
}
|
||||
},
|
||||
@@ -8468,7 +8470,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "energy investment",
|
||||
description: "every 10 seconds drain your <strong class='color-f'>energy</strong><br>return it doubled 10 seconds later<br>lasts 180 seconds",
|
||||
description: "every 10 seconds drain your <strong class='color-f'>energy</strong><br>return it doubled 5 seconds later",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
@@ -8477,20 +8479,20 @@ const tech = {
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0; i < 18; i++) {
|
||||
setTimeout(() => { //drain energy
|
||||
setInterval(() => {
|
||||
if (!simulation.paused) {
|
||||
const energy = m.energy
|
||||
m.energy = 0
|
||||
setTimeout(() => { //return energy
|
||||
m.energy += 2 * energy
|
||||
}, 5000);
|
||||
}, i * 10000);
|
||||
}
|
||||
}, 10000);
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "missile Launching System",
|
||||
name: "missile launching system",
|
||||
description: "fire missiles for the next 120 seconds",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -8524,12 +8526,14 @@ const tech = {
|
||||
requires: "",
|
||||
effect() {
|
||||
setInterval(() => {
|
||||
if (!simulation.paused && document.visibilityState !== "hidden") {
|
||||
b.grenade(Vector.add(m.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -Math.PI / 2) //fire different angles for each grenade
|
||||
const who = bullet[bullet.length - 1]
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.1,
|
||||
y: who.velocity.y * 0.1
|
||||
});
|
||||
}
|
||||
}, 2000);
|
||||
},
|
||||
remove() {}
|
||||
|
||||
50
todo.txt
50
todo.txt
@@ -1,20 +1,46 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
JUNK tech: tinker - unlock JUNK tech in experiment mode
|
||||
this effect is stored for future visits on the same browser
|
||||
several JUNK tech text have been cleaned up
|
||||
new level: reactor - midBoss fight
|
||||
it's not well balanced yet
|
||||
Let me know if there are any impossible gun combinations
|
||||
|
||||
your explosions do 8% more damage, but not more harm
|
||||
grenade gun fires 5% faster
|
||||
ruins/pavilion map is adjusted to be a bit easier to move around
|
||||
crouching speeds up exit door animation
|
||||
for new players the training button at the start screen now cycles colors
|
||||
effect shows if you haven't cleared the first training level, and you haven't done at least a few normal runs
|
||||
|
||||
removed google analytics
|
||||
bug fix with power ups and frozen time
|
||||
bug fix with elevators and map collision
|
||||
standing wave expansion tech is 40% larger and gives 25% deflecting efficiency
|
||||
ammonium nitrate gives 30 -> 27% damage and range
|
||||
heuristics gives 30 -> 33% fire rate
|
||||
wormhole invariant tech drains energy much slower while time is paused
|
||||
|
||||
bug fixes
|
||||
null level now longer progresses level.onLevel
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
reactor
|
||||
give map some background graphics
|
||||
it's a little short
|
||||
add alternate boss
|
||||
add a boss that spawns after the first one dies
|
||||
balance
|
||||
boss damage reduction
|
||||
bullet size
|
||||
bullet spawn number
|
||||
bounce speed
|
||||
add horizontal flip mode
|
||||
|
||||
bug: possibly clearing away all bullets causes a problem
|
||||
bullet.js 255 (.do() is missing)
|
||||
I died and quantum immortality triggered (I had needles and ice-IX)
|
||||
game crashed but recovered
|
||||
|
||||
go non-collide with mobs when immune to damage?
|
||||
|
||||
mobs that are invulnerable from the front
|
||||
|
||||
vertical reversed version of reservoir level, start at top and press buttons to lower slime
|
||||
mechanic: push a very large block into slime in order to stand on it and avoid slime
|
||||
|
||||
add anticipation to more mob attacks
|
||||
stabber
|
||||
striker
|
||||
@@ -28,8 +54,6 @@ path finding system
|
||||
|
||||
figure out how to get friction effects on map/body to apply to player
|
||||
|
||||
vertical reversed version of reservoir level, start at top and press buttons to lower slime
|
||||
|
||||
growBoss and cellBoss are too similar
|
||||
|
||||
variant of Occam's razor - remove 50% of your tech for each removed get:
|
||||
@@ -540,6 +564,8 @@ possible names for tech
|
||||
hall effect thrusters
|
||||
spaghettification
|
||||
particle accelerator
|
||||
superluminal signalling
|
||||
NP-complete
|
||||
|
||||
a tutorial / lore intro
|
||||
needs to be optional so it doesn't slow experienced players
|
||||
|
||||
Reference in New Issue
Block a user