level ban setting
new setting: level ban list bug fix: removed a command to preventDefault on space key, this might break something else new boss added to level - Temple snake tails have a lower mass and whip around a bit auto targeting no longer works for stealth mobs snipers, sneakers, ghosters snipers fire more often at high difficulty, but bullets move slower at all difficulties hoppers have move gravity, so it feels like they are hopping a bit faster
This commit is contained in:
64
index.html
64
index.html
@@ -49,12 +49,6 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary>settings</summary>
|
<summary>settings</summary>
|
||||||
<div style="line-height: 150%;" class="details-div">
|
<div style="line-height: 150%;" class="details-div">
|
||||||
|
|
||||||
<label for="seed">randomization seed:</label>
|
|
||||||
<input type="text" id="seed" name="seed" autocomplete="off" spellcheck="false" minlength="1" size="20" style="width: 120px;">
|
|
||||||
<br>
|
|
||||||
<span id="previous-seed" style="color:#bbb"></span>
|
|
||||||
|
|
||||||
<label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">combat difficulty:</label>
|
<label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">combat difficulty:</label>
|
||||||
<select name="difficulty-select" id="difficulty-select" style="background-color: #fff">
|
<select name="difficulty-select" id="difficulty-select" style="background-color: #fff">
|
||||||
<option value="1">easy</option>
|
<option value="1">easy</option>
|
||||||
@@ -63,12 +57,61 @@
|
|||||||
<option value="6">why?</option>
|
<option value="6">why?</option>
|
||||||
</select>
|
</select>
|
||||||
<br>
|
<br>
|
||||||
|
<label for="fps-select" title="use this to slow the game down">limit frames per second:</label>
|
||||||
|
<select name="fps-select" id="fps-select">
|
||||||
|
<option value="max" selected>no cap</option>
|
||||||
|
<option value="72">72 fps</option>
|
||||||
|
<option value="60">60 fps</option>
|
||||||
|
<option value="45">45 fps</option>
|
||||||
|
<option value="30">30 fps</option>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<label for="seed">randomization seed:</label>
|
||||||
|
<input type="text" id="seed" name="seed" autocomplete="off" spellcheck="false" minlength="1" style="width: 120px;">
|
||||||
|
<br>
|
||||||
|
<span id="previous-seed" style="color:#bbb"></span>
|
||||||
<label for="community-maps" title="">include community maps:</label>
|
<label for="community-maps" title="">include community maps:</label>
|
||||||
<input type="checkbox" id="community-maps" name="community-maps" style="width:17px; height:17px;">
|
<input type="checkbox" id="community-maps" name="community-maps" style="width:17px; height:17px;">
|
||||||
<!-- <br>
|
<!-- <br>
|
||||||
<label for="body-damage" title="allow damage from the ground and large fast moving blocks">collision damage from blocks:</label>
|
<label for="body-damage" title="allow damage from the ground and large fast moving blocks">collision damage from blocks:</label>
|
||||||
<input type="checkbox" id="body-damage" name="body-damage" checked style="width:17px; height:17px;"> -->
|
<input type="checkbox" id="body-damage" name="body-damage" checked style="width:17px; height:17px;"> -->
|
||||||
<br>
|
<br>
|
||||||
|
<label for="banned">banned levels:</label>
|
||||||
|
<input list="ban-suggest" id="banned" name="banned" placeholder="list levels by name" autocomplete="off" spellcheck="false" style="width: 182px;" />
|
||||||
|
<datalist id="ban-suggest">
|
||||||
|
<option value="testChamber">
|
||||||
|
<option value="sewers">
|
||||||
|
<option value="satellite">
|
||||||
|
<option value="aerie">
|
||||||
|
<option value="office">
|
||||||
|
<option value="highrise">
|
||||||
|
<option value="warehouse">
|
||||||
|
<option value="skyscrapers">
|
||||||
|
<option value="rooftops">
|
||||||
|
<option value="pavilion">
|
||||||
|
<option value="labs">
|
||||||
|
<option value="______">
|
||||||
|
<option value="islands">
|
||||||
|
<option value="tunnel">
|
||||||
|
<option value="coliseum">
|
||||||
|
<option value="dripp">
|
||||||
|
<option value="perplex">
|
||||||
|
<option value="n-gon">
|
||||||
|
<option value="vats">
|
||||||
|
<option value="basement">
|
||||||
|
<option value="stronghold">
|
||||||
|
<option value="crossfire">
|
||||||
|
<option value="house">
|
||||||
|
<option value="dripp">
|
||||||
|
<option value="temple">
|
||||||
|
<option value="run">
|
||||||
|
</datalist>
|
||||||
|
<!-- communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp"], -->
|
||||||
|
<!-- playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"], -->
|
||||||
|
|
||||||
|
<!-- <label for="banned">banned levels:</label>
|
||||||
|
<input type="text" id="ban-list" name="banned" placeholder="list levels by name" autocomplete="off" spellcheck="true" style="width: 183px;"> -->
|
||||||
|
<br>
|
||||||
<label for="classic-select" title="play older versions of n-gon">classic n-gon:</label>
|
<label for="classic-select" title="play older versions of n-gon">classic n-gon:</label>
|
||||||
<select name="classic-select" id="classic-select" onChange="window.location.href=this.value">
|
<select name="classic-select" id="classic-select" onChange="window.location.href=this.value">
|
||||||
<option value="https://scratch.mit.edu/projects/14005697/fullscreen/">mech: 2014</option>
|
<option value="https://scratch.mit.edu/projects/14005697/fullscreen/">mech: 2014</option>
|
||||||
@@ -85,15 +128,6 @@
|
|||||||
<option value="classic/6-1-2021/">n-gon: spring-2021</option>
|
<option value="classic/6-1-2021/">n-gon: spring-2021</option>
|
||||||
<option value="" selected>current version</option>
|
<option value="" selected>current version</option>
|
||||||
</select>
|
</select>
|
||||||
<br>
|
|
||||||
<label for="fps-select" title="use this to slow the game down">limit frames per second:</label>
|
|
||||||
<select name="fps-select" id="fps-select">
|
|
||||||
<option value="max" selected>no cap</option>
|
|
||||||
<option value="72">72 fps</option>
|
|
||||||
<option value="60">60 fps</option>
|
|
||||||
<option value="45">45 fps</option>
|
|
||||||
<option value="30">30 fps</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
19
js/index.js
19
js/index.js
@@ -247,6 +247,8 @@ const build = {
|
|||||||
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} difficulty: ${(1/simulation.dmgScale).toPrecision(3)}
|
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} difficulty: ${(1/simulation.dmgScale).toPrecision(3)}
|
||||||
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
|
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
|
||||||
<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
|
<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
|
||||||
|
<br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)}
|
||||||
|
${m.coupling> 0 ? '<br>'+m.couplingDescription(): ""}
|
||||||
${botText}
|
${botText}
|
||||||
<br>
|
<br>
|
||||||
<br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})
|
<br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})
|
||||||
@@ -920,7 +922,7 @@ window.addEventListener("keydown", function(event) {
|
|||||||
input.fire = true
|
input.fire = true
|
||||||
break
|
break
|
||||||
case input.key.field:
|
case input.key.field:
|
||||||
event.preventDefault();
|
// event.preventDefault();
|
||||||
input.field = true
|
input.field = true
|
||||||
break
|
break
|
||||||
case input.key.nextGun:
|
case input.key.nextGun:
|
||||||
@@ -1248,7 +1250,6 @@ if (localstorageCheck()) {
|
|||||||
localSettings = { isAllowed: false }
|
localSettings = { isAllowed: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (localSettings.isAllowed && !localSettings.isEmpty) {
|
if (localSettings.isAllowed && !localSettings.isEmpty) {
|
||||||
console.log('restoring previous settings')
|
console.log('restoring previous settings')
|
||||||
|
|
||||||
@@ -1279,10 +1280,18 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
|
|||||||
simulation.fpsCapDefault = Number(localSettings.fpsCapDefault)
|
simulation.fpsCapDefault = Number(localSettings.fpsCapDefault)
|
||||||
}
|
}
|
||||||
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
||||||
|
|
||||||
|
if (localSettings.banList.length === 0 || localSettings.banList === "undefined") {
|
||||||
|
localSettings.banList = ""
|
||||||
|
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||||
|
}
|
||||||
|
document.getElementById("banned").value = localSettings.banList
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log('setting default localSettings')
|
console.log('setting default localSettings')
|
||||||
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
|
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
|
||||||
localSettings = {
|
localSettings = {
|
||||||
|
banList: "",
|
||||||
isAllowed: isAllowed,
|
isAllowed: isAllowed,
|
||||||
personalSeeds: [],
|
personalSeeds: [],
|
||||||
isJunkExperiment: false,
|
isJunkExperiment: false,
|
||||||
@@ -1302,6 +1311,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
|
|||||||
simulation.isCommunityMaps = localSettings.isCommunityMaps
|
simulation.isCommunityMaps = localSettings.isCommunityMaps
|
||||||
document.getElementById("difficulty-select").value = localSettings.difficultyMode
|
document.getElementById("difficulty-select").value = localSettings.difficultyMode
|
||||||
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
||||||
|
document.getElementById("banned").value = localSettings.banList
|
||||||
}
|
}
|
||||||
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
|
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
|
||||||
// document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
|
// document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
|
||||||
@@ -1322,6 +1332,11 @@ document.getElementById("fps-select").addEventListener("input", () => {
|
|||||||
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById("banned").addEventListener("input", () => {
|
||||||
|
localSettings.banList = document.getElementById("banned").value
|
||||||
|
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById("community-maps").addEventListener("input", () => {
|
document.getElementById("community-maps").addEventListener("input", () => {
|
||||||
simulation.isCommunityMaps = document.getElementById("community-maps").checked
|
simulation.isCommunityMaps = document.getElementById("community-maps").checked
|
||||||
localSettings.isCommunityMaps = simulation.isCommunityMaps
|
localSettings.isCommunityMaps = simulation.isCommunityMaps
|
||||||
|
|||||||
194
js/level.js
194
js/level.js
@@ -16,16 +16,16 @@ const level = {
|
|||||||
start() {
|
start() {
|
||||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.difficultyIncrease(1 * 4) //30 is near max on hard //60 is near max on why
|
// level.difficultyIncrease(5 * 4) //30 is near max on hard //60 is near max on why
|
||||||
// simulation.isHorizontalFlipped = true
|
// simulation.isHorizontalFlipped = true
|
||||||
// m.maxHealth = m.health = 100
|
// m.maxHealth = m.health = 100
|
||||||
// tech.isRerollDamage = true
|
// tech.isRerollDamage = true
|
||||||
// powerUps.research.changeRerolls(100000)
|
// powerUps.research.changeRerolls(100000)
|
||||||
// m.immuneCycle = Infinity //you can't take damage
|
// m.immuneCycle = Infinity //you can't take damage
|
||||||
// tech.tech[297].frequency = 100
|
// tech.tech[297].frequency = 100
|
||||||
// b.guns[0].ammo = 10000
|
|
||||||
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
|
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
|
||||||
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||||
|
// b.guns[0].ammo = 1000000
|
||||||
// tech.giveTech("sentry");
|
// tech.giveTech("sentry");
|
||||||
// tech.giveTech("MACHO");
|
// tech.giveTech("MACHO");
|
||||||
// tech.giveTech("elephant's toothpaste")
|
// tech.giveTech("elephant's toothpaste")
|
||||||
@@ -36,10 +36,8 @@ const level = {
|
|||||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
|
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
|
||||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
|
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
|
||||||
|
|
||||||
// spawn.flutter(1900, -500, 10)
|
|
||||||
// spawn.starter(1900, -500, 200)
|
// spawn.starter(1900, -500, 200)
|
||||||
// spawn.historyBoss(1900, -400)
|
// spawn.snakeSpitBoss(1900, -400)
|
||||||
// spawn.beetleBoss(1900, -400)
|
|
||||||
// for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
|
// for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
|
||||||
// level.testing();
|
// level.testing();
|
||||||
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
|
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
|
||||||
@@ -239,30 +237,44 @@ const level = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
populateLevels() { //run a second time if URL is loaded
|
populateLevels() { //run a second time if URL is loaded
|
||||||
if (document.getElementById("seed").value) {
|
if (document.getElementById("banned").value) { //remove levels from ban list in settings
|
||||||
|
const banList = document.getElementById("banned").value.replace(/,/g, ' ').replace(/\s\s+/g, ' ').replace(/[^\w\s]/g, '') //replace commas with spaces, replace double spaces with single, remove strange symbols
|
||||||
|
const remove = banList.split(" ");
|
||||||
|
console.log('remove these', remove)
|
||||||
|
console.log('community levels before', level.communityLevels)
|
||||||
|
for (let i = 0; i < remove.length; i++) {
|
||||||
|
const index = level.communityLevels.indexOf(remove[i])
|
||||||
|
if (index !== -1) level.communityLevels.splice(index, 1);
|
||||||
|
}
|
||||||
|
console.log('community levels after', level.communityLevels)
|
||||||
|
console.log('Landgreen levels before', level.playableLevels)
|
||||||
|
for (let i = 0; i < remove.length; i++) {
|
||||||
|
if (level.playableLevels.length + level.communityLevels.length * simulation.isCommunityMaps < 10) break //can't remove too many levels
|
||||||
|
const index = level.playableLevels.indexOf(remove[i])
|
||||||
|
if (index !== -1) level.playableLevels.splice(index, 1);
|
||||||
|
}
|
||||||
|
console.log('Landgreen levels after', level.playableLevels)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById("seed").value) { //check for player entered seed in settings
|
||||||
Math.initialSeed = String(document.getElementById("seed").value)
|
Math.initialSeed = String(document.getElementById("seed").value)
|
||||||
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it
|
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simulation.isTraining) {
|
if (simulation.isTraining) {
|
||||||
level.levels = level.trainingLevels.slice(0) //copy array, not by just by assignment
|
level.levels = level.trainingLevels.slice(0) //copy array, not by just by assignment
|
||||||
} else {
|
} else { //add remove and shuffle levels for the normal game (not training levels)
|
||||||
simulation.isHorizontalFlipped = (Math.seededRandom() < 0.5) ? true : false //if true, some maps are flipped horizontally
|
|
||||||
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
|
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
|
||||||
if (simulation.isCommunityMaps) {
|
if (simulation.isCommunityMaps) {
|
||||||
// level.levels.push(level.communityLevels)
|
|
||||||
level.levels = level.levels.concat(level.communityLevels)
|
level.levels = level.levels.concat(level.communityLevels)
|
||||||
level.levels = shuffle(level.levels); //shuffles order of maps
|
|
||||||
level.levels.splice(0, level.communityLevels.length); //remove some random levels to make up for adding the community levels
|
|
||||||
simulation.isHorizontalFlipped = false;
|
simulation.isHorizontalFlipped = false;
|
||||||
} else {
|
} else {
|
||||||
level.levels = shuffle(level.levels); //shuffles order of maps
|
simulation.isHorizontalFlipped = (Math.seededRandom() < 0.5) ? true : false //if true, some maps are flipped horizontally
|
||||||
}
|
}
|
||||||
// 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 = shuffle(level.levels); //shuffles order of maps with seeded random
|
||||||
|
level.levels.length = 9 //remove any extra levels past 9
|
||||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list
|
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list
|
||||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||||
// level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.2, level.levels.length * 0.5)), 0, "reactor"); //add level to the back half of the randomized levels list
|
|
||||||
// level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.7, level.levels.length)), 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
|
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
|
level.levels.unshift("intro"); //add level to the start of the randomized levels list
|
||||||
level.levels.push("gauntlet"); //add level to the end of the randomized levels list
|
level.levels.push("gauntlet"); //add level to the end of the randomized levels list
|
||||||
@@ -9923,7 +9935,6 @@ const level = {
|
|||||||
powerUps.spawn(3000, -230, "heal");
|
powerUps.spawn(3000, -230, "heal");
|
||||||
// level.difficultyIncrease(60)
|
// level.difficultyIncrease(60)
|
||||||
},
|
},
|
||||||
|
|
||||||
temple() {
|
temple() {
|
||||||
simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
|
simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
|
||||||
|
|
||||||
@@ -9977,6 +9988,26 @@ const level = {
|
|||||||
Rect.fromBounds = function(min, max) {
|
Rect.fromBounds = function(min, max) {
|
||||||
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
|
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
|
||||||
}
|
}
|
||||||
|
Rect.prototype.isCollidingWith = function(other) {
|
||||||
|
const tc = {
|
||||||
|
p1: [this.pos.x, this.pos.y],
|
||||||
|
p2: [this.pos.x + this.width, this.pos.y + this.height]
|
||||||
|
};
|
||||||
|
const oc = {
|
||||||
|
p1: [other.pos.x, other.pos.y],
|
||||||
|
p2: [other.pos.x + other.width, other.pos.y + other.height]
|
||||||
|
};
|
||||||
|
|
||||||
|
// If one rectangle is on left side of other
|
||||||
|
if (tc.p1[0] >= oc.p2[0] || oc.p1[0] >= tc.p2[0])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If one rectangle is above other
|
||||||
|
if (tc.p1[1] >= oc.p2[1] || oc.p1[1] >= tc.p2[1])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return Rect;
|
return Rect;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -9998,7 +10029,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function secondRoomBoss(x, y, radius = 25, isDark = false) {
|
function secondRoomSuckerBoss(x, y, isDark = false, radius = 25) {
|
||||||
mobs.spawn(x, y, 12, radius, isDark ? "#000" : "#fff");
|
mobs.spawn(x, y, 12, radius, isDark ? "#000" : "#fff");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
@@ -10100,6 +10131,119 @@ const level = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function secondRoomPlacerBoss(x, y, isDark = false, size = 70) {
|
||||||
|
mobs.spawn(x, y, isDark ? 3 : 4, size, isDark ? "#0008" : "#fff8");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
me.isBoss = true;
|
||||||
|
me.isDark = isDark;
|
||||||
|
|
||||||
|
me.stroke = isDark ? "#000" : "#fff";
|
||||||
|
me.seeAtDistance2 = 5e6; // Basically just see at all times, in the context it's given
|
||||||
|
me.accelMag = 0.0001 * simulation.accelScale;
|
||||||
|
me.collisionFilter.mask = cat.player | cat.bullet;
|
||||||
|
me.memory = 1600;
|
||||||
|
me.randomPRNGMult = Math.random() * 500;
|
||||||
|
|
||||||
|
me.attackCycle = 0;
|
||||||
|
me.maxAttackCycle = isDark ? 90 : 240;
|
||||||
|
Matter.Body.setDensity(me, 0.006); // extra dense, normal is 0.001 // makes effective life much larger
|
||||||
|
me.onDeath = function() {
|
||||||
|
powerUps.spawn(this.position.x + 20, this.position.y, "ammo");
|
||||||
|
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
|
||||||
|
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
|
||||||
|
};
|
||||||
|
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
|
||||||
|
me.do = function() {
|
||||||
|
// keep it slow, to stop issues from explosion knock backs
|
||||||
|
if (this.speed > 2) {
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: this.velocity.x * 0.95,
|
||||||
|
y: this.velocity.y * 0.95
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||||
|
if (this.distanceToPlayer2() < this.seeAtDistance2) { // ignore cloak
|
||||||
|
this.locatePlayer();
|
||||||
|
if (!this.seePlayer.yes) this.seePlayer.yes = true;
|
||||||
|
} else if (this.seePlayer.recall) {
|
||||||
|
this.lostPlayer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.checkStatus();
|
||||||
|
if (this.seePlayer.recall) {
|
||||||
|
// accelerate towards the player
|
||||||
|
const forceMag = this.accelMag * this.mass;
|
||||||
|
const dx = this.seePlayer.position.x - this.position.x
|
||||||
|
const dy = this.seePlayer.position.y - this.position.y
|
||||||
|
const mag = Math.sqrt(dx * dx + dy * dy)
|
||||||
|
this.force.x += forceMag * dx / mag;
|
||||||
|
this.force.y += forceMag * dy / mag;
|
||||||
|
this.attackCycle++;
|
||||||
|
if (this.attackCycle > this.maxAttackCycle) {
|
||||||
|
this.attackCycle = 0;
|
||||||
|
secondRoomObstacle(this.position.x, this.position.y, this.isDark, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function secondRoomObstacle(x, y, isDark = false, size = 70) {
|
||||||
|
mobs.spawn(x, y, isDark ? 3 : 4, size, isDark ? "#0004" : "#fff4");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
|
||||||
|
me.stroke = isDark ? "#000b" : "#fffb";
|
||||||
|
me.collisionFilter.mask = isDark ? cat.player | cat.bullet : 0;
|
||||||
|
me.isDropPowerUp = false;
|
||||||
|
me.showHealthBar = false;
|
||||||
|
me.leaveBody = false;
|
||||||
|
me.timeLeft = 1200;
|
||||||
|
me.isObstacle = true;
|
||||||
|
me.damageReduction = isDark ? 0.5 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) : 0;
|
||||||
|
if (!isDark) {
|
||||||
|
me.isBadTarget = true;
|
||||||
|
me.attackCycle = 0;
|
||||||
|
me.maxAttackCycle = 10;
|
||||||
|
me.inertia = Infinity;
|
||||||
|
}
|
||||||
|
me.do = isDark ? function() {
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: this.velocity.x * 0.95,
|
||||||
|
y: this.velocity.y * 0.95
|
||||||
|
});
|
||||||
|
} : function() {
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: this.velocity.x * 0.95,
|
||||||
|
y: this.velocity.y * 0.95
|
||||||
|
});
|
||||||
|
if (Rect.fromBounds(this.bounds.min, this.bounds.max).isCollidingWith(Rect.fromBounds(player.bounds.min, player.bounds.max))) {
|
||||||
|
this.attackCycle++;
|
||||||
|
this.attackCycle = Math.min(this.attackCycle, 10);
|
||||||
|
} else {
|
||||||
|
this.attackCycle--;
|
||||||
|
this.attackCycle = Math.max(this.attackCycle, 0);
|
||||||
|
}
|
||||||
|
if (this.attackCycle > 0) {
|
||||||
|
ctx.beginPath();
|
||||||
|
const vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
if (this.attackCycle >= 10) {
|
||||||
|
ctx.shadowBlur = 10;
|
||||||
|
ctx.shadowColor = "rgb(255, 210, 64)";
|
||||||
|
}
|
||||||
|
ctx.fillStyle = `rgba(255, 210, 64, ${this.attackCycle / 15})`;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.shadowBlur = 0;
|
||||||
|
if (this.attackCycle >= 10) {
|
||||||
|
DrawTools.lightning(this.position, m.pos, simulation.cycle);
|
||||||
|
m.damage(0.003 * simulation.dmgScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.timeLimit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function mobGrenade(...args) {
|
function mobGrenade(...args) {
|
||||||
spawn.grenade(...args);
|
spawn.grenade(...args);
|
||||||
const pulseRadius = args[3] || Math.min(550, 250 + simulation.difficulty * 3)
|
const pulseRadius = args[3] || Math.min(550, 250 + simulation.difficulty * 3)
|
||||||
@@ -10209,12 +10353,12 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
me.horizon = function() {
|
me.horizon = function() {
|
||||||
if (this.isInvulnerable) return;
|
if (this.isInvulnerable) return this.fill = "#f00";
|
||||||
// eventHorizon waves in and out
|
// eventHorizon waves in and out
|
||||||
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008));
|
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008));
|
||||||
|
|
||||||
const charge = this.attackCycle / 90;
|
const charge = this.attackCycle / 90;
|
||||||
this.fill = this.isInvulnerable ? "#f00" : `rgb(${charge * 255},${charge * 255},${charge * 255})`;
|
this.fill = `rgb(${charge * 255},${charge * 255},${charge * 255})`;
|
||||||
// draw darkness
|
// draw darkness
|
||||||
ctx.fillStyle = `rgba(${charge * 225},${20 + charge * 195},${40 + charge * 215},0.6)`;
|
ctx.fillStyle = `rgba(${charge * 225},${20 + charge * 195},${40 + charge * 215},0.6)`;
|
||||||
DrawTools.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
|
DrawTools.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
|
||||||
@@ -11048,7 +11192,7 @@ const level = {
|
|||||||
if (simulation.cycle % 4 === 0) {
|
if (simulation.cycle % 4 === 0) {
|
||||||
let newMobPositions = [];
|
let newMobPositions = [];
|
||||||
for (const i of mob) {
|
for (const i of mob) {
|
||||||
if (!(i.isMACHO || i.isWIMP)) newMobPositions.push({ x: i.position.x, y: i.position.y });
|
if (!(i.isMACHO || i.isWIMP || i.isObstacle)) newMobPositions.push({ x: i.position.x, y: i.position.y });
|
||||||
}
|
}
|
||||||
mobPositionsQueue.shift();
|
mobPositionsQueue.shift();
|
||||||
mobPositionsQueue.push(newMobPositions);
|
mobPositionsQueue.push(newMobPositions);
|
||||||
@@ -11135,11 +11279,12 @@ const level = {
|
|||||||
room2() {
|
room2() {
|
||||||
if (!isInBound(secondRoomBounds)) return;
|
if (!isInBound(secondRoomBounds)) return;
|
||||||
if (templePlayer.room2.spawnInitiatorCycles > Objects.room2Initiator.cap) {
|
if (templePlayer.room2.spawnInitiatorCycles > Objects.room2Initiator.cap) {
|
||||||
|
const randomSecondRoomBoss = [secondRoomSuckerBoss, secondRoomPlacerBoss];
|
||||||
if (templePlayer.room2.cycles % 720 === 0 && templePlayer.room2.cycles <= 2160) {
|
if (templePlayer.room2.cycles % 720 === 0 && templePlayer.room2.cycles <= 2160) {
|
||||||
const isOdd = Math.floor(templePlayer.room2.cycles / 720) & 1;
|
const isOdd = Math.floor(templePlayer.room2.cycles / 720) & 1;
|
||||||
secondRoomBoss(-600, -9800, 25, isOdd);
|
randomSecondRoomBoss[Math.floor(randomSecondRoomBoss.length * Math.random())](-600, -9800, isOdd);
|
||||||
secondRoomBoss(600, -9800, 25, isOdd);
|
randomSecondRoomBoss[Math.floor(randomSecondRoomBoss.length * Math.random())](600, -9800, isOdd);
|
||||||
secondRoomBoss(0, -9800, 25, !isOdd);
|
randomSecondRoomBoss[Math.floor(randomSecondRoomBoss.length * Math.random())](0, -9800, !isOdd);
|
||||||
}
|
}
|
||||||
templePlayer.room2.cycles++;
|
templePlayer.room2.cycles++;
|
||||||
if (templePlayer.room2.cycles === 2400) {
|
if (templePlayer.room2.cycles === 2400) {
|
||||||
@@ -11310,6 +11455,7 @@ const level = {
|
|||||||
DrawHandler.room2Top();
|
DrawHandler.room2Top();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
// temple() {
|
// temple() {
|
||||||
// simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
|
// simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
|
||||||
|
|
||||||
|
|||||||
29
js/player.js
29
js/player.js
@@ -898,6 +898,7 @@ const m = {
|
|||||||
maxEnergy: 1, //can be increased by a tech
|
maxEnergy: 1, //can be increased by a tech
|
||||||
holdingTarget: null,
|
holdingTarget: null,
|
||||||
timeSkipLastCycle: 0,
|
timeSkipLastCycle: 0,
|
||||||
|
coupling: 0,
|
||||||
// these values are set on reset by setHoldDefaults()
|
// these values are set on reset by setHoldDefaults()
|
||||||
fieldFx: 1,
|
fieldFx: 1,
|
||||||
fieldJump: 1,
|
fieldJump: 1,
|
||||||
@@ -1517,6 +1518,30 @@ const m = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
hold() {},
|
hold() {},
|
||||||
|
couplingDescription() {
|
||||||
|
switch (m.fieldMode) {
|
||||||
|
case 0: //field emitter
|
||||||
|
return `gain the effects of all <strong class='color-f'>fields</strong>`
|
||||||
|
case 1: //standing wave
|
||||||
|
return `<strong>+20</strong> max <strong class='color-f'>energy</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 2: //perfect diamagnetism
|
||||||
|
return `<strong>+10°</strong> <strong>arc</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 3: //negative mass
|
||||||
|
return `<strong>+25%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 4: //assembler
|
||||||
|
return `generate <strong>4</strong> <strong class='color-f'>energy</strong> per second per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 5: //plasma
|
||||||
|
return `<strong>+13%</strong> <strong class='color-d'>damage</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 6: //time dilation
|
||||||
|
return `<strong>+20%</strong> <strong><em>fire rate</em></strong> per <strong class='color-coupling'>coupling</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
|
||||||
|
case 7: //cloaking
|
||||||
|
return `remove <strong>+10%</strong> mob <strong>durability</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 8: //pilot wave
|
||||||
|
return `________ per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
case 9: //wormhole
|
||||||
|
return `<strong>+5%</strong> <strong class='color-dup'>duplication</strong> per <strong class='color-coupling'>coupling</strong>`
|
||||||
|
}
|
||||||
|
},
|
||||||
setField(index) {
|
setField(index) {
|
||||||
if (isNaN(index)) { //find index by name
|
if (isNaN(index)) { //find index by name
|
||||||
let found = false
|
let found = false
|
||||||
@@ -3240,13 +3265,13 @@ const m = {
|
|||||||
{
|
{
|
||||||
name: "wormhole",
|
name: "wormhole",
|
||||||
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
||||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+4%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+3%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||||
drain: 0,
|
drain: 0,
|
||||||
effect: function() {
|
effect: function() {
|
||||||
m.fieldMeterColor = "#bbf" //"#0c5"
|
m.fieldMeterColor = "#bbf" //"#0c5"
|
||||||
m.eyeFillColor = m.fieldMeterColor
|
m.eyeFillColor = m.fieldMeterColor
|
||||||
|
|
||||||
m.duplicateChance = 0.04
|
m.duplicateChance = 0.03
|
||||||
m.fieldRange = 0
|
m.fieldRange = 0
|
||||||
powerUps.setDupChance(); //needed after adjusting duplication chance
|
powerUps.setDupChance(); //needed after adjusting duplication chance
|
||||||
|
|
||||||
|
|||||||
@@ -921,7 +921,7 @@ const powerUps = {
|
|||||||
if (tech.isExtraBotOption) {
|
if (tech.isExtraBotOption) {
|
||||||
const botTech = [] //make an array of bot options
|
const botTech = [] //make an array of bot options
|
||||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||||
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) botTech.push(i)
|
if (tech.tech[i].isBotTech && tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isRecentlyShown) botTech.push(i)
|
||||||
}
|
}
|
||||||
if (botTech.length > 0) { //pick random bot tech
|
if (botTech.length > 0) { //pick random bot tech
|
||||||
const choose = botTech[Math.floor(Math.random() * botTech.length)];
|
const choose = botTech[Math.floor(Math.random() * botTech.length)];
|
||||||
|
|||||||
114
js/spawn.js
114
js/spawn.js
@@ -1577,8 +1577,8 @@ const spawn = {
|
|||||||
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
||||||
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.accelMag = 0.04;
|
me.accelMag = 0.05;
|
||||||
me.g = 0.0017; //required if using this.gravity
|
me.g = 0.0032; //required if using this.gravity
|
||||||
me.frictionAir = 0.01;
|
me.frictionAir = 0.01;
|
||||||
me.friction = 1
|
me.friction = 1
|
||||||
me.frictionStatic = 1
|
me.frictionStatic = 1
|
||||||
@@ -1598,7 +1598,7 @@ const spawn = {
|
|||||||
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
|
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
|
||||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||||
this.force.x += forceMag * Math.cos(angle);
|
this.force.x += forceMag * Math.cos(angle);
|
||||||
this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.07 + 0.06) * this.mass; //antigravity
|
this.force.y += forceMag * Math.sin(angle) - (Math.random() * 0.06 + 0.1) * this.mass; //antigravity
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//randomly hob if not aware of player
|
//randomly hob if not aware of player
|
||||||
@@ -1609,7 +1609,7 @@ const spawn = {
|
|||||||
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.1 + Math.random() * 0.3);
|
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.1 + Math.random() * 0.3);
|
||||||
const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
|
const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
|
||||||
this.force.x += forceMag * Math.cos(angle);
|
this.force.x += forceMag * Math.cos(angle);
|
||||||
this.force.y += forceMag * Math.sin(angle) - 0.05 * this.mass; //antigravity
|
this.force.y += forceMag * Math.sin(angle) - 0.07 * this.mass; //antigravity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -4782,6 +4782,7 @@ const spawn = {
|
|||||||
me.alpha = 1; //used in drawSneaker
|
me.alpha = 1; //used in drawSneaker
|
||||||
// me.leaveBody = false;
|
// me.leaveBody = false;
|
||||||
me.canTouchPlayer = false; //used in drawSneaker
|
me.canTouchPlayer = false; //used in drawSneaker
|
||||||
|
me.isBadTarget = true;
|
||||||
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
me.memory = 240;
|
me.memory = 240;
|
||||||
@@ -4801,6 +4802,7 @@ const spawn = {
|
|||||||
this.healthBar();
|
this.healthBar();
|
||||||
if (!this.canTouchPlayer) {
|
if (!this.canTouchPlayer) {
|
||||||
this.canTouchPlayer = true;
|
this.canTouchPlayer = true;
|
||||||
|
this.isBadTarget = false;
|
||||||
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
|
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4816,6 +4818,7 @@ const spawn = {
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
} else if (this.canTouchPlayer) { //stealth
|
} else if (this.canTouchPlayer) { //stealth
|
||||||
this.canTouchPlayer = false;
|
this.canTouchPlayer = false;
|
||||||
|
this.isBadTarget = true;
|
||||||
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -4830,6 +4833,7 @@ const spawn = {
|
|||||||
me.stroke = "transparent"; //used for drawGhost
|
me.stroke = "transparent"; //used for drawGhost
|
||||||
me.alpha = 1; //used in drawGhost
|
me.alpha = 1; //used in drawGhost
|
||||||
me.canTouchPlayer = false; //used in drawGhost
|
me.canTouchPlayer = false; //used in drawGhost
|
||||||
|
me.isBadTarget = true;
|
||||||
// me.leaveBody = false;
|
// me.leaveBody = false;
|
||||||
me.collisionFilter.mask = cat.bullet //| cat.body
|
me.collisionFilter.mask = cat.bullet //| cat.body
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
@@ -4857,6 +4861,7 @@ const spawn = {
|
|||||||
this.healthBar();
|
this.healthBar();
|
||||||
if (!this.canTouchPlayer) {
|
if (!this.canTouchPlayer) {
|
||||||
this.canTouchPlayer = true;
|
this.canTouchPlayer = true;
|
||||||
|
this.isBadTarget = false;
|
||||||
this.collisionFilter.mask = cat.player | cat.bullet
|
this.collisionFilter.mask = cat.player | cat.bullet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4873,6 +4878,7 @@ const spawn = {
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
} else if (this.canTouchPlayer) {
|
} else if (this.canTouchPlayer) {
|
||||||
this.canTouchPlayer = false;
|
this.canTouchPlayer = false;
|
||||||
|
this.isBadTarget = true;
|
||||||
this.collisionFilter.mask = cat.bullet; //can't touch player or walls
|
this.collisionFilter.mask = cat.bullet; //can't touch player or walls
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -5055,7 +5061,7 @@ const spawn = {
|
|||||||
};
|
};
|
||||||
Matter.Body.setDensity(me, 0.00004); //normal is 0.001
|
Matter.Body.setDensity(me, 0.00004); //normal is 0.001
|
||||||
me.timeLeft = 200;
|
me.timeLeft = 200;
|
||||||
me.g = 0.001; //required if using this.gravity
|
// me.g = 0.001; //required if using this.gravity
|
||||||
me.frictionAir = 0;
|
me.frictionAir = 0;
|
||||||
me.restitution = 0.8;
|
me.restitution = 0.8;
|
||||||
me.leaveBody = false;
|
me.leaveBody = false;
|
||||||
@@ -5066,7 +5072,7 @@ const spawn = {
|
|||||||
me.collisionFilter.category = cat.mobBullet;
|
me.collisionFilter.category = cat.mobBullet;
|
||||||
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||||
me.do = function() {
|
me.do = function() {
|
||||||
this.gravity();
|
// this.gravity();
|
||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -5134,10 +5140,11 @@ const spawn = {
|
|||||||
me.frictionStatic = 0;
|
me.frictionStatic = 0;
|
||||||
me.friction = 0;
|
me.friction = 0;
|
||||||
me.canTouchPlayer = false; //used in drawSneaker
|
me.canTouchPlayer = false; //used in drawSneaker
|
||||||
|
me.isBadTarget = true;
|
||||||
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
|
|
||||||
me.memory = 60 //140;
|
me.memory = 30 //140;
|
||||||
me.fireFreq = 0.006 + Math.random() * 0.002;
|
me.fireFreq = 0.005 + Math.random() * 0.002 + 0.0005 * simulation.difficulty; //larger = fire more often
|
||||||
me.noseLength = 0;
|
me.noseLength = 0;
|
||||||
me.fireAngle = 0;
|
me.fireAngle = 0;
|
||||||
me.accelMag = 0.0005 * simulation.accelScale;
|
me.accelMag = 0.0005 * simulation.accelScale;
|
||||||
@@ -5183,8 +5190,8 @@ const spawn = {
|
|||||||
this.torque -= 0.000004 * this.inertia;
|
this.torque -= 0.000004 * this.inertia;
|
||||||
} else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) {
|
} else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) {
|
||||||
//fire
|
//fire
|
||||||
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 4);
|
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 5);
|
||||||
const v = 10 + 15 * simulation.accelScale;
|
const v = 10 + 8 * simulation.accelScale;
|
||||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
||||||
y: this.velocity.y + this.fireDir.y * v + Math.random()
|
y: this.velocity.y + this.fireDir.y * v + Math.random()
|
||||||
@@ -5216,6 +5223,7 @@ const spawn = {
|
|||||||
this.healthBar();
|
this.healthBar();
|
||||||
if (!this.canTouchPlayer) {
|
if (!this.canTouchPlayer) {
|
||||||
this.canTouchPlayer = true;
|
this.canTouchPlayer = true;
|
||||||
|
this.isBadTarget = false;
|
||||||
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
|
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5231,11 +5239,12 @@ const spawn = {
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
} else if (this.canTouchPlayer) {
|
} else if (this.canTouchPlayer) {
|
||||||
this.canTouchPlayer = false;
|
this.canTouchPlayer = false;
|
||||||
|
this.isBadTarget = true
|
||||||
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
sniperBullet(x, y, radius = 9, sides = 4) { //bullets
|
sniperBullet(x, y, radius = 9, sides = 5) { //bullets
|
||||||
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
|
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.stroke = "transparent";
|
me.stroke = "transparent";
|
||||||
@@ -5924,11 +5933,12 @@ const spawn = {
|
|||||||
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
|
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
me.accelMag = 0.0004 + 0.0002 * Math.sqrt(simulation.accelScale)
|
me.accelMag = 0.0001 + 0.0004 * Math.sqrt(simulation.accelScale)
|
||||||
|
// me.accelMag = 0.0004 + 0.0002 * Math.sqrt(simulation.accelScale)
|
||||||
me.memory = 250;
|
me.memory = 250;
|
||||||
me.laserRange = 500;
|
me.laserRange = 500;
|
||||||
Matter.Body.setDensity(me, 0.0022 + 0.00022 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.0022 + 0.00022 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
me.startingDamageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
me.startingDamageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
me.damageReduction = 0
|
me.damageReduction = 0
|
||||||
me.isInvulnerable = true
|
me.isInvulnerable = true
|
||||||
|
|
||||||
@@ -5952,7 +5962,7 @@ const spawn = {
|
|||||||
this.cycle++
|
this.cycle++
|
||||||
if (this.seePlayer.recall && ((this.cycle % 10) === 0)) {
|
if (this.seePlayer.recall && ((this.cycle % 10) === 0)) {
|
||||||
if (this.canFire) {
|
if (this.canFire) {
|
||||||
if (this.cycle > 100) {
|
if (this.cycle > 120) {
|
||||||
this.cycle = 0
|
this.cycle = 0
|
||||||
this.canFire = false
|
this.canFire = false
|
||||||
// Matter.Body.setAngularVelocity(this, 0.1)
|
// Matter.Body.setAngularVelocity(this, 0.1)
|
||||||
@@ -5963,7 +5973,7 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6)
|
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6)
|
||||||
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
|
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
|
||||||
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -13)
|
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.closestVertex1], this.position)), 15)
|
||||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
x: this.velocity.x + velocity.x,
|
x: this.velocity.x + velocity.x,
|
||||||
y: this.velocity.y + velocity.y
|
y: this.velocity.y + velocity.y
|
||||||
@@ -5975,7 +5985,7 @@ const spawn = {
|
|||||||
// x: this.velocity.x + velocity2.x,
|
// x: this.velocity.x + velocity2.x,
|
||||||
// y: this.velocity.y + velocity2.y
|
// y: this.velocity.y + velocity2.y
|
||||||
// });
|
// });
|
||||||
} else if (this.cycle > 210) {
|
} else if (this.cycle > 200) {
|
||||||
this.cycle = 0
|
this.cycle = 0
|
||||||
this.canFire = true
|
this.canFire = true
|
||||||
|
|
||||||
@@ -6011,6 +6021,8 @@ const spawn = {
|
|||||||
mag -= 10
|
mag -= 10
|
||||||
let previousTailID = 0
|
let previousTailID = 0
|
||||||
|
|
||||||
|
const damping = 1
|
||||||
|
const stiffness = 1
|
||||||
for (let i = 0; i < nodes; ++i) {
|
for (let i = 0; i < nodes; ++i) {
|
||||||
angle -= 0.15 + i * 0.008
|
angle -= 0.15 + i * 0.008
|
||||||
mag -= (i < 2) ? -15 : 5
|
mag -= (i < 2) ? -15 : 5
|
||||||
@@ -6021,7 +6033,7 @@ const spawn = {
|
|||||||
mob[mob.length - 1].previousTailID = previousTailID
|
mob[mob.length - 1].previousTailID = previousTailID
|
||||||
previousTailID = mob[mob.length - 1].id
|
previousTailID = mob[mob.length - 1].id
|
||||||
}
|
}
|
||||||
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
|
this.constrain2AdjacentMobs(nodes, stiffness, false, damping);
|
||||||
|
|
||||||
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
||||||
if (i % 2) {
|
if (i % 2) {
|
||||||
@@ -6034,40 +6046,45 @@ const spawn = {
|
|||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes],
|
bodyA: mob[mob.length - nodes],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes + 1],
|
bodyA: mob[mob.length - nodes + 1],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes + 2],
|
bodyA: mob[mob.length - nodes + 2],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
// spawn.shield(me, x, y, 1);
|
// spawn.shield(me, x, y, 1);
|
||||||
},
|
},
|
||||||
dragonFlyBoss(x, y, radius = 42) { //snake boss with a laser head
|
dragonFlyBoss(x, y, radius = 42) { //snake boss with a laser head
|
||||||
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
|
|
||||||
let angle = Math.PI
|
let angle = Math.PI
|
||||||
let mag = 300
|
let mag = 300
|
||||||
|
|
||||||
const color1 = "#00bfd9" //"#f27"
|
|
||||||
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, "#000"); //"rgb(55,170,170)"
|
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, "#000"); //"rgb(55,170,170)"
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
me.accelMag = 0.0009 + 0.0002 * Math.sqrt(simulation.accelScale)
|
|
||||||
me.memory = 250;
|
|
||||||
me.laserRange = 400;
|
|
||||||
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
me.startingDamageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
me.startingDamageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
me.damageReduction = 0
|
me.damageReduction = 0
|
||||||
me.isInvulnerable = true
|
me.isInvulnerable = true
|
||||||
|
|
||||||
|
me.accelMag = 0.0001 + 0.0004 * Math.sqrt(simulation.accelScale)
|
||||||
|
me.memory = 250;
|
||||||
|
me.flapRate = 0.4
|
||||||
|
me.flapArc = 0.2 //don't go past 1.57 for normal flaps
|
||||||
|
me.wingLength = 150
|
||||||
|
me.ellipticity = 0.3
|
||||||
|
me.angleOff = 0.4
|
||||||
|
|
||||||
me.onDeath = function() {
|
me.onDeath = function() {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
@@ -6101,15 +6118,10 @@ const spawn = {
|
|||||||
this.wing(a - Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
|
this.wing(a - Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
|
||||||
this.wing(a + Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
|
this.wing(a + Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
|
||||||
};
|
};
|
||||||
me.flapRate = 0.4
|
|
||||||
me.flapArc = 0.2 //don't go past 1.57 for normal flaps
|
|
||||||
me.wingLength = 150
|
|
||||||
me.ellipticity = 0.3
|
|
||||||
me.angleOff = 0.4
|
|
||||||
//extra space to give head room
|
|
||||||
angle -= 0.1
|
angle -= 0.1
|
||||||
mag -= 10
|
mag -= 10
|
||||||
let previousTailID = 0
|
let previousTailID = 0
|
||||||
|
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
|
||||||
for (let i = 0; i < nodes; ++i) {
|
for (let i = 0; i < nodes; ++i) {
|
||||||
angle -= 0.15 + i * 0.008
|
angle -= 0.15 + i * 0.008
|
||||||
mag -= (i < 2) ? -15 : 5
|
mag -= (i < 2) ? -15 : 5
|
||||||
@@ -6119,7 +6131,9 @@ const spawn = {
|
|||||||
mob[mob.length - 1].previousTailID = previousTailID
|
mob[mob.length - 1].previousTailID = previousTailID
|
||||||
previousTailID = mob[mob.length - 1].id
|
previousTailID = mob[mob.length - 1].id
|
||||||
}
|
}
|
||||||
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
|
const damping = 1
|
||||||
|
const stiffness = 1
|
||||||
|
this.constrain2AdjacentMobs(nodes, stiffness, false, damping);
|
||||||
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
||||||
mob[i].fill = `hsla(${160+40*Math.random()}, 100%, ${5 + 25*Math.random()*Math.random()}%, 0.9)`
|
mob[i].fill = `hsla(${160+40*Math.random()}, 100%, ${5 + 25*Math.random()*Math.random()}%, 0.9)`
|
||||||
}
|
}
|
||||||
@@ -6127,19 +6141,22 @@ const spawn = {
|
|||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes],
|
bodyA: mob[mob.length - nodes],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes + 1],
|
bodyA: mob[mob.length - nodes + 1],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - nodes + 2],
|
bodyA: mob[mob.length - nodes + 2],
|
||||||
bodyB: mob[mob.length - 1 - nodes],
|
bodyB: mob[mob.length - 1 - nodes],
|
||||||
stiffness: 0.05
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
// spawn.shield(me, x, y, 1);
|
// spawn.shield(me, x, y, 1);
|
||||||
@@ -6147,15 +6164,15 @@ const spawn = {
|
|||||||
snakeBody(x, y, radius = 10) {
|
snakeBody(x, y, radius = 10) {
|
||||||
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
|
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.collisionFilter.mask = cat.bullet | cat.player | cat.mob //| cat.body
|
me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body
|
||||||
me.damageReduction = 0.23
|
me.damageReduction = 0.015
|
||||||
Matter.Body.setDensity(me, 0.005); //normal is 0.001
|
Matter.Body.setDensity(me, 0.0001); //normal is 0.001
|
||||||
|
|
||||||
// me.accelMag = 0.0007 * simulation.accelScale;
|
// me.accelMag = 0.0007 * simulation.accelScale;
|
||||||
me.leaveBody = Math.random() < 0.33 ? true : false;
|
me.leaveBody = Math.random() < 0.33 ? true : false;
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
me.isDropPowerUp = false;
|
me.isDropPowerUp = false;
|
||||||
me.frictionAir = 0.015;
|
me.frictionAir = 0;
|
||||||
me.isSnakeTail = true;
|
me.isSnakeTail = true;
|
||||||
me.stroke = "transparent"
|
me.stroke = "transparent"
|
||||||
me.onDeath = function() {
|
me.onDeath = function() {
|
||||||
@@ -6476,13 +6493,14 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
constrain2AdjacentMobs(nodes, stiffness, loop = false) {
|
constrain2AdjacentMobs(nodes, stiffness, loop = false, damping = 0) {
|
||||||
//runs through every combination of last 'num' bodies and constrains them
|
//runs through every combination of last 'num' bodies and constrains them
|
||||||
for (let i = 0; i < nodes - 1; ++i) {
|
for (let i = 0; i < nodes - 1; ++i) {
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - i - 1],
|
bodyA: mob[mob.length - i - 1],
|
||||||
bodyB: mob[mob.length - i - 2],
|
bodyB: mob[mob.length - i - 2],
|
||||||
stiffness: stiffness
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
}
|
}
|
||||||
@@ -6491,7 +6509,8 @@ const spawn = {
|
|||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - i - 1],
|
bodyA: mob[mob.length - i - 1],
|
||||||
bodyB: mob[mob.length - i - 3],
|
bodyB: mob[mob.length - i - 3],
|
||||||
stiffness: stiffness
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
}
|
}
|
||||||
@@ -6501,19 +6520,22 @@ const spawn = {
|
|||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - 1],
|
bodyA: mob[mob.length - 1],
|
||||||
bodyB: mob[mob.length - nodes],
|
bodyB: mob[mob.length - nodes],
|
||||||
stiffness: stiffness
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - 2],
|
bodyA: mob[mob.length - 2],
|
||||||
bodyB: mob[mob.length - nodes],
|
bodyB: mob[mob.length - nodes],
|
||||||
stiffness: stiffness
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: mob[mob.length - 1],
|
bodyA: mob[mob.length - 1],
|
||||||
bodyB: mob[mob.length - nodes + 1],
|
bodyB: mob[mob.length - nodes + 1],
|
||||||
stiffness: stiffness
|
stiffness: stiffness,
|
||||||
|
damping: damping
|
||||||
});
|
});
|
||||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||||
}
|
}
|
||||||
|
|||||||
58
js/tech.js
58
js/tech.js
@@ -306,7 +306,41 @@ const tech = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tech: [{
|
tech: [
|
||||||
|
// {
|
||||||
|
// name: "field coupling",
|
||||||
|
// descriptionFunction() {
|
||||||
|
// return `<strong>+1</strong> <strong class='color-f'>field</strong> <strong class='color-coupling'>coupling</strong> (${m.fieldUpgrades[m.fieldMode].name})<br>${ m.couplingDescription()}`
|
||||||
|
// },
|
||||||
|
// // isFieldTech: true,
|
||||||
|
// maxCount: 9,
|
||||||
|
// count: 0,
|
||||||
|
// frequency: 2,
|
||||||
|
// frequencyDefault: 2,
|
||||||
|
// allowed() {
|
||||||
|
// return (build.isExperimentSelection || powerUps.research.count > 1)
|
||||||
|
// },
|
||||||
|
// requires: "",
|
||||||
|
// // researchUsed: 0,
|
||||||
|
// // couplingToResearch: 0.1,
|
||||||
|
// effect() {
|
||||||
|
// m.coupling++
|
||||||
|
// // while (powerUps.research.count > 0) {
|
||||||
|
// // powerUps.research.changeRerolls(-1)
|
||||||
|
// // this.researchUsed++
|
||||||
|
// // m.coupling += this.couplingToResearch
|
||||||
|
// // }
|
||||||
|
// },
|
||||||
|
// remove() {
|
||||||
|
// m.coupling = 0
|
||||||
|
// // if (this.count) {
|
||||||
|
// // m.coupling -= this.researchUsed * this.couplingToResearch
|
||||||
|
// // powerUps.research.changeRerolls(this.researchUsed)
|
||||||
|
// // this.researchUsed = 0
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
{
|
||||||
name: "ordnance",
|
name: "ordnance",
|
||||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
|
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -644,7 +678,7 @@ const tech = {
|
|||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isEnergyHealth //(tech.crouchAmmoCount || tech.isCrouchRegen) &&
|
return !tech.isEnergyHealth //(tech.crouchAmmoCount || tech.isCrouchRegen) &&
|
||||||
},
|
},
|
||||||
requires: "not mass-energy", //inductive coupling, desublimated ammunition,
|
requires: "not mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isTurret = true
|
tech.isTurret = true
|
||||||
},
|
},
|
||||||
@@ -2428,7 +2462,7 @@ const tech = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inductive coupling",
|
name: "inductive charging",
|
||||||
description: "if <strong>crouched</strong> <strong>+600%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled",
|
description: "if <strong>crouched</strong> <strong>+600%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -2511,7 +2545,7 @@ const tech = {
|
|||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isCrouchRegen
|
return !tech.isCrouchRegen
|
||||||
},
|
},
|
||||||
requires: "not inductive coupling",
|
requires: "not inductive charging",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isDamageAfterKillNoRegen = true;
|
tech.isDamageAfterKillNoRegen = true;
|
||||||
m.regenEnergy = function() {
|
m.regenEnergy = function() {
|
||||||
@@ -5788,21 +5822,11 @@ const tech = {
|
|||||||
requires: "foam",
|
requires: "foam",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isFoamPressure = true;
|
tech.isFoamPressure = true;
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
b.guns[8].chooseFireMethod()
|
||||||
if (b.guns[i].name === "foam") {
|
|
||||||
b.guns[i].chooseFireMethod()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.isFoamPressure = false;
|
tech.isFoamPressure = false;
|
||||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
b.guns[8].chooseFireMethod()
|
||||||
if (b.guns[i].name === "foam") {
|
|
||||||
b.guns[i].chooseFireMethod()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -7032,7 +7056,7 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "plasma-bot",
|
name: "plasma-bot",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">plasma-bot</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">plasma-bot</a>`,
|
||||||
description: "remove your <strong>field</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>",
|
description: "remove your <strong class='color-f'>field</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>",
|
||||||
isFieldTech: true,
|
isFieldTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
|||||||
31
style.css
31
style.css
@@ -38,7 +38,7 @@ input {
|
|||||||
border: 1px #333 solid;
|
border: 1px #333 solid;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
/* margin: 0.2em; */
|
/* margin: 0.2em; */
|
||||||
width: 38px;
|
/* width: 38px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -924,6 +924,34 @@ summary {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-coupling {
|
||||||
|
/* animation: coupling 1000ms linear infinite alternate; */
|
||||||
|
/* animation: vibrate 500ms linear infinite alternate;
|
||||||
|
display: inline-block; */
|
||||||
|
/* text-shadow: 0px 0px 2px #0cf; */
|
||||||
|
text-shadow: 0px 0px 1.5px #0cf;
|
||||||
|
/* color: hsl(255, 82%, 59%); */
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @keyframes coupling{
|
||||||
|
0%{
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes vibrate{
|
||||||
|
0% {
|
||||||
|
transform: translateY(-0.25px)
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0.25px)
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
padding: 3px 8px 3px 8px;
|
padding: 3px 8px 3px 8px;
|
||||||
@@ -956,7 +984,6 @@ summary {
|
|||||||
animation: textColor 3s linear infinite;
|
animation: textColor 3s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@keyframes fieldColorCycle {
|
@keyframes fieldColorCycle {
|
||||||
0% {
|
0% {
|
||||||
background-color: rgb(255, 255, 255)
|
background-color: rgb(255, 255, 255)
|
||||||
|
|||||||
91
todo.txt
91
todo.txt
@@ -1,19 +1,37 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
finalBoss black hole phase:
|
new setting: level ban list
|
||||||
makes 100% more bullets
|
bug fix: removed a command to preventDefault on space key, this might break something else
|
||||||
grows and shrinks smoothly near start and end of phase
|
new boss added to level - Temple
|
||||||
does 20% more damage to player
|
|
||||||
|
|
||||||
historyBoss has a "fun" graphical effect
|
snake tails have a lower mass and whip around a bit
|
||||||
acetone peroxide has 50 -> 40% less explosion defense
|
auto targeting no longer works for stealth mobs
|
||||||
|
snipers, sneakers, ghosters
|
||||||
bug fix: timeSkip graphic glitch
|
snipers fire more often at high difficulty, but bullets move slower at all difficulties
|
||||||
there is a chance to cause other bugs with timeSkip effects
|
hoppers have move gravity, so it feels like they are hopping a bit faster
|
||||||
|
|
||||||
*********************************************************** TODO *****************************************************
|
*********************************************************** TODO *****************************************************
|
||||||
|
tech: field coupling - +1 field coupling, coupling is a new stat that provides different buffs for each field
|
||||||
|
you can see your coupling in the pause menu
|
||||||
|
make field coupling a stat that shows in pause menu and is effected by other tech?
|
||||||
|
names: fine-structure constant, strongly coupled, Vibronic coupling
|
||||||
|
tech: convert all research into "coupling"
|
||||||
|
tech: +x% field coupling, your field changes randomly every y seconds
|
||||||
|
tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use
|
||||||
|
some fields aren't used much (that's ok?)
|
||||||
|
|
||||||
screen shake effect - add random numbers to ctx.translate
|
buffing your deflecting for 1 second after pressing the field button sounds cool
|
||||||
|
2 second cooldown on the effect to prevent spamming it
|
||||||
|
buff: giving energy or doing damage makes sense
|
||||||
|
maybe this could be a rework for bremstralung
|
||||||
|
|
||||||
|
greatly increase walking speed
|
||||||
|
not mid air control?
|
||||||
|
for time dilation field
|
||||||
|
make jumping normal
|
||||||
|
|
||||||
|
after taking damage explode while invulnerable
|
||||||
|
scale explosion radius with damage
|
||||||
|
|
||||||
quantum immortality: send you to a new tab after you die with a random load out
|
quantum immortality: send you to a new tab after you die with a random load out
|
||||||
basically everything is the same as it is now, but you switch tabs
|
basically everything is the same as it is now, but you switch tabs
|
||||||
@@ -25,17 +43,29 @@ tech: get sent to a new tab that closes in 3 minutes
|
|||||||
count guns, field, tech and give random stuff on new tab
|
count guns, field, tech and give random stuff on new tab
|
||||||
i-frame instead of tab?
|
i-frame instead of tab?
|
||||||
|
|
||||||
field efficiency - Give each field an extra numerical effect, and add a 'field efficiency' stat that increases it
|
reduce the amount of research and nerf anti randomization tech
|
||||||
field numbers
|
increase possible synergies that go nuts
|
||||||
standing wave, molecular assembler: energy efficiency
|
|
||||||
plasma, metamaterial: damage
|
|
||||||
time dilation: movement, jump, fire rate
|
|
||||||
negative mass: defense
|
|
||||||
diamagnetism: arc length
|
|
||||||
wormhole: (i dislike it but idk of other things) dupe chance
|
|
||||||
tech: +x% field efficiency, your field changes randomly every y seconds
|
|
||||||
tech: starts at 200%, but decays when the field is in use, efficiency recharges when the field is not in use
|
|
||||||
|
|
||||||
|
tech expansion: field coupling also expands each fields in different ways
|
||||||
|
how to make the description work
|
||||||
|
change description based on your current field?
|
||||||
|
perfect diamagnetism moves forward when you hold down the shield
|
||||||
|
it's great, but maybe annoying?
|
||||||
|
maybe only with crouch?
|
||||||
|
perfect diamagnetism just replace or increase Messier effect
|
||||||
|
time dilation drains 1/2 as much energy when paused
|
||||||
|
grow plasma torch as you hold it down
|
||||||
|
negative mass effects much more space
|
||||||
|
needs more benefit?
|
||||||
|
reduces the cloaking vision effect?
|
||||||
|
needs more benefit?
|
||||||
|
|
||||||
|
tech: missiles explode a 2nd time after 1/2 a second (with a slightly different position determined by original velocity)
|
||||||
|
|
||||||
|
1st ionisation energy should scale with heath powerup efficiency
|
||||||
|
The tech that makes blocks that fall into a wormhole give energy should scale with block size, with the same formula as tokomak
|
||||||
|
|
||||||
|
junk suggestion: useless machine - ejects itself and removes itself from the item pool
|
||||||
|
|
||||||
bug blocks and power ups falling through map
|
bug blocks and power ups falling through map
|
||||||
always foam gun (4-5 times)
|
always foam gun (4-5 times)
|
||||||
@@ -221,20 +251,6 @@ pause time like invariant for other things...
|
|||||||
charging railgun
|
charging railgun
|
||||||
charging anything?
|
charging anything?
|
||||||
|
|
||||||
tech expansion: should also make other fields do things
|
|
||||||
how to make the description work
|
|
||||||
change description based on your current field?
|
|
||||||
perfect diamagnetism moves forward when you hold down the shield
|
|
||||||
it's great, but maybe annoying?
|
|
||||||
maybe only with crouch?
|
|
||||||
perfect diamagnetism just replace Messier effect
|
|
||||||
time dilation drains 1/2 as much energy when paused
|
|
||||||
grow plasma torch as you hold it down
|
|
||||||
negative mass effects much more space
|
|
||||||
needs more benefit?
|
|
||||||
reduces the cloaking vision effect?
|
|
||||||
needs more benefit?
|
|
||||||
|
|
||||||
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
|
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
|
||||||
like overwatch roadhog
|
like overwatch roadhog
|
||||||
|
|
||||||
@@ -480,8 +496,6 @@ auto-gon - auto battler with n-gon mob AI and tech
|
|||||||
similar research and tech system to n-gon
|
similar research and tech system to n-gon
|
||||||
some mobs can fire player weapons
|
some mobs can fire player weapons
|
||||||
|
|
||||||
harpoon grappling hook - basic effect is working, but needs work before it becomes fun
|
|
||||||
|
|
||||||
tech: relativistic jets:
|
tech: relativistic jets:
|
||||||
small particles that shot out from front and back poles and end up in a wide variety of spirals
|
small particles that shot out from front and back poles and end up in a wide variety of spirals
|
||||||
slow trickle when charging and several more when firing
|
slow trickle when charging and several more when firing
|
||||||
@@ -493,16 +507,11 @@ adapt the cloaking graphics to make a flashlight cone visual effect
|
|||||||
|
|
||||||
be nice if block throwing had a projected path
|
be nice if block throwing had a projected path
|
||||||
|
|
||||||
JUNK tech: planetesimals game inside n-gon
|
|
||||||
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010
|
|
||||||
|
|
||||||
Pilot wave tech
|
Pilot wave tech
|
||||||
Energy use is increased, but you can now shape blocks using pressure
|
Energy use is increased, but you can now shape blocks using pressure
|
||||||
Grouping blocks will merge them into a massive ball
|
Grouping blocks will merge them into a massive ball
|
||||||
Size, density is determined by total mass
|
Size, density is determined by total mass
|
||||||
|
|
||||||
look into 360 matter wave lag
|
|
||||||
|
|
||||||
aoe effect pushes mobs away, then rapidly pulls them in
|
aoe effect pushes mobs away, then rapidly pulls them in
|
||||||
for mines?
|
for mines?
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user