`
const hideStyle = `style="height:auto; border: none; background-color: transparent;"`
for (let i = 0, len = m.fieldUpgrades.length; i < len; i++) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[i].name}${i === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
- text += `
`
}
for (let i = 0, len = b.guns.length; i < len; i++) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/gun/${b.guns[i].name}.webp');"`
- text += `
`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment) && !tech.tech[i].isLore) {
const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? hideStyle : `style="background-image: url('img/${tech.tech[i].name}.webp');"`
- if ((tech.tech[i].allowed() || tech.tech[i].count > 0) && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
+ if ((tech.tech[i].allowed() || tech.tech[i].count > 0) && (!tech.tech[i].isInstant || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
text += `
`
} else { //disabled
text += `
`
@@ -951,6 +1008,8 @@ ${simulation.isCheating ? "
lore disabled " : ""}
text += build.skinTechText(i)
} else if (tech.tech[i].isJunk) {
text += build.junkTechText(i)
+ } else if (tech.tech[i].isInstant) {
+ text += build.instantTechText(i)
} else {
text += build.techText(i)
}
@@ -970,14 +1029,14 @@ ${simulation.isCheating ? "
lore disabled " : ""}
}
document.getElementById("sort-input").addEventListener('keydown', pressEnterSort);
- document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
- document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
- simulation.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
- lore.setTechGoal()
- localSettings.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
- document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
- if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
- });
+ // document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
+ // document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
+ // simulation.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
+ // lore.setTechGoal()
+ // localSettings.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
+ // document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
+ // if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
+ // });
//add tooltips
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (document.getElementById(`tech-${i}`)) {
@@ -985,11 +1044,11 @@ ${simulation.isCheating ? "
lore disabled " : ""}
// document.getElementById(`tech-${i}`).setAttribute('title', tech.tech[i].requires); //add tooltip
}
}
- //highlight selected
+ requestAnimationFrame(() => { document.getElementById("sort-input").focus(); });
},
nameLink(text) { //converts text into a clickable wikipedia search
- return `
${text} `
+ return `
${text} `
},
reset() {
build.isExperimentSelection = true;
@@ -998,7 +1057,7 @@ ${simulation.isCheating ? "
lore disabled " : ""}
build.isExperimentSelection = true;
build.isExperimentRun = true;
simulation.paused = true;
- b.inventory = []; //removes guns and ammo
+ b.inventory = []; //removes guns and ammo
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].count = 0;
b.guns[i].have = false;
@@ -1014,7 +1073,7 @@ ${simulation.isCheating ? "
lore disabled " : ""}
document.getElementById("experiment-grid").style.display = "grid"
},
shareURL(isCustom = false) {
- let url = "https://landgreen.github.io/sidescroller/index.html?"
+ let url = "https://landgreen.github.io/n-gon/index.html?"
url += `&seed=${Math.initialSeed}`
let count = 0;
for (let i = 0; i < b.inventory.length; i++) {
@@ -1026,7 +1085,7 @@ ${simulation.isCheating ? "
lore disabled " : ""}
count = 0;
for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < tech.tech[i].count; j++) {
- if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isNonRefundable) {
+ if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isInstant) {
url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
count++
}
@@ -1045,7 +1104,7 @@ ${simulation.isCheating ? "
lore disabled " : ""}
// url += `&level=${Math.abs(Number(document.getElementById("starting-level").value))}`
// alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
} else {
- simulation.makeTextLog("n-gon build URL copied to clipboard.
Paste into browser address bar.")
+ simulation.inGameConsole("n-gon build URL copied to clipboard.
Paste into browser address bar.")
}
console.log('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
console.log(url)
@@ -1097,9 +1156,6 @@ ${simulation.isCheating ? "
lore disabled " : ""}
} else { //if you have no tech (not cheating) remove all power ups that might have spawned from tech
for (let i = 0; i < powerUp.length; ++i) Matter.Composite.remove(engine.world, powerUp[i]);
powerUp = [];
- // if (build.hasExperimentalMode) {
- // for (let i = 0; i < 7; i++) tech.giveTech("undefined")
- // }
}
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
@@ -1188,7 +1244,7 @@ const input = {
document.getElementById("key-pause").innerHTML = cleanText(input.key.pause)
document.getElementById("key-next-gun").innerHTML = cleanText(input.key.nextGun)
document.getElementById("key-previous-gun").innerHTML = cleanText(input.key.previousGun)
- document.getElementById("key-testing").innerHTML = cleanText(input.key.testing) //if (localSettings.loreCount > 0)
+ document.getElementById("key-testing").innerHTML = cleanText(input.key.testing) //if (localSettings.loreCount > 0)
document.getElementById("splash-up").innerHTML = cleanText(input.key.up)[0]
document.getElementById("splash-down").innerHTML = cleanText(input.key.down)[0]
@@ -1352,7 +1408,6 @@ window.addEventListener("keydown", function (event) {
simulation.previousGun();
break
case input.key.pause:
-
if (input.isPauseKeyReady && m.alive && !build.isExperimentSelection) {
input.isPauseKeyReady = false
setTimeout(function () { input.isPauseKeyReady = true }, 300);
@@ -1412,75 +1467,77 @@ window.addEventListener("keydown", function (event) {
break
case input.key.testing:
if (m.alive && localSettings.loreCount > 0 && !simulation.paused && !build.isExperimentSelection) {
- if (simulation.difficultyMode > 4) {
- simulation.makeTextLog("
testing mode disabled for this difficulty ");
+ if (simulation.difficultyMode > 5) {
+ simulation.inGameConsole("
testing mode disabled for this difficulty ");
break
}
if (simulation.testing) {
simulation.testing = false;
simulation.loop = simulation.normalLoop
if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'none'
- simulation.makeTextLog("", 0);
- } else { //if (keys[191])
+ simulation.inGameConsole("", 0);
+ } else {
simulation.testing = true;
simulation.loop = simulation.testingLoop
- if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'inline'
if (simulation.testing) tech.setCheating();
- simulation.makeTextLog(
- `
-
- T
- toggle testing
-
-
- R
- teleport to mouse
-
-
- F
- cycle field
-
-
- G
- all guns
-
-
- H
- +100% defense
-
-
- B
- damage, research
-
-
- N
- fill health, energy
-
-
- Y
- random tech
-
-
- U
- next level
-
-
- J
- clear mobs
-
-
- I/O
- zoom in / out
-
-
- 1-8
- spawn things
-
-
- ⇧X
- restart
-
-
`, Infinity);
+ if (simulation.isConstructionMode) {
+ document.getElementById("construct").style.display = 'inline'
+ } else {
+ simulation.inGameConsole(
+ `
+
+ T
+ toggle testing
+
+
+ R
+ teleport to mouse
+
+
+ F
+ cycle field
+
+
+ G
+ all guns
+
+
+ H
+ +100% defense
+
+
+ B
+ damage, research
+
+
+ N
+ fill health, energy
+
+
+ Y
+ random tech
+
+
+ U
+ next level
+
+
+ J
+ clear mobs
+
+
+ I/O
+ zoom in / out
+
+
+ 1-8
+ spawn things
+
+
+ ⇧X
+ restart
+
`, Infinity);
+ }
}
}
break
@@ -1602,10 +1659,7 @@ window.addEventListener("keydown", function (event) {
case "r":
m.resetHistory();
Matter.Body.setPosition(player, simulation.mouseInGame);
- Matter.Body.setVelocity(player, {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(player, { x: 0, y: 0 });
// move bots to player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
@@ -1635,7 +1689,7 @@ window.addEventListener("keydown", function (event) {
case "l":
document.getElementById("field").style.display = "none"
document.getElementById("guns").style.display = "none"
- document.getElementById("tech").style.display = "none"
+ document.getElementById("right-HUD").style.display = "none"
break
}
}
@@ -1753,11 +1807,6 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
- if (localSettings.difficultyMode === undefined) localSettings.difficultyMode = "2"
- simulation.difficultyMode = localSettings.difficultyMode
- lore.setTechGoal()
- document.getElementById("difficulty-select").value = localSettings.difficultyMode
-
if (localSettings.fpsCapDefault === undefined) localSettings.fpsCapDefault = 'max'
if (localSettings.personalSeeds === undefined) localSettings.personalSeeds = [];
if (localSettings.fpsCapDefault === 'max') {
@@ -1785,6 +1834,19 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
if (localSettings.isHideHUD === undefined) localSettings.isHideHUD = true
document.getElementById("hide-hud").checked = localSettings.isHideHUD
+ if (localSettings.difficultyCompleted === undefined) {
+ localSettings.difficultyCompleted = [null, false, false, false, false, false, false] //null because there isn't a difficulty zero
+ localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
+ }
+
+ if (localSettings.difficultyMode === undefined) localSettings.difficultyMode = "2"
+ simulation.difficultyMode = localSettings.difficultyMode
+ lore.setTechGoal()
+
+ if (localSettings.pauseMenuDetailsOpen === undefined) {
+ localSettings.pauseMenuDetailsOpen = [true, false, false, true]
+ localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
+ }
} else {
console.log('setting default localSettings')
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
@@ -1795,6 +1857,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
isJunkExperiment: false,
isCommunityMaps: false,
difficultyMode: '2',
+ difficultyCompleted: [null, false, false, false, false, false, false],
fpsCapDefault: 'max',
runCount: 0,
isTrainingNotAttempted: true,
@@ -1805,24 +1868,37 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
key: undefined,
isHideImages: true, //default to hide images
isHideHUD: false,
+ pauseMenuDetailsOpen: [true, false, false, true]
};
input.setDefault()
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("hide-images").checked = localSettings.isHideImages
- document.getElementById("difficulty-select").value = localSettings.difficultyMode
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("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
-
input.controlTextUpdate()
+
//**********************************************************************
-// settings
+// settings
//**********************************************************************
+
+
+// difficulty-select-experiment event listener is set in build.makeGrid
+// document.getElementById("difficulty-select").addEventListener("input", () => {
+// simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
+// lore.setTechGoal()
+// localSettings.difficultyMode = simulation.difficultyMode
+// localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
+// localSettings.entanglement = undefined //after changing difficulty, reset stored tech
+// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
+// });
+
+
document.getElementById("fps-select").addEventListener("input", () => {
let value = document.getElementById("fps-select").value
if (value === 'max') {
@@ -1845,17 +1921,6 @@ document.getElementById("community-maps").addEventListener("input", () => {
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
-// difficulty-select-experiment event listener is set in build.makeGrid
-document.getElementById("difficulty-select").addEventListener("input", () => {
- simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
- lore.setTechGoal()
- localSettings.difficultyMode = simulation.difficultyMode
- localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
- localSettings.entanglement = undefined //after changing difficulty, reset stored tech
- if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
-});
-
-
document.getElementById("updates").addEventListener("toggle", function () {
function loadJSON(path, success, error) { //generic function to get JSON
var xhr = new XMLHttpRequest();
diff --git a/js/level.js b/js/level.js
index 884f39a8..18ee2452 100644
--- a/js/level.js
+++ b/js/level.js
@@ -4,87 +4,75 @@ let cons = []; //all constraints between a point and a body
let consBB = []; //all constraints between two bodies
let composite = [] //rotors and other map elements that don't fit
const level = {
- isEndlessFall: false,
+ fallMode: "",
defaultZoom: 1400,
onLevel: -1,
levelsCleared: 0,
- // playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
- playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
- communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", 'arena'],
+ playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers", "flocculation"],
+ communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", "arena", "soft", "flappyGon", "rings", "trial"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
+ // level.levelsCleared = 4
+ // level.updateDifficulty()
// tech.giveTech("performance")
- // level.difficultyIncrease(7 * 2) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 1//00000000
// m.maxEnergy = m.energy = 10000000
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(99999)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
+ // tech.addJunkTechToPool(0.5)
// m.couplingChange(10)
- // m.setField("plasma torch") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
+ // m.setField("grappling hook") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.energy = 0
+ // powerUps.research.count = 3
// tech.isHookWire = true
// m.energy = 0
// simulation.molecularMode = 2
// m.damage(0.1);
- // b.giveGuns("mine") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
+ // b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
+ // b.giveGuns("spores") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
+ // tech.laserColor = "#fff"
+ // tech.laserColorAlpha = "rgba(255, 255, 255, 0.5)"
+
// b.guns[8].ammo = 100000000
- // requestAnimationFrame(() => { tech.giveTech("eternalism") });
- // for (let i = 0; i < 1; ++i) tech.giveTech("beforeunload")
- // for (let i = 0; i < 1; ++i) tech.giveTech("Sleipnir")
- // for (let i = 0; i < 1; ++i) tech.giveTech("dark patterns")
- // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("paradigm shift") });
- // requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
- // m.skin.hexagon();
- // for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
+ // requestAnimationFrame(() => { tech.giveTech("stimulated emission") });
+ // tech.giveTech("Hilbert space")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("decoherence")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("depolarization")
+ // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("wikipedia") });
+ // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("field coupling") });
+ // for (let i = 0; i < 1; i++) tech.giveTech("interest")
// m.lastKillCycle = m.cycle
- // for (let i = 0; i < 1; ++i) tech.giveTech("what the block?")
- // for (let i = 0; i < 1; ++i) tech.giveTech("unified field theory")
- // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
- // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
- // for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
- // spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
- // level.testChamber();
-
- // for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
- // Matter.Body.setPosition(player, { x: -200, y: -3330 });
- // for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
- // for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500)
- // for (let i = 0; i < 1; ++i) spawn.dragonFlyBoss(1900, -500)
- // spawn.beetleBoss(1900, -500, 25)
- // spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
- // for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
- // tech.addJunkTechToPool(2)
- // tech.tech[322].frequency = 100
- // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
- // for (let i = 0; i < 40; ++i) tech.giveTech()
+ // for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech");
+ // for (let i = 0; i < 3; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 50, "boost", false);
+ // spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
+ // level.heal();
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
- // for (let i = 0; i < 2; i++) spawn.ghoster(1300, -500) //ghosters need to spawn after the map loads
- // spawn.bodyRect(2425, -120, 200, 200);
- // console.log(body[body.length - 1].mass)
- // simulation.isAutoZoom = false; //look in close
- // simulation.zoomScale *= 0.5;
- // simulation.setZoom();
- // for (let i = 0; i < 10; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
+ // for (let i = 0; i < 1; ++i) spawn.revolutionBoss(1900, -500)
+ // for (let i = 0; i < 3; i++) spawn.starter(1900, -500) //ghosters need to spawn after the map loads
+
+ // for (let i = 0; i < 1; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "entanglement");
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "boost");
- // for (let i = 0; i < 20; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "heal");
+ // for (let i = 0; i < 100; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
//lore testing
// localSettings.isTrainingNotAttempted = true
// simulation.isCheating = false //true;
// for (let i = 0; i < 5; i++) tech.giveTech("undefined")
- // lore.techCount = 2
+ // lore.techCount = 1
// level.levelsCleared = 10
- // localSettings.loreCount = 5 //this sets what conversation is heard
+ // localSettings.loreCount = 2 //this sets what conversation is heard
+ // localSettings.levelsClearedLastGame = 10
// if (localSettings.isAllowed) 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()
@@ -96,9 +84,10 @@ const level = {
// tech.giveTech("tinker"); //show junk tech in experiment mode
// m.storeTech()
// powerUps.spawn(m.pos.x, m.pos.y, "entanglement", false);
+ // for (let i = 0; i < 6; i++) localSettings.difficultyCompleted[i] = false
+ // localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
-
// spawn.pickList = ["focuser", "focuser"]
level[level.levels[level.onLevel]](); //picks the current map from the the levels array
if (!simulation.isCheating && !build.isExperimentRun && !simulation.isTraining) {
@@ -107,7 +96,6 @@ const level = {
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
}
- if (!simulation.isTraining) level.levelAnnounce();
simulation.setupCamera(player.position);
simulation.setZoom();
level.addToWorld(); //add bodies to game engine
@@ -128,30 +116,49 @@ const level = {
}
}
}
- if (tech.isMACHO) spawn.MACHO()
+ if (tech.isDarkMatter) spawn.darkMatter()
for (let i = 0; i < tech.wimpCount; i++) {
spawn.WIMP()
mob[mob.length - 1].isDecoupling = true //so you can find it to remove
for (let j = 0, len = 4; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
}
- // if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) {
- if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) {
- tech.isFlipFlopOn = true
- if (tech.isFlipFlopHealth) m.setMaxHealth()
- if (tech.isRelayEnergy) m.setMaxEnergy()
- m.eyeFillColor = m.fieldMeterColor
- simulation.makeTextLog(`tech.isFlipFlopOn
= true`);
- }
- // if (m.plasmaBall) m.plasmaBall.reset()
+
if (m.plasmaBall) m.plasmaBall.fire()
if (localSettings.entanglement && localSettings.entanglement.levelName === level.levels[level.onLevel]) {
const flip = localSettings.entanglement.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
powerUps.directSpawn(flip * localSettings.entanglement.position.x, localSettings.entanglement.position.y, "entanglement", false);
}
level.newLevelOrPhase()
+ if (simulation.isTraining) {
+ simulation.difficultyMode = 2
+ } else {
+ simulation.inGameConsole(`
level .onLevel
= "
${level.levels[level.onLevel]} "`);
+ document.title = "n-gon: " + level.levelAnnounce();
+ }
+
+ level.setConstraints()
+ if (!localSettings.isHideHUD) {
+ requestAnimationFrame(() => {
+ //grow and get bright
+ document.getElementById("right-HUD-constraint").style.opacity = 1
+ document.getElementById("right-HUD-constraint").style.fontSize = "23px"
+ document.getElementById("right-HUD-constraint").style.top = simulation.difficultyMode > 4 ? "6px" : "9px"
+ setTimeout(() => {
+ if (m.alive) {
+ //fade to background
+ document.getElementById("right-HUD-constraint").style.opacity = 0.35
+ document.getElementById("right-HUD-constraint").style.fontSize = "20px"
+ document.getElementById("right-HUD-constraint").style.top = "12px"
+ }
+ }, 5000);
+ });
+ }
+
},
newLevelOrPhase() { //runs on each new level but also on final boss phases
//used for generalist and pigeonhole principle
+ tech.cancelTechCount = 0
+ tech.tokamakHealCount = 0
tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle && b.activeGun !== null && b.inventory.length) {
@@ -160,102 +167,418 @@ const level = {
}
if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) {
var gun = b.guns[b.inventory[tech.buffedGun]].name
- simulation.makeTextLog(`pigeonhole principle:
+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for
${gun} `, 600);
+ simulation.inGameConsole(`pigeonhole principle:
${(1.3 * Math.max(0, b.inventory.length)).toFixed(2)}x damage for
${gun} `, 600);
}
if (tech.isSwitchReality && level.levelsCleared !== 0) {
- simulation.makeTextLog(`simulation.amplitude
= ${Math.random()}`);
+ simulation.inGameConsole(`simulation.amplitude
= ${Math.random()}`);
m.switchWorlds()
simulation.trails()
- powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
+ powerUps.spawn(player.position.x + 50, player.position.y - Math.random() * 50, "tech", false);
+ powerUps.spawnDelay("coupling", 3);
}
if (tech.isHealLowHealth) {
- if (tech.isEnergyHealth) {
- var len = 4 * (1 - m.energy / m.maxEnergy) //as a percent
- } else {
- var len = 4 * (1 - m.health / m.maxHealth) //as a percent
- }
+ const len = tech.isEnergyHealth ? 5 * Math.max(0, m.maxEnergy - m.energy) : 5 * Math.max(0, m.maxHealth - m.health)
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
}
+ if (tech.interestRate > 0) {
+ const rate = ((level[level.levels[level.onLevel]].name === "final" || level[level.levels[level.onLevel]].name === "subway") ? 1 / 3 : 1) * tech.interestRate //this effect triggers extra times on these final levels
+
+ let ammoSum = 0
+ for (let i = 0; i < b.inventory.length; i++) {
+ if (b.guns[b.inventory[i]].ammo !== Infinity) ammoSum += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
+ }
+ if (ammoSum > 0 && b.inventory.length > 0) {
+ const amount = Math.ceil(rate * ammoSum / b.inventory.length)
+ powerUps.spawnDelay("ammo", amount, 4);
+ simulation.inGameConsole(`${(rate * 100).toFixed(0)}
% interest on
ammo = ${amount > 20 ? amount + powerUps.orb.ammo(1) : powerUps.orb.ammo(amount)}`)
+ }
+
+ // if (b.activeGun !== null && b.activeGun !== undefined && b.guns[b.activeGun].ammo !== Infinity) {
+ // const ammoPerOrb = b.guns[b.activeGun].ammoPack
+ // const a = Math.ceil(rate * b.guns[b.activeGun].ammo / ammoPerOrb)
+ // powerUps.spawnDelay("ammo", a, 4);
+ // simulation.inGameConsole(`${(rate * 100).toFixed(0)}
% interest on
ammo = ${a > 20 ? a + powerUps.orb.ammo(1) : powerUps.orb.ammo(a)}`)
+ // }
+ if (powerUps.research.count > 0) {
+ const r = Math.ceil(rate * powerUps.research.count)
+ simulation.inGameConsole(`${(rate * 100).toFixed(0)}
% interest on
research = ${r > 20 ? r + powerUps.orb.research(1) : powerUps.orb.research(r)}`)
+ powerUps.spawnDelay("research", r, 4);
+ }
+ if (m.coupling > 0) {
+ const c = Math.ceil(rate * m.coupling)
+ powerUps.spawnDelay("coupling", c, 4);
+ simulation.inGameConsole(`${(rate * 100).toFixed(0)}
% interest on
coupling = ${c > 20 ? c + powerUps.orb.coupling(1) : powerUps.orb.coupling(c)}`)
+ }
+ const healPerOrb = (powerUps.heal.size() / 40 / (simulation.healScale ** 0.25)) ** 2
+ const h = Math.ceil(rate * m.health / healPerOrb)
+ powerUps.spawnDelay("heal", h, 4);
+ simulation.inGameConsole(`${(rate * 100).toFixed(0)}
% interest on
health = ${h > 20 ? h + powerUps.orb.heal(1) : powerUps.orb.heal(h)}`)
+
+ // trying to spawn smaller heals
+ // const healPerOrb = (powerUps.heal.size() / 40 / (simulation.healScale ** 0.25)) ** 2
+ // console.log(healPerOrb)
+ // let h = tech.interestRate * m.health / healPerOrb
+ // console.log(tech.interestRate, m.health, healPerOrb, h)
+ // const overHeal = h - Math.floor(h)
+ // powerUps.spawn(m.pos.x, m.pos.y, "heal", true, null, Math.max(0.25, overHeal) * 40 * (simulation.healScale ** 0.25))
+ // if (h > healPerOrb) powerUps.spawnDelay("heal", h);
+ // simulation.inGameConsole(`${(Math.ceil(tech.interestRate * 100)).toFixed(0)}
% interest on
health = ${h > 20 ? h + powerUps.orb.heal(1) : powerUps.orb.heal(h)}`)
+ }
+ if (tech.isEjectOld) {
+ let index = null //find oldest tech that you have
+ for (let i = 0; i < tech.tech.length; i++) {
+ if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
+ index = i
+ }
+ }
+ if (index) { //eject it
+ const effect = Math.pow(1.1, tech.tech[index].count)
+ simulation.inGameConsole(`
${(effect).toFixed(2)}x damage //from obsolescence `, 360)
+ tech.damage *= effect
+ powerUps.ejectTech(index)
+ }
+ }
},
trainingText(say) {
simulation.lastLogTime = 0; //clear previous messages
simulation.isTextLogOpen = true
- simulation.makeTextLog(`
supervised.learning (${(Date.now() / 1000).toFixed(0)} s ): ${say}`, Infinity)
+ simulation.inGameConsole(`
supervised.learning (${(Date.now() / 1000).toFixed(0)} s ): ${say}`, Infinity)
simulation.isTextLogOpen = false
- // lore.trainer.text("Wow. Just a platform.")
},
trainingBackgroundColor: "#e1e1e1",
custom() { },
customTopLayer() { },
- setDifficulty() {
- simulation.difficulty = 0
- m.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 = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
- simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
- },
- difficultyIncrease(num = 1) {
- for (let i = 0; i < num; i++) {
- simulation.difficulty++
- m.dmgScale *= 0.905; //damage done by player decreases each level
- if (simulation.accelScale < 6) simulation.accelScale *= 1.024 //mob acceleration increases each level
- if (simulation.CDScale > 0.15) simulation.CDScale *= 0.964 //mob CD time decreases each level
- }
- simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
+ updateDifficulty() {
+ simulation.difficulty = level.levelsCleared * simulation.difficultyMode
+ if (simulation.isTraining) simulation.difficulty = 1
+
+ let scale = 1
+ if (simulation.difficultyMode > 3) {
+ scale = 3
+ } else if (simulation.difficultyMode > 1) {
+ scale = 2
+ }
+ m.dmgScale = Math.pow(0.87, level.levelsCleared * scale)
+ simulation.dmgScale = Math.max(0.1, 0.22 * level.levelsCleared * scale) //damage done by mobs scales with total levels //a bigger number means the player takes more damage
+ if (simulation.difficultyMode === 6) {
+ m.dmgScale *= 0.5
+ simulation.dmgScale *= 2
+ }
+
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //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--
- m.dmgScale /= 0.905; //damage done by player decreases each level
- if (simulation.accelScale > 1) simulation.accelScale /= 1.024 //mob acceleration increases each level
- if (simulation.CDScale < 1) simulation.CDScale /= 0.964 //mob CD time decreases each level
- }
- if (simulation.difficulty < 1) simulation.difficulty = 0;
- simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
- simulation.healScale = 1 / (1 + simulation.difficulty * 0.043)
- },
- difficultyText() {
if (simulation.difficultyMode === 1) {
- return "easy"
- } else if (simulation.difficultyMode === 2) {
- return "normal"
- } else if (simulation.difficultyMode === 4) {
- return "hard"
- } else if (simulation.difficultyMode === 5) {
- return "why"
+ simulation.accelScale = 1.1
+ simulation.CDScale = 0.9
+ } else {
+ simulation.accelScale = Math.min(6, Math.pow(1.024, simulation.difficulty))
+ simulation.CDScale = Math.max(0.15, Math.pow(0.964, simulation.difficulty))
+ }
+ },
+ constraintIndex: 0,
+ setConstraints() {
+ //populate array with possible constraints and reset constraints
+ level.constraintDescription1 = level.constraintDescription2 = ""
+ const possible = []
+ for (let i = 0; i < level.constraint.length; i++) {
+ level.constraint[i].remove()
+ possible.push(i)
+ }
+ if (level.levels[level.onLevel] !== "null" && level.levels[level.onLevel] !== "initial" && !simulation.isTraining && m.alive && level.levelsCleared) {
+ if (simulation.difficultyMode > 2 && possible.length) {
+ //choose a random constraint from possible array and remove it from that array
+ // const index = possible[Math.floor(possible.length * Math.random())]
+ // const index = level.constraintIndex
+ // level.constraintIndex = 0 //REMOVE THIS FROM LIVE GAME, FOR TESTING ONLY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ level.constraint[level.constraintIndex].effect()
+ possible.splice(level.constraintIndex, 1)
+ //generate text to describe the active constraints for the pause menu
+ level.constraintDescription1 = level.constraint[level.constraintIndex].description
+ // simulation.inGameConsole(`
${level.constraint[level.constraintIndex].description} `, 900);
+
+ level.constraintIndex++
+ if (level.constraintIndex > level.constraint.length - 1) level.constraintIndex = 0
+
+ if (simulation.difficultyMode > 4 && possible.length) {
+ // const index = possible[Math.floor(possible.length * Math.random())]
+ level.constraint[level.constraintIndex].effect()
+ possible.splice(level.constraintIndex, 1)
+ level.constraintDescription2 += level.constraint[level.constraintIndex].description
+ // simulation.inGameConsole(`
${level.constraint[level.constraintIndex].description} `, 900);
+
+ level.constraintIndex++
+ if (level.constraintIndex > level.constraint.length - 1) level.constraintIndex = 0
+ }
+ document.getElementById("right-HUD-constraint").style.display = "block";
+ } else {
+ document.getElementById("right-HUD-constraint").style.display = "none";
+ }
+ } else {
+ document.getElementById("right-HUD-constraint").style.display = "none";
+ }
+ //update HUD with constraints
+ let text = `${level.constraintDescription1}`
+ if (simulation.difficultyMode > 4 && level.constraintDescription2) {
+ text += `
${level.constraintDescription2}`
+ }
+ document.getElementById("right-HUD-constraint").innerHTML = text
+ if (level.constraintDescription1) {
+ if (level.constraintDescription2) {
+ document.getElementById("right-HUD").style.top = "80px";
+ } else {
+ document.getElementById("right-HUD").style.top = "57px"; //make room for tech list in "right-HUD"
+ }
+ } else {
+ document.getElementById("right-HUD").style.top = "15px";
}
},
+ constraintDescription1: "", //used in pause menu and console
+ constraintDescription2: "",
+ constraint: [
+ {
+ description: "0.5x energy regen",
+ effect() {
+ level.isReducedRegen = 0.5
+ },
+ remove() {
+ level.isReducedRegen = 1
+ }
+ },
+ {
+ description: "0.5x max health",
+ effect() {
+ level.isReducedHealth = true
+ m.setMaxHealth()
+ },
+ remove() {
+ if (level.isReducedHealth) {
+ level.isReducedHealth = false
+ m.setMaxHealth()
+ m.addHealth(level.reducedHealthLost);
+ level.reducedHealthLost = 0
+ } else {
+ level.isReducedHealth = false
+ }
+
+ }
+ },
+ {
+ description: "after 30 seconds spawn WIMPs",
+ effect() {
+ simulation.ephemera.push({
+ name: "WIMPS",
+ time: 0,
+ levelName: level.levels[level.onLevel],
+ do() {
+ this.time++
+ if (level.levels[level.onLevel] === this.levelName) {
+ if (this.time > 1800 && !(this.time % 360)) spawn.WIMP(level.enter.x, level.enter.y)
+ } else {
+ simulation.removeEphemera(this.name);
+ }
+ },
+ })
+ },
+ remove() {
+
+ }
+ },
+ {
+ description: "0.1x damage after getting power ups",
+ effect() {
+ level.isNoDamage = true
+ level.noDamageCycle = 0
+ },
+ remove() {
+ level.isNoDamage = false
+ level.noDamageCycle = 0
+ }
+ },
+ {
+ description: "mobs heal after you take damage",
+ effect() {
+ level.isMobHealPlayerDamage = true
+ },
+ remove() {
+ level.isMobHealPlayerDamage = false
+ }
+ },
+ {
+ description: "mob death heals nearby mobs",
+ effect() {
+ level.isMobDeathHeal = true
+ },
+ remove() {
+ level.isMobDeathHeal = false
+ }
+ },
+ // {
+ // description: "full damage taken after boss dies",
+ // // description: "after boss dies damage taken = 1",
+ // effect() {
+ // level.noDefenseSetting = 1 //defense goes to zero once equal to 2
+ // },
+ // remove() {
+ // level.noDefenseSetting = 0
+ // }
+ // },
+ {
+ description: "4x shielded mobs",
+ effect() {
+ level.isMobShields = true
+ },
+ remove() {
+ level.isMobShields = false
+ }
+ },
+ {
+ description: "40% JUNK chance",
+ effect() {
+ level.junkAdded = 0.4
+ },
+ remove() {
+ level.junkAdded = 0
+ }
+ },
+ {
+ description: "-1 choice",
+ effect() {
+ level.fewerChoices = true
+ },
+ remove() {
+ level.fewerChoices = false
+ }
+ },
+ {
+ description: "power ups in stasis",
+ effect() {
+ level.isNextLevelPowerUps = true
+ //remove all current power ups
+ for (let i = powerUp.length - 1; i > -1; i--) {
+ powerUps.powerUpStorage.push({ name: powerUp[i].name, size: powerUp[i].size })
+ Matter.Composite.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1)
+ }
+ },
+ remove() {
+ level.isNextLevelPowerUps = false
+ if (powerUps.powerUpStorage.length) {
+ const delay = 5
+ let i = 0
+ let cycle = () => {
+ if (powerUps.powerUpStorage.length && m.alive && powerUp.length < 300) {
+ requestAnimationFrame(cycle);
+ if (!simulation.paused && !simulation.isChoosing) {
+ if (!(simulation.cycle % delay)) {
+ const where = { x: m.pos.x + 70 * (Math.random() - 0.5), y: m.pos.y + 70 * (Math.random() - 0.5) }
+ powerUps.directSpawn(where.x, where.y, powerUps.powerUpStorage[i].name, true, powerUps.powerUpStorage[i].size);
+ powerUps.powerUpStorage.splice(i, 1);
+ }
+ }
+ } else {
+ powerUps.powerUpStorage = []
+ }
+ }
+ requestAnimationFrame(cycle);
+ }
+ }
+ },
+ {
+ description: "33% of mobs respawn",
+ effect() {
+ level.isMobRespawn = true
+ },
+ remove() {
+ level.isMobRespawn = false
+ }
+ },
+ {
+ description: "0 duplication",
+ effect() {
+ level.isNoDuplicate = true
+ },
+ remove() {
+ level.isNoDuplicate = false
+ }
+ },
+ {
+ description: "2x ammo cost",
+ effect() {
+ level.is2xAmmo = true
+ },
+ remove() {
+ level.is2xAmmo = false
+ }
+ },
+ {
+ description: "0.5x max energy",
+ effect() {
+ level.isReducedEnergy = true
+ m.setMaxEnergy()
+ },
+ remove() {
+ if (level.isReducedEnergy) {
+ level.isReducedEnergy = false
+ m.setMaxEnergy()
+ } else {
+ level.isReducedEnergy = false
+ }
+
+ }
+ },
+ {
+ description: "slow bots",
+ effect() {
+ level.isSlowBots = true
+ b.clearPermanentBots();
+ b.respawnBots();
+ },
+ remove() {
+ if (level.isSlowBots) {
+ level.isSlowBots = false
+ b.clearPermanentBots();
+ b.respawnBots();
+ } else {
+ level.isSlowBots = false
+ }
+
+ }
+ },
+ ],
+ isMobShields: false,
+ junkAdded: 0,
+ isNextLevelPowerUps: false,
+ isMobRespawn: false,
+ fewerChoices: false,
+ isNoDuplicate: false,
+ is2xAmmo: false,
+ isReducedEnergy: false,
+ isSlowBots: false,
+ // noDefenseSetting: 0,
+ isMobDeathHeal: false,
+ isMobHealPlayerDamage: false,
+ isNoDamage: false,
+ noDamageCycle: 0,
+ reducedHealthLost: 0,
+ isReducedHealth: false,
+ isReducedRegen: 1,
levelAnnounce() {
- const difficulty = simulation.isCheating ? "testing" : level.difficultyText()
+ const cheating = simulation.isCheating ? "(testing)" : ""
if (level.levelsCleared === 0) {
- document.title = "n-gon: (" + difficulty + ")";
+ return `initial ${cheating}`;
} else {
- document.title = `n-gon: ${level.levelsCleared} ${level.levels[level.onLevel]} (${difficulty})`
- simulation.makeTextLog(`
level .onLevel
= "
${level.levels[level.onLevel]} "`);
- }
- // simulation.makeTextLog(`
- // input.key.up = ["
${input.key.up} ", "
ArrowUp "]
- //
input.key.left = ["
${input.key.left} ", "
ArrowLeft "]
- //
input.key.down = ["
${input.key.down} ", "
ArrowDown "]
- //
input.key.right = ["
${input.key.right} ", "
ArrowRight "]
- //
- //
m .fieldMode = "
${m.fieldUpgrades[m.fieldMode].name} "
- //
input.key.field = ["
${input.key.field} ", "
right mouse "]
- //
m .field.description = "
${m.fieldUpgrades[m.fieldMode].description} "
- // `, 1200);
+ return `${level.levelsCleared} ${level.levels[level.onLevel]} ${cheating}`
+ }
},
announceMobTypes() {
- simulation.makeTextLog(`spawn
. ${spawn.pickList[0]}
( x
, y
) `)
- simulation.makeTextLog(`spawn
. ${spawn.pickList[1]}
( x
, y
) `)
+ simulation.inGameConsole(`spawn
. ${spawn.pickList[0]}
( x
, y
) `)
+ simulation.inGameConsole(`spawn
. ${spawn.pickList[1]}
( x
, y
) `)
},
disableExit: false,
nextLevel() {
if (!level.disableExit) {
level.levelsCleared++;
level.onLevel++; //cycles map to next level
+ level.updateDifficulty()
if (simulation.isTraining) {
if (level.onLevel > level.levels.length - 1) { //if all training levels are completed
@@ -276,14 +599,10 @@ const level = {
simulation.splashReturn();
}, 6000);
return
- } else {
- level.setDifficulty()
}
} else {
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
- level.difficultyIncrease(simulation.difficultyMode)
}
-
//reset lost tech display
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isLost) tech.tech[i].isLost = false;
@@ -293,7 +612,8 @@ const level = {
simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
//pop up new level info screen for a few seconds //|| level.levels[level.onLevel] === "subway"
- if (!localSettings.isHideHUD && !simulation.isCheating && m.alive && (level.levels[level.onLevel] === "final" || level.levels[level.onLevel] === "reactor")) {
+ if (!localSettings.isHideHUD && m.alive && (level.levels[level.onLevel] === "final" || level.levels[level.onLevel] === "reactor")) {
+ // if (!localSettings.isHideHUD && m.alive) {
//pause
if (!simulation.paused) {
simulation.paused = true;
@@ -302,7 +622,8 @@ const level = {
//build level info
document.getElementById("choose-grid").style.gridTemplateColumns = "250px"
//onclick="level.unPause()"
- let text = `
`
+ // if (level.levels[level.onLevel] === "final") { //|| level.levels[level.onLevel] === "reactor"
+ let text = `
`
for (let i = 0; i < level.levels.length; i++) {
if (i < level.levelsCleared) {
text += `
${level.levels[i]}
`
@@ -317,14 +638,14 @@ const level = {
// text += `
`
}
}
- text += `
`
+ text += `
`
document.getElementById("choose-grid").innerHTML = text
//show level info
document.getElementById("choose-grid").style.opacity = "1"
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
-
+ // }
simulation.draw.cons();
simulation.draw.body();
level.customTopLayer();
@@ -358,37 +679,6 @@ const level = {
}
requestAnimationFrame(newLevelDraw);
}
- // else {
- // //pause
- // if (!simulation.paused) {
- // simulation.paused = true;
- // simulation.isChoosing = true; //stops p from un pausing on key down
- // }
- // let count = countMax = simulation.testing ? 0 : 60
- // let newLevelDraw = () => {
- // count--
- // if (count > 0) {
- // requestAnimationFrame(newLevelDraw);
- // } else { //unpause
- // // if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
- // if (simulation.paused) requestAnimationFrame(cycle);
- // if (m.alive) simulation.paused = false;
- // simulation.isChoosing = false; //stops p from un pausing on key down
- // build.unPauseGrid()
- // }
- // //draw
- // simulation.wipe();
- // m.look();
- // simulation.camera();
- // const scale = 30
- // ctx.setLineDash([scale * (countMax - count), scale * count]);
- // simulation.draw.wireFrame();
- // ctx.setLineDash([]);
- // ctx.restore();
- // simulation.drawCursor();
- // }
- // requestAnimationFrame(newLevelDraw);
- // }
}
},
unPause() {
@@ -413,7 +703,7 @@ const level = {
if (index !== -1) {
level.communityLevels.splice(index, 1);
// console.log('removed level:', remove[i])
- requestAnimationFrame(() => { simulation.makeTextLog(`banned level:
${remove[i]} `); });
+ requestAnimationFrame(() => { simulation.inGameConsole(`banned level:
${remove[i]} `); });
}
}
// console.log('community levels after', level.communityLevels)
@@ -424,7 +714,7 @@ const level = {
if (index !== -1) {
level.playableLevels.splice(index, 1);
// console.log('removed level:', remove[i])
- requestAnimationFrame(() => { simulation.makeTextLog(`banned level:
${remove[i]} `); });
+ requestAnimationFrame(() => { simulation.inGameConsole(`banned level:
${remove[i]} `); });
}
}
// console.log('Landgreen levels after', level.playableLevels)
@@ -487,21 +777,6 @@ const level = {
level.exit.x = -level.exit.x - 100 //minus the 100 because of the width of the graphic
},
exitCount: 0,
- // playerExitCheck() {
- // if (
- // player.position.x > level.exit.x &&
- // player.position.x < level.exit.x + 100 &&
- // player.position.y > level.exit.y - 150 &&
- // player.position.y < level.exit.y - 40 &&
- // player.velocity.y < 0.1
- // ) {
- // level.exitCount++
- // if (level.exitCount > 120) {
- // level.exitCount = 0
- // level.nextLevel()
- // }
- // }
- // },
setPosToSpawn(xPos, yPos) {
m.spawnPos.x = m.pos.x = xPos;
m.spawnPos.y = m.pos.y = yPos;
@@ -548,9 +823,9 @@ const level = {
player.velocity.y < 0.15
) {
// level.exitCount += input.down ? 8 : 2
- level.exitCount += 2
+ level.exitCount += 3
} else if (level.exitCount > 0) {
- level.exitCount -= 2
+ level.exitCount -= 3
}
ctx.beginPath();
@@ -598,13 +873,12 @@ const level = {
let text = `
training
- Begin the guided tutorial that shows you how to use your field and gun .
+ Begin the guided tutorial that shows you how to use your ${powerUps.orb.field()} and ${powerUps.orb.gun()}.
play
Begin the standard game where you progress through 13 random levels and beat the final boss.
`
- //use you use your
gun ,
field , and
tech
document.getElementById("choose-grid").innerHTML = text
//show level info
document.getElementById("choose-grid").style.opacity = "1"
@@ -769,70 +1043,121 @@ const level = {
return who
},
- boost(x, y, height = 1000) { //height is how high the player will be flung above y
- who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("120 40 -120 40 -50 -40 50 -40"), {
- collisionFilter: {
- category: cat.body,
- mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
- },
- boostBounds: {
- min: {
- x: x,
- y: y - 20
+ boost(x, y, speed = 1000, angle = Math.PI / 2) { //height is how high the player will be flung above y
+ if (angle !== Math.PI / 2) { //angle !== 3 * Math.PI / 2
+ angle *= -1
+ who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("80 40 -80 40 -50 -40 50 -40"), {
+ collisionFilter: {
+ category: cat.body,
+ mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
- max: {
- x: x + 100,
- y: y
- }
- },
- yVelocity: -1.21 * Math.sqrt(Math.abs(height)),
- query() {
- // check for collisions
- query = (who) => {
- if (Matter.Query.region(who, this.boostBounds).length > 0) {
- list = Matter.Query.region(who, this.boostBounds)
- Matter.Body.setVelocity(list[0], {
- x: list[0].velocity.x + (Math.random() - 0.5) * 2.5, //add a bit of horizontal drift to reduce endless bounces
- y: this.yVelocity //give a upwards velocity
- });
+ query() {
+ // check for collisions
+ const rayVector = Vector.add(this.position, Vector.rotate({ x: 100, y: 0 }, angle))
+ query = (who) => {
+ const list = Matter.Query.ray(who, this.position, rayVector, 100)
+ if (list.length > 0) {
+ Matter.Body.setVelocity(list[0].bodyA, Vector.rotate({ x: 1.21 * Math.sqrt(Math.abs(speed)), y: 0 }, angle));
+ }
}
- }
- query(body)
- query(mob)
- query(bullet)
- query(powerUp)
- //player collision
- if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) {
- m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
- m.hardLandCD = 0 // disable hard landing
- if (player.velocity.y > 26) {
- Matter.Body.setVelocity(player, {
- x: player.velocity.x,
- y: -15 //gentle bounce if coming down super fast
- });
- } else {
- Matter.Body.setVelocity(player, {
- x: player.velocity.x + (Math.random() - 0.5) * 2.5,
- y: this.yVelocity //give a upwards velocity that will put the player that the height desired
- });
+ query(body)
+ query(mob)
+ query(bullet)
+ query(powerUp)
+ //player collision
+ const list = Matter.Query.ray([player], this.position, rayVector, 100)
+ if (list.length > 0) {
+ Matter.Body.setVelocity(player, Vector.rotate({ x: 1.21 * Math.sqrt(Math.abs(speed)), y: 0 }, angle));
+ m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
+ m.hardLandCD = 0 // disable hard landing
}
- }
- //draw
- ctx.fillStyle = "rgba(200,0,255,0.15)";
- ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 10, 100, 30);
- ctx.fillStyle = "rgba(200,0,255,0.05)";
- ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 50, 100, 70);
- // ctx.fillStyle = "rgba(200,0,255,0.02)";
- // ctx.fillRect(x, y - 120, 100, 120);
- },
- });
- return who
+ //draw
+ const v1 = this.vertices[0]
+ const v2 = this.vertices[1]
+ let unit = Vector.rotate({ x: 60, y: 0 }, angle)
+ let v3 = Vector.add(v2, unit)
+ let v4 = Vector.add(v1, unit)
+ ctx.beginPath();
+ ctx.moveTo(v1.x, v1.y)
+ ctx.lineTo(v2.x, v2.y)
+ ctx.lineTo(v3.x, v3.y)
+ ctx.lineTo(v4.x, v4.y)
+ ctx.fillStyle = "rgba(200,0,255,0.05)";
+ ctx.fill()
+ unit = Vector.rotate({ x: 20, y: 0 }, angle)
+ v3 = Vector.add(v2, unit)
+ v4 = Vector.add(v1, unit)
+ ctx.beginPath();
+ ctx.moveTo(v1.x, v1.y)
+ ctx.lineTo(v2.x, v2.y)
+ ctx.lineTo(v3.x, v3.y)
+ ctx.lineTo(v4.x, v4.y)
+ ctx.fillStyle = "rgba(200,0,255,0.15)";
+ ctx.fill()
+ },
+ });
+ Matter.Body.rotate(who, angle + Math.PI / 2);
+ return who
+ } else {
+ who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("120 40 -120 40 -50 -40 50 -40"), {
+ collisionFilter: {
+ category: cat.body,
+ mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ },
+ boostBounds: {
+ min: {
+ x: x,
+ y: y - 20
+ },
+ max: {
+ x: x + 100,
+ y: y
+ }
+ },
+ query() {
+ // check for collisions
+ query = (who) => {
+ if (Matter.Query.region(who, this.boostBounds).length > 0) {
+ list = Matter.Query.region(who, this.boostBounds)
+ Matter.Body.setVelocity(list[0], {
+ x: list[0].velocity.x + (Math.random() - 0.5) * 2.5, //add a bit of horizontal drift to reduce endless bounces
+ y: -1.21 * Math.sqrt(Math.abs(speed)) //give a upwards velocity
+ });
+ }
+ }
+ query(body)
+ query(mob)
+ query(bullet)
+ query(powerUp)
+ //player collision
+ if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) {
+ m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts
+ m.hardLandCD = 0 // disable hard landing
+ if (player.velocity.y > 26) {
+ Matter.Body.setVelocity(player, {
+ x: player.velocity.x,
+ y: -15 //gentle bounce if coming down super fast
+ });
+ } else {
+ Matter.Body.setVelocity(player, {
+ x: player.velocity.x + (Math.random() - 0.5) * 2.5,
+ y: -1.21 * Math.sqrt(Math.abs(speed)) //give an upwards velocity that will put the player that the height desired
+ });
+ }
+ }
+
+ //draw
+ ctx.fillStyle = "rgba(200,0,255,0.15)";
+ ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 10, 100, 30);
+ ctx.fillStyle = "rgba(200,0,255,0.05)";
+ ctx.fillRect(this.boostBounds.min.x, this.boostBounds.min.y - 50, 100, 70);
+ },
+ });
+ return who
+ }
},
- elevator(x, y, width, height, maxHeight, force = 0.003, friction = {
- up: 0.01,
- down: 0.2
- }, isAtTop = false) {
+ elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }, isAtTop = false) {
x += width / 2
y += height / 2
maxHeight += height / 2
@@ -841,7 +1166,7 @@ const level = {
const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, {
collisionFilter: {
category: cat.body, //cat.map,
- mask: cat.map | cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ mask: cat.player | cat.body | cat.bullet | cat.mob | cat.mobBullet //| cat.powerUp
},
inertia: Infinity, //prevents rotation
isNotHoldable: true,
@@ -897,17 +1222,69 @@ const level = {
x: this.holdX,
y: this.position.y
});
+ },
+ moveOnTouch() {
+ if (!m.isBodiesAsleep) {
+ if (this.isUp) { //moving up still with high air friction
+ this.force.y -= force * this.mass //hard force propels up, even with high friction
+ if (this.position.y < maxHeight) { //switch to down mode
+ this.isUp = false
+ this.frictionAir = friction.down
+ //adds a hard jerk at the top of vertical motion because it's fun
+ Matter.Body.setPosition(this, { x: this.holdX, y: maxHeight });
+ Matter.Body.setVelocity(this, { x: 0, y: 0 });
+ }
+ } else if (this.position.y + 10 * this.velocity.y > y) { //free falling down, with only air friction
+ //slow down early to avoid a jerky stop that can pass through blocks
+ Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y * 0.7 });
+ //switch to up mode
+ // if (this.position.y + this.velocity.y > y) {
+ // this.isUp = true
+ // this.frictionAir = friction.up
+ // }
+ }
+ Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y });
+ }
+ //draw line to show how far to will extend
+ ctx.beginPath();
+ ctx.moveTo(x, y + height / 2);
+ ctx.lineTo(x, maxHeight - height / 2);
+ ctx.strokeStyle = `rgba(0,0,0,0.2)`
+ ctx.lineWidth = "2"
+ ctx.stroke();
+
+ //draw body
+ ctx.beginPath();
+ ctx.moveTo(this.vertices[0].x, this.vertices[0].y);
+ for (let j = 1; j < this.vertices.length; j++) {
+ ctx.lineTo(this.vertices[j].x, this.vertices[j].y);
+ }
+ ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
+ ctx.lineWidth = "2"
+ ctx.strokeStyle = `#333`
+ ctx.fillStyle = `rgba(200,200,200,1)`
+ //edge limits
+ if (this.position.y < maxHeight) {
+ Matter.Body.setPosition(this, { x: this.holdX, y: maxHeight });
+ } else if (this.position.y > y) {
+ ctx.fillStyle = `rgba(255,255,255,${0.5 + 0.15 * Math.random()})`
+ Matter.Body.setPosition(this, { x: this.holdX, y: y });
+ //undoing force of gravity
+ this.force.y -= this.mass * simulation.g;
+ if (Matter.Query.collides(this, [player]).length) {
+ this.isUp = true
+ this.frictionAir = friction.up
+ }
+ }
+ ctx.fill();
+ ctx.stroke();
+ // hold horizontal position
+ Matter.Body.setPosition(this, { x: this.holdX, y: this.position.y });
},
off() {
- Matter.Body.setPosition(this, {
- x: this.holdX,
- y: this.position.y
- });
- Matter.Body.setVelocity(this, {
- x: 0,
- y: this.velocity.y
- });
+ Matter.Body.setPosition(this, { x: this.holdX, y: this.position.y });
+ Matter.Body.setVelocity(this, { x: 0, y: this.velocity.y });
},
constraint: this.null,
addConstraint() {
@@ -935,73 +1312,69 @@ const level = {
who.classType = "body"
return who
},
- spring(x, y, v = "-100 0 100 0 70 40 0 50 -70 40", force = 0.01, distance = 300, angle = 0) {
- const who = body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(v), {
- collisionFilter: {
- category: cat.body,
- mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
- },
- inertia: Infinity, //prevents rotation
- isNotHoldable: true,
- friction: 1,
- frictionStatic: 1,
- restitution: 0,
- frictionAir: 1,
- density: 0.1,
- isReady: true,
- isResetting: false,
- query() {
- if (this.isReady) {
- if (Matter.Query.collides(this, [player]).length) {
- this.isReady = false
- this.constraint.stiffness = 0
- this.constraint.damping = 0 //0.3
- this.frictionAir = 0
- Matter.Body.setVelocity(this, {
- x: 0,
- y: 0
- });
- //show graphically being ready?
-
- }
- } else {
- if (this.isResetting) {
- this.constraint.stiffness += 0.0005
- if (this.constraint.stiffness > 0.1) {
- this.isResetting = false
- this.isReady = true
- }
- } else {
- if (Vector.magnitudeSquared(Vector.sub(this.position, {
- x: x,
- y: y
- })) < distance * distance) {
- this.force.y -= force * this.mass
- } else {
- this.constraint.damping = 1
- this.frictionAir = 1
- this.isResetting = true
- Matter.Body.setVelocity(this, {
- x: 0,
- y: 0
- });
- }
- }
- }
- }
- });
- who.constraint = Constraint.create({
- pointA: {
- x: who.position.x,
- y: who.position.y
- },
- bodyB: who,
- stiffness: 1,
- damping: 1
- });
- Composite.add(engine.world, who.constraint);
- return who
- },
+ // spring(x, y, v = "-100 0 100 0 70 40 0 50 -70 40", force = 0.01, distance = 300, angle = 0) {
+ // const who = body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(v), {
+ // collisionFilter: {
+ // category: cat.body,
+ // mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ // },
+ // inertia: Infinity, //prevents rotation
+ // isNotHoldable: true,
+ // friction: 1,
+ // frictionStatic: 1,
+ // restitution: 0,
+ // frictionAir: 1,
+ // density: 0.1,
+ // isReady: true,
+ // isResetting: false,
+ // query() {
+ // if (this.isReady) {
+ // if (Matter.Query.collides(this, [player]).length) {
+ // this.isReady = false
+ // this.constraint.stiffness = 0
+ // this.constraint.damping = 0 //0.3
+ // this.frictionAir = 0
+ // Matter.Body.setVelocity(this, { x: 0, y: 0 });
+ // //show graphically being ready?
+ // }
+ // } else {
+ // if (this.isResetting) {
+ // this.constraint.stiffness += 0.0005
+ // if (this.constraint.stiffness > 0.1) {
+ // this.isResetting = false
+ // this.isReady = true
+ // }
+ // } else {
+ // if (Vector.magnitudeSquared(Vector.sub(this.position, {
+ // x: x,
+ // y: y
+ // })) < distance * distance) {
+ // this.force.y -= force * this.mass
+ // } else {
+ // this.constraint.damping = 1
+ // this.frictionAir = 1
+ // this.isResetting = true
+ // Matter.Body.setVelocity(this, {
+ // x: 0,
+ // y: 0
+ // });
+ // }
+ // }
+ // }
+ // }
+ // });
+ // who.constraint = Constraint.create({
+ // pointA: {
+ // x: who.position.x,
+ // y: who.position.y
+ // },
+ // bodyB: who,
+ // stiffness: 1,
+ // damping: 1
+ // });
+ // Composite.add(engine.world, who.constraint);
+ // return who
+ // },
// rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
// const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
// density: density,
@@ -1170,10 +1543,7 @@ const level = {
y: list[0].position.y
})
}
- Matter.Body.setVelocity(list[0], {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(list[0], { x: 0, y: 0 });
}
}
this.isUp = false;
@@ -1747,12 +2117,12 @@ const level = {
if (this.height > 0 && Matter.Query.region([player], this).length) {
if (m.immuneCycle < m.cycle) {
- const DRAIN = 0.004 * (tech.isRadioactiveResistance ? 0.25 : 1)
+ const DRAIN = 0.004 * (tech.isRadioactiveResistance ? 0.2 : 1)
if (m.energy > DRAIN) {
m.energy -= DRAIN
if (tech.isEnergyHealth && m.energy < 0) m.death()
} else {
- m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
+ m.damage(damage * (tech.isRadioactiveResistance ? 0.2 : 1))
}
}
@@ -2102,7 +2472,6 @@ const level = {
document.body.style.backgroundColor = "#fff";
// color.map = "#444" //custom map color
- // level.difficultyIncrease(14); //hard mode level 7
level.defaultZoom = 1500
simulation.zoomTransition(level.defaultZoom)
@@ -2189,7 +2558,6 @@ const level = {
//???
- // level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
// m.addHealth(Infinity)
// spawn.starter(1900, -500, 200) //big boy
@@ -2345,56 +2713,68 @@ const level = {
spawn.mapRect(-500, -25, 25, 50); //edge shelf
spawn.mapRect(475, -25, 25, 50); //edge shelf
},
- initial() {
- if (level.levelsCleared === 0) { //if this is the 1st level of the game
- if (simulation.difficultyMode > 2) spawn.setSpawnList() // hard and why difficulty don't begin with starter mobs
-
- //wait to spawn power ups until unpaused
- //power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
- const goal = simulation.cycle + 10
+ initialPowerUps() {
+ //wait to spawn power ups until unpaused
+ //power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
+ const goal = simulation.cycle + 10
+ function cycle() {
+ if (simulation.cycle > goal) {
+ if (localSettings.loreCount === 6) {
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2170, "field", false);
+ } else {
+ powerUps.spawnStartingPowerUps(2095 + 20 * (Math.random() - 0.5), -2200);
+ }
+ if (simulation.difficultyMode === 1) {
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2600, "ammo", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2550, "ammo", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2400, "heal", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2350, "heal", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2350, "heal", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2100, "research", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2060, "research", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2120, "research", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2075, "research", false);
+ } else if (simulation.difficultyMode === 6) {
- function cycle() {
- if (simulation.cycle > goal) {
- if (localSettings.loreCount === 6) {
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2170, "field", false);
- } else {
- powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
- }
- if (simulation.difficultyMode < 5) { //hard, normal and easy
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 25, "heal", false);
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
- }
- if (simulation.difficultyMode < 3) { //normal and easy
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
- }
- if (simulation.difficultyMode < 2) { //easy
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
- powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
- }
} else {
- requestAnimationFrame(cycle);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2300, "heal", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2100, "heal", false);
+ powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2060, "research", false);
}
+ //spin the power ups to prevent them from stacking awkwardly
+ for (let i = 0; i < powerUp.length; i++) {
+ Matter.Body.setAngularVelocity(powerUp[i], 5 * (Math.random() - 0.5))
+ }
+ } else {
+ requestAnimationFrame(cycle);
+ }
+ }
+ requestAnimationFrame(cycle);
+ },
+ initial() {
+ if (level.levelsCleared === 0) { //if this is the 1st level of the game
+ if (simulation.difficultyMode > 2) spawn.setSpawnList() // hard and why difficulty don't begin with starter mobs
+ level.initialPowerUps()
+ if (level.levelsCleared === 0) powerUps.directSpawn(-60, -950, "difficulty", false);
+
+ if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
+ spawn.wireFoot();
+ spawn.wireFootLeft();
+ spawn.wireKnee();
+ spawn.wireKneeLeft();
+ spawn.wireHead();
+ } else {
+ simulation.isCheating = true;
}
- requestAnimationFrame(cycle);
if (localSettings.levelsClearedLastGame < 3) {
- if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
- spawn.wireFoot();
- spawn.wireFootLeft();
- spawn.wireKnee();
- spawn.wireKneeLeft();
- spawn.wireHead();
- // for (let i = 0; i < 3; i++) powerUps.spawn(2095, -1220 - 50 * i, "tech", false); //unavailable tech spawns
- // spawn.mapRect(2000, -1025, 200, 25);
- }
} else if (!build.isExperimentRun) {
- simulation.trails()
+ simulation.trails(70)
//bonus power ups for clearing runs in the last game
if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(2095 + 2 * Math.random(), -1270 - 50 * i, "tech", false); //spawn a tech for levels cleared in last game
- simulation.makeTextLog(`for (let i
= 0; i
< localSettings.levelsClearedLastGame
/ 3; i
++ )`);
- simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech")
//simulation superposition }`);
+ simulation.inGameConsole(`for (let i
= 0; i
< localSettings.levelsClearedLastGame
/ 3; i
++ )`);
+ simulation.inGameConsole(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech")
//simulation superposition }`);
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
@@ -2492,6 +2872,14 @@ const level = {
wires.lineTo(2600, -690)
level.custom = () => {
+ //working on a message using text
+ // ctx.font = "50px Arial";
+ // ctx.fillStyle = "rgba(0,0,0,0.3)"
+ // for (let i = 0; i < 5; i++) {
+ // const wiggle = 10
+ // ctx.fillText("move", 500 + wiggle * Math.random(), -500 + wiggle * Math.random());
+ // }
+
//push around power ups stuck in the tube wall
if (!(simulation.cycle % 30)) {
for (let i = 0, len = powerUp.length; i < len; i++) {
@@ -2538,27 +2926,6 @@ const level = {
ctx.fillStyle = "#ccc"
ctx.fill()
- //power up dispenser
- // ctx.beginPath()
- // for (let i = 2; i < 10; i++) {
- // ctx.moveTo(2000, -100 * i)
- // ctx.lineTo(2080, -100 * i)
- // }
- // ctx.strokeStyle = "#ddd"
- // ctx.lineWidth = 5;
- // ctx.stroke();
-
- // ctx.beginPath()
- // for (let i = 2; i < 10; i++) {
- // ctx.arc(2040, -100 * i, 30, 0, 2 * Math.PI);
- // ctx.moveTo(2040, -100 * i)
- // }
- // ctx.fillStyle = "rgba(0,0,0,0.3)"
- // ctx.fill()
-
- // ctx.fillStyle = "rgba(240,255,255,0.5)"
- // ctx.fillRect(2000, -1000, 80, 700)
-
//exit room
ctx.fillStyle = "#f2f2f2"
ctx.fillRect(2600, -600, 400, 300)
@@ -2591,8 +2958,13 @@ const level = {
spawn.mapRect(3000, -2800, 2600, 4600); //right wall
// spawn.mapRect(-250, 0, 3600, 1800); //ground
- spawn.mapRect(-250, 0, 2300, 1800); //split roof
- spawn.mapRect(2150, 0, 1200, 1800); //split roof
+ spawn.mapRect(-250, 0, 2300, 1800); //ground
+
+ Matter.Body.setVelocity(map[map.length - 1], {
+ x: 10,
+ y: -10
+ });
+ spawn.mapRect(2150, 0, 1200, 1800); //ground
spawn.mapRect(2025, -3, 25, 15); //lip on power up chamber
spawn.mapRect(2150, -3, 25, 15); //lip on power up chamber
@@ -2790,7 +3162,6 @@ const level = {
},
subway() {
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
- // level.difficultyIncrease(10 * 4);
// m.maxHealth = m.health = 100
// color.map = "#333" //custom map color
document.body.style.backgroundColor = "#e3e3e3"//"#e3e3e3"//color.map//"#333"//"#000"
@@ -2801,7 +3172,6 @@ const level = {
level.exit.x = 0;
level.exit.y = -9000;
// spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump disabled for performance
-
const stationWidth = 9000
let stationNumber = 0;
let stationCustom = () => { }
@@ -2857,7 +3227,7 @@ const level = {
if (gateButton.isUp) {
gateButton.query();
if (!gateButton.isUp) {
- simulation.makeTextLog(`station gate opened`, 360);
+ simulation.inGameConsole(`station gate opened`, 360);
if (stationNumber > 0) {
if (!isExitOpen && gatesOpenRight < stationNumber) level.newLevelOrPhase() //run some new level tech effects
gatesOpenRight = stationNumber
@@ -2869,7 +3239,7 @@ const level = {
gatesOpenRight = stationNumber
}
if (Math.abs(stationNumber) > 0 && ((Math.abs(stationNumber) + 1) % stationList.length) === 0) {
- simulation.makeTextLog(`level exit opened`, 360);
+ simulation.inGameConsole(`level exit opened`, 360);
isExitOpen = true;
}
}
@@ -2882,6 +3252,7 @@ const level = {
if (isExitOpen) {
level.exit.x = x - 50;
level.exit.y = -260;
+ if (simulation.difficultyMode < 6) powerUps.spawn(level.exit.x, level.exit.y - 100, "tech");
} else {
var gateButton = level.button(x - 62, -237, 125, false) //x, y, width = 126, isSpawnBase = true
gateButton.isUp = true
@@ -4013,9 +4384,10 @@ const level = {
} else {
isSpawnedBoss = true
isDoorsLocked = true
- for (let i = 0; i < 9; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "ammo")
- for (let i = 0; i < 3; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "heal");
- const scale = Math.pow(simulation.difficulty, 0.7) //hard around 30, why around 54
+ for (let i = 0; i < 12; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1800, "ammo")
+ for (let i = 0; i < 5; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "heal");
+ for (let i = 0; i < 1; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1750, "research");
+ const scale = Math.pow(simulation.difficulty, 0.7)
if (mobs.mobDeaths < level.levelsCleared && !simulation.isCheating) {
for (let i = 0; i < 250; i++) spawn.starter(-2700 + 2400 * Math.random(), -1300 - 500 * Math.random())
} else {
@@ -4036,7 +4408,6 @@ const level = {
}
}
}
- // spawn.secondaryBossChance(-2300, -800)
}
} else {
doorIn.isClosing = false
@@ -4056,8 +4427,7 @@ const level = {
// powerUps.spawnBossPowerUp(-3600, -100)
powerUps.spawn(-3650, -50, "tech")
powerUps.spawn(-3650, -150, "tech")
- powerUps.spawn(-3650, -300, "tech")
- // if (player.position.x < 2760 && player.position.x > 210) {}
+ if (simulation.difficultyMode < 6) powerUps.spawn(-3650, -300, "tech")
}
}
};
@@ -4166,10 +4536,267 @@ const level = {
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
+ towers() {
+ // simulation.isHorizontalFlipped = true
+ level.announceMobTypes()
+ const isFlipped = (simulation.isHorizontalFlipped && Math.random() < 0.33) ? true : false
+ if (isFlipped) {
+ level.setPosToSpawn(9150 + 50, -2230 - 25);
+ level.exit.x = 400 - 50;
+ level.exit.y = -50 + 25;
+ leftRoomColor = "#cff"
+ rightRoomColor = "rgba(0,0,0,0.13)"
+ } else {
+ level.setPosToSpawn(400, -50);
+ level.exit.x = 9150;
+ level.exit.y = -2230;
+ }
+
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ level.fallMode = "position"; //must set level.fallModeBounds in this mode to prevent player getting stuck left or right
+ level.fallModeBounds = { left: level.enter.x, right: level.exit.x } //used with level.fallMode = "position";
+ if (isFlipped) level.fallModeBounds = { left: level.exit.x, right: level.enter.x } //used with level.fallMode = "position";
+ simulation.fallHeight = 5000 //level.enter.y - 4000
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 2300
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#cdd9df";
+ powerUps.spawnStartingPowerUps(6300, 1025)
+
+ const boost1 = level.boost(7560, 1480, 1700, 1.75)
+ const boost2 = level.boost(7098, 0, 1250, Math.PI / 3) //x,y,push,angle radians
+ const boost3 = level.boost(9700, -730, 1050, 1.95)
+ const boost4 = level.boost(4300, -720, 1500, 1.25)
+ const boost5 = level.boost(3000, -1215, 3000, 1.25)
+ const boost6 = level.boost(8251, -619, 1200, 2.7)
+ const boost7 = level.boost(7750, -1540, 1050, 1.2)
+ // const boost6 = level.boost(8235, -619, 3500, 2.9)
+
+ const train1 = level.transport(3650, 100, 415, 500, 8); //x,y,width.height,VxGoal,force
+ const train2 = level.transport(1250, 100, 415, 500, -8); //x,y,width.height,VxGoal,force
+ const train3 = level.transport(4050, 100, 415, 500, 8); //x,y,width.height,VxGoal,force
+
+ let portal1, portal2
+ portal1 = level.portal({
+ x: 3675,
+ y: -2225 + 1025
+ }, -Math.PI / 2, { //up
+ x: 3675,
+ y: -375
+ }, Math.PI / 2) //down
+
+ portal2 = level.portal({
+ x: 6300,
+ y: -1225
+ }, -Math.PI / 2, { //up
+ x: 6300,
+ y: -375
+ }, Math.PI / 2) //down
+ level.custom = () => {
+ boost1.query();
+ boost2.query();
+ boost3.query();
+ boost4.query();
+ boost5.query();
+ boost6.query();
+ boost7.query();
+ //trains oscillate back and forth and act like they are bouncing off each other
+ if (train1.position.x < 2850) {
+ train1.changeDirection(true) //go right
+ } else if (train1.position.x > 3850) {
+ train1.changeDirection(false) //go left
+ }
+ if (train2.position.x < 1450) {
+ train2.changeDirection(true) //go right
+ } else if (train2.position.x > 2450) {
+ train2.changeDirection(false) //go left
+ }
+ if (train3.position.x < 4250) {
+ train3.changeDirection(true) //go right
+ } else if (train3.position.x > 5250) {
+ train3.changeDirection(false) //go left
+ }
+ train1.move();
+ train2.move();
+ train3.move();
+ ctx.fillStyle = "rgba(0,0,0,0.25)"
+ ctx.fillRect(1250, 121, 4200, 6)
+ ctx.fillStyle = "rgba(50,70,100,0.04)"
+ ctx.fillRect(2500, -10000, 1800, 30000);
+ ctx.fillRect(8300, -10000, 1800, 30000);
+ ctx.fillRect(-500, -10000, 1800, 30000);
+ ctx.fillRect(5400, -10000, 1800, 30000);
+
+ portal1[2].query()
+ portal1[3].query()
+ portal2[2].query()
+ portal2[3].query()
+
+ ctx.fillStyle = "#cff"
+ if (isFlipped) {
+ ctx.fillRect(150, -300, 525, 325); //entrance typically
+ } else {
+ ctx.fillRect(8925, -2575, 525, 400) //exit typically
+ }
+
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ ctx.fillStyle = "rgba(0,0,0,0.13)"
+ ctx.fillRect(8300, -1950, 1550, 1275);
+ ctx.fillRect(5400, 875, 1800, 650);
+ ctx.fillRect(2950, -2200, 875, 1050);
+ ctx.fillRect(5900, -1025, 800, 450);
+ if (isFlipped) {
+ ctx.fillRect(8925, -2575, 575, 400) //exit typically
+ } else {
+ ctx.fillRect(150, -300, 525, 325); //entrance typically
+ }
+
+ ctx.fillStyle = "rgba(0,0,0,0.5)"
+ ctx.fillRect(7175, -1515, 125, 180);
+ portal1[0].draw();
+ portal1[1].draw();
+ portal1[2].draw();
+ portal1[3].draw();
+ portal2[0].draw();
+ portal2[1].draw();
+ portal2[2].draw();
+ portal2[3].draw();
+ };
+
+ // four large rounded squares
+ let a = 900 //side length
+ let c = 100 //corner offset
+ // spawn.mapVertex(3400, -1300, `${-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
+ // spawn.mapVertex(9200, -1300, `${-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
+ // spawn.mapVertex(6300, 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
+ spawn.mapVertex(400, 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
+ //lower 1st zone entrance /exit
+ spawn.mapRect(100, -350, 575, 75);
+ spawn.mapRect(100, -300, 75, 375);
+ spawn.mapRect(600, -325, 75, 175);
+ spawn.mapRect(600, -10, 75, 50);
+
+
+ //2nd zone upper hollow square
+ spawn.mapVertex(5650 - 2900, 900 - 2200, `${-a} ${-a + c} ${-a + c} ${-a} ${-400} ${-a} ${-400} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //1/2 square with edges cut off
+ spawn.mapVertex(6950 - 2900, 900 - 2200, `${400} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${a - c} ${a - c} ${a} ${400} ${a}`); //1/2 square with edges cut off
+ // spawn.mapRect(5600 - 2900, 1400 - 2200, 1350, 400);
+ spawn.mapRect(2950, -1175, 650, 775);
+ spawn.mapRect(3750, -1175, 100, 775);
+ spawn.mapRect(3575, -1025, 200, 475);
+
+
+ //4th zone far right hollow square near exit
+ spawn.mapVertex(9200, -2050, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${-600} ${-a} ${-600}`); //square with edges cut off --- hollow top
+ spawn.mapVertex(9200, -550, `${-a} ${600} ${a} ${600} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off --- hollow bottom
+ spawn.mapRect(9800, -2100, 300, 1600); //hollow left wall
+ spawn.mapVertex(8175, -1425, "-1400 -90 350 -90 400 -40 400 40 350 90 -1400 90");
+ spawn.mapVertex(6856, -1425, "300 -90 -350 -90 -400 -40 -400 40 -350 90 300 90");
+ //exit housing
+ spawn.mapRect(8925, -2575, 575, 75);
+ if (isFlipped) {
+ spawn.mapRect(8925, -2550, 75, 400);
+ spawn.mapRect(9425, -2550, 75, 125);
+ spawn.mapRect(9425, -2215, 75, 50);
+ spawn.bodyRect(9425, -2425, 75, 210);
+ } else {
+ spawn.mapRect(9425, -2550, 75, 400);
+ spawn.mapRect(8925, -2550, 75, 125);
+ spawn.mapRect(8925, -2215, 75, 50);
+ }
+
+
+
+ //lower 3rd zone
+ spawn.mapVertex(6300, 450, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${0} ${-a} ${0}`); //square with edges cut off --- hollow top
+ spawn.mapVertex(6300, 1200, "-400 -40 -350 -90 350 -90 400 -40 400 40 350 90 -350 90 -400 40");
+ spawn.mapVertex(6450, 1650, `${-a} ${600} ${a + 700} ${600} ${a + 700} ${a - c} ${a - c + 700} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off --- hollow bottom
+
+ //upper 3rd zone
+ a = 400 //side length
+ c = 50 //corner offset
+ // spawn.mapVertex(6300, -800, `${-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
+ spawn.mapVertex(6300, -1100, `${-a} ${-a + c} ${-a + c} ${-a} ${a - c} ${-a} ${a} ${-a + c} ${a} ${-200} ${-a} ${-200}`); //square with edges cut off
+ spawn.mapVertex(6300, -500, `${-a} ${200} ${a} ${200} ${a} ${a - c} ${a - c} ${a} ${-a + c} ${a} ${-a} ${a - c}`); //square with edges cut off
+ spawn.mapVertex(5800, -1425, "-300 -40 -250 -90 250 -90 300 -40 300 40 250 90 -250 90 -300 40");
+ spawn.mapVertex(5485, -1850, "-400 -40 -350 -90 350 -90 400 -40 400 40 350 90 -350 90 -400 40");
+ spawn.mapVertex(7115, -1850, "-400 -40 -350 -90 350 -90 400 -40 400 40 350 90 -350 90 -400 40"); //long
+ spawn.mapVertex(6300, -2175, "-300 -40 -250 -90 250 -90 300 -40 300 40 250 90 -250 90 -300 40"); //highest
+ spawn.mapVertex(4450, -1850, "-200 -40 -150 -90 150 -90 200 -40 200 40 150 90 -150 90 -200 40");
+ // spawn.mapVertex(5300, -300, "-300 -60 -270 -90 270 -90 300 -60 300 60 270 90 -270 90 -300 60");
+ spawn.mapVertex(5300, -300, "-300 -40 -250 -90 250 -90 300 -40 300 40 250 90 -250 90 -300 40");
+ spawn.mapVertex(4500, -590, "-300 -90 250 -90 300 -40 300 40 250 90 -300 90");
+ // spawn.mapVertex(4600, -590, "-500 -90 170 -90 200 -60 200 60 170 90 -500 90");
+
+ //no debris on this level, so spawn some heals and ammo
+ powerUps.chooseRandomPowerUp(6275, 1425);
+ powerUps.chooseRandomPowerUp(6300, -650);
+ powerUps.chooseRandomPowerUp(9550, -750);
+
+ //random blocks
+ spawn.bodyRect(7725, -2200, 150, 250, 0.2);
+ spawn.bodyRect(4625, -825, 75, 125, 0.2);
+ spawn.bodyRect(3250, -1200, 25, 25, 0.2);
+ spawn.bodyRect(3375, -1275, 25, 75, 0.2);
+ spawn.bodyRect(3450, -1200, 50, 25, 0.2);
+ spawn.bodyRect(2825, -2225, 25, 25, 0.2);
+ spawn.bodyRect(4075, -2225, 50, 25, 0.2);
+ spawn.bodyRect(8850, -800, 75, 100, 0.2);
+ spawn.bodyRect(6900, -100, 75, 100, 0.2);
+ spawn.bodyRect(8975, -1575, 50, 50, 0.2);
+ spawn.bodyRect(5725, -1700, 125, 175, 0.2);
+ spawn.bodyRect(6850, -1725, 150, 200, 0.2);
+ spawn.bodyRect(500, -400, 100, 50, 0.3);
+ spawn.bodyRect(6025, 1050, 100, 50, 0.2);
+ spawn.bodyRect(6000, -800, 75, 200, 0.2);
+ spawn.bodyRect(6775, -75, 125, 75, 0.5);
+ spawn.bodyRect(7200, 1300, 50, 200, 0.5);
+
+
+ //mobs
+ spawn.randomMob(5700, -75, 0);
+ spawn.randomMob(6200, -100, 0);
+ spawn.randomMob(6900, -100, 0.1);
+ spawn.randomMob(5550, -500, 0.1);
+ spawn.randomMob(4675, -850, 0.1);
+ spawn.randomMob(4450, -2050, 0.1);
+ spawn.randomMob(4050, -2325, 0.1);
+ spawn.randomMob(3350, -1325, 0.2);
+ spawn.randomMob(5300, -2050, 0.2);
+ spawn.randomMob(5675, -2050, 0.2);
+ spawn.randomMob(5850, -1625, 0.3);
+ spawn.randomMob(6775, -1600, 0.3);
+ spawn.randomMob(7700, -1625, 0.4);
+ spawn.randomMob(7850, -2000, 0.4);
+ spawn.randomMob(7225, -2000, 0.4);
+ spawn.randomMob(6350, -2400, 0.5);
+ spawn.randomMob(8850, -1650, 0.5);
+ spawn.randomMob(9500, -1300, 0.5);
+ spawn.randomMob(9250, -900, 0.5);
+ spawn.randomMob(8600, -875, 0.6);
+ spawn.randomMob(5575, 1350, 0.6);
+ spawn.randomMob(6075, 1025, 0.6);
+ spawn.randomMob(6300, 1025, 0.7);
+ spawn.randomMob(6525, 1425, 0.8);
+ spawn.randomMob(7125, 1450, 0.9);
+ // spawn.randomMob(8600, -2325, 0.7);
+ // spawn.randomMob(8650, -2825, 0.8);
+ // spawn.randomMob(9225, -2850, 0.9);
+ // spawn.randomMob(8525, -2375, 0.9);
+ spawn.randomGroup(4925, -2850, 1);
+ if (simulation.difficulty > 1) {
+ spawn.randomLevelBoss(7275, -2475);
+ spawn.secondaryBossChance(8400, -1025)
+ }
+ powerUps.addResearchToLevel() //needs to run after mobs are spawned
+
+ },
factory() {
level.announceMobTypes()
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
level.setPosToSpawn(2235, -1375); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
@@ -4179,7 +4806,7 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
level.defaultZoom = 1500
simulation.zoomTransition(level.defaultZoom)
- document.body.style.backgroundColor = "#d0d2d4s";
+ document.body.style.backgroundColor = "#d0d2d4";
// color.map = "#262a2f"
let isPowerLeft = true
const movers = []
@@ -4290,6 +4917,23 @@ const level = {
if (!buttonLeft.isUp) {
setMoverDirection(7)
buttonRight.isUp = true //flip the other button up
+
+ //remove any blocks on top of right button
+ const badBlocks = Matter.Query.region(body, buttonRight)
+ //figure out block's index
+ for (let j = 0; j < badBlocks.length; j++) {
+ let index = null
+ for (let i = 0; i < body.length; i++) {
+ if (badBlocks[j] === body[i]) index = i
+ }
+ //remove block
+ console.log(index, j)
+ if (index) {
+ Matter.Composite.remove(engine.world, badBlocks[j]);
+ body.splice(index, 1);
+ }
+ }
+
}
} else if (buttonRight.isUp) {
buttonRight.query();
@@ -4311,7 +4955,7 @@ const level = {
}
}
- if (button1.isUp) {
+ if (button1.isUp) { //opens up secondary zone
button1.query();
if (!button1.isUp) {
isPowerLeft = false
@@ -4547,7 +5191,6 @@ const level = {
balance1 = level.spinner(x + 200, y - 500, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5)) // spinner(x, y, width, height, density = 0.001, angle=0,frictionAir=0.001,angularVelocity=0) {
balance2 = level.spinner(x + 200, y - 950, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance3 = level.spinner(x + 650, y - 750, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
- // balance4 = level.spinner(x + 750, y - 1050, 25, 350, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
balance4 = level.spinner(x + 1250, y - 1000, 30, 400, density, angle + variance * (Math.random() - 0.5), frictionAir, angularVelocity + spinVariance * (Math.random() - 0.5))
let isInRoom = false
@@ -4997,7 +5640,7 @@ const level = {
powerUps.directSpawn(x + 998, y - 333, "tech", false);
}
const powerUp1 = powerUp[powerUp.length - 1]
- powerUp1.holdPosition = { x: powerUp1.position.x, y: powerUp1.position.y }
+ if (powerUp1) powerUp1.holdPosition = { x: powerUp1.position.x, y: powerUp1.position.y }
let isSpawnedMobs = false
doCustom.push(
() => {
@@ -5006,7 +5649,7 @@ const level = {
// if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2000 && m.pos.y > y - 1300 && m.pos.y < y) { //is player inside this room?
// isInRoom = true
// } else
- if (powerUp1.velocity.y !== 0) { //don't run this code if power up is gone //hack: powerUp1.velocity.y !== 0 seems to only be true if the power up up doesn't exist and is no longer being affected by gravity
+ if (powerUp1 && powerUp1.velocity.y !== 0) { //don't run this code if power up is gone //hack: powerUp1.velocity.y !== 0 seems to only be true if the power up doesn't exist and is no longer being affected by gravity
ctx.strokeStyle = "#f0f"
ctx.lineWidth = 2;
if (Vector.magnitudeSquared(Vector.sub(m.pos, powerUp1.position)) < 90000) { //zone radius is 300
@@ -5068,10 +5711,7 @@ const level = {
x: powerUp1.holdPosition.x + 4 * Math.random(), //1300 -2
y: powerUp1.holdPosition.y + 4 * Math.random() //335 -2
});
- Matter.Body.setVelocity(powerUp1, {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(powerUp1, { x: 0, y: 0 });
} else if (!isSpawnedMobs) {
isSpawnedMobs = true
if (chamberY === -650) { //lower chamber
@@ -5564,7 +6204,7 @@ const level = {
},
pavilion() {
level.announceMobTypes()
- level.isEndlessFall = true;
+ level.fallMode = "start";
const vanish = []
level.exit.x = -850;
level.exit.y = -1485;
@@ -6414,10 +7054,264 @@ const level = {
balance5 = level.rotor(2605, 1100, 390, 25, 0.001) //falling
}
+ },
+ flocculation() {
+ level.announceMobTypes()
+ const button0 = level.button(1125, 795)
+ const button1 = level.button(6538, 2670)
+ const button2 = level.button(1225, -100)
+ button0.isUp = true
+ button1.isUp = true
+ button2.isUp = true
+ // const hazard = level.hazard(4550, 2750, 4550, 150)
+ const hazard = level.hazard(simulation.isHorizontalFlipped ? -7200 : 675, 50, 7500, 3000) //1869
+ // hazard.min.y = 3000 //REMOVE THIS IN LIVE VERSION!!!!! set slime to lowest level
+ let balance1, balance2, balance3, rotor1, rotor2
+
+ const drip1 = level.drip(6100, 1900, 2900, 100) // drip(x, yMin, yMax, period = 100, color = "hsla(160, 100%, 35%, 0.5)") {
+ const drip2 = level.drip(7300, 1900, 2900, 150)
+ const drip3 = level.drip(8750, 1900, 2900, 70)
+
+ //up mode triggered by player contact
+ const elevator0 = level.elevator(700, 1865, 200, 490, 1400, 0.011, { up: 0.01, down: 0.7 })
+ const elevator1 = level.elevator(3995, 2335, 210, 150, 1700, 0.011, { up: 0.01, down: 0.7 })
+
+ level.custom = () => {
+ drip1.draw();
+ drip2.draw();
+ drip3.draw();
+ if (button0.isUp) {
+ button0.query();
+ if (!button0.isUp) { //summon second set of mobs
+ //1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
+ spawn.randomMob(918, 2695, 0.1);
+ spawn.randomMob(1818, 2719, 0.2);
+ spawn.randomMob(2530, 2460, 0.2);
+ spawn.randomMob(3109, 2665, 0.3);
+ spawn.randomMob(3909, 2191, 0.3);
+ spawn.randomMob(4705, 2711, 0.4);
+ spawn.randomMob(5800, 2796, 0.5);
+ spawn.randomMob(7287, 2757, 0.6);
+ spawn.randomMob(5759, 2691, 0.9);
+ spawn.randomMob(5675, 2225, 0.8);
+ spawn.randomMob(7450, 2775, 0.8);
+
+ spawn.randomGroup(6600, 2400, 0.1);
+ if (simulation.difficulty > 1) spawn.randomLevelBoss(6076, 2341);
+ }
+ }
+ button0.draw();
+ if (button1.isUp) button1.query();
+ button1.draw();
+ if (button2.isUp) button2.query();
+ button2.draw();
+ ctx.fillStyle = "hsl(175, 15%, 76%)"
+ ctx.fillRect(7625, 2625, 400, 300)
+ ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
+ ctx.fillRect(6250, 1875, 700, 875)
+ ctx.fillRect(900, 1200, 600, 1725) //900, 1350, 600, 1600);
+ ctx.fillRect(3000, 1200, 1000, 1750);
+ ctx.fillRect(2200, 625, 400, 2050);
+
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ elevator0.moveOnTouch()
+ elevator1.moveOnTouch()
+ rotor1.rotate();
+ rotor2.rotate();
+
+ ctx.fillStyle = "#233"
+ ctx.beginPath();
+ ctx.arc(balance1.center.x, balance1.center.y, 9, 0, 2 * Math.PI);
+ ctx.moveTo(balance2.center.x, balance2.center.y)
+ ctx.arc(balance2.center.x, balance2.center.y, 9, 0, 2 * Math.PI);
+ ctx.moveTo(balance3.center.x, balance3.center.y)
+ ctx.arc(balance3.center.x, balance3.center.y, 9, 0, 2 * Math.PI);
+ ctx.moveTo(balance5.center.x, balance5.center.y)
+ ctx.arc(balance5.center.x, balance5.center.y, 9, 0, 2 * Math.PI);
+ ctx.moveTo(rotor1.center.x, rotor1.center.y)
+ ctx.arc(rotor1.center.x, rotor1.center.y, 9, 0, 2 * Math.PI);
+ ctx.moveTo(rotor2.center.x, rotor2.center.y)
+ ctx.arc(rotor2.center.x, rotor2.center.y, 9, 0, 2 * Math.PI);
+ ctx.fill();
+ hazard.query();
+ const drainRate = Math.max(1, 4 - hazard.min.y / 800)
+ hazard.level(
+ (button2.isUp || hazard.height < 1150) &&
+ (button0.isUp || hazard.height < 350) &&
+ button1.isUp
+ , drainRate) //true = hold, false = lower
+ exitDoor.isClosing = hazard.min.y < 2900
+ exitDoor.openClose();
+ exitDoor.draw();
+ };
+
+ level.setPosToSpawn(0, -50); //normal spawn
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
+ level.exit.x = 7800;
+ level.exit.y = 2865;
+ const exitDoor = level.door(7637, 2680, 25, 225, 195, 5)
+
+ level.defaultZoom = 1800
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "hsl(138, 3%, 74%)";
+ color.map = "#3d4240"
+ powerUps.spawnStartingPowerUps(3475, 1775);
+ spawn.debris(4575, 2550, 1600, 6); //16 debris per level
+ spawn.debris(750, 2550, 2250, 6); //16 debris per level
+
+ spawn.mapRect(-500, -600, 200, 800); //left entrance wall
+ spawn.mapRect(-400, -600, 3550, 200); //ceiling
+ spawn.mapRect(-400, 0, 1400, 600);
+
+ spawn.mapRect(575, 475, 250, 250);
+ Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
+ spawn.mapRect(4075, 75, 250, 250);
+ Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
+ spawn.mapRect(4259, 1559, 282.5, 282.5);
+ Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
+
+ spawn.mapRect(3140, -600, 200, 800); //right down tube wall
+ spawn.mapRect(3150, 0, 1200, 200); //tube right exit ceiling
+ spawn.mapVertex(2400, 500, "-200 -100 -100 -200 100 -200 200 -100 200 200 -200 200");
+ spawn.mapVertex(2400, 1200, "-200 -200 200 -200 200 100 100 200 -100 200 -200 100");
+ spawn.mapVertex(1200, 2150, "-300 -300 300 -300 300 200 200 300 -200 300 -300 200");
+ spawn.mapVertex(1200, 1100, "-300 -200 -200 -300 200 -300 300 -200 300 300 -300 300");
+ spawn.mapVertex(3500, 950, "-500 -450 -400 -550 400 -550 500 -450 500 450 400 550 -400 550 -500 450");
+ spawn.mapVertex(3500, 1990, "-300 -40 -230 -110 230 -110 300 -40 300 40 230 110 -230 110 -300 40");
+ // spawn.mapVertex(2400, 1940, "-200 -40 -150 -90 150 -90 200 -40 200 40 150 90 -150 90 -200 40");
+ spawn.mapRect(2200, 1850, 400, 200);
+ spawn.bodyRect(3825, 2240, 150, 75, 0.5);
+
+ spawn.mapVertex(3500, 2452, "-500 -135 500 -135 500 35 400 135 -400 135 -500 35");
+ spawn.mapVertex(1200, 2875, "-400 0 -300 -100 300 -100 400 0");
+ spawn.mapVertex(1317, 275, "-500 0 -300 -200 300 -200 550 50 550 500 -500 500");
+ spawn.mapVertex(1300, -357, "-300 0 -400 -100 400 -100 300 0");
+ spawn.bodyRect(1550, -308, 50, 208, 0.5);
+ spawn.bodyRect(2000, 965, 525, 25, 0.5);
+ spawn.mapVertex(2400, 2850, "-350 -50 -300 -100 300 -100 350 -50 350 300 -350 300");
+ spawn.mapVertex(6600, 1925, "-350 0 -450 -100 450 -100 350 0");
+ spawn.mapVertex(6600, 2875, "-400 -50 -350 -100 350 -100 400 -50 400 300 -400 300");
+
+ spawn.bodyRect(2375, 300, 100, 100, 0.6);
+ spawn.bodyRect(1025, 1775, 100, 75, 0.6);
+ spawn.bodyRect(1250, 1825, 50, 25, 0.6);
+ spawn.bodyRect(3700, 275, 125, 125, 0.6);
+ spawn.bodyRect(5875, 2725, 200, 200, 0.6);
+ spawn.bodyRect(6900, 2590, 50, 50, 0.6);
+ spawn.mapRect(4200, 2325, 250, 625);
+ spawn.mapRect(-500, 50, 1200, 3050);
+ spawn.mapRect(-500, 2900, 9600, 775);
+
+ spawn.mapRect(4400, 0, 4700, 1900);
+ spawn.mapRect(4200, 0, 200, 1700);
+ // spawn.mapRect(6250, 2675, 700, 325);
+ // spawn.mapRect(6250, 1875, 700, 150);
+
+ //exit room
+ spawn.mapRect(8000, 1775, 1100, 1375);
+ spawn.mapRect(7625, 1825, 450, 825);
+ spawn.mapRect(7625, 2625, 50, 75);
+ spawn.mapRect(7625, 2890, 400, 25);
+ spawn.mapRect(7800, 2880, 100, 25);
+
+ spawn.randomMob(2450, 250, 0.2);
+ spawn.randomMob(3250, 325, 0.2);
+ spawn.randomMob(3625, 350, 0.3);
+ spawn.randomMob(1750, -25, 0.4);
+ spawn.randomMob(1300, 1750, 0.5);
+ spawn.randomMob(2350, 1725, 0.6);
+ spawn.randomMob(3350, 1775, 0.7);
+ spawn.randomMob(1025, 750, 0.8);
+ spawn.randomMob(2400, 1775, 0.8);
+ spawn.randomMob(1250, 1725, 0.8);
+ spawn.randomMob(775, 1775, 0.9);
+ powerUps.addResearchToLevel() //needs to run after mobs are spawned
+ spawn.secondaryBossChance(1822, 1336)
+
+ if (simulation.isHorizontalFlipped) { //flip the map horizontally
+ level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
+ rotor1 = level.rotor(-5600, 2390, 850, 50, 0.001, 0, 0.01, 0, 0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) {
+ rotor2 = level.rotor(-2175, 1900, 650, 50, 0.001, 0, 0.01, 0, 0.0007)
+
+ balance1 = level.rotor(-800 - 25, -395, 25, 390, 0.001) //entrance
+ balance2 = level.rotor(-2605 - 390, 500, 390, 25, 0.001) //falling
+ balance3 = level.rotor(-2608 - 584, 1950, 584, 25, 0.001) //falling
+ balance5 = level.rotor(-2605 - 390, 1020, 390, 25, 0.001) //falling
+
+ button1.min.x = -button1.min.x - 126
+ button1.max.x = -button1.max.x + 126
+ button0.min.x = -button0.min.x - 126
+ button0.max.x = -button0.max.x + 126
+ button2.min.x = -button2.min.x - 126
+ button2.max.x = -button2.max.x + 126 // flip the button horizontally
+ drip1.x *= -1
+ drip2.x *= -1
+ drip3.x *= -1
+ elevator0.holdX *= -1
+ elevator1.holdX *= -1
+ // console.log(hazard)
+ hazard.min.x -= 840
+ hazard.max.x -= 840
+
+ level.custom = () => {
+ drip1.draw();
+ drip2.draw();
+ drip3.draw();
+
+ if (button0.isUp) {
+ button0.query();
+ if (!button0.isUp) { //summon second set of mobs
+ //1 boss, 1-2 groups, 11 mobs (all on lower ground level, where the slime is leaving)
+ spawn.randomMob(-7475, 2800, 0.1);
+ spawn.randomMob(-6475, 2500, 0.2);
+ spawn.randomMob(-4575, 2775, 0.3);
+ spawn.randomMob(-7575, 2850, 0.3);
+ spawn.randomMob(-6425, 2575, 0.3);
+ spawn.randomMob(-5750, 2775, 0.4);
+ spawn.randomMob(-4675, 2800, 0.5);
+ spawn.randomMob(-3425, 2800, 0.6);
+ spawn.randomMob(-2475, 2475, 0.7);
+ spawn.randomMob(-3350, 2250, 0.8);
+ spawn.randomMob(-1275, 2725, 0.9);
+ spawn.randomGroup(-6225, 2400, 0.1);
+ if (simulation.difficulty > 1) spawn.randomLevelBoss(-6250, 2350);
+ }
+ }
+ button0.draw();
+ if (button1.isUp) button1.query();
+ button1.draw();
+ if (button2.isUp) button2.query();
+ button2.draw();
+ rotor1.rotate();
+ rotor2.rotate();
+ ctx.fillStyle = "hsl(175, 15%, 76%)"
+ ctx.fillRect(-8025, 2625, 400, 300)
+ ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
+ ctx.fillRect(-6950, 1875, 700, 875)
+ ctx.fillRect(-4000, 1400, 1000, 1550);
+ ctx.fillRect(-2600, 675, 400, 2025);
+ ctx.fillRect(-1500, 1375, 600, 1500);
+
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ // level.customTopLayer = () => {};
+ } else {
+ rotor1 = level.rotor(4700, 2390, 850, 50, 0.001, 0, 0.01, 0, -0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) {
+ rotor2 = level.rotor(1525, 1900, 650, 50, 0.001, 0, 0.01, 0, -0.0007)
+ balance1 = level.rotor(800, -395, 25, 390, 0.001) //entrance
+ balance2 = level.rotor(2605, 500, 390, 25, 0.001) //falling
+ balance3 = level.rotor(2608, 1950, 584, 25, 0.001) //falling
+ balance5 = level.rotor(2605, 1020, 390, 25, 0.001) //falling
+ }
+
},
satellite() {
level.announceMobTypes()
- level.isEndlessFall = true;
+ level.fallMode = "start";
const boost1 = level.boost(5825, 235, 1400)
const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 }
level.custom = () => {
@@ -6594,7 +7488,7 @@ const level = {
},
rooftops() {
level.announceMobTypes()
- level.isEndlessFall = true;
+
// level.fallPosition = { x: 5000, y:-4000}
const elevator = level.elevator(1450, -990, 235, 45, -2000)
const boost1 = level.boost(4950, 0, 1100)
@@ -6603,7 +7497,6 @@ const level = {
boost1.query();
elevator.move();
elevator.drawTrack();
-
ctx.fillStyle = "#d4f4f4"
if (isBackwards) {
ctx.fillRect(-650, -2300, 440, 300)
@@ -6611,7 +7504,6 @@ const level = {
ctx.fillRect(3460, -700, 1090, 800)
}
level.exit.drawAndCheck();
-
level.enter.draw();
};
@@ -6637,6 +7529,9 @@ const level = {
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
+
+
+ // level.fallMode = "start";
let isBackwards = false
if (Math.random() < 0.75) {
//normal direction start in top left
@@ -6780,10 +7675,16 @@ const level = {
}
};
}
+ level.fallMode = "position"; //must set level.fallModeBounds in this mode to prevent player getting stuck left or right
+ if (level.enter.x > level.exit.x) {
+ level.fallModeBounds = { left: level.exit.x, right: level.enter.x } //used with level.fallMode = "position";
+ } else {
+ level.fallModeBounds = { left: level.enter.x, right: level.exit.x } //used with level.fallMode = "position";
+ }
},
aerie() {
level.announceMobTypes()
- level.isEndlessFall = true;
+ level.fallMode = "start";
const boost1 = level.boost(-425, 100, 1400)
const boost2 = level.boost(5350, 275, 2850);
@@ -6831,7 +7732,6 @@ const level = {
ctx.fill()
};
- // simulation.difficulty = 4; //for testing to simulate possible mobs spawns
level.defaultZoom = 2100
simulation.zoomTransition(level.defaultZoom)
@@ -7013,7 +7913,7 @@ const level = {
},
skyscrapers() {
level.announceMobTypes()
- level.isEndlessFall = true;
+ level.fallMode = "start";
const boost1 = level.boost(475, 0, 1300)
const boost2 = level.boost(4450, 0, 1300);
level.custom = () => {
@@ -7152,11 +8052,8 @@ const level = {
},
highrise() {
level.announceMobTypes()
- level.isEndlessFall = true;
- const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, {
- up: 0.01,
- down: 0.2
- }, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
+ level.fallMode = "start";
+ const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, { up: 0.01, down: 0.2 }, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator1.addConstraint();
// const button1 = level.button(-500, -200)
const toggle1 = level.toggle(-300, -200) //(x,y,isOn,isLockOn = true/false)
@@ -7438,7 +8335,7 @@ const level = {
},
warehouse() {
level.announceMobTypes()
- level.isEndlessFall = true;
+ level.fallMode = "start";
level.custom = () => {
ctx.fillStyle = "#444" //light fixtures
ctx.fillRect(-920, -505, 40, 10)
@@ -7946,7 +8843,7 @@ const level = {
},
stronghold() { // player made level by Francois 👑 from discord
- simulation.makeTextLog(`
stronghold by
Francois `);
+ simulation.inGameConsole(`
stronghold by
Francois `);
const boost1 = level.boost(1470, -250, 1080)
const boost2 = level.boost(-370, 0, 800)
@@ -8116,7 +9013,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
basement() { // player made level by Francois 👑 from discord
- simulation.makeTextLog(`
basement by
Francois `);
+ simulation.inGameConsole(`
basement by
Francois `);
let button, door, buttonDoor, buttonPlateformEnd, doorPlateform
let isLevelReversed = Math.random();
if (isLevelReversed < 0.7) {
@@ -8400,7 +9297,7 @@ const level = {
powerUps.chooseRandomPowerUp(3100, 1630);
},
// detours() { //by Francois from discord
- // simulation.makeTextLog(`
detours by
Francois `);
+ // simulation.inGameConsole(`
detours by
Francois `);
// level.setPosToSpawn(0, 0); //lower start
// level.exit.y = 150;
// spawn.mapRect(level.enter.x, 45, 100, 20);
@@ -8713,7 +9610,7 @@ const level = {
// }
// },
house() { //by Francois from discord
- simulation.makeTextLog(`
house by
Francois `);
+ simulation.inGameConsole(`
house by
Francois `);
const rotor = level.rotor(4251, -325, 120, 20, 200, 0, 0.01, 0, -0.0001);
const hazard = level.hazard(4350, -1000, 300, 110);
const doorBedroom = level.door(1152, -1150, 25, 250, 250);
@@ -9189,7 +10086,7 @@ const level = {
}
},
perplex() { //by Oranger from discord
- simulation.makeTextLog(`
perplex by
Oranger `);
+ simulation.inGameConsole(`
perplex by
Oranger `);
document.body.style.backgroundColor = "#dcdcde";
level.setPosToSpawn(-600, 400);
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
@@ -9375,7 +10272,7 @@ const level = {
spawn.secondaryBossChance(7725, 2275)
},
coliseum() {
- simulation.makeTextLog(`
coliseum by
iNoobBoi `);
+ simulation.inGameConsole(`
coliseum by
iNoobBoi `);
level.custom = () => {
level.exit.drawAndCheck();
@@ -9526,7 +10423,7 @@ const level = {
spawn.secondaryBossChance(6600, 600)
},
crossfire() {
- simulation.makeTextLog(`
crossfire by
iNoobBoi `);
+ simulation.inGameConsole(`
crossfire by
iNoobBoi `);
//*1.5
//Level Setup
@@ -9691,9 +10588,9 @@ const level = {
spawn.debris(9300, -900, 400, debrisCount);
},
vats() { // Made by Dablux#6610 on Discord
- simulation.makeTextLog(`
vats by
Dablux `);
-
- simulation.zoomScale = 1500;
+ simulation.inGameConsole(`
vats by
Dablux `);
+ level.defaultZoom = 1500
+ simulation.zoomTransition(level.defaultZoom)
level.setPosToSpawn(4400, -1060)
spawn.mapRect(level.enter.x, level.enter.y + 30, 100, 20)
level.exit.x = 3900;
@@ -10133,7 +11030,7 @@ const level = {
}
},
ngon() { //make by Oranger
- simulation.makeTextLog(`
"ngon" by
Oranger `);
+ simulation.inGameConsole(`
"ngon" by
Oranger `);
document.body.style.backgroundColor = "#dcdcde";
let needGravity = [];
@@ -10538,7 +11435,7 @@ const level = {
}
},
tunnel() { // by Scarlettt
- simulation.makeTextLog(`
tunnel by
Scarlettt `);
+ simulation.inGameConsole(`
tunnel by
Scarlettt `);
level.custom = () => {
level.exit.drawAndCheck();
@@ -10855,8 +11752,8 @@ const level = {
let isButtonTapped = false;
// if (b.inventory.length < 5) powerUps.spawn(3800, -3200, "gun");
- powerUps.spawn(3900, -3100, "heal", true, null, 30);
- powerUps.spawn(3900, -3100, "heal", true, null, 30);
+ powerUps.spawn(3900, -3100, "heal", true, 30);
+ powerUps.spawn(3900, -3100, "heal", true, 30);
// path to the third room
spawn.mapRect(2000, -1850, 50, 200);
@@ -11012,7 +11909,7 @@ const level = {
}
},
run() {
- simulation.makeTextLog(`
run by
iNoobBoi `);
+ simulation.inGameConsole(`
run by
iNoobBoi `);
addPartToMap = (len) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
map[len].collisionFilter.category = cat.map;
@@ -11023,16 +11920,6 @@ const level = {
anotherBoss = (x, y) => {
if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
- tech.isScaleMobsWithDuplication = true
- spawn.randomLevelBoss(x, y, ["historyBoss"]);
- tech.isScaleMobsWithDuplication = false
- } else if (tech.isResearchBoss) {
- if (powerUps.research.count > 2) {
- powerUps.research.changeRerolls(-3)
- simulation.makeTextLog(`
m .
research -= 3
${powerUps.research.count}`)
- } else {
- tech.addJunkTechToPool(0.49)
- }
spawn.randomLevelBoss(x, y, ["historyBoss"]);
}
}
@@ -11071,14 +11958,14 @@ const level = {
addPartToMap(map.length - 1);
simulation.draw.setPaths();
- simulation.makeTextLog(`
UNKNOWN : "Well done. Now climb."`, 600);
- simulation.makeTextLog(`
UNKNOWN : "I left a gift at the top."`, 600);
+ simulation.inGameConsole(`
UNKNOWN : "Well done. Now climb."`, 600);
+ simulation.inGameConsole(`
UNKNOWN : "I left a gift at the top."`, 600);
climbTime = true;
} //toggles on a mapRect when player passes a certain area
if (m.pos.x > 9000 && endTime === false) {
- simulation.makeTextLog("
UNKNOWN : \"Good luck. I hope you get out of here.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"Good luck. I hope you get out of here.\"", 600);
endTime = true;
}
@@ -11259,11 +12146,11 @@ const level = {
//Mob Spawning
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"You cannot kill them.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"You cannot kill them.\"", 600);
}, 2000);
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"But I have slowed them down for you.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"But I have slowed them down for you.\"", 600);
}, 6000);
@@ -11279,7 +12166,7 @@ const level = {
spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](6600, -1000);
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"Run.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"Run.\"", 600);
}, 10000);
} //some of the mobs
if (simulation.difficulty > 20) {
@@ -11289,7 +12176,7 @@ const level = {
spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](7400, -800);
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"RUN!\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"RUN!\"", 600);
}, 11000);
} //most of the mobs
if (simulation.difficulty > 30) {
@@ -11299,7 +12186,7 @@ const level = {
spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](7500, -300);
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"GET OUT OF HERE.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"GET OUT OF HERE.\"", 600);
}, 12000);
} //all the mobs
@@ -11308,7 +12195,7 @@ const level = {
spawn.randomLevelBoss(-2200, -700, ["powerUpBossBaby", "blockBoss", "revolutionBoss"]);
setTimeout(() => {
- simulation.makeTextLog("
UNKNOWN : \"They are coming for you.\"", 600);
+ simulation.inGameConsole("
UNKNOWN : \"They are coming for you.\"", 600);
}, 14000);
}
anotherBoss(-1800, -700); //custom second boss spawn
@@ -11364,7 +12251,7 @@ const level = {
}
},
islands() {
- simulation.makeTextLog(`
islands by
Richard0820 `);
+ simulation.inGameConsole(`
islands by
Richard0820 `);
const boost1 = level.boost(58500, -18264, 1300);
let portal2, portal3;
@@ -11707,10 +12594,9 @@ const level = {
simulation.fallHeight = -15000;
powerUps.addResearchToLevel();
powerUps.spawn(3000, -230, "heal");
- // level.difficultyIncrease(60)
},
temple() {
- simulation.makeTextLog(`
temple by
Scar1337 `);
+ simulation.inGameConsole(`
temple by
Scar1337 `);
const V = Vector;
const Equation = (function () {
@@ -11798,12 +12684,6 @@ const level = {
return bound.has(player.bounds.min) || bound.has(player.bounds.max);
}
- function addWIMP(x, y) {
- spawn.WIMP(x, y);
- const me = mob[mob.length - 1];
- me.isWIMP = true;
- }
-
function relocateWIMPs(x, y) {
for (const i of mob) {
if (i.isWIMP) {
@@ -11836,9 +12716,9 @@ const level = {
// applying forces to player doesn't seem to work inside this method, not sure why
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));
+ if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, 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.damageReduction = 0.25
me.do = function () {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) {
@@ -11939,9 +12819,9 @@ const level = {
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));
+ if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, 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.damageReduction = 0.25
me.do = function () {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 2) {
@@ -11975,7 +12855,6 @@ const level = {
}
}
};
-
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];
@@ -11987,7 +12866,7 @@ const level = {
me.leaveBody = false;
me.timeLeft = 1200;
me.isObstacle = true;
- me.damageReduction = isDark ? 0.5 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) : 0;
+ me.damageReduction = isDark ? 0.5 : 0
if (!isDark) {
me.isBadTarget = true;
me.attackCycle = 0;
@@ -12115,7 +12994,7 @@ const level = {
this.damageReduction = 0;
}
};
- me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
+ me.damageReduction = 0.25
me.rings = [{
colour: "#65f",
radius: 300,
@@ -12270,7 +13149,7 @@ const level = {
if (Math.floor(cycle / spawnDelay) >= spawnCycles - 1) {
this.trapCycle = 0;
this.isInvulnerable = false;
- this.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
+ this.damageReduction = 0.25
}
}
}
@@ -12342,10 +13221,11 @@ const level = {
Promise.resolve().then(() => {
// Clear all WIMPS and their research
for (let i = 0; i < mob.length; i++) {
- while (mob[i] && !mob[i].isMACHO) {
- mob[i].replace(i);
+ if (mob[i] && !mob[i].isDarkMatter) {
+ mob[i].isWIMP = true;
}
}
+ relocateWIMPs(0, -10030);
for (let i = 0; i < powerUp.length; i++) {
while (powerUp[i] && powerUp[i].name === "research") {
Matter.Composite.remove(engine.world, powerUp[i]);
@@ -12429,11 +13309,11 @@ const level = {
// Trolled
const hasCPT = tech.isRewindAvoidDeath;
tech.isRewindAvoidDeath = false;
- const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + 0.001;
+ const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.2 : 1) + 0.001;
if (m.energy > DRAIN && !tech.isEnergyHealth) {
m.energy -= DRAIN;
}
- m.damage(0.00015 * (tech.isRadioactiveResistance ? 0.25 : 1));
+ m.damage(0.00015 * (tech.isRadioactiveResistance ? 0.2 : 1));
if (tech.isEnergyHealth) {
const previousEnergy = m.energy;
m.regenEnergy();
@@ -12561,7 +13441,7 @@ const level = {
return this.rings.length;
},
get cap() {
- return (this.ringNumber + 1) * 90 + 240;
+ return this.ringNumber * 90 + 180;
},
get capped() {
return templePlayer.room2.spawnInitiatorCycles > this.cap;
@@ -12596,8 +13476,8 @@ const level = {
y: -300
}), simulation.cycle - 5);
}
- if (!this.capped && cycle >= this.cap - 200) {
- const multCoeff = (cycle - this.cap + 200) * 0.4
+ if (!this.capped && cycle >= this.cap - 180) {
+ const multCoeff = (cycle - this.cap + 180) * 0.4
ctx.translate((Math.random() - 0.5) * multCoeff, (Math.random() - 0.5) * multCoeff);
}
ctx.shadowBlur = 20;
@@ -12607,12 +13487,12 @@ const level = {
DrawTools.arcOut(this.pos.x, this.pos.y, 100, 0, Math.PI * 2);
if (templePlayer.room2.cycles <= 100) {
for (let i = 0; i < this.ringNumber; i++) {
- if (cycle < i * 90 + 90) break;
+ if (cycle < i * 90) break;
const ring = this.rings[i];
ctx.shadowColor = `rgb(${ring.colour.join(",")})`;
- const opacity = this.capped ? 1 - 0.01 * templePlayer.room2.cycles : (cycle / 180 - i / 2 - 0.5);
+ const opacity = this.capped ? 1 - 0.01 * templePlayer.room2.cycles : (cycle / 180 - i / 2);
ctx.strokeStyle = `rgba(${ring.colour.join(",")}, ${Math.min(opacity, 1)})`;
- const radius = (this.capped ? 1 + 0.07 * templePlayer.room2.cycles : Math.sin(Math.min(cycle - i * 90 - 90, 45) / 90 * Math.PI)) * ring.radius;
+ const radius = (this.capped ? 1 + 0.07 * templePlayer.room2.cycles : Math.sin(Math.min(cycle - i * 90, 45) / 90 * Math.PI)) * ring.radius;
DrawTools.arcOut(this.pos.x, this.pos.y, radius, 0, Math.PI * 2);
}
}
@@ -12760,67 +13640,50 @@ const level = {
room0() {
if (templePlayer.startAnim <= 0) return;
templePlayer.startAnim++;
- if (templePlayer.startAnim == 120) {
+ if (templePlayer.startAnim == 60) {
makeLore("Not so fast.");
}
- if (templePlayer.startAnim < 360) {
+ if (templePlayer.startAnim < 180) {
trapPlayer(1000, templePlayer.initialTrapY);
} else {
level.exit.x = 4500;
level.exit.y = -2030;
+ relocateWIMPs(level.exit.x, level.exit.y);
relocateTo(50, -2050);
simulation.fallHeight = -1000;
- // simulation.setZoom(1800);
- simulation.zoomTransition(1800)
+ level.defaultZoom = 1800
+ simulation.zoomTransition(level.defaultZoom)
templePlayer.startAnim = -1;
templePlayer.drawExit = false;
}
},
room1() {
- if (templePlayer.room1ToRoom2Anim <= 0) return;
- if (templePlayer.room1ToRoom2Anim === 1) {
+ const frame = templePlayer.room1ToRoom2Anim;
+ if (frame <= 0) return;
+ if (frame === 1) {
level.exit.x = -50;
level.exit.y = -10030;
makeLore("Pathetic.");
}
- if (templePlayer.room1ToRoom2Anim === 121) {
- makeLore("You will never succeed.");
- }
- if (templePlayer.room1ToRoom2Anim >= 360 && templePlayer.room1ToRoom2Anim <= 720) {
- const factor = 200 - 200 * Math.cos((templePlayer.room1ToRoom2Anim / 120 - 3) * Math.PI);
+ if (frame >= 1 && frame <= 360) {
+ const factor = 100 - 100 * Math.cos((frame / 90) * Math.PI);
ctx.translate(factor, factor);
Promise.resolve().then(() => {
ctx.save();
ctx.globalCompositeOperation = "color-burn";
- ctx.fillStyle = DrawTools.randomColours;
+ ctx.fillStyle = DrawTools.randomColours((frame) * (360 - frame) / 32400);
DrawTools.updateRandomColours(5);
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
});
}
- if (templePlayer.room1ToRoom2Anim === 720) {
+ if (frame === 180) {
makeLore("You are trying too hard.");
relocateTo(0, -7050);
simulation.fallHeight = -6000;
templePlayer.stage = 2;
- }
- if (templePlayer.room1ToRoom2Anim === 960) {
- makeLore("I have mastered the understandings of the universe.");
- }
- if (templePlayer.room1ToRoom2Anim === 1200) {
- // Congrats, you discovered the actual words by looking at the source code. Are you happy now?
- const x = (
- ["a speck of dust", "an insignificant hindrance", "a tiny obstacle"]
- )[Math.floor(Math.random() * 3)].split("");
- for (let i = 0; i < x.length / 1.6; i++) {
- const randomIndex = Math.floor(Math.random() * x.length);
- if (x[randomIndex] !== " ") {
- x[randomIndex] = String.fromCharCode(Math.floor(Math.random() * 50) + 192);
- }
- };
- makeLore(`You are no more than ${x.join("")} to me.`);
- relocateWIMPs(0, -10030);
+ relocateWIMPs(level.exit.x, level.exit.y - 3000);
}
templePlayer.room1ToRoom2Anim++;
},
@@ -12831,23 +13694,10 @@ const level = {
level.exit.y = -13130;
makeLore("Do not try me.");
}
- if (templePlayer.room2ToRoom3Anim === 180) {
- makeLore("I have absolute power over you.");
- canvas.style.filter = "hue-rotate(90deg)";
- }
- if (templePlayer.room2ToRoom3Anim === 360) {
- makeLore("You will not succeed...");
- canvas.style.filter = "invert(0.2)";
+ if (templePlayer.room2ToRoom3Anim >= 1 && templePlayer.room2ToRoom3Anim <= 180) {
+ canvas.style.filter = `sepia(${templePlayer.room2ToRoom3Anim / 180}) invert(${templePlayer.room2ToRoom3Anim / 180})`;
}
- if (templePlayer.room2ToRoom3Anim === 420) {
- makeLore("
... ");
- canvas.style.filter = "invert(0.4)";
- }
- if (templePlayer.room2ToRoom3Anim > 480 && templePlayer.room2ToRoom3Anim <= 660) {
- canvas.style.filter = `sepia(${(templePlayer.room2ToRoom3Anim - 480) / 180}) invert(${0.5 + (templePlayer.room2ToRoom3Anim - 480) / 180})`;
- }
- if (templePlayer.room2ToRoom3Anim === 780) {
- makeLore("Do not interfere with me.");
+ if (templePlayer.room2ToRoom3Anim === 180) {
templePlayer.stage = 3;
relocateTo(50, -13150);
simulation.fallHeight = -10000;
@@ -12859,43 +13709,28 @@ const level = {
mob[i].replace(i);
}
}
+ templePlayer.drawExit = true;
+ for (let i = 0; i < 5 * tech.wimpCount; i++) {
+ powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false);
+ }
+ canvas.style.filter = "";
}
- if (templePlayer.room2ToRoom3Anim > 780 && templePlayer.room2ToRoom3Anim <= 960) {
- canvas.style.filter = `sepia(${(960 - templePlayer.room2ToRoom3Anim) / 180}) invert(${(960 - templePlayer.room2ToRoom3Anim) / 180})`;
+ if (templePlayer.room2ToRoom3Anim > 180 && templePlayer.room2ToRoom3Anim <= 360) {
+ canvas.style.filter = `sepia(${(360 - templePlayer.room2ToRoom3Anim) / 180}) invert(${(360 - templePlayer.room2ToRoom3Anim) / 180})`;
}
templePlayer.room2ToRoom3Anim++;
},
room3() {
if (templePlayer.room3ToEndAnim <= 0) return;
if (templePlayer.room3ToEndAnim === 1) {
- makeLore("No.");
- }
- if (templePlayer.room3ToEndAnim === 120) {
- makeLore("This cannot be.");
- }
- if (templePlayer.room3ToEndAnim === 240) {
- makeLore("Has my power failed me?");
- }
- if (templePlayer.room3ToEndAnim === 360) {
- makeLore("Was it worth it, destroying this place?");
- }
- if (templePlayer.room3ToEndAnim === 600) {
- makeLore("No one is greater than me.");
- }
- const text = "noone-";
- for (let i = 0; i < 12; i++) {
- if (templePlayer.room3ToEndAnim === 720 + i * 20) {
- name = name.slice(0, -1);
- simulation.makeTextLog(`
${name}: ${text[i % 6]}`);
- canvas.style.filter = `brightness(${1 - i / 22})`;
- }
- }
- if (templePlayer.room3ToEndAnim === 1060) {
- templePlayer.drawExit = true;
- for (let i = 0; i < 5 * tech.wimpCount; i++) {
- powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false);
- }
- canvas.style.filter = "";
+ const x = "Nooooooooooo".split("");
+ for (let i = 0; i < x.length / 1.6; i++) {
+ const randomIndex = Math.floor(Math.random() * x.length);
+ if (x[randomIndex] !== " ") {
+ x[randomIndex] = String.fromCharCode(Math.floor(Math.random() * 50) + 192);
+ }
+ };
+ makeLore(x.join(""));
}
templePlayer.room3ToEndAnim++;
},
@@ -12904,11 +13739,11 @@ const level = {
Promise.resolve().then(() => {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
- ctx.fillStyle = `rgba(0, 0, 0, ${(simulation.cycle - templePlayer.clearedCycle) / 300})`;
+ ctx.fillStyle = `rgba(0, 0, 0, ${(simulation.cycle - templePlayer.clearedCycle) / 30})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
});
- if (simulation.cycle - templePlayer.clearedCycle > 420) level.nextLevel();
+ if (simulation.cycle - templePlayer.clearedCycle > 30) level.nextLevel();
}
};
const LogicHandler = {
@@ -12923,7 +13758,7 @@ const level = {
if (!isInBounds) {
m.damage(0.1 * simulation.difficultyMode);
trapPlayer(level.enter.x, level.enter.y);
- simulation.makeTextLog("
" + name + " : You thought I could let you get away with that?");
+ simulation.inGameConsole("
" + name + " : You thought I could let you get away with that?");
}
},
room0() {
@@ -13037,7 +13872,7 @@ const level = {
if (simulation.cycle % 4 === 0) {
let newMobPositions = [];
for (const i of mob) {
- if (!(i.isMACHO || i.isWIMP || i.isObstacle)) newMobPositions.push({
+ if (!(i.isDarkMatter || i.isWIMP || i.isObstacle)) newMobPositions.push({
x: i.position.x,
y: i.position.y
});
@@ -13060,7 +13895,7 @@ const level = {
const roomConditions = [
isInBound(firstRoomBounds) && templePlayer.room1.cycles < 2400,
isInBound(secondRoomBounds) && templePlayer.room2.cycles > 0 && templePlayer.room2.cycles < 2160,
- isInBound(thirdRoomBounds) && templePlayer.room2ToRoom3Anim < 1320
+ isInBound(thirdRoomBounds) && templePlayer.room2ToRoom3Anim < 540
];
Promise.resolve(roomConditions).then(roomConditions => {
// First Room
@@ -13090,7 +13925,7 @@ const level = {
ctx.fillStyle = "#0004";
ctx.fillRect(canvas.width2 - 288, 50, 576, 20);
ctx.fillStyle = "#000";
- ctx.fillRect(canvas.width2 - 288, 50, 1.6 * (1320 - templePlayer.room2ToRoom3Anim), 20);
+ ctx.fillRect(canvas.width2 - 288, 50, 1.6 * (540 - templePlayer.room2ToRoom3Anim), 20);
ctx.restore();
}
});
@@ -13142,7 +13977,7 @@ const level = {
}
},
room3() {
- if (templePlayer.room2ToRoom3Anim === 1320) {
+ if (templePlayer.room2ToRoom3Anim === 540) {
thirdRoomBoss(1800, -13700);
for (let i = 0; i < 3; i++) {
powerUps.spawn(m.spawnPos.x, m.spawnPos.y, "heal");
@@ -13151,8 +13986,8 @@ const level = {
}
};
const DrawTools = {
- get randomColours() {
- return `rgb(${this._randomColours.join(",")})`
+ randomColours(alpha = 1) {
+ return `rgba(${this._randomColours.join(",")},${alpha})`
},
_randomColours: [Math.random() * 255, Math.random() * 255, Math.random() * 255],
updateRandomColours(x = 0.8) {
@@ -13307,7 +14142,7 @@ const level = {
level.setPosToSpawn(x, y);
trapPlayer(x, y);
for (let i = 0; i < mob.length; i++) {
- if (mob[i].isMACHO) {
+ if (mob[i].isDarkMatter) {
setPos(mob[i], {
x,
y
@@ -13329,7 +14164,7 @@ const level = {
setPos(a, b);
freeze(a);
};
- const makeLore = (x, t) => simulation.makeTextLog(`
${name}: ${x} `, t);
+ const makeLore = (x, t) => simulation.inGameConsole(`
${name}: ${x} `, t);
level.custom = () => {
// All the logic gets handled here. How nice!
for (const i in LogicHandler) {
@@ -13358,7 +14193,7 @@ const level = {
};
},
dripp() {
- simulation.makeTextLog(`
dripp by
M. B. `);
+ simulation.inGameConsole(`
dripp by
M. B. `);
const door = level.door(780, -350, 15, 400, 265);
const buttonDoor = level.button(420, -10);
@@ -13553,7 +14388,7 @@ const level = {
},
biohazard() {
// MAP BY INOOBBOI AND THESHWARMA
- simulation.makeTextLog(`
biohazard by
INOOBBOI and
THESHWARMA `);
+ simulation.inGameConsole(`
biohazard by
INOOBBOI and
THESHWARMA `);
// set here for the cutscene later
level.setPosToSpawn(-2800, -150)
@@ -14016,18 +14851,6 @@ const level = {
const anotherBoss = (x, y) => {
if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
- tech.isScaleMobsWithDuplication = true
- spawn.historyBoss(x, y)
- tech.isScaleMobsWithDuplication = false
- } else if (tech.isResearchBoss) {
- if (powerUps.research.count > 2) {
- powerUps.research.changeRerolls(-3)
- simulation.makeTextLog(
- `
m .
research -= 3
${powerUps.research.count}`
- )
- } else {
- tech.addJunkTechToPool(0.49)
- }
spawn.historyBoss(x, y)
}
}
@@ -14400,7 +15223,7 @@ const level = {
me.deadOrbs = []
me.energy = 1
// this boss has no orbitals, because it's not meant to ever attack on its own
- me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.25
// has a shield and sustains that shield
spawn.shield(me, x, y, Infinity)
me.fireFreq = 30
@@ -14712,7 +15535,7 @@ const level = {
anotherBoss(0, 0) //will only spawn historyBoss if there is an additional boss
},
stereoMadness() {
- simulation.makeTextLog(`
stereoMadness by
Richard0820 `);
+ simulation.inGameConsole(`
stereoMadness by
Richard0820 `);
let totalCoin = 0;
const hunter = function (x, y, radius = 30) { //doesn't stop chasing until past 105000
mobs.spawn(x, y, 6, radius, "black");
@@ -14726,7 +15549,7 @@ const level = {
me.memory = Infinity;
me.seeAtDistance2 = Infinity;
Matter.Body.setDensity(me, 1)
- simulation.makeTextLog(`
Ω: Intruder Detected `);
+ simulation.inGameConsole(`
Ω: Intruder Detected `);
me.boost = 10;
me.do = function () {
if (me.boost == 1 && m.fieldMode == 3 || m.fieldMode == 9 && me.boost == 1) {
@@ -14763,7 +15586,7 @@ const level = {
me.onDeath = function () {
totalCoin++;
};
- me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.35
me.do = function () {
ctx.save()
ctx.translate(this.position.x, this.position.y)
@@ -14840,9 +15663,6 @@ const level = {
me.collisionFilter.mask = cat.player | cat.mob | cat.bullet;
}, 1000);
}
- me.onDeath = function () {
- tech.addJunkTechToPool(0.1)
- }
Composite.add(engine.world, me.constraint);
}
@@ -14912,7 +15732,7 @@ const level = {
innerBar.style.backgroundColor = m.eyeFillColor;
}
if (m.pos.x > 25360 && textlogOne == 0) {
- simulation.makeTextLog(`
A stong force pushes you forward...
`)
+ simulation.inGameConsole(`
A stong force pushes you forward...
`)
textlogOne++;
}
if (m.pos.x < -3000) {
@@ -14922,12 +15742,12 @@ const level = {
});
if (textlogTwo == 0)
- simulation.makeTextLog(`
A strong force pushes you away...
`);
+ simulation.inGameConsole(`
A strong force pushes you away...
`);
textlogTwo++;
}
if (m.pos.y > 1055) {
Matter.Body.setPosition(player, { x: 0, y: -150 });
- simulation.makeTextLog(`
There is nowhere to run...
`);
+ simulation.inGameConsole(`
There is nowhere to run...
`);
m.damage(0.1 * simulation.difficultyMode);
}
if (m.alive == false && barThere == true) {
@@ -15529,7 +16349,7 @@ const level = {
}
document.body.style.transitionDuration = "0ms";
document.body.style.backgroundColor = "#696969";
- simulation.makeTextLog(`
You have earned: ` + Math.min(3, totalCoin) + ` tech
`)
+ simulation.inGameConsole(`
You have earned: ` + Math.min(3, totalCoin) + ` tech
`)
if (barThere == true) { //only runs once
document.body.removeChild(bar);
for (let i = 0, len = Math.min(3, totalCoin); i < len; i++) powerUps.directSpawn(player.position.x, player.position.y, "tech");
@@ -16295,7 +17115,7 @@ const level = {
hunter(0, -1000)
},
yingYang() {
- simulation.makeTextLog(`
yingYang by
Richard0820 `);
+ simulation.inGameConsole(`
yingYang by
Richard0820 `);
let destroyed = false;
const lock = level.door(425, -1400, 50, 300, 300);
@@ -16647,7 +17467,7 @@ const level = {
powerUps.addResearchToLevel()
},
staircase() {
- simulation.makeTextLog(`
staircase by
ryanbear `);
+ simulation.inGameConsole(`
staircase by
ryanbear `);
level.custom = () => {
level.exit.drawAndCheck();
@@ -16735,7 +17555,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
fortress() {
- simulation.makeTextLog(`
fortress by
Desboot `);
+ simulation.inGameConsole(`
fortress by
Desboot `);
const boost1 = level.boost(3600, -250, 1000)
const boost2 = level.boost(60, -604, 1000)
const boost3 = level.boost(2160, -1260, 1000)
@@ -16876,7 +17696,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
commandeer() {
- simulation.makeTextLog(`
commandeer by
Desboot `);
+ simulation.inGameConsole(`
commandeer by
Desboot `);
let waterFallWidth = 400
let waterFallX = 15900
@@ -17479,7 +18299,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
clock() {
- simulation.makeTextLog(`
clock by
Cornbread 2100 `);
+ simulation.inGameConsole(`
clock by
Cornbread 2100 `);
function drawBackgroundGear(x, y, r1, r2, rot, color, speed, numTeeth = 5, toothWidth = 75, linew = 2) {
var vertices = getGearVertices(x, y, r1, r2, numTeeth, simulation.cycle * speed + rot, toothWidth / 100);
@@ -19217,7 +20037,7 @@ const level = {
}
},
buttonbutton() {
- simulation.makeTextLog(`
buttonbutton by
||Destabilized E|| `);
+ simulation.inGameConsole(`
buttonbutton by
||Destabilized E|| `);
const mover = level.mover(1425, -1949, 600, 25); //x,y,width.height,VxGoal,force
let portal
@@ -19324,7 +20144,7 @@ const level = {
spawn.randomLevelBoss(1840, 675)
},
movers() {
- simulation.makeTextLog(`
movers by
ryanbear `);
+ simulation.inGameConsole(`
movers by
ryanbear `);
level.custom = () => {
level.exit.drawAndCheck();
level.enter.draw();
@@ -19477,7 +20297,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
downpour() {
- simulation.makeTextLog(`
Downpour by
DesBoot `);
+ simulation.inGameConsole(`
Downpour by
DesBoot `);
let mobsspawned = 0
const laser = level.hazard(7492, -2612, 10, 500, 0.3) //laserintro
@@ -19512,7 +20332,7 @@ const level = {
// color.map = "#444" //custom map color
- //simulation.makeTextLog(stopcycle)
+ //simulation.inGameConsole(stopcycle)
level.custom = () => {
do {
@@ -19539,17 +20359,17 @@ const level = {
// }
// if (rainCount > 12) {
// rainCount = 1
- // simulation.makeTextLog(rainCount)
+ // simulation.inGameConsole(rainCount)
// } else {
// rainCount = rainCount + 1
- // simulation.makeTextLog(rainCount)
+ // simulation.inGameConsole(rainCount)
// }
} while (Math.random() < 0.8);
- //simulation.makeTextLog(stopcycle)
- //simulation.makeTextLog(m.cycle)
+ //simulation.inGameConsole(stopcycle)
+ //simulation.inGameConsole(m.cycle)
// ctx.fillStyle = "rgba(228,255,0,0.8)"
- // //simulation.makeTextLog(stopcycle)
+ // //simulation.inGameConsole(stopcycle)
// ctx.fillRect(50.4, -1210.0, 100, 100)
// stopcycle = m.cycle + Math.random * 600;
//stopcycle = m.cycles + Math.random * 600
@@ -21081,7 +21901,7 @@ const level = {
if (m.alive) {
// tech.damage *= 2;
let text = "";
- if (!tech.isSuperDeterminism) { text += `
${tech.isCancelTech ? "?" : "✕"}
`; };
+ if (!tech.isSuperDeterminism) { text += `
${(tech.isCancelTech && tech.cancelTechCount === 0) ? "?" : "✕"}
`; };
text += `
Blessing Of Sal `;
text += `
`;
text += `
`;
@@ -21095,8 +21915,8 @@ const level = {
},
choose(index) {
if (index == 1) {
- tech.squirrelFx += 0.25;
- tech.squirrelJump += 0.1;
+ m.squirrelFx += 0.25;
+ m.squirrelJump += 0.1;
m.setMovement();
powerUps.endDraft("buff");
} else if (index == 2) {
@@ -22344,7 +23164,7 @@ const level = {
Object.assign(spawn, obj); //ez
},
superNgonBros() {
- simulation.makeTextLog(`
Super N-gon Bros by
DesBoot `);
+ simulation.inGameConsole(`
Super N-gon Bros by
DesBoot `);
let bowserKilled = 0
let flagY = -750
@@ -22468,19 +23288,19 @@ const level = {
me.onDeath = function () {
if (Math.random() < 0.1) {
spawn.randomSmallMob(me.position.x, me.position.y - 75);
- simulation.makeTextLog('mob')
+ simulation.inGameConsole('mob')
} else {
if (Math.random() < 0.07) {
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "tech", true);
- simulation.makeTextLog('tech')
+ simulation.inGameConsole('tech')
} else {
if (Math.random() < 0.4) {
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "heal", true);
- simulation.makeTextLog('heal')
+ simulation.inGameConsole('heal')
} else {
//if (Math.random() < 0.8){
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "ammo", true);
- simulation.makeTextLog('ammo')
+ simulation.inGameConsole('ammo')
//}
}
}
@@ -22528,7 +23348,7 @@ const level = {
firstElevatorY -= 5
}
- //simulation.makeTextLog(firstElevatorY)
+ //simulation.inGameConsole(firstElevatorY)
elevator1.move();
elevator2.move();
if (player.position.x > 0 && player.position.y < -9000 && player.position.y > -10000) {
@@ -22544,7 +23364,7 @@ const level = {
portal[3].query()
portal2[2].query()
portal2[3].query()
- //simulation.makeTextLog(firstBlockBroken)
+ //simulation.inGameConsole(firstBlockBroken)
level.exit.drawAndCheck();
if (player.position.x > 4100 && secondMobsReached == 0) {
secondMobsSpawned = 1
@@ -22587,7 +23407,7 @@ const level = {
level.enter.draw();
if (finalRoomReached == 0 && player.position.x > 21150) {
finalRoomReached = 1
- simulation.makeTextLog('Thank you M, but our techs are in another castle!')
+ simulation.inGameConsole('Thank you M, but our techs are in another castle!')
}
//mobs
if (firstMobsSpawned == 1 && firstMobsReached == 0) {
@@ -22863,13 +23683,14 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
underpass() {
- simulation.makeTextLog(`
underpass by
Richard0820 `);
+ simulation.inGameConsole(`
underpass by
Richard0820 `);
let key = false;
const door = level.door(2650, -825, 50, 250, 250, 10);
const elevator = level.elevator(-11050, -650, 450, 75, -2975, 0.003, { up: 0.1, down: 0.1 })
const slimePit = level.hazard(-4775, -350, 1975, 175);
- const boost = level.boost(137.5, -600, 75, 25);
+ const boost = level.boost(137.5, -600, 75);
+
let base = Matter.Bodies.rectangle(-4375, -1000, 100, 100, {
density: 0.05,
isNotHoldable: true,
@@ -24126,64 +24947,6 @@ const level = {
ctx.setLineDash([]);
}
};
- // if(powerUps.pass == undefined) {
- // let pass = {pass:true, activated:false};
- // Object.assign(powerUps, pass)
- // }
- // const loadOut = {
- // loadOut: {
- // name: "loadOut",
- // color: "#000000", //"hsl(248,100%,65%)",
- // size() { return 40 },
- // effect() {
- // if(m.alive) {
- // // tech.damage *= 2;
- // let text = "";
- // if (!tech.isSuperDeterminism) { text += `
${tech.isCancelTech ? "?":"✕"}
`; };
- // text += `
Blessing Of Sal `;
- // text += `
`;
- // text += `
`;
- // text += `
`;
- // if(powerUps.pass == true) {
- // text += `
Press Shift to summon the
Mythical Las Slayer Drains Energy
`;
- // }
- // document.getElementById("choose-grid").innerHTML = text;
- // powerUps.showDraft();//no known bugs ig idk, im keep this as it is
- // }
- // },
- // choose(index) {
- // if(index == 1) {
- // tech.squirrelFx += 0.25;
- // tech.squirrelJump += 0.1;
- // m.setMovement();
- // powerUps.endDraft("buff");
- // } else if(index == 2) {
- // simulation.dmgScale *= 0.95;
- // powerUps.endDraft("buff");
- // } else if(index == 3) {
- // m.dmgScale *= 1.1;
- // powerUps.endDraft("buff");
- // } else if(index == 4) { //sword!
- // powerUps.pass = false;
- // addEventListener("keydown", function(event) {
- // if(event.key == "Shift" && powerUps.activated == false) {
- // sword()
- // powerUps.activated = true;
- // } else if(event.key == "Shift" && powerUps.activated == true) {
- // for(let i = 0; i < mob.length; i++) {
- // if(mob[i].isSword) {
- // mob[i].death()
- // }
- // powerUps.activated = false;
- // }
- // }
- // })
- // powerUps.endDraft("buff");
- // }
- // }
- // }
- // }
- // Object.assign(powerUps, loadOut)
const restoreBoss = function (x, y, radius = 30) { //ATTENTION LANDGREEN: RESTOREBOSS WILL NOT DROP ANY TECH, NOR WILL THERE BE ANY IN THE MAP. DO NOT ADD ANY TECH TO MY MAP
mobs.spawn(x, y, 8, radius, 'transparent');
let me = mob[mob.length - 1];
@@ -25801,7 +26564,7 @@ const level = {
},
cantilever() { // made by Eclipse#7932 on discord, (TheSpudguy)(@PurpleSunsetGames on github)
// simulation.enableConstructMode();
- simulation.makeTextLog(`
underpass by
Eclipse#7932 `);
+ simulation.inGameConsole(`
underpass by
Eclipse#7932 `);
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 5500;
@@ -25864,7 +26627,7 @@ const level = {
powerUps.addResearchToLevel(); //needs to run after mobs are spawned
},
tlinat() { // _Destined_ formerly Richard0820#2652
- simulation.makeTextLog(`
tlinat by
Richard0820 `);
+ simulation.inGameConsole(`
tlinat by
Richard0820 `);
simulation.fallHeight = 1 / 0, level.setPosToSpawn(0, -1e3), level.exit.x = 5100, level.exit.y = 3770, spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20), spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20), level.defaultZoom = 3000, simulation.zoomTransition(level.defaultZoom), document.body.style.backgroundColor = "#d8dadf";
let e = 0,
t = 0;
@@ -26004,7 +26767,7 @@ const level = {
n(o[l], e + 250 * l - Math.abs(1.5 * e), t)
}
}
- simulation.makeTextLog(`
Look up
Walk right to tp to maze Exit is at the bottom left `), Matter.Body.scale(player.parts[3], 2, 2), level.custom = () => {
+ simulation.inGameConsole(`
Look up
Walk right to tp to maze Exit is at the bottom left `), Matter.Body.scale(player.parts[3], 2, 2), level.custom = () => {
if (level.exit.drawAndCheck(), level.enter.draw(), player.position.y > 1e5 && Matter.Body.setPosition(player, {
x: 5100,
y: -5925
@@ -26014,7 +26777,7 @@ const level = {
y: -5925
}), e++;
for (let e = 0; e < map.length; e++) Math.random() < .75 && ghoster(map[e].position.x, map[e].position.y);
- simulation.makeTextLog("Watch out for
ghosters Peace ✌️")
+ simulation.inGameConsole("Watch out for
ghosters Peace ✌️")
}
player.position.x > level.exit.x && player.position.x < level.exit.x + 100 && player.position.y > level.exit.y - 150 && player.position.y < level.exit.y - 0 && player.velocity.y < .15 && 0 == t && (t++, Matter.Body.scale(player.parts[3], .5, .5))
}, level.customTopLayer = () => {
@@ -26087,7 +26850,7 @@ const level = {
},
ruins() { // by SiddhUPe
// simulation.enableConstructMode()
- simulation.makeTextLog(`
ruins by
SiddhUPe `);
+ simulation.inGameConsole(`
ruins by
SiddhUPe `);
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 19531;
@@ -27167,14 +27930,13 @@ const level = {
spawn.mapRect(-100, 0, 1000, 100);
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
- ace() { //join us at discord.gg/Q8gY4WeUcm
- simulation.makeTextLog(`
ace by
Richard0820 `);
+ ace() {
+ simulation.inGameConsole(`
ace by
Richard0820 `);
let isDestroyed = false;
const ace = {
spawnOrbitals(who, radius, chance = Math.min(0.25 + simulation.difficulty * 0.005)) {
if (Math.random() < chance) {
- // simulation.difficulty = 50
- const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
+ const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.003 + 0.004 * Math.random() + 0.002 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
const offSet = 6.28 * Math.random()
for (let i = 0; i < len; i++) ace.orbital(who, radius, i / len * 2 * Math.PI + offSet, speed)
@@ -27224,16 +27986,15 @@ const level = {
}
};
},
- shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance(), isExtraShield = false) {
+ shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
if (this.allowShields && Math.random() < chance) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(255,255,255,0.9)");
let me = mob[mob.length - 1];
me.stroke = "rgb(0,0,0)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
- me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.05
me.isUnblockable = true
- me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
consBB[consBB.length] = Constraint.create({
@@ -27255,6 +28016,12 @@ const level = {
me.shieldTargetID = target.id
target.isShielded = true;
+ if (target.shieldCount > 0) {
+ target.shieldCount++
+ } else {
+ target.shieldCount = 1
+ }
+ me.shieldCount = target.shieldCount //used with "bubble fusion"
target.shieldID = me.id
me.onDeath = function () {
//clear isShielded status from target
@@ -27281,7 +28048,7 @@ const level = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.frictionAir = 0;
me.shield = true;
- me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.075
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
@@ -27706,7 +28473,7 @@ const level = {
me.isBoss = true;
me.isSlashBoss = true;
me.showHealthBar = false;
- me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -28437,12 +29204,11 @@ const level = {
}
},
crimsonTowers() {
- simulation.makeTextLog(`crimsonTowers by Richard0820. Thank you desboot for the video:
Source `)
+ simulation.inGameConsole(`crimsonTowers by Richard0820. Thank you desboot for the video:
Source `)
const ace = {
spawnOrbitals(who, radius, chance = Math.min(0.25 + simulation.difficulty * 0.005)) {
if (Math.random() < chance) {
- // simulation.difficulty = 50
- const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
+ const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.003 + 0.004 * Math.random() + 0.002 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
const offSet = 6.28 * Math.random()
for (let i = 0; i < len; i++) ace.orbital(who, radius, i / len * 2 * Math.PI + offSet, speed)
@@ -28492,16 +29258,15 @@ const level = {
}
};
},
- shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance(), isExtraShield = false) {
+ shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
if (this.allowShields && Math.random() < chance) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(255,255,255,0.9)");
let me = mob[mob.length - 1];
me.stroke = "rgb(0,0,0)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
- me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.05
me.isUnblockable = true
- me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
consBB[consBB.length] = Constraint.create({
@@ -28523,6 +29288,12 @@ const level = {
me.shieldTargetID = target.id
target.isShielded = true;
+ if (target.shieldCount > 0) {
+ target.shieldCount++
+ } else {
+ target.shieldCount = 1
+ }
+ me.shieldCount = target.shieldCount //used with "bubble fusion"
target.shieldID = me.id
me.onDeath = function () {
//clear isShielded status from target
@@ -28549,7 +29320,7 @@ const level = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.frictionAir = 0;
me.shield = true;
- me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.075
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
@@ -28974,7 +29745,7 @@ const level = {
me.isBoss = true;
me.isSlashBoss = true;
me.showHealthBar = false;
- me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -29568,8 +30339,8 @@ const level = {
level.exit.x = map[272].position.x;
},
LaunchSite() {
- simulation.makeTextLog(`
Launch Site by
Des Boot `);
- simulation.makeTextLog(`The rain stopped...`);
+ simulation.inGameConsole(`
Launch Site by
Des Boot `);
+ simulation.inGameConsole(`The rain stopped...`);
level.setPosToSpawn(0, -50); //normal spawn
const elevatortoggle = level.toggle(13650, 3000)
let newMobsSpawned = false;
@@ -29984,7 +30755,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
shipwreck() {
- simulation.makeTextLog(`
shipwreck by
3xionDev `);
+ simulation.inGameConsole(`
shipwreck by
3xionDev `);
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 1500;
level.exit.y = -1875;
@@ -30295,9 +31066,10 @@ const level = {
level.enter.draw();
};
+ level.customTopLayer = () => { };
},
unchartedCave() {
- simulation.makeTextLog(`
unchartedCave by
3xionDev `);
+ simulation.inGameConsole(`
unchartedCave by
3xionDev `);
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 20985;
level.exit.y = 2816;
@@ -30705,9 +31477,10 @@ const level = {
level.enter.draw();
};
+ level.customTopLayer = () => { };
},
dojo() { // By weird_pusheen
- simulation.makeTextLog(`
dojo by
werid_pusheen , fixed by
Cornbread 2100 `)
+ simulation.inGameConsole(`
dojo by
werid_pusheen , fixed by
Cornbread 2100 `)
const vanishes = [];
const smoofes = [];
const leftRotor = level.rotor(-550, 900, 950, 25);
@@ -31001,7 +31774,7 @@ const level = {
*/
var boss = mob[mob.length - 1];
boss.isBoss = true;
- boss.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
+ boss.damageReduction = 0.2
boss.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y);
level.exit.x = 2560;
@@ -31157,7 +31930,687 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
arena() {
- simulation.makeTextLog(`
arena by
Richard0820 `)
+ simulation.inGameConsole(`
arena by
Whyisthisnotavalable `)
+ let genisis, genisisJumpSensor, genisisBody, genisisHead, genisisHeadSensor, genisisBodySensor;
+ let control = { left: false, right: false, up: false, down: false };
+ const g = {
+ spawn() {
+ //load genisis in matter.js physic engine
+ // let vector = Vertices.fromPath("0 40 50 40 50 115 0 115 30 130 20 130"); //genisis as a series of vertices
+ let vertices = Vertices.fromPath("0,40, 50,40, 50,115, 30,130, 20,130, 0,115, 0,40"); //genisis as a series of vertices
+ genisisBody = Bodies.fromVertices(0, 0, vertices);
+ genisisJumpSensor = Bodies.rectangle(0, 46, 36, 6, {
+ //this sensor check if the genisis is on the ground to enable jumping
+ sleepThreshold: 99999999999,
+ isSensor: true
+ });
+ vertices = Vertices.fromPath("16 -82 2 -66 2 -37 43 -37 43 -66 30 -82");
+ genisisHead = Bodies.fromVertices(0, -55, vertices); //this part of the genisis lowers on crouch
+ genisisHeadSensor = Bodies.rectangle(0, -57, 48, 45, {
+ //senses if the genisis's head is empty and can return after crouching
+ sleepThreshold: 99999999999,
+ isSensor: true
+ });
+ genisisBodySensor = Bodies.rectangle(0, 0, 70, 45, {
+ sleepThreshold: 99999999999,
+ isSensor: true
+ });
+ genisis = Body.create({
+ //combine genisisJumpSensor and genisisBody
+ parts: [genisisBody, genisisHead, genisisJumpSensor, genisisHeadSensor, genisisBodySensor],
+ inertia: Infinity, //prevents genisis rotation
+ friction: 0.002,
+ frictionAir: 0.001,
+ //frictionStatic: 0.5,
+ restitution: 0,
+ sleepThreshold: Infinity,
+ collisionFilter: {
+ group: 0,
+ category: cat.mob,
+ mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield | cat.player | cat.bullet
+ },
+ // death() {
+ // g.death();
+ // }
+ });
+ Matter.Body.setMass(genisis, g.mass);
+ Composite.add(engine.world, [genisis]);
+ },
+ health: 1000,
+ maxHealth: 1000, //set in simulation.reset()
+ cycle: 600, //starts at 600 cycles instead of 0 to prevent bugs with g.history
+ lastKillCycle: 0,
+ lastHarmCycle: 0,
+ width: 50,
+ radius: 30,
+ eyeFillColor: null,
+ fillColor: null, //set by setFillColors
+ fillColorDark: null, //set by setFillColors
+ bodyGradient: null, //set by setFillColors
+ color: {
+ hue: 0,
+ sat: 0,
+ light: 50,
+ },
+ setFillColors() {
+ g.fillColor = `hsl(${g.color.hue},${g.color.sat}%,${g.color.light}%)`
+ g.fillColorDark = `hsl(${g.color.hue},${g.color.sat}%,${g.color.light - 25}%)`
+ let grd = ctx.createLinearGradient(-30, 0, 30, 0);
+ grd.addColorStop(0, g.fillColorDark);
+ grd.addColorStop(1, g.fillColor);
+ g.bodyGradient = grd
+ },
+ setFillColorsAlpha(alpha = 0.5) {
+ g.fillColor = `hsla(${g.color.hue},${g.color.sat}%,${g.color.light}%,${alpha})`
+ g.fillColorDark = `hsla(${g.color.hue},${g.color.sat}%,${g.color.light - 25}%,${alpha})`
+ let grd = ctx.createLinearGradient(-30, 0, 30, 0);
+ grd.addColorStop(0, g.fillColorDark);
+ grd.addColorStop(1, g.fillColor);
+ g.bodyGradient = grd
+ },
+ height: 42,
+ yOffWhen: {
+ crouch: 22,
+ stand: 49,
+ jump: 70
+ },
+ defaultMass: 5,
+ mass: 5,
+ FxNotHolding: 0.015,
+ Fx: 0.016, //run Force on ground //
+ jumpForce: 0.64,
+ setMovement() {
+ // g.Fx = 0.08 / mass * tech.squirrelFx
+ // g.FxAir = 0.4 / mass / mass
+ g.Fx = tech.baseFx * g.fieldFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / genisis.mass //base genisis mass is 5
+ g.jumpForce = tech.baseJumpForce * g.fieldJump * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) / genisis.mass / genisis.mass //base genisis mass is 5
+ },
+ FxAir: 0.032, // 0.4/5/5 run Force in Air
+ yOff: 70,
+ yOffGoal: 70,
+ onGround: false, //checks if on ground or in air
+ lastOnGroundCycle: 0, //use to calculate coyote time
+ standingOn: undefined,
+ numTouching: 0,
+ crouch: false,
+ // isHeadClear: true,
+ spawnPos: {
+ x: 0,
+ y: 0
+ },
+ spawnVel: {
+ x: 0,
+ y: 0
+ },
+ pos: {
+ x: 0,
+ y: 0
+ },
+ yPosDifference: 24.2859, //genisis.position.y - g.pos.y //24.285923217549026
+ // yPosDifferenceCrouched: -2.7140767824453604,
+ Sy: 0, //adds a smoothing effect to vertical only
+ Vx: 0,
+ Vy: 0,
+ friction: {
+ ground: 0.01,
+ air: 0.0025
+ },
+ airSpeedLimit: 125, // 125/mass/mass = 5
+ angle: 0,
+ walk_cycle: 0,
+ stepSize: 0,
+ flipLegs: -1,
+ hip: {
+ x: 12,
+ y: 24
+ },
+ knee: {
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 0
+ },
+ foot: {
+ x: 0,
+ y: 0
+ },
+ legLength1: 55,
+ legLength2: 45,
+ transX: 0,
+ transY: 0,
+ history: new Array(600), //[], //tracks the last second of genisis position
+ rewindCount: 0, //used with CPT
+ resetHistory() {
+ const set = {
+ position: {
+ x: genisis.position.x,
+ y: genisis.position.y,
+ },
+ velocity: {
+ x: genisis.velocity.x,
+ y: genisis.velocity.y
+ },
+ yOff: g.yOff,
+ angle: g.angle,
+ health: g.health,
+ energy: g.energy,
+ activeGun: b.activeGun
+ }
+ for (let i = 0; i < 600; i++) { //reset history
+ g.history[i] = set
+ }
+ },
+ move() {
+ g.pos.x = genisis.position.x;
+ g.pos.y = genisisBody.position.y - g.yOff;
+ g.Vx = genisis.velocity.x;
+ g.Vy = genisis.velocity.y;
+
+ //tracks the last 10s of genisis information
+ g.history.splice(g.cycle % 600, 1, {
+ position: {
+ x: genisis.position.x,
+ y: genisis.position.y,
+ },
+ velocity: {
+ x: genisis.velocity.x,
+ y: genisis.velocity.y
+ },
+ yOff: g.yOff,
+ angle: g.angle,
+ health: g.health,
+ energy: g.energy,
+ activeGun: b.activeGun
+ });
+ // const back = 59 // 59 looks at 1 second ago //29 looks at 1/2 a second ago
+ // historyIndex = (g.cycle - back) % 600
+ },
+ targetX: 0,
+ targetY: 0,
+ transSmoothX: 0,
+ transSmoothY: 0,
+ lastGroundedPositionY: 0,
+ // mouseZoom: 0,
+ lookSmoothing: 0.07, //1 is instant jerky, 0.001 is slow smooth zoom, 0.07 is standard
+ look() { }, //set to lookDefault()
+ lookDefault() {
+ g.angle = Math.atan2(
+ g.targetY - g.pos.y,
+ g.targetX - g.pos.x
+ );
+ // //smoothed mouse look translations
+ const scale = 0.8;
+ g.transSmoothX = canvas.width2 - g.pos.x - (simulation.mouse.x - canvas.width2) * scale;
+ g.transSmoothY = canvas.height2 - g.pos.y - (simulation.mouse.y - canvas.height2) * scale;
+
+ g.transX += (g.transSmoothX - g.transX) * g.lookSmoothing;
+ g.transY += (g.transSmoothY - g.transY) * g.lookSmoothing;
+ },
+ doCrouch() {
+ if (!g.crouch) {
+ g.crouch = true;
+ g.yOffGoal = g.yOffWhen.crouch;
+ if ((genisisHead.position.y - genisis.position.y) < 0) {
+ Matter.Body.setPosition(genisisHead, {
+ x: genisis.position.x,
+ y: genisis.position.y + 9.1740767
+ })
+ }
+ }
+ },
+ undoCrouch() {
+ if (g.crouch) {
+ g.crouch = false;
+ g.yOffGoal = g.yOffWhen.stand;
+ if ((genisisHead.position.y - genisis.position.y) > 0) {
+ Matter.Body.setPosition(genisisHead, {
+ x: genisis.position.x,
+ y: genisis.position.y - 30.28592321
+ })
+ }
+ }
+ },
+ hardLandCD: 0,
+ checkHeadClear() {
+ if (Matter.Query.collides(headSensor, map).length > 0) {
+ return false
+ } else {
+ return true
+ }
+ },
+ buttonCD_jump: 0, //cool down for genisis buttons
+ jump() {
+ // if (!g.onGround) g.lastOnGroundCycle = 0 //g.cycle - tech.coyoteTime
+ g.buttonCD_jump = g.cycle + 20; //can't jump again until 20 cycles pass
+ //apply a fraction of the jump force to the body the genisis is jumping off of
+ Matter.Body.applyForce(g.standingOn, g.pos, {
+ x: 0,
+ y: g.jumpForce * 0.12 * Math.min(g.standingOn.mass, 5)
+ });
+
+ genisis.force.y = -g.jumpForce; //genisis jump force
+ Matter.Body.setVelocity(genisis, { //zero genisis y-velocity for consistent jumps
+ x: genisis.velocity.x,
+ y: Math.max(-10, Math.min(g.standingOn.velocity.y, 10)) //cap velocity contribution from blocks you are standing on to 10 in the vertical
+ });
+ },
+ groundControl() {
+ //check for crouch or jump
+ if (g.crouch) {
+ if (!(control.down) && g.checkHeadClear() && g.hardLandCD < g.cycle) g.undoCrouch();
+ } else if (control.down || g.hardLandCD > g.cycle) {
+ g.doCrouch(); //on ground && not crouched and pressing s or down
+ } else if (control.up && g.buttonCD_jump + 20 < g.cycle && g.yOffWhen.stand > 23) {
+ g.jump()
+ }
+
+ if (control.left) {
+ if (genisis.velocity.x > -2) {
+ genisis.force.x -= g.Fx * 1.5
+ } else {
+ genisis.force.x -= g.Fx
+ }
+ // }
+ } else if (control.right) {
+ if (genisis.velocity.x < 2) {
+ genisis.force.x += g.Fx * 1.5
+ } else {
+ genisis.force.x += g.Fx
+ }
+ } else {
+ const stoppingFriction = 0.92; //come to a stop if no move key is pressed
+ Matter.Body.setVelocity(genisis, {
+ x: genisis.velocity.x * stoppingFriction,
+ y: genisis.velocity.y * stoppingFriction
+ });
+ }
+ //come to a stop if fast
+ if (genisis.speed > 4) {
+ const stoppingFriction = (g.crouch) ? 0.65 : 0.89; // this controls speed when crouched
+ Matter.Body.setVelocity(genisis, {
+ x: genisis.velocity.x * stoppingFriction,
+ y: genisis.velocity.y * stoppingFriction
+ });
+ }
+ },
+ airControl() {
+ //check for coyote time jump
+ // if (control.up && g.buttonCD_jump + 20 + tech.coyoteTime < g.cycle && g.yOffWhen.stand > 23 && g.lastOnGroundCycle + tech.coyoteTime > g.cycle) g.jump()
+ if (control.up && g.buttonCD_jump + 20 < g.cycle && g.yOffWhen.stand > 23 && g.lastOnGroundCycle + 5 > g.cycle) g.jump()
+
+ //check for short jumps //moving up //recently pressed jump //but not pressing jump key now
+ if (g.buttonCD_jump + 60 > g.cycle && !(control.up) && g.Vy < 0) {
+ Matter.Body.setVelocity(genisis, {
+ //reduce genisis y-velocity every cycle
+ x: genisis.velocity.x,
+ y: genisis.velocity.y * 0.94
+ });
+ }
+
+ if (control.left) {
+ if (genisis.velocity.x > -g.airSpeedLimit / genisis.mass / genisis.mass) genisis.force.x -= g.FxAir; // move genisis left / a
+ } else if (control.right) {
+ if (genisis.velocity.x < g.airSpeedLimit / genisis.mass / genisis.mass) genisis.force.x += g.FxAir; //move genisis right / d
+ }
+ },
+ alive: true,
+ dmgScale: 1, //scales all damage, but not raw .dmg //set in levels.setDifficulty
+ defaultFPSCycle: 0, //tracks when to return to normal fps
+ immuneCycle: 0, //used in engine
+ collisionImmuneCycles: 30,
+ buttonCD: 0, //cool down for genisis buttons
+ drawLeg(stroke) {
+ // if (simulation.mouseInGame.x > g.pos.x) {
+ if (g.angle > -Math.PI / 2 && g.angle < Math.PI / 2) {
+ g.flipLegs = 1;
+ } else {
+ g.flipLegs = -1;
+ }
+ ctx.save();
+ ctx.scale(g.flipLegs, 1); //leg lines
+ ctx.beginPath();
+ ctx.moveTo(g.hip.x, g.hip.y);
+ ctx.lineTo(g.knee.x, g.knee.y);
+ ctx.lineTo(g.foot.x, g.foot.y);
+ ctx.strokeStyle = stroke;
+ ctx.lineWidth = 7;
+ ctx.stroke();
+
+ //toe lines
+ ctx.beginPath();
+ ctx.moveTo(g.foot.x, g.foot.y);
+ ctx.lineTo(g.foot.x - 15, g.foot.y + 5);
+ ctx.moveTo(g.foot.x, g.foot.y);
+ ctx.lineTo(g.foot.x + 15, g.foot.y + 5);
+ ctx.lineWidth = 4;
+ ctx.stroke();
+
+ //hip joint
+ ctx.beginPath();
+ ctx.arc(g.hip.x, g.hip.y, 11, 0, 2 * Math.PI);
+ //knee joint
+ ctx.moveTo(g.knee.x + 7, g.knee.y);
+ ctx.arc(g.knee.x, g.knee.y, 7, 0, 2 * Math.PI);
+ //foot joint
+ ctx.moveTo(g.foot.x + 6, g.foot.y);
+ ctx.arc(g.foot.x, g.foot.y, 6, 0, 2 * Math.PI);
+ ctx.fillStyle = g.fillColor;
+ ctx.fill();
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.restore();
+ },
+ calcLeg(cycle_offset, offset) {
+ g.hip.x = 12 + offset;
+ g.hip.y = 24 + offset;
+ //stepSize goes to zero if Vx is zero or not on ground (make m transition cleaner)
+ g.stepSize = 0.8 * g.stepSize + 0.2 * (7 * Math.sqrt(Math.min(9, Math.abs(g.Vx))) * g.onGround);
+ //changes to stepsize are smoothed by adding only a percent of the new value each cycle
+ const stepAngle = 0.034 * g.walk_cycle + cycle_offset;
+ g.foot.x = 2.2 * g.stepSize * Math.cos(stepAngle) + offset;
+ g.foot.y = offset + 1.2 * g.stepSize * Math.sin(stepAngle) + g.yOff + g.height;
+ const Ymax = g.yOff + g.height;
+ if (g.foot.y > Ymax) g.foot.y = Ymax;
+
+ //calculate knee position as intersection of circle from hip and foot
+ const d = Math.sqrt((g.hip.x - g.foot.x) * (g.hip.x - g.foot.x) + (g.hip.y - g.foot.y) * (g.hip.y - g.foot.y));
+ const l = (g.legLength1 * g.legLength1 - g.legLength2 * g.legLength2 + d * d) / (2 * d);
+ const h = Math.sqrt(g.legLength1 * g.legLength1 - l * l);
+ g.knee.x = (l / d) * (g.foot.x - g.hip.x) - (h / d) * (g.foot.y - g.hip.y) + g.hip.x + offset;
+ g.knee.y = (l / d) * (g.foot.y - g.hip.y) + (h / d) * (g.foot.x - g.hip.x) + g.hip.y;
+ },
+ draw() { },
+ drawDefault() {
+ ctx.fillStyle = g.fillColor;
+ g.walk_cycle += g.flipLegs * g.Vx;
+ ctx.save();
+ ctx.globalAlpha = (g.immuneCycle < g.cycle) ? 1 : 0.5 //|| (g.cycle % 40 > 20)
+ ctx.translate(g.pos.x, g.pos.y);
+ g.calcLeg(Math.PI, -3);
+ g.drawLeg("#FFFFFF");
+ g.calcLeg(0, 0);
+ g.drawLeg("#FFFFFF");
+ ctx.rotate(g.angle);
+ ctx.beginPath();
+ ctx.arc(0, 0, 30, 0, 2 * Math.PI);
+ ctx.fillStyle = g.bodyGradient
+ ctx.fill();
+ ctx.arc(15, 0, 4, 0, 2 * Math.PI);
+ ctx.strokeStyle = "#FFFFFF";
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.restore();
+ g.yOff = g.yOff * 0.85 + g.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ },
+ drawDamage() {
+ ctx.fillStyle = "red";
+ g.walk_cycle += g.flipLegs * g.Vx;
+ ctx.save();
+ ctx.globalAlpha = 0.7;
+ ctx.translate(g.pos.x, g.pos.y);
+ g.calcLeg(Math.PI, -3);
+ g.drawLeg("#FF0000");
+ g.calcLeg(0, 0);
+ g.drawLeg("#FF0000");
+ ctx.rotate(g.angle);
+ ctx.beginPath();
+ ctx.arc(0, 0, 30, 0, 2 * Math.PI);
+ ctx.fillStyle = g.bodyGradient
+ ctx.fill();
+ ctx.arc(15, 0, 4, 0, 2 * Math.PI);
+ ctx.strokeStyle = "#FF0000";
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.restore();
+ g.yOff = g.yOff * 0.85 + g.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ },
+ damage(dmg) {
+ g.health -= dmg;
+ },
+ rebirth() {
+ g.health = g.maxHealth;
+ genisis.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield | cat.player | cat.bullet
+ },
+ lastHealth: 1000,
+ drawHealth() {
+ let interpolated = this.lastHealth + (g.health - this.lastHealth) * 0.1;
+
+ ctx.save();
+ ctx.setTransform(1, 0, 0.2, 1, 0, 0); //slanted
+ ctx.fillStyle = "rgba(250, 100, 100, 0.3)";
+ ctx.fillRect(canvas.width2 / 2, canvas.height2 / 10, canvas.width2, 30);
+ const grad = ctx.createLinearGradient(0, 0, canvas.width2, 0);
+ grad.addColorStop(0, "lightblue");
+ grad.addColorStop(1, "crimson");
+
+ ctx.fillStyle = grad;
+ ctx.fillRect(canvas.width2 / 2, canvas.height2 / 10, canvas.width2 * interpolated / 1000, 30);
+ ctx.restore();
+
+ this.lastHealth = interpolated;
+ },
+ genisisOnGroundCheck(event) {
+ //runs on collisions events
+ function enter() {
+ g.numTouching++;
+ if (!g.onGround) {
+ g.onGround = true;
+ if (g.crouch) {
+ if (g.checkHeadClear()) {
+ g.undoCrouch();
+ } else {
+ g.yOffGoal = g.yOffWhen.crouch;
+ }
+ } else {
+ //sets a hard land where genisis stays in a crouch for a bit and can't jump
+ //crouch is forced in groundControl below
+ const momentum = genisis.velocity.y * genisis.mass //genisis mass is 5 so this triggers at 26 down velocity, unless the genisis is holding something
+ if (momentum > 130) {
+ g.doCrouch();
+ g.yOff = g.yOffWhen.jump;
+ g.hardLandCD = g.cycle + Math.min(momentum / 6.5 - 6, 40)
+ //falling damage
+ if (tech.isFallingDamage && g.immuneCycle < g.cycle && momentum > 150) {
+ g.damage(Math.min(Math.sqrt(momentum - 133) * 0.01, 0.25));
+ if (g.immuneCycle < g.cycle + g.collisionImmuneCycles) g.immuneCycle = g.cycle + g.collisionImmuneCycles; //genisis is immune to damage for 30 cycles
+ }
+ } else {
+ g.yOffGoal = g.yOffWhen.stand;
+ }
+ }
+ }
+ }
+ const pairs = event.pairs;
+ for (let i = 0, j = pairs.length; i != j; ++i) {
+ let pair = pairs[i];
+ if (pair.bodyA === genisisJumpSensor) {
+ g.standingOn = pair.bodyB; //keeping track to correctly provide recoil on jump
+ if (g.standingOn.alive !== true) enter();
+ } else if (pair.bodyB === genisisJumpSensor) {
+ g.standingOn = pair.bodyA; //keeping track to correctly provide recoil on jump
+ if (g.standingOn.alive !== true) enter();
+ }
+ }
+ g.numTouching = 0;
+ },
+ genisisOffGroundCheck(event) {
+ //runs on collisions events
+ const pairs = event.pairs;
+ for (let i = 0, j = pairs.length; i != j; ++i) {
+ if (pairs[i].bodyA === genisisJumpSensor || pairs[i].bodyB === genisisJumpSensor) {
+ if (g.onGround && g.numTouching === 0) {
+ g.onGround = false;
+ g.lastOnGroundCycle = g.cycle;
+ g.hardLandCD = 0 // disable hard landing
+ if (g.checkHeadClear()) {
+ if (g.crouch) {
+ g.undoCrouch();
+ }
+ g.yOffGoal = g.yOffWhen.jump;
+ }
+ }
+ }
+ }
+ }
+ };
+ function GenisisCollisionChecks(event) {
+ const pairs = event.pairs;
+ for (let i = 0, j = pairs.length; i != j; i++) {
+ for (let k = 0; k < bullet.length; k++) {
+ if (pairs[i].bodyA === bullet[k]) {
+ collideBullet(pairs[i].bodyB);
+ break;
+ } else if (pairs[i].bodyB === bullet[k]) {
+ collideBullet(pairs[i].bodyA);
+ break;
+ }
+
+ function collideBullet(obj) {
+ if (
+ g.immuneCycle < g.cycle &&
+ (obj === genisisBody || obj === genisisHead)
+ ) {
+ let dmg = Math.sqrt(Math.abs(0.000025 * Math.sqrt((bullet[k].mass + Math.sqrt(Vector.magnitude(bullet[k].velocity)) * 0.0000125))));
+ g.damage(dmg);
+ return;
+ }
+ }
+ }
+ for (let k = 0; k < mob.length; k++) {
+ if (mob[k].alive) {
+ if (pairs[i].bodyA === mob[k]) {
+ collideMob(pairs[i].bodyB);
+ break;
+ } else if (pairs[i].bodyB === mob[k]) {
+ collideMob(pairs[i].bodyA);
+ break;
+ }
+
+ function collideMob(obj) {
+ //genisis + mob collision
+ if (
+ g.immuneCycle < g.cycle &&
+ (obj === genisisBody || obj === genisisHead) &&
+ !mob[k].isSlowed && !mob[k].isStunned
+ ) {
+ let dmg = Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05);
+ // if (g.isCloak) dmg *= 0.5
+ if (tech.isRewindAvoidDeath && g.energy > 0.85 * Math.min(1, g.maxEnergy) && dmg > 0.01) { //CPT reversal runs in g.damage, but it stops the rest of the collision code here too
+ g.damage(dmg);
+ return
+ }
+ g.damage(dmg);
+
+ if (tech.isCollisionRealitySwitch && g.alive) {
+ g.switchWorlds()
+ simulation.trails()
+ simulation.inGameConsole(`simulation.amplitude
= ${Math.random()}`);
+ }
+ if (tech.isPiezo) g.energy += 20.48;
+ if (tech.isCouplingNoHit && g.coupling > 0) {
+ g.couplingChange(-3)
+
+ const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random())
+ let where = Vector.add(g.pos, Vector.mult(unit, 17))
+ simulation.drawList.push({ //add dmg to draw queue
+ x: where.x,
+ y: where.y,
+ radius: 22,
+ color: 'rgba(0, 171, 238, 0.33)',
+ time: 8
+ });
+ where = Vector.add(g.pos, Vector.mult(unit, 60))
+ simulation.drawList.push({ //add dmg to draw queue
+ x: where.x,
+ y: where.y,
+ radius: 18,
+ color: 'rgba(0, 171, 238, 0.5)',
+ time: 16
+ });
+ where = Vector.add(g.pos, Vector.mult(unit, 100))
+ simulation.drawList.push({ //add dmg to draw queue
+ x: where.x,
+ y: where.y,
+ radius: 14,
+ color: 'rgba(0, 171, 238, 0.6)',
+ time: 24
+ });
+ where = Vector.add(g.pos, Vector.mult(unit, 135))
+ simulation.drawList.push({ //add dmg to draw queue
+ x: where.x,
+ y: where.y,
+ radius: 10,
+ color: 'rgba(0, 171, 238, 0.7)',
+ time: 32
+ });
+ // simulation.drawList.push({ //add dmg to draw queue
+ // x: g.pos.x,
+ // y: g.pos.y,
+ // radius: 150,
+ // color: 'rgba(0, 171, 238, 0.33)',
+ // time: 6
+ // });
+ // simulation.drawList.push({ //add dmg to draw queue
+ // x: g.pos.x,
+ // y: g.pos.y,
+ // radius: 75,
+ // color: 'rgba(0, 171, 238, 0.5)',
+ // time: 16
+ // });
+ // simulation.drawList.push({ //add dmg to draw queue
+ // x: g.pos.x,
+ // y: g.pos.y,
+ // radius: 25,
+ // color: 'rgba(0, 171, 238, 0.75)',
+ // time: 25
+ // });
+ }
+ if (mob[k].onHit) mob[k].onHit();
+ if (g.immuneCycle < g.cycle + g.collisionImmuneCycles) g.immuneCycle = g.cycle + g.collisionImmuneCycles; //genisis is immune to damage for 30 cycles
+ //extra kick between genisis and mob //this section would be better with forces but they don't work...
+ let angle = Math.atan2(genisis.position.y - mob[k].position.y, genisis.position.x - mob[k].position.x);
+ Matter.Body.setVelocity(genisis, {
+ x: genisis.velocity.x + 8 * Math.cos(angle),
+ y: genisis.velocity.y + 8 * Math.sin(angle)
+ });
+ Matter.Body.setVelocity(mob[k], {
+ x: mob[k].velocity.x - 8 * Math.cos(angle),
+ y: mob[k].velocity.y - 8 * Math.sin(angle)
+ });
+
+ if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && g.energy > 0.1 && mob[k].damageReduction > 0) {
+ g.energy -= 0.1 //* Math.max(g.maxEnergy, g.energy) //0.33 * g.energy
+ if (g.immuneCycle === g.cycle + g.collisionImmuneCycles) g.immuneCycle = 0; //genisis doesn't go immune to collision damage
+ mob[k].death();
+ simulation.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: Math.sqrt(dmg) * 500,
+ color: "rgba(255,0,255,0.2)",
+ time: simulation.drawTime
+ });
+ } else {
+ simulation.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: Math.sqrt(dmg) * 200,
+ color: simulation.mobDmgColor,
+ time: simulation.drawTime
+ });
+ }
+ // return;
+ // }
+ }
+ }
+ }
+ }
+ }
+ }
+ g.spawn();
+ Matter.Body.setPosition(genisis, {
+ x: 7875,
+ y: -2530
+ })
let isUsingSwordMod = false;
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].name === 'size-weight illusion') { //to detect if the player is using the sword mod so that it won't mess up their mod. The sword mod adds this tech so if it is detected then the sword won't be removed from the gun array //Landgreen, don't add a tech with the same name
@@ -31165,40 +32618,47 @@ const level = {
}
}
if (!isUsingSwordMod) {
- (function () {
- const e = {
- name: "sword",
- descriptionFunction() { return `swing a
sword that
lifesteals health drains
health instead of ammunition
doesn't use
ammo ` },
- ammo: Infinity,
- ammoPack: Infinity,
- defaultAmmoPack: Infinity,
- have: false,
- cycle: 0,
- sword: undefined,
- bladeSegments: undefined,
- bladeTrails: [],
- angle: 0,
- constraint: undefined,
- do() {
- if (input.fire && m.fireCDcycle > m.cycle) {
+ const e = {
+ name: "sword",
+ descriptionFunction() { return `swing a
sword that
lifesteals health drains
health instead of ammunition
doesn't use
ammo ` },
+ ammo: Infinity,
+ ammoPack: Infinity,
+ defaultAmmoPack: Infinity,
+ have: false,
+ cycle: 0,
+ sword: undefined,
+ swordArray: [],
+ bladeSegments: undefined,
+ bladeTrails: [],
+ angle: 0,
+ constraint: undefined,
+ charge: 0,
+ angle2: 0,
+ fire() { },
+ do() {
+ if (this.sword && this.cycle < 1) {
+ this.angle2 = Math.atan2(this.sword.position.y - m.pos.y, this.sword.position.x - m.pos.x);
+ }
+ if (this.sword) {
+ this.cycle++;
+ }
+ this.normalFire();
+ this.renderDefault();
+ this.collision();
+ },
+ normalFire() {
+ if (this.constraint) {
+ this.constraint.pointA = player.position;
+ }
+ if (tech.isStabSword && !m.crouch && this.cycle > 0 && this.stabStatus) {
+ if (this.sword) {
+ this.stabStatus = false;
if (tech.isEnergyHealth) {
- m.energy -= 0.004;
- } else {
- m.health -= 0.001;
- m.displayHealth();
- }
- }
- if (b.activeGun !== null && input.fire && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
- if (!this.sword && b.guns[b.activeGun].name === 'sword') {
- Matter.Body.setMass(player, 1000);
- ({ sword: this.sword, bladeSegments: this.bladeSegments } = this.createAndSwingSword());
- this.angle = m.angle;
+ m.energy = 0.01;
+ m.immuneCycle = m.cycle + 30;
}
- }
- if (this.sword && !input.fire) {
this.cycle = 0;
Matter.Body.setAngularVelocity(this.sword, 0);
- Matter.Body.setMass(player, 5)
Composite.remove(engine.world, this.sword);
this.sword.parts.forEach(part => {
Composite.remove(engine.world, part);
@@ -31213,136 +32673,273 @@ const level = {
this.constraint = undefined;
}
this.bladeTrails = [];
- m.fireCDcycle = m.cycle + 10;
+ m.fireCDcycle = 0;
+ }
+ }
+
+ if (input.fire && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
+ if (tech.isEnergyHealth) {
+ m.energy -= 0.004;
} else {
- if (this.sword && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
- let handle;
- for (let i = 0; i < bullet.length; i++) {
- if (bullet[i].customName == "handle") {
- handle = bullet[i];
- }
- }
- if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) {
- Matter.Body.setAngularVelocity(this.sword, -Math.PI * 0.1);
- } else {
- Matter.Body.setAngularVelocity(this.sword, Math.PI * 0.1);
+ m.health -= 0.001;
+ m.displayHealth();
+ }
+ }
+ if (input.fire && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
+ if (!this.sword && b.guns[b.activeGun].name === 'sword') {
+ ({ sword: this.sword, bladeSegments: this.bladeSegments } = this.createAndSwingSword());
+ this.angle = m.angle;
+ }
+ }
+ if (this.sword && !input.fire) {
+ this.cycle = 0;
+ Matter.Body.setAngularVelocity(this.sword, 0);
+ player.force.x *= 0.01;
+ player.force.y *= 0.01;
+ Composite.remove(engine.world, this.sword);
+ this.sword.parts.forEach(part => {
+ Composite.remove(engine.world, part);
+ const index = bullet.indexOf(part);
+ if (index !== -1) {
+ bullet.splice(index, 1);
+ }
+ });
+ this.sword = undefined;
+ if (this.constraint) {
+ Composite.remove(engine.world, this.constraint);
+ this.constraint = undefined;
+ }
+ this.bladeTrails = [];
+ m.fireCDcycle = m.cycle + 10;
+ } else {
+ if (this.sword && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
+ let handle;
+ for (let i = 0; i < bullet.length; i++) {
+ if (bullet[i].customName == "handle") {
+ handle = bullet[i];
}
- if (!this.constraint && (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
- this.constraint = Constraint.create({
- bodyA: player,
- bodyB: this.sword,
- pointB: { x: -9, y: ((handle.position.y - this.sword.position.y)) },
- stiffness: 0.1,
- damping: 0.0001815,
- length: 0,
+ }
+ if (tech.infinityEdge) {
+ const newSize = Math.sqrt(0.5 * m.health) + 1;
+ Matter.Body.scale(this.sword, newSize * (1 / (this.sword.scale == undefined ? 1 : this.sword.scale)), newSize * (1 / (this.sword.scale == undefined ? 1 : this.sword.scale)), handle.position);
+ this.sword.scale = newSize;
+ }
+ if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) {
+ Matter.Body.setAngularVelocity(this.sword, -Math.PI * 0.1);
+ } else {
+ Matter.Body.setAngularVelocity(this.sword, Math.PI * 0.1);
+ }
+ if (tech.sizeIllusion) {
+ player.force.x += Math.cos(m.angle) * player.mass / 500;
+ player.force.y += Math.sin(m.angle) * player.mass / 500;
+ }
+ if (!this.constraint && (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
+ this.constraint = Constraint.create({
+ pointA: player.position,
+ bodyB: this.sword,
+ pointB: { x: -9, y: ((handle.position.y - this.sword.position.y)) },
+ stiffness: (tech.infinityEdge ? 0.05 : 0.1),
+ damping: 0.001815,
+ length: 0,
- });
- Composite.add(engine.world, this.constraint);
- } else if (!this.constraint) {
- this.constraint = Constraint.create({
- bodyA: player,
- bodyB: this.sword,
- pointB: { x: 9, y: ((handle.position.y - this.sword.position.y)) },
- stiffness: 0.1,
- damping: 0.0001815,
- length: 0,
- });
- Composite.add(engine.world, this.constraint);
- }
- } else if (this.sword) {
- if (tech.isEnergyHealth) {
- m.energy = 0.01;
- m.immuneCycle = m.cycle + 30;
- }
- this.cycle = 0;
- Matter.Body.setAngularVelocity(this.sword, 0);
- Matter.Body.setMass(player, 5)
- Composite.remove(engine.world, this.sword);
- this.sword.parts.forEach(part => {
- Composite.remove(engine.world, part);
- const index = bullet.indexOf(part);
- if (index !== -1) {
- bullet.splice(index, 1);
- }
});
- this.sword = undefined;
- if (this.constraint) {
- Composite.remove(engine.world, this.constraint);
- this.constraint = undefined;
+ Composite.add(engine.world, this.constraint);
+ } else if (!this.constraint) {
+ this.constraint = Constraint.create({
+ pointA: player.position,
+ bodyB: this.sword,
+ pointB: { x: 9, y: ((handle.position.y - this.sword.position.y)) },
+ stiffness: (tech.infinityEdge ? 0.05 : 0.1),
+ damping: 0.001815,
+ length: 0,
+ });
+ Composite.add(engine.world, this.constraint);
+ }
+ } else if (this.sword) {
+ if (tech.isEnergyHealth) {
+ m.energy = 0.01;
+ m.immuneCycle = m.cycle + 30;
+ }
+ this.cycle = 0;
+ Matter.Body.setAngularVelocity(this.sword, 0);
+ player.force.x *= 0.01;
+ player.force.y *= 0.01;
+ Composite.remove(engine.world, this.sword);
+ this.sword.parts.forEach(part => {
+ Composite.remove(engine.world, part);
+ const index = bullet.indexOf(part);
+ if (index !== -1) {
+ bullet.splice(index, 1);
}
- this.bladeTrails = [];
- m.fireCDcycle = 0;
+ });
+ this.sword = undefined;
+ if (this.constraint) {
+ Composite.remove(engine.world, this.constraint);
+ this.constraint = undefined;
}
+ this.bladeTrails = [];
+ m.fireCDcycle = 0;
}
- if (this.sword) {
- for (let i = 0; i < this.bladeSegments.length; i++) {
- const blade = this.bladeSegments[i];
- const trail = this.bladeTrails[i] || [];
- const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y }));
- trail.push(vertices);
- if (trail.length > 10) {
- trail.shift();
- }
- this.bladeTrails[i] = trail;
+ }
+ },
+ createAndSwingSword(x = player.position.x, y = player.position.y, angle = m.angle) {
+ const handleWidth = 20;
+ const handleHeight = 150;
+ const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = handle;
+ handle.customName = "handle";
+ bullet[bullet.length - 1].do = () => { };
+ const pommelWidth = 30;
+ const pommelHeight = 40;
+ const pommelVertices = [
+ { x: x, y: y + handleHeight / 2 + pommelHeight / 2 },
+ { x: x + pommelWidth / 2, y: y + handleHeight / 2 },
+ { x: x, y: y + handleHeight / 2 - pommelHeight / 2 },
+ { x: x - pommelWidth / 2, y: y + handleHeight / 2 },
+ ];
+ const pommel = Bodies.fromVertices(x, y + handleHeight / 2, pommelVertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = pommel;
+ bullet[bullet.length - 1].do = () => { };
+ if (tech.soundSword) {
+ bullet[bullet.length - 1].draw = () => { };
+ }
+ // Blade setup
+ const bladeWidth = 100 * (tech.soundSword ? 3 : 1);
+ const bladeHeight = 20 * (tech.soundSword ? 3 : 1);
+ const numBlades = 15;
+ const extensionFactor = 5;
+ const bladeSegments = [];
+
+ if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const bladeX = x + i * (bladeWidth / 20);
+ const bladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
+
+ const vertices = [
+ { x: bladeX, y: bladeY - bladeHeight / 2 },
+ { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
+ ];
+
+ const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = blade;
+ bullet[bullet.length - 1].do = () => { };
+ if (tech.soundSword) {
+ bullet[bullet.length - 1].draw = () => { };
+ }
+ Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 270) * 15));
+ bladeSegments.push(blade);
+ }
+ } else {
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const mirroredBladeX = x - i * (bladeWidth / 20);
+ const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
+ const mirroredVertices = [
+ { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
+ { x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
+ { x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
+ { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
+ ];
+ const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = mirroredBlade;
+ bullet[bullet.length - 1].do = () => { };
+ if (tech.soundSword) {
+ bullet[bullet.length - 1].draw = () => { };
}
+ Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
+ bladeSegments.push(mirroredBlade);
+ }
+ }
+ bladeSegments.push(pommel);
+ const sword = Body.create({
+ parts: [handle, ...bladeSegments],
+ });
- for (let i = 0; i < this.bladeTrails.length; i++) {
- const trail = this.bladeTrails[i];
+ Composite.add(engine.world, sword);
+ Matter.Body.setPosition(sword, { x, y });
- const alphaStep = 1 / trail.length;
- let alpha = 0;
+ sword.collisionFilter.category = cat.bullet;
+ sword.collisionFilter.mask = cat.mobBullet | cat.powerup | cat.mob;
+ Body.scale(sword, -1, 1, { x, y });
- for (let j = 0; j < trail.length; j++) {
- const vertices = trail[j];
- ctx.beginPath();
- ctx.moveTo(vertices[0].x, vertices[0].y);
+ return { sword, bladeSegments };
+ },
+ renderDefault() {
+ if (this.sword) {
+ for (let i = 0; i < this.bladeSegments.length; i++) {
+ const blade = this.bladeSegments[i];
+ const trail = this.bladeTrails[i] || [];
+ const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y }));
+ trail.push(vertices);
+ if (trail.length > 10) {
+ trail.shift();
+ }
+ this.bladeTrails[i] = trail;
+ }
- for (let k = 1; k < vertices.length; k++) {
- ctx.lineTo(vertices[k].x, vertices[k].y);
- };
+ for (let i = 0; i < this.bladeTrails.length; i++) {
+ const trail = this.bladeTrails[i];
- alpha += alphaStep;
- ctx.closePath();
- if (tech.isEnergyHealth) {
- const eyeColor = m.fieldMeterColor;
- const r = eyeColor[1];
- const g = eyeColor[2];
- const b = eyeColor[3];
- const color = `#${r}${r}${g}${g}${b}${b}${Math.round(alpha * 255).toString(16).padStart(2, '0')}`;
- ctx.fillStyle = color;
- } else {
- ctx.fillStyle = `rgba(220, 20, 60, ${alpha})`;
- }
- ctx.fill();
- }
- }
- for (let i = 0; i < this.bladeSegments.length; i++) {
+ const alphaStep = 1 / trail.length;
+ let alpha = 0;
+
+ for (let j = 0; j < trail.length; j++) {
+ const vertices = trail[j];
ctx.beginPath();
- ctx.lineJoin = "miter";
- ctx.miterLimit = 100;
- ctx.strokeStyle = tech.isEnergyHealth ? m.fieldMeterColor : tech.isAmmoSword ? "#c0c0c0" : "crimson";
- ctx.lineWidth = 5;
- ctx.fillStyle = "black";
- ctx.moveTo(this.bladeSegments[i].vertices[0].x, this.bladeSegments[i].vertices[0].y);
- for (let j = 0; j < this.bladeSegments[i].vertices.length; j++) {
- ctx.lineTo(this.bladeSegments[i].vertices[j].x, this.bladeSegments[i].vertices[j].y)
+ ctx.moveTo(vertices[0].x, vertices[0].y);
+
+ for (let k = 1; k < vertices.length; k++) {
+ ctx.lineTo(vertices[k].x, vertices[k].y);
};
+
+ alpha += alphaStep;
ctx.closePath();
- ctx.stroke();
+ if (tech.isEnergyHealth) {
+ const eyeColor = m.fieldMeterColor;
+ const r = eyeColor[1];
+ const g = eyeColor[2];
+ const b = eyeColor[3];
+ const color = `#${r}${r}${g}${g}${b}${b}${Math.round(alpha * 255).toString(16).padStart(2, '0')}`;
+ ctx.fillStyle = color;
+ } else {
+ ctx.fillStyle = `rgba(220, 20, 60, ${alpha})`;
+ }
ctx.fill();
- ctx.lineJoin = "round";
- ctx.miterLimit = 10;
}
}
- if (this.sword) {
- for (let i = 0; i < mob.length; i++) {
- if (Matter.Query.collides(this.sword, [mob[i]]).length > 0) {
- const dmg = m.dmgScale * 6 * Math.sqrt(this.sword.speed);
- if (m.health < 0.9) {
+ for (let i = 0; i < this.bladeSegments.length; i++) {
+ ctx.beginPath();
+ ctx.lineJoin = "miter";
+ ctx.miterLimit = 100;
+ ctx.strokeStyle = tech.isEnergyHealth ? m.fieldMeterColor : tech.isAmmoSword ? "#c0c0c0" : "crimson";
+ ctx.lineWidth = 5;
+ ctx.fillStyle = "black";
+ ctx.moveTo(this.bladeSegments[i].vertices[0].x, this.bladeSegments[i].vertices[0].y);
+ for (let j = 0; j < this.bladeSegments[i].vertices.length; j++) {
+ ctx.lineTo(this.bladeSegments[i].vertices[j].x, this.bladeSegments[i].vertices[j].y)
+ };
+ ctx.closePath();
+ ctx.stroke();
+ ctx.fill();
+ ctx.lineJoin = "round";
+ ctx.miterLimit = 10;
+ }
+ }
+ },
+ collision() {
+ if (this.sword) {
+ for (let i = 0; i < mob.length; i++) {
+ if (Matter.Query.collides(this.sword, [mob[i]]).length > 0) {
+ const dmg = m.dmgScale * Math.sqrt(this.sword.speed) * (tech.sizeIllusion ? 1.1 : 1) * (tech.isStabSword ? 1.5 : 1) * (tech.infinityEdge ? 1.1 : 1);
+ if (!tech.soundSword) {
+ if (m.health < m.maxHealth) {
if (tech.isEnergyHealth) {
m.energy += 0.04;
} else {
- m.health += 0.001 * (dmg - mob[i].health);
+ m.health += 0.01 * (dmg - mob[i].health);
m.displayHealth();
}
} else {
@@ -31353,100 +32950,35 @@ const level = {
m.displayHealth();
}
}
- mob[i].damage(dmg, true);
- simulation.drawList.push({
- x: mob[i].position.x,
- y: mob[i].position.y,
- radius: Math.sqrt(dmg / this.sword.speed) * 50,
- color: simulation.mobDmgColor,
- time: simulation.drawTime
- });
- const angle = Math.atan2(mob[i].position.y - this.sword.position.y, mob[i].position.x - this.sword.position.x);
- this.sword.force.x -= Math.cos(angle) * 5;
- this.sword.force.y -= Math.sin(angle) * 5;
- break
}
+ mob[i].damage(dmg, true);
+ simulation.drawList.push({
+ x: mob[i].position.x,
+ y: mob[i].position.y,
+ radius: Math.abs(Math.log(dmg * this.sword.speed) * 40 * mob[i].damageReduction + 3),
+ color: (tech.soundSword ? "rgba(0, 0, 0, 0.3)" : simulation.mobDmgColor),
+ time: simulation.drawTime
+ });
+ break
}
}
- },
- createAndSwingSword(x = player.position.x, y = player.position.y, angle = m.angle) {
- if (this.cycle < m.cycle) {
- this.cycle = Infinity;
- m.fireCDcycle = Infinity;
- const handleWidth = 20;
- const handleHeight = 150;
- const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
- bullet[bullet.length] = handle;
- handle.customName = "handle";
- bullet[bullet.length - 1].do = () => { };
- const bladeWidth = 100;
- const bladeHeight = 20;
- const numBlades = 15;
- const extensionFactor = 5;
- const bladeSegments = [];
- if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
- for (let i = 0; i < numBlades; i++) {
- const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
- const bladeX = x + i * (bladeWidth / 20);
- const bladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
-
- const vertices = [
- { x: bladeX, y: bladeY - bladeHeight / 2 },
- { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
- { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
- { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
- ];
-
- const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
- bullet[bullet.length] = blade;
- bullet[bullet.length - 1].do = () => { };
- Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 270) * 15));
- bladeSegments.push(blade);
- }
- } else {
- for (let i = 0; i < numBlades; i++) {
- const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
- const mirroredBladeX = x - i * (bladeWidth / 20);
- const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
- const mirroredVertices = [
- { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
- { x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
- { x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
- { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
- ];
- const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
- bullet[bullet.length] = mirroredBlade;
- bullet[bullet.length - 1].do = () => { };
- Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
- bladeSegments.push(mirroredBlade);
- }
- }
- const sword = Body.create({
- parts: [handle, ...bladeSegments],
- });
-
- Composite.add(engine.world, sword);
- Matter.Body.setPosition(sword, { x, y });
-
- sword.collisionFilter.category = cat.bullet;
- sword.collisionFilter.mask = cat.mobBullet | cat.mob;
- Body.scale(sword, -1, 1, { x, y });
- // sword.frictionAir -= 0.01;
-
- return { sword, bladeSegments };
+ if (Matter.Query.collides(this.sword, [genisis]).length > 0) {
+ m.damage(-0.0142) //balanced!
}
- },
- fire() { }
- };
- b.guns.push(e);
- const gunArray = b.guns.filter(
- (obj, index, self) =>
- index === self.findIndex((item) => item.name === obj.name)
- );
- b.guns = gunArray;
- })();
+ }
+ }
+ };
+ b.guns.push(e);
+ const gunArray = b.guns.filter(
+ (obj, index, self) =>
+ index === self.findIndex((item) => item.name === obj.name)
+ );
+ b.guns = gunArray;
+ } else {
+ simulation.inGameConsole(`Thank you for using my sword mod
I'll save you the trouble of killing genisis
g.damage (Infinity)
`);
+ g.damage(Infinity);
}
- simulation.makeTextLog(`
arena by
Richard0820 `);
+ simulation.inGameConsole(`
arena by
Richard0820 `);
let index = 0;
let index2 = 0;
let { sword: sword, bladeSegments: bladeSegments } = createSword();
@@ -31457,21 +32989,13 @@ const level = {
level.exit.y = -2530;
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
- level.defaultZoom = 8000
+ level.defaultZoom = 2000
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#987654";
color.map = "#765432" //custom map color
color.block = "#876543";
door.isClosing = true;
door2.isClosing = true;
- spawnStuff(1000, -3100, 4450, 3125, 50 / simulation.difficultyMode);
- spawnStuff(5400, -2425, 200, 2250, 5 / simulation.difficultyMode);
- spawnStuff(5625, -2425, 2000, 275, 5 / simulation.difficultyMode);
- spawnStuff(5625, -2125, 850, 1125, 5 / simulation.difficultyMode);
- spawnStuff(6500, -2150, 475, 650, 5 / simulation.difficultyMode);
- spawnStuff(7000, -2125, 325, 275, 5 / simulation.difficultyMode);
- spawnStuff(5650, -950, 300, 450, 5 / simulation.difficultyMode);
- spawn.randomLevelBoss(4225, -575);
for (let i = 0; i < 5; i++) {
powerUps.spawn(-6075, -2000, "heal");
}
@@ -31511,7 +33035,7 @@ const level = {
this.maxLife = this.life;
}
- draw(ctx) {
+ draw() {
ctx.beginPath();
ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
@@ -31570,7 +33094,10 @@ const level = {
system.update();
}
function draw() {
- system.particles.forEach(particle => particle.draw(ctx));
+ system.particles.forEach(particle => particle.draw());
+ }
+ for (let i = 0; i < system.particles.length; i++) {
+ system.particles[i].life = 0;
}
level.custom = () => {
update();
@@ -31640,7 +33167,7 @@ const level = {
}
}
index2++;
- simulation.makeTextLog(`If you want to keep this sword, visit
https://github.com/Whyisthisnotavalable/n-scythe . The sword is there.`)
+ setTimeout(() => { simulation.inGameConsole(`If you want to keep this sword, visit
https://github.com/Whyisthisnotavalable/n-scythe . The sword is there.`) }, 1000)
}
for (let i = 0; i < bladeSegments.length; i++) {
const blade = bladeSegments[i];
@@ -31718,7 +33245,419 @@ const level = {
}
};
level.customTopLayer = () => { };
+ simulation.ephemera.push({
+ name: "genesis",
+ death: false,
+ pwuspawn: 0,
+ do() {
+ if (this.death === true) {
+ b.explosion(g.pos, 200 * Math.random(), "#000000")
+ setTimeout(() => {
+ if (this.pwuspawn === 0) {
+ powerUps.spawnBossPowerUp(g.pos.x, g.pos.y)
+ this.pwuspawn++;
+ }
+ simulation.removeEphemera(this.name);
+ simulation.removeEphemera("genisisScythe");
+ }, 1000);
+ }
+ if (g.health >= 0) {
+ if (g.health < g.maxHealth) {
+ g.health++;
+ }
+ const dist = Matter.Vector.magnitudeSquared(Matter.Vector.sub(genisis.position, player.position));
+ const time = Math.sqrt(dist) / 60;
+ g.alive = true;
+ g.targetX = m.pos.x + player.velocity.x * time;
+ g.targetY = m.pos.y + player.velocity.y * time;
+ } else {
+ this.death = true;
+ g.alive = false;
+ }
+ if (g.alive) {
+ g.cycle++;
+ g.move()
+ g.lookDefault();
+ g.drawDefault();
+ g.drawHealth();
+ genisis.force.y += g.mass * simulation.g
+ g.setFillColors();
+ control.right = g.angle > -Math.PI * 2 / 5 && g.angle < Math.PI * 2 / 5;
+ control.left = g.angle > Math.PI * 3 / 5 || g.angle < -Math.PI * 3 / 5;
+ control.down = g.angle > Math.PI * 3 / 10 && g.angle < Math.PI * 7 / 10;
+ if (Matter.Query.collides(genisis, body).length || Matter.Query.collides(genisisHead, map).length || Matter.Query.collides(genisisBodySensor, map).length && !control.down) {
+ if (g.buttonCD_jump < g.cycle) {
+ g.jump();
+ }
+ }
+ control.up = g.angle > -Math.PI * 6 / 10 && g.angle < -Math.PI * 4 / 10;
+
+ if (g.onGround) {
+ g.groundControl()
+ } else {
+ g.airControl()
+ }
+
+ if (g.pos.y > simulation.fallHeight) {
+ Matter.Body.setPosition(genisis, {
+ x: level.exit.x,
+ y: level.exit.y
+ })
+ }
+ } else {
+ genisis.collisionFilter.mask = cat.map | cat.body;
+ Matter.Body.setPosition(genisis, {
+ x: 0,
+ y: 0
+ })
+ }
+
+ if (simulation.testing) {
+ ctx.beginPath();
+ let bodyDraw = genisisJumpSensor.vertices;
+ ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
+ for (let j = 1; j < bodyDraw.length; ++j) {
+ ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
+ }
+ ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
+ ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
+ ctx.fill();
+
+ ctx.beginPath();
+ bodyDraw = genisisBody.vertices;
+ ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
+ for (let j = 1; j < bodyDraw.length; ++j) {
+ ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
+ }
+ ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
+ ctx.fillStyle = "rgba(0, 255, 255, 0.25)";
+ ctx.fill();
+
+ ctx.beginPath();
+ bodyDraw = genisisHead.vertices;
+ ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
+ for (let j = 1; j < bodyDraw.length; ++j) {
+ ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
+ }
+ ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
+ ctx.fillStyle = "rgba(255, 255, 0, 0.4)";
+ ctx.fill();
+
+ ctx.beginPath();
+ bodyDraw = genisisHeadSensor.vertices;
+ ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
+ for (let j = 1; j < bodyDraw.length; ++j) {
+ ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
+ }
+ ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
+ ctx.fillStyle = "rgba(0, 0, 255, 0.25)";
+ ctx.fill();
+
+ ctx.beginPath();
+ bodyDraw = genisisBodySensor.vertices;
+ ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
+ for (let j = 1; j < bodyDraw.length; ++j) {
+ ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
+ }
+ ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
+ ctx.fillStyle = "rgba(255, 0, 255, 0.25)";
+ ctx.fill();
+ }
+
+ Events.on(engine, "collisionStart", function (event) {
+ g.genisisOnGroundCheck(event);
+ GenisisCollisionChecks(event);
+ });
+ Events.on(engine, "collisionActive", function (event) {
+ g.genisisOnGroundCheck(event);
+ });
+ Events.on(engine, "collisionEnd", function (event) {
+ g.genisisOffGroundCheck(event);
+ });
+ }
+ })
+ let evo = {
+ isLongBlade: true,
+ isScytheRange: true,
+ scytheRange: 3,
+ isScytheRad: false,
+ scytheRad: 0,
+ isDoubleScythe: false,
+ isPhaseScythe: false,
+ isMeleeScythe: false,
+ isStunScythe: false,
+ };
+ simulation.ephemera.push({
+ name: "genisisScythe",
+ cycle: 0,
+ scythe: undefined,
+ bladeSegments: undefined,
+ bladeTrails: [],
+ angle: 0,
+ constraint: undefined,
+ fireCD: 0,
+ do() {
+ if (isOwned) {
+ if (g.health < 500 && g.health > 200) {
+ evo = {
+ isLongBlade: true,
+ isScytheRange: true,
+ scytheRange: 3,
+ isScytheRad: false,
+ scytheRad: 1,
+ isDoubleScythe: true,
+ isPhaseScythe: false,
+ isMeleeScythe: false,
+ isStunScythe: false,
+ };
+ } else if (g.health < 200 && g.health > 50) {
+ evo = {
+ isLongBlade: true,
+ isScytheRange: true,
+ scytheRange: 3,
+ isScytheRad: true,
+ scytheRad: 1,
+ isDoubleScythe: true,
+ isPhaseScythe: true,
+ isMeleeScythe: true,
+ isStunScythe: true,
+ };
+ } else if (g.health < 50) {
+ evo = {
+ isLongBlade: true,
+ isScytheRange: true,
+ scytheRange: 9,
+ isScytheRad: true,
+ scytheRad: 6,
+ isDoubleScythe: true,
+ isPhaseScythe: true,
+ isMeleeScythe: true,
+ isStunScythe: true,
+ };
+ }
+ if (g.cycle > this.fireCD && !this.scythe) {
+ this.fireCD = g.cycle + 30;
+ if (!this.scythe) {
+ ({ scythe: this.scythe, bladeSegments: this.bladeSegments } = this.createAndSwingScythe());
+ this.angle = g.angle;
+ }
+ }
+ if (this.scythe && g.cycle > this.cycle + 30 || !g.alive && this.scythe) {
+ Composite.remove(engine.world, this.scythe);
+ this.scythe.parts.forEach(part => {
+ Composite.remove(engine.world, part);
+ const index = bullet.indexOf(part);
+ if (index !== -1) {
+ bullet.splice(index, 1);
+ }
+ });
+ this.scythe = undefined;
+ this.bladeTrails = [];
+ } else {
+ if (this.scythe && !evo.isMeleeScythe) {
+ if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) {
+ Matter.Body.setAngularVelocity(this.scythe, -Math.PI * 0.15 - (evo.scytheRad ? evo.scytheRad * 0.1 : 0));
+ } else {
+ Matter.Body.setAngularVelocity(this.scythe, Math.PI * 0.15 + (evo.scytheRad ? evo.scytheRad * 0.1 : 0));
+ }
+ Matter.Body.setVelocity(this.scythe, {
+ x: Math.cos(this.angle) * 30,
+ y: Math.sin(this.angle) * 30
+ });
+ } else if (this.scythe && evo.isMeleeScythe) {
+ if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) {
+ Matter.Body.setAngularVelocity(this.scythe, -Math.PI * 0.1 + (evo.isStunScythe ? 0.1 : 0));
+ } else {
+ Matter.Body.setAngularVelocity(this.scythe, Math.PI * 0.1 - (evo.isStunScythe ? 0.1 : 0));
+ }
+ Matter.Body.setPosition(this.scythe, genisis.position);
+ }
+ }
+ if (this.scythe) {
+ for (let i = 0; i < this.bladeSegments.length; i++) {
+ const blade = this.bladeSegments[i];
+ const trail = this.bladeTrails[i] || [];
+ const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y }));
+ trail.push(vertices);
+ if (trail.length > 10) {
+ trail.shift();
+ }
+ this.bladeTrails[i] = trail;
+ }
+ for (let i = 0; i < this.bladeTrails.length; i++) {
+ const trail = this.bladeTrails[i];
+
+ const alphaStep = 1 / trail.length;
+ let alpha = 0;
+
+ for (let j = 0; j < trail.length; j++) {
+ const vertices = trail[j];
+ ctx.beginPath();
+ ctx.moveTo(vertices[0].x, vertices[0].y);
+
+ for (let k = 1; k < vertices.length; k++) {
+ ctx.lineTo(vertices[k].x, vertices[k].y);
+ };
+
+ alpha += alphaStep;
+ ctx.closePath();
+ ctx.fillStyle = `rgba(100, 20, 255, ${alpha})`;
+ ctx.fill();
+ }
+ }
+ for (let i = 0; i < this.bladeSegments.length; i++) {
+ ctx.beginPath();
+ ctx.lineJoin = "miter";
+ ctx.miterLimit = 100;
+ ctx.strokeStyle = `rgb(100, 20, 255)`;
+ ctx.lineWidth = 5;
+ ctx.fillStyle = "black";
+ ctx.moveTo(this.bladeSegments[i].vertices[0].x, this.bladeSegments[i].vertices[0].y);
+ for (let j = 0; j < this.bladeSegments[i].vertices.length; j++) {
+ ctx.lineTo(this.bladeSegments[i].vertices[j].x, this.bladeSegments[i].vertices[j].y)
+ };
+ ctx.closePath();
+ ctx.stroke();
+ ctx.fill();
+ ctx.lineJoin = "round";
+ ctx.miterLimit = 10;
+ }
+ }
+ if (this.scythe) {
+ for (let i = 0; i < mob.length; i++) {
+ if (Matter.Query.collides(this.scythe, [mob[i]]).length > 0) {
+ const dmg = m.dmgScale * 0.12 * 2.73 * (evo.isLongBlade ? 1.3 : 1) * (evo.scytheRange ? evo.scytheRange * 1.15 : 1) * (evo.isDoubleScythe ? 0.9 : 1) * (evo.scytheRad ? evo.scytheRad * 1.5 : 1);
+ mob[i].damage(dmg, true);
+ simulation.drawList.push({
+ x: mob[i].position.x,
+ y: mob[i].position.y,
+ radius: Math.sqrt(dmg) * 50,
+ color: simulation.mobDmgColor,
+ time: simulation.drawTime
+ });
+ if (!evo.isMeleeScythe) {
+ const angle = Math.atan2(mob[i].position.y - this.scythe.position.y, mob[i].position.x - this.scythe.position.x);
+ this.scythe.force.x += Math.cos(angle) * 2;
+ this.scythe.force.y += Math.sin(angle) * 2;
+ }
+ if (evo.isStunScythe) {
+ mobs.statusStun(mob[i], 90);
+ }
+ break
+ }
+ }
+ if (Matter.Query.collides(this.scythe, [player]).length > 0 && m.immuneCycle < m.cycle) {
+ const dmg = 0.02 * (evo.isLongBlade ? 1.3 : 1) * (evo.scytheRange ? evo.scytheRange * 1.15 : 1) * (evo.isDoubleScythe ? 0.9 : 1) * (evo.scytheRad ? evo.scytheRad * 1.5 : 1); // actual scythe scallings one tap the player so this is nerfed for genisis
+ m.damage(dmg);
+ m.immuneCycle = m.cycle + 10;
+ simulation.drawList.push({
+ x: player.position.x,
+ y: player.position.y,
+ radius: Math.sqrt(dmg) * 50,
+ color: simulation.mobDmgColor,
+ time: simulation.drawTime
+ });
+ if (!evo.isMeleeScythe) {
+ const angle = Math.atan2(player.position.y - this.scythe.position.y, player.position.x - this.scythe.position.x);
+ this.scythe.force.x += Math.cos(angle) * 2;
+ this.scythe.force.y += Math.sin(angle) * 2;
+ }
+ }
+ }
+ }
+ },
+ createAndSwingScythe(x = genisis.position.x, y = genisis.position.y, angle = g.angle) {
+ this.cycle = g.cycle + 60 + (evo.scytheRange * 6);
+ const handleWidth = 20;
+ const handleHeight = 200 + (evo.isLongBlade ? 30 : 0) + (evo.isMeleeScythe ? 200 : 0);
+ const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = handle;
+ bullet[bullet.length - 1].do = () => { };
+ const bladeWidth = 100;
+ const bladeHeight = 20;
+ const numBlades = 10 + (evo.isLongBlade ? 1 : 0) + (evo.isMeleeScythe ? 3 : 0);
+ const extensionFactor = 5.5;
+ const bladeSegments = [];
+ if (!evo.isDoubleScythe) {
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const bladeX = x - handleWidth / 2 + i * (bladeWidth / 2) - extensionFactorFraction * (bladeWidth / 2);
+ const bladeY = y + handleHeight / 2 - i * (bladeHeight / (3 ** i));
+
+ const vertices = [
+ { x: bladeX, y: bladeY - bladeHeight / 2 },
+ { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
+ ];
+
+ const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = blade;
+ bullet[bullet.length - 1].do = () => { };
+ Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5));
+ bladeSegments.push(blade);
+ }
+ } else {
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const bladeX = x - handleWidth / 2 + i * (bladeWidth / 2) - extensionFactorFraction * (bladeWidth / 2);
+ const bladeY = y + handleHeight / 2 - i * (bladeHeight / (3 ** i));
+
+ const vertices = [
+ { x: bladeX, y: bladeY - bladeHeight / 2 },
+ { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
+ ];
+
+ const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = blade;
+ bullet[bullet.length - 1].do = () => { };
+ Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5));
+ bladeSegments.push(blade);
+ }
+
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const bladeX = x + handleWidth / 2 - i * (bladeWidth / 2) + extensionFactorFraction * (bladeWidth / 2);
+ const bladeY = y - handleHeight / 2 - i * (bladeHeight / (3 ** i));
+
+ const vertices = [
+ { x: bladeX, y: bladeY - bladeHeight / 2 },
+ { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
+ { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
+ ];
+
+ const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = blade;
+ bullet[bullet.length - 1].do = () => { };
+ Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5) + Math.PI);
+ bladeSegments.push(blade);
+ }
+ }
+ const scythe = Body.create({
+ parts: [handle, ...bladeSegments],
+ });
+ Composite.add(engine.world, scythe);
+ Matter.Body.setPosition(scythe, { x, y });
+ scythe.collisionFilter.category = cat.body;
+ scythe.collisionFilter.mask = cat.mobBullet | cat.player;
+ if (!evo.isMeleeScythe) {
+ setTimeout(() => {
+ scythe.collisionFilter.mask = cat.mobBullet | cat.mob | cat.player;
+ }, 1000)
+ }
+ if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
+ Body.scale(scythe, -1, 1, { x, y });
+ }
+
+ scythe.frictionAir -= 0.01;
+
+ return { scythe, bladeSegments };
+ },
+ })
spawn.mapRect(-10000, 0, 20000, 2000);
spawn.mapRect(-10000, -10000, 2000, 10000);
spawn.mapRect(8000, -10000, 2000, 10000);
@@ -31730,56 +33669,54 @@ const level = {
spawn.mapRect(4000, -10, 100, 20);
spawn.mapRect(-1000, -10000, 2000, 8000);
- spawn.mapRect(-500, -10000, 1000, 9700);
- function createSword(x = 0, y = 0, angle = 0) { //sword asthetic
+ // spawn.mapRect(-500, -10000, 1000, 9700);
+ function createSword(x = 0, y = 0) { //sword asthetic
const handleWidth = 20;
const handleHeight = 150;
const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
bullet[bullet.length] = handle;
handle.customName = "handle";
bullet[bullet.length - 1].do = () => { };
- const bladeWidth = 100;
- const bladeHeight = 20;
+ const pommelWidth = 30;
+ const pommelHeight = 40;
+ const pommelVertices = [
+ { x: x, y: y + handleHeight / 2 + pommelHeight / 2 },
+ { x: x + pommelWidth / 2, y: y + handleHeight / 2 },
+ { x: x, y: y + handleHeight / 2 - pommelHeight / 2 },
+ { x: x - pommelWidth / 2, y: y + handleHeight / 2 },
+ ];
+ const pommel = Bodies.fromVertices(x, y + handleHeight / 2, pommelVertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = pommel;
+ bullet[bullet.length - 1].do = () => { };
+ if (tech.soundSword) {
+ bullet[bullet.length - 1].draw = () => { };
+ }
+ // Blade setup
+ const bladeWidth = 100 * (tech.soundSword ? 3 : 1);
+ const bladeHeight = 20 * (tech.soundSword ? 3 : 1);
const numBlades = 15;
const extensionFactor = 5;
const bladeSegments = [];
- if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
- for (let i = 0; i < numBlades; i++) {
- const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
- const bladeX = x + i * (bladeWidth / 20);
- const bladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
-
- const vertices = [
- { x: bladeX, y: bladeY - bladeHeight / 2 },
- { x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
- { x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
- { x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
- ];
-
- const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
- bullet[bullet.length] = blade;
- bullet[bullet.length - 1].do = () => { };
- Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 270) * 15));
- bladeSegments.push(blade);
- }
- } else {
- for (let i = 0; i < numBlades; i++) {
- const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
- const mirroredBladeX = x - i * (bladeWidth / 20);
- const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
- const mirroredVertices = [
- { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
- { x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
- { x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
- { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
- ];
- const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
- bullet[bullet.length] = mirroredBlade;
- bullet[bullet.length - 1].do = () => { };
- Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
- bladeSegments.push(mirroredBlade);
+ for (let i = 0; i < numBlades; i++) {
+ const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
+ const mirroredBladeX = x - i * (bladeWidth / 20);
+ const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
+ const mirroredVertices = [
+ { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
+ { x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
+ { x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
+ { x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
+ ];
+ const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
+ bullet[bullet.length] = mirroredBlade;
+ bullet[bullet.length - 1].do = () => { };
+ if (tech.soundSword) {
+ bullet[bullet.length - 1].draw = () => { };
}
+ Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
+ bladeSegments.push(mirroredBlade);
}
+ bladeSegments.push(pommel);
const sword = Body.create({
parts: [handle, ...bladeSegments],
});
@@ -31788,28 +33725,948 @@ const level = {
Matter.Body.setPosition(sword, { x, y });
sword.collisionFilter.category = cat.bullet;
- sword.collisionFilter.mask = cat.bullet;
+ sword.collisionFilter.mask = cat.mobBullet | cat.powerup | cat.mob;
Body.scale(sword, -1, 1, { x, y });
- Body.rotate(sword, Math.PI / 1.05)
- sword.frictionAir = -0.01;
+ Body.rotate(sword, Math.PI + Math.PI / 15)
return { sword, bladeSegments };
}
- function spawnStuff(x, y, width, height, num) {
- for (let i = 0; i < num; i++) {
- randomMob(x + width * Math.random(), y + height * Math.random(), Infinity)
+ },
+ soft() {
+ simulation.inGameConsole(`
`);
+ simulation.inGameConsole(`
soft by
Richard0820 `);
+ simulation.inGameConsole("
The lasers deal less damage the higher level you are ")
+ const portals = [];
+ portals.push(level.portal({
+ x: -1525,
+ y: -250
+ }, Math.PI / 2, {
+ x: 1100,
+ y: -1025
+ }, Math.PI / 2))
+ const soft = {
+ createCloth(x, y, radius, width, height, attachToPlayer = false, stayStill = false, options, touchPlayer = true, constrictionStrength = 0.001) {
+ const bodies = [];
+ const constraints = [];
+ const otherCons = [];
+ const bodyWidth = radius;
+ const bodyHeight = radius;
+ const numRows = Math.ceil(height / bodyHeight);
+ const numCols = Math.ceil(width / bodyWidth);
+
+ for (let i = 0; i < numRows; i++) {
+ for (let j = 0; j < numCols; j++) {
+ const posX = x + j * bodyWidth + bodyWidth / 2;
+ const posY = y + i * bodyHeight + bodyHeight / 2;
+
+ const rect = Matter.Bodies.circle(posX, posY, (bodyWidth + bodyHeight) / 4, options);
+ rect.collisionFilter.category = cat.body;
+ rect.collisionFilter.mask = (touchPlayer ? cat.player | cat.body | cat.bullet | cat.mob | cat.mobBullet : cat.body | cat.bullet | cat.mob | cat.mobBullet);
+ rect.classType = "body";
+
+ Composite.add(engine.world, rect);
+
+ bodies.push(rect);
+ }
+ }
+
+ for (let i = 0; i < numRows; i++) {
+ for (let j = 0; j < numCols; j++) {
+ const bodyIndexA = i * numCols + j;
+ if (j < numCols - 1) {
+ const bodyIndexB = i * numCols + (j + 1);
+ const constraint = Constraint.create({
+ bodyA: bodies[bodyIndexA],
+ bodyB: bodies[bodyIndexB],
+ stiffness: 0.06,
+ damping: 0.001
+ });
+ Composite.add(engine.world, constraint);
+ constraints.push(constraint);
+ }
+ if (i < numRows - 1) {
+ const bodyIndexB = (i + 1) * numCols + j;
+ const constraint = Constraint.create({
+ bodyA: bodies[bodyIndexA],
+ bodyB: bodies[bodyIndexB],
+ stiffness: 0.06,
+ damping: 0.001
+ });
+ Composite.add(engine.world, constraint);
+ constraints.push(constraint);
+ }
+ }
+ }
+
+ for (let i = 0; i < numRows - 1; i++) {
+ for (let j = 0; j < numCols - 1; j++) {
+ const bodyA = bodies[i * numCols + j];
+ const bodyB = bodies[(i + 1) * numCols + j + 1];
+ const constraint = Constraint.create({
+ bodyA: bodyA,
+ bodyB: bodyB,
+ stiffness: 0.02
+ });
+ constraints.push(constraint);
+ }
+ }
+
+ for (let i = 0; i < numRows - 1; i++) {
+ for (let j = 1; j < numCols; j++) {
+ const bodyA = bodies[i * numCols + j];
+ const bodyB = bodies[(i + 1) * numCols + j - 1];
+ const constraint = Constraint.create({
+ bodyA: bodyA,
+ bodyB: bodyB,
+ stiffness: 0.02
+ });
+ constraints.push(constraint);
+ }
+ }
+ if (stayStill) {
+ for (let i = 0; i < bodies.length; i++) {
+ const by = bodies[i];
+ const spawnX = by.position.x + bodyWidth / 2;
+ const spawnY = by.position.y + bodyHeight / 2;
+ const isLastColumn = (i + 1) % numCols === 0;
+ const isFirstColumn = i % numCols === 0;
+ const stiffness = constrictionStrength * (isLastColumn || isFirstColumn ? 100 : 1); // Apply extra stiffness to first and last columns
+
+ const cost = Constraint.create({
+ bodyA: by,
+ pointB: { x: spawnX, y: spawnY },
+ stiffness: stiffness,
+ length: 0
+ });
+
+ Composite.add(engine.world, cost);
+ otherCons.push(cost);
+ }
+ }
+ if (attachToPlayer) {
+ for (let i = 0; i < bodies.length; i++) {
+ const cost = Constraint.create({
+ bodyA: bodies[i],
+ pointB: player.position,
+ stiffness: 0.0005,
+ length: 0
+ });
+ Composite.add(engine.world, cost);
+ }
+ }
+
+ return { bodies, constraints, otherCons };
+ },
+ clothOptions: {
+ frictionAir: 0.005,
+ },
+ isOuterBoundary(body, bodies) { //unused
+ const neighbors = [
+ { x: body.position.x + 1, y: body.position.y },
+ { x: body.position.x - 1, y: body.position.y },
+ { x: body.position.x, y: body.position.y + 1 },
+ { x: body.position.x, y: body.position.y - 1 }
+ ];
+
+ for (let i = 0; i < neighbors.length; i++) {
+ const neighbor = neighbors[i];
+ const isNeighbor = bodies.some(b => b.position.x === neighbor.x && b.position.y === neighbor.y);
+ if (!isNeighbor) {
+ return true;
+ }
+ }
+ return false;
+ },
+ draw(cloth) {
+ ctx.beginPath();
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = "rgba(0,0,0,0.3)";
+ ctx.fillStyle = "black";
+ for (let i = 0, len = cloth.constraints.length; i < len; ++i) {
+ const constraint = cloth.constraints[i];
+ ctx.moveTo(constraint.bodyA.position.x, constraint.bodyA.position.y);
+ ctx.lineTo(constraint.bodyB.position.x, constraint.bodyB.position.y);
+ }
+ ctx.closePath();
+ ctx.fill();
+ ctx.stroke();
+ },
+ addGravity(bodies, magnitude) {
+ for (var i = 0; i < bodies.length; i++) {
+ bodies[i].force.y += bodies[i].mass * magnitude;
+ }
+ },
+ gravity(cloth) {
+ this.addGravity(cloth.bodies, simulation.g);
+ },
+ breaker(cloth, percentage = 0.5) {
+ const totalConstraints = cloth.constraints.length;
+ const constraintsToRemove = Math.ceil(totalConstraints * percentage);
+
+ for (let i = 0; i < constraintsToRemove; i++) {
+ const randomIndex = Math.floor(Math.random() * cloth.constraints.length);
+
+ let removedConstraint = cloth.constraints.splice(randomIndex, 1)[0];
+ Composite.remove(engine.world, removedConstraint);
+ }
+ },
+ destroyer(cloth, percentage = 0.99999) {
+ const otherCons = cloth.otherCons.length;
+ const otherCons2Remove = Math.ceil(otherCons * percentage);
+
+ for (let i = 0; i < otherCons2Remove; i++) {
+ const randomIndex = Math.floor(Math.random() * cloth.otherCons.length);
+
+ let removedConstraint = cloth.otherCons.splice(randomIndex, 1)[0];
+ Composite.remove(engine.world, removedConstraint);
+ }
+ },
+ annihilate(cloth) {
+ const totalBodies = cloth.bodies.length;
+ for (let i = 0; i < totalBodies; i++) {
+ const removeBody = cloth.bodies[i];
+ Composite.remove(engine.world, removeBody);
+ }
+ cloth.bodies.length = 0; // Clear the bodies array after removal
}
}
- function randomMob(x, y, chance = 1) {
- if (spawn.spawnChance(chance) || chance === Infinity) {
- const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
- spawn[pick](x, y);
+ const clothArray = [];
+ clothArray.push(soft.createCloth(-100, 0, 50, 1000, 300, false, true, soft.clothOptions, true))
+ clothArray.push(soft.createCloth(-2000, 2375, 50, 1525, 200, false, true, soft.clothOptions, true))
+ clothArray.push(soft.createCloth(-3950, 125, 50, 1800, 125, false, true, soft.clothOptions, true))
+ const annoyingStuff = {
+ lasers(where, angle) {
+ const vertexCollision = function (v1, v1End, domain) {
+ for (let i = 0; i < domain.length; ++i) {
+ let vertices = domain[i].vertices;
+ const len = vertices.length - 1;
+ for (let j = 0; j < len; j++) {
+ results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[j],
+ v2: vertices[j + 1]
+ };
+ }
+ }
+ results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2) best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[0],
+ v2: vertices[len]
+ };
+ }
+ }
+ };
+
+ const seeRange = 7000;
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ const look = {
+ x: where.x + seeRange * Math.cos(angle),
+ y: where.y + seeRange * Math.sin(angle)
+ };
+ // vertexCollision(where, look, mob);
+ vertexCollision(where, look, map);
+ vertexCollision(where, look, body);
+ if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]);
+ if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
+ m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
+ const dmg = 0.5 / simulation.dmgScale;
+ m.damage(dmg);
+ simulation.drawList.push({ //add dmg to draw queue
+ x: best.x,
+ y: best.y,
+ radius: dmg * 1500,
+ color: "rgba(80,0,255,0.5)",
+ time: 20
+ });
+ }
+ //draw beam
+ if (best.dist2 === Infinity) best = look;
+ ctx.moveTo(where.x, where.y);
+ ctx.lineTo(best.x, best.y);
+ },
+ laserBoss(x, y, radius = 30) {
+ mobs.spawn(x, y, 6, radius, "#f00");
+ let me = mob[mob.length - 1];
+
+ setTimeout(() => { //fix mob in place, but allow rotation
+ me.constraint = Constraint.create({
+ pointA: {
+ x: me.position.x,
+ y: me.position.y
+ },
+ bodyB: me,
+ stiffness: 1,
+ damping: 1
+ });
+ Composite.add(engine.world, me.constraint);
+ }, 2000); //add in a delay in case the level gets flipped left right
+ me.count = 0;
+ me.frictionAir = 0.03;
+ // me.torque -= me.inertia * 0.002
+ spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
+ Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
+ me.damageReduction = 0.25
+ me.isBoss = true;
+ // spawn.shield(me, x, y, 1); //not working, not sure why
+ me.onDeath = function () {
+ powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ };
+ me.rotateVelocity = -Math.min(0.0045, 0.0015 * simulation.accelScale * simulation.accelScale) * (level.levelsCleared > 8 ? 1 : -1)
+ me.do = function () {
+ this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors
+ this.checkStatus();
+
+ if (!this.isStunned) {
+ //check if slowed
+ let slowed = false
+ for (let i = 0; i < this.status.length; i++) {
+ if (this.status[i].type === "slow") {
+ slowed = true
+ break
+ }
+ }
+ if (!slowed) {
+ this.count++
+ Matter.Body.setAngle(this, this.count * this.rotateVelocity)
+ Matter.Body.setAngularVelocity(this, 0)
+ }
+
+ ctx.beginPath();
+ for (let i = 0; i < this.vertices.length; i++) {
+ if (Math.sin((2 * Math.PI * simulation.cycle) / (50 + i)) > 0) {
+ this.lasers(this.vertices[i], Math.atan2(this.vertices[i].y - this.position.y, this.vertices[i].x - this.position.x));
+ }
+ }
+ ctx.strokeStyle = "#50f";
+ ctx.lineWidth = 1.5;
+ ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
+ ctx.stroke(); // Draw it
+ ctx.setLineDash([]);
+ ctx.lineWidth = 20;
+ ctx.strokeStyle = "rgba(80,0,255,0.07)";
+ ctx.stroke(); // Draw it
+ }
+ };
+ me.lasers = function (where, angle) {
+ const vertexCollision = function (v1, v1End, domain) {
+ for (let i = 0; i < domain.length; ++i) {
+ let vertices = domain[i].vertices;
+ const len = vertices.length - 1;
+ for (let j = 0; j < len; j++) {
+ results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[j],
+ v2: vertices[j + 1]
+ };
+ }
+ }
+ results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2) best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[0],
+ v2: vertices[len]
+ };
+ }
+ }
+ };
+
+ const seeRange = 7000;
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ const look = {
+ x: where.x + seeRange * Math.cos(angle),
+ y: where.y + seeRange * Math.sin(angle)
+ };
+ // vertexCollision(where, look, mob);
+ vertexCollision(where, look, map);
+ vertexCollision(where, look, body);
+ if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]);
+ if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
+ m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
+ const dmg = 0.5 / simulation.dmgScale;
+ m.damage(dmg);
+ simulation.drawList.push({ //add dmg to draw queue
+ x: best.x,
+ y: best.y,
+ radius: dmg * 1500,
+ color: "rgba(80,0,255,0.5)",
+ time: 20
+ });
+ }
+ //draw beam
+ if (best.dist2 === Infinity) best = look;
+ ctx.moveTo(where.x, where.y);
+ ctx.lineTo(best.x, best.y);
+ }
}
- if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
- const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
- spawn[pick](x, y);
+ }
+ level.setPosToSpawn(-350, 0);
+ level.exit.x = 1075;
+ level.exit.y = 20;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#aaFFFF55";
+ spawn.mapRect(900, 50, 425, 250);
+ // spawn.mapRect(900, -1050, 0.1, 1350);
+ spawn.mapRect(-475, 2375, 1800, 250);
+ spawn.mapRect(-4400, 2375, 2475, 250);
+ spawn.mapRect(-4400, -450, 250, 3075);
+ spawn.mapRect(-4400, -450, 2225, 250);
+ spawn.mapRect(-2425, -1300, 250, 1100);
+ spawn.mapRect(-2425, -1300, 3825, 250);
+ spawn.mapRect(1325, -1300, 250, 3925);
+ spawn.mapRect(-875, -1300, 250, 1375);
+ spawn.mapRect(-725, 50, 675, 250);
+ spawn.mapRect(-875, 175, 175, 125);
+ for (let i = 0; i < 6; i++) {
+ spawn.mapRect(-4175, 2000 - i * 375, 50, 125);
+ }
+ spawn.mapRect(-3925, 162.5, 50, 125);
+ spawn.mapRect(-2175, 162.5, 50, 125);
+ spawn.mapRect(300, 2025, 250, 600);
+ spawn.mapRect(-2150, 175, 50, 25);
+ spawn.mapRect(-2150, 250, 50, 25);
+ spawn.mapRect(-900, 175, 50, 25);
+ spawn.mapRect(-900, 250, 50, 25);
+ spawn.mapRect(-1600, 175, 50, 25);
+ spawn.mapRect(-1500, 175, 50, 25);
+ spawn.mapRect(-1600, 250, 50, 25);
+ spawn.mapRect(-1500, 250, 50, 25);
+ spawn.mapRect(-1925, 175, 50, 25);
+ spawn.mapRect(-1925, 250, 50, 25);
+ spawn.mapRect(-1200, 175, 50, 25);
+ spawn.mapRect(-1200, 250, 50, 25);
+ spawn.bodyRect(-2125, 200, 1250, 50);
+ spawn.debris(425, 200, 50);
+ spawn.debris(-650, 2100, 50);
+ spawn.debris(-3000, 1925, 50);
+ spawn.debris(-3825, 1550, 50);
+ spawn.debris(-2475, -50, 50);
+
+ const bouncyBody = body[body.length - 1];
+ bouncyBody.restitution = 0.9;
+ spawn.mapVertex(-2175 + 1300 / 2, -1050 + 1225 / 2, "0 -400 -100 -300 -100 0 100 0 100 -300");
+
+ spawn.mapVertex(-4150 + 1975 / 2, -200 + 2575 / 2, "0 -800 -200 -600 -200 0 0 200 200 0 200 -600 0 200");
+ const mapWithVertex = map[map.length - 1];
+ let index1 = 0;
+ level.custom = () => {
+ level.exit.drawAndCheck();
+
+ level.enter.draw();
+
+ if (player.position.x > 425 && index1 === 0) {
+ soft.breaker(clothArray[0], 0.7);
+ soft.destroyer(clothArray[0]);
+ index1++;
+ }
+ if (player.position.y > 1300 && index1 === 1) {
+ setTimeout(() => {
+ soft.breaker(clothArray[0], 1);
+ soft.annihilate(clothArray[0]);
+ clothArray.splice(0, 1);
+ }, 1000); //prevents bugs
+ simulation.inGameConsole("Couldn't be so simple, could it?", 2000 * Math.random());
+ index1++;
+ }
+ };
+ level.customTopLayer = () => {
+ for (let i = 0; i < portals.length; i++) {
+ portals[i][2].query();
+ portals[i][3].query();
+ portals[i][0].draw();
+ portals[i][1].draw();
+ portals[i][2].draw();
+ portals[i][3].draw();
+ }
+ ctx.beginPath();
+ if (Math.sin((2 * Math.PI * simulation.cycle) / (50)) > 0) {
+ annoyingStuff.lasers(mapWithVertex.vertices[0], Math.atan2(mapWithVertex.vertices[0].y - mapWithVertex.position.y, mapWithVertex.vertices[0].x - mapWithVertex.position.x));
+ annoyingStuff.lasers(mapWithVertex.vertices[3], Math.atan2(mapWithVertex.vertices[3].y - mapWithVertex.position.y, mapWithVertex.vertices[3].x - mapWithVertex.position.x));
+ }
+ if (Math.sin((2 * Math.PI * simulation.cycle) / (51)) > 0) {
+ annoyingStuff.lasers(mapWithVertex.vertices[1], Math.atan2(mapWithVertex.vertices[1].y - mapWithVertex.position.y, mapWithVertex.vertices[1].x - mapWithVertex.position.x));
+ annoyingStuff.lasers(mapWithVertex.vertices[4], Math.atan2(mapWithVertex.vertices[4].y - mapWithVertex.position.y, mapWithVertex.vertices[4].x - mapWithVertex.position.x));
+ }
+ if (Math.sin((2 * Math.PI * simulation.cycle) / (52)) > 0) {
+ annoyingStuff.lasers(mapWithVertex.vertices[2], Math.atan2(mapWithVertex.vertices[2].y - mapWithVertex.position.y, mapWithVertex.vertices[2].x - mapWithVertex.position.x));
+ annoyingStuff.lasers(mapWithVertex.vertices[5], Math.atan2(mapWithVertex.vertices[5].y - mapWithVertex.position.y, mapWithVertex.vertices[5].x - mapWithVertex.position.x));
+ }
+
+ ctx.strokeStyle = "#000";
+ ctx.lineWidth = 1.5;
+ ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
+ ctx.stroke(); // Draw it
+ ctx.setLineDash([]);
+ ctx.lineWidth = 20;
+ ctx.strokeStyle = "rgba(0,0,0,0.07)";
+ ctx.stroke(); // Draw it
+
+ for (let i = 0; i < clothArray.length; i++) {
+ soft.draw(clothArray[i]);
+ soft.gravity(clothArray[i]);
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = "rgba(69, 69, 69, 0.1)";
+ ctx.rect(-475, 175, 425, 2300);
+ ctx.rect(900, 175, 425, 2300);
+ ctx.rect(-875, 175, 400, 10000);
+ ctx.rect(-4200, -250, 2025, 2775);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.fillStyle = (m.pos.x < -725 && m.pos.y < 175) ? `rgba(68, 68, 68, ${Math.max(0.3, Math.min((-775 - m.pos.x) / 100, 0.99))})` : color.map;
+ ctx.rect(-875, 50, 175, 150);
+ ctx.fill();
+
+ };
+ annoyingStuff.laserBoss(-1525, 1025);
+ spawn.pulsar(-1525, -850);
+ spawn.pulsar(1125, 1600);
+ spawn.pulsar(-250, 1600);
+ spawn.pulsar(-1450, 1600);
+ spawn.pulsar(-2950, 1750);
+ spawn.pulsar(-3375, 1750);
+ spawn.pulsar(-3825, 1300);
+ spawn.pulsar(-3825, 850);
+ spawn.pulsar(-3450, 50);
+ spawn.pulsar(-2925, 50);
+ spawn.pulsar(-1900, -400);
+ spawn.pulsar(-1200, -400);
+
+ powerUps.addResearchToLevel()
+ powerUps.directSpawn(-775, 125, "tech");
+ if (!level.isNextLevelPowerUps && powerUp[powerUp.length - 1]) powerUp[powerUp.length - 1].collisionFilter.mask = cat.map | cat.body | cat.powerUp
+ spawn.bodyRect(-875, 75, 25, 100);
+ let hardBody = body[body.length - 1];
+ hardBody.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.powerUp
+ },
+ flappyGon() { //community map by digin
+ level.announceMobTypes();
+ simulation.inGameConsole(`
flappy n-gon by
Digin `);
+ setTimeout(() => { simulation.inGameConsole("
gravity is a
choice "); }, 1000);
+ setTimeout(() => { simulation.inGameConsole("everyone will fly"); }, 2000);
+ setTimeout(() => { simulation.inGameConsole("
jump from the post and find out "); }, 3000);
+ level.setPosToSpawn(0, -50); //normal spawn
+ level.exit.x = 8600;
+ level.exit.y = -1100;
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#55FF55";
+
+ var slimey = level.hazard(-200, -10, 9000, 10);
+
+ // allow "flight"
+
+ const old_playerOffGroundCheck = playerOffGroundCheck;
+
+ playerOffGroundCheck = (event) => {
+ old_playerOffGroundCheck(event);
+ if (player.position.y < -300) {
+ m.onGround = true;
+ }
+ };
+
+ const oldNextLevel = level.nextLevel;
+ level.nextLevel = () => { // clear the flappy effects, because apparently there's no established api for this
+ playerOffGroundCheck = old_playerOffGroundCheck;
+
+ level.nextLevel = oldNextLevel;
+ oldNextLevel();
+ };
+
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); // standard bumps
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
+ spawn.mapRect(level.exit.x - 100, level.exit.y + 40, 200, 100);
+
+ // room basis
+ spawn.mapRect(-200, 0, 9000, 100);
+ spawn.mapRect(-200, -1500, 9000, 100);
+ spawn.mapRect(-200, -1500, 100, 1500);
+ spawn.mapRect(8700, -1500, 100, 1500);
+
+ // somewhat randomized flappy pylons
+ const pylon = 1500; // height of the entire pylon assembly
+ for (var i = 0; i < 10; i++) {
+ var xbasis = 700 + i * 750;
+ var window = 300 + (10 - i) * 50;
+ var toph = pylon - window - 400 + (Math.random() - 0.5) * 400 - i * 50;
+ if (i == 0) { // on the first one, the lower pile will always have a height of 300
+ toph = pylon - window - 300;
+ }
+ spawn.mapRect(xbasis, -1500, 100, toph);
+ spawn.mapRect(xbasis, toph + window - pylon, 100, pylon - toph - window);
+ if (i < 9) {
+ spawn.randomMob(xbasis + 300, Math.random() * -1400);
+ }
+ else {
+ spawn.randomLevelBoss(xbasis + 300, Math.random() * -1400);
}
+ if (i == 5) {
+ spawn.secondaryBossChance(xbasis + 300, Math.random() * -1400);
+ }
+ }
+
+ level.custom = () => {
+ level.exit.drawAndCheck();
+ player.onGround = true;
+ level.enter.draw();
+ };
+ const slimeRise = 0.15;
+ level.customTopLayer = () => {
+ slimey.height += slimeRise;
+ slimey.min.y -= slimeRise;
+ slimey.query();
+ };
+ powerUps.addResearchToLevel();
+ },
+ rings() {
+ level.announceMobTypes();
+ simulation.inGameConsole(`
rings by
ThatLittleFrog `);
+ setTimeout(() => {
+ simulation.inGameConsole("
go up ");
+ }, 2000);
+ level.setPosToSpawn(0, -2000); // spawn high up so you can go to the bottom of the lowest ring without tripping the too-low reset
+ level.exit.x = 0;
+ level.exit.y = -6400;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#d8dadf";
+
+ function mkrect(x, y, w, h) {
+ let who = body[body.length] = Bodies.rectangle(x, y, w, h, {
+ collisionFilter: {
+ category: cat.map,
+ mask: cat.body | cat.player | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
+ },
+ inertia: Infinity, //prevents rotation
+ isNotHoldable: true,
+ friction: 1,
+ frictionStatic: 1,
+ restitution: 0,
+ frictionAir: 1,
+ isStatic: true
+ });
+ Composite.add(engine.world, who);
+ who.classType = "body";
+ return body[body.length - 1];
+ }
+
+ function makeRing(x, y, linegth, thicc = 200) { // I don't feel like doing trigonometry, so linegth is slightly different from the radius
+ var _shape = [undefined, undefined, undefined, undefined];
+ _shape[0] = mkrect(x - linegth / 2 - thicc, y - linegth / 2 - thicc, linegth, thicc);
+ _shape[1] = mkrect(x - linegth / 2 - thicc, y - linegth / 2, thicc, linegth);
+ _shape[2] = mkrect(x - linegth / 2, y + linegth / 2 - thicc, linegth, thicc);
+ _shape[3] = mkrect(x + linegth / 2 - thicc, y - linegth / 2 - thicc, thicc, linegth - thicc * 2);
+ let ret = {
+ shape: _shape,
+ x: x,
+ y: y,
+ r: 0,
+ rot(ang) {
+ this.r = ang;
+ let offs = 0;
+ for (let shape of this.shape) {
+ offs += Math.PI / 2;
+ Matter.Body.setAngle(shape, ang);
+ if (shape == this.shape[3]) {
+ Matter.Body.setPosition(shape, {
+ x: this.x + Math.cos(ang + offs) * (linegth / 2 - thicc / 2) - Math.cos(ang + offs + Math.PI / 2) * thicc,
+ y: this.y + Math.sin(ang + offs) * (linegth / 2 - thicc / 2) - Math.sin(ang + offs + Math.PI / 2) * thicc
+ });
+ }
+ else {
+ Matter.Body.setPosition(shape, {
+ x: this.x + Math.cos(ang + offs) * (linegth / 2 - thicc / 2),
+ y: this.y + Math.sin(ang + offs) * (linegth / 2 - thicc / 2)
+ });
+ }
+ }
+ },
+ rotBy(ang) {
+ this.rot(this.r + ang);
+ }
+ };
+ ret.rot(0);
+ return ret;
+ }
+
+ var inner = makeRing(level.enter.x, level.enter.y, 1000);
+ var mid = makeRing(level.enter.x, level.enter.y, 2500);
+ var mid2 = makeRing(level.enter.x, level.enter.y, 4000);
+ var out = makeRing(level.enter.x, level.enter.y, 6000);
+
+ spawn.randomMob(level.enter.x + 250, level.enter.y);
+
+ spawn.randomMob(level.enter.x + 1250, level.enter.y);
+ spawn.randomMob(level.enter.x - 1250, level.enter.y);
+ spawn.randomMob(level.enter.x, level.enter.y + 1250);
+ spawn.randomMob(level.enter.x, level.enter.y - 1250);
+ spawn.randomMob(level.enter.x + 1250, level.enter.y + 500);
+ spawn.randomMob(level.enter.x - 1250, level.enter.y + 500);
+ spawn.randomMob(level.enter.x + 500, level.enter.y + 1250);
+ spawn.randomMob(level.enter.x + 500, level.enter.y - 1250);
+
+ spawn.randomMob(level.enter.x + 2750, level.enter.y);
+ spawn.randomMob(level.enter.x - 2750, level.enter.y);
+ spawn.randomMob(level.enter.x, level.enter.y + 2750);
+ spawn.randomMob(level.enter.x, level.enter.y - 2750);
+ spawn.randomMob(level.enter.x + 2750, level.enter.y + 500);
+ spawn.randomMob(level.enter.x - 2750, level.enter.y + 500);
+ spawn.randomMob(level.enter.x + 500, level.enter.y + 2750);
+ spawn.randomMob(level.enter.x + 500, level.enter.y - 2750);
+
+ spawn.randomLevelBoss(level.enter.x, level.enter.y - 4250);
+ spawn.secondaryBossChance(level.enter.x, level.enter.y + 4250);
+
+ level.custom = () => {
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ inner.rotBy(0.01);
+ mid.rotBy(-0.005);
+ mid2.rotBy(0.003);
+ out.rotBy(-0.002);
+ };
+
+ powerUps.addResearchToLevel();
+ },
+ trial() { // trial, collab between Cirryn and Tarantula Hawk
+ simulation.inGameConsole(`
trial by
Cirryn and Tarantula Hawk `);
+ level.setPosToSpawn(0, -50);
+ level.exit.x = 4150;
+ level.exit.y = -30;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800;
+ simulation.zoomTransition(level.defaultZoom);
+ document.body.style.backgroundColor = "#d8dadf";
+ const button = level.button(2000, 0);
+ const door = level.door(3930, -300, 40, 300, 300, 10);
+ door.isClosing = false;
+ var didTrialBegin = false;
+
+ const customMob = {
+ assassin(x, y) { // modified slasher
+ mobs.spawn(x, y, 3, 30, "black");
+ let me = mob[mob.length - 1];
+ Matter.Body.rotate(me, 2 * Math.PI * Math.random());
+ me.accelMag = 0.0008 * simulation.accelScale;
+ me.torqueMagnitude = 0.00002 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
+ me.frictionStatic = 0;
+ me.frictionAir = 0.08;
+ me.delay = 120 * simulation.CDScale;
+ me.cd = 0;
+ spawn.shield(me, x, y);
+ me.damageReduction = 0;
+ const start = window.performance.now(); // they only last ~ten seconds
+ const lifespan = 15000 + 700 * (Math.random() - 0.5);
+ me.onDamage = function () {
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
+ };
+ me.do = function () {
+ this.checkStatus();
+ this.alwaysSeePlayer();
+ this.attraction();
+ this.health = 1 - (window.performance.now() - start) / lifespan;
+ if (this.health < 0) {
+ this.death();
+ }
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 0.05);
+ };
+ },
+ mercenary(x, y) { // fast boi
+ mobs.spawn(x, y, 3, 60, "white");
+ let me = mob[mob.length - 1];
+ Matter.Body.rotate(me, 2 * Math.PI * Math.random());
+ me.accelMag = 0.001 * simulation.accelScale;
+ me.torqueMagnitude = 0.00001 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
+ me.frictionStatic = 0;
+ me.frictionAir = 0.03;
+ me.delay = 120 * simulation.CDScale;
+ me.cd = 0;
+ spawn.shield(me, x, y);
+ me.damageReduction = 0;
+ const start = window.performance.now(); // they only last ~ten seconds
+ const lifespan = 25000 + 700 * (Math.random() - 0.5);
+ me.onDamage = function () {
+ Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
+ };
+ me.do = function () {
+ this.checkStatus();
+ this.attraction();
+ this.health = 1 - (window.performance.now() - start) / lifespan;
+ if (this.health < 0) {
+ this.death();
+ }
+ this.alwaysSeePlayer();
+ };
+ }
+ // eventually maybe add more custom mob types
+ };
+
+ function randomWave(count, source) { // generates a wave list from a source
+ // checks in spawn first, then customMob, for the sources
+ var ret = [];
+ for (var i = 0; i < count; i++) {
+ var pick = source[Math.floor(Math.random() * source.length)];
+ if (spawn[pick]) {
+ ret.push(spawn[pick]);
+ }
+ else if (customMob[pick]) {
+ ret.push(customMob[pick]);
+ }
+ }
+ return ret;
+ }
+
+ function wave(mobs) { // takes a list of functions that accept x,y coordinates to spawn a mob and spawns them in the ceiling
+ for (var i = 0; i < mobs.length; i++) {
+ var x = 1000 + 2400 * i / mobs.length + 200 * (Math.random() - 0.5);
+ var y = -950 - 100 * Math.random();
+ mobs[i](x, y);
+ }
+ const ammoCount = Math.random() * (10 - simulation.difficulty / 4);
+ for (var i = 0; i < ammoCount; i++) {
+ powerUps.spawn(3300, -1000, "ammo");
+ }
+ }
+
+ level.custom = () => {
+ door.openClose();
+ level.exit.drawAndCheck();
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ button.query();
+ button.draw();
+ door.draw();
+ if (!button.isUp && !didTrialBegin) {
+ didTrialBegin = true;
+ simulation.inGameConsole('
The Trial has begun. ');
+
+ setTimeout(() => {
+ simulation.inGameConsole('
first wave (domitable) ');
+ wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
+ }, 3000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
second wave (domitable) ');
+ wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
+ }, 13000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
third wave (indomitable) ');
+ wave(randomWave(4, ["assassin"]));
+ }, 23000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
fourth wave (domitable) ');
+ wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
+ }, 39000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
fifth wave (domitable) ');
+ wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
+ }, 49000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
sixth wave (indomitable) ');
+ wave(randomWave(7, ["mercenary"]));
+ }, 59000);
+
+ setTimeout(() => {
+ simulation.inGameConsole('
seventh wave (boss) ');
+ spawn.randomLevelBoss(700, -1000);
+ var mainBoss = mob[mob.length - 1];
+ mainBoss.oldOnDeath = mainBoss.onDeath;
+ mainBoss.onDeath = () => {
+ door.isClosing = false;
+ powerUps.spawn(4150, -30, "tech");
+ powerUps.spawn(4150, -30, "tech");
+ mainBoss.oldOnDeath();
+ }
+ spawn.secondaryBossChance(3500, -1000);
+ }, 86000);
+
+ door.isClosing = true;
+ }
+ };
+
+ spawn.mapRect(-100, 0, 10000, 10000); // the left half of the room
+ spawn.mapRect(-10000, -300, 9900, 10000);
+ spawn.mapRect(-100, -300, 400, 100);
+ spawn.mapRect(200, -800, 100, 500);
+ spawn.mapRect(200, -800, 500, 100);
+ spawn.mapRect(600, -1000, 100, 200);
+
+ spawn.mapRect(600, -1100, 3000, 100); // the ceiling
+
+ spawn.mapRect(3500, -1000, 100, 200); // the right half of the room
+ spawn.mapRect(3500, -800, 500, 100);
+ spawn.mapRect(3900, -800, 100, 500);
+ spawn.mapRect(3900, -300, 400, 100);
+ spawn.mapRect(4300, -300, 10000, 10000);
+
+ for (var i = 0; i < 4; i++) { // "door" at the entrance
+ spawn.bodyRect(200, -200 + i * 50, 20, 50);
+ }
+
+ for (var i = 0; i < 5; i++) { // some random rubble in the first half of the room
+ spawn.bodyRect(400 + Math.random() * 1000, -200, 40 + Math.random() * 40, 40 + Math.random() * 40);
}
+
+ powerUps.addResearchToLevel(); //needs to run after mobs are spawneds
},
// ********************************************************************************************************
// ********************************************************************************************************
@@ -32226,27 +35083,27 @@ const level = {
const buttonDoor = level.button(400, 0)
let instruction = 0
- level.trainingText(`use your
field to pick up the gun power up`)
+ level.trainingText(`use your
field to pick up ${powerUps.orb.gun()}`)
level.custom = () => {
if (instruction === 0 && simulation.isChoosing) {
instruction++
- level.trainingText(`
use your field to pick up the gun power up
+ level.trainingText(`
use your field to pick up ${powerUps.orb.gun()}
choose a
gun `)
} else if (instruction === 1 && !simulation.isChoosing) {
instruction++
- level.trainingText(`
use your field to pick up the gun power up
+ level.trainingText(`use your field to pick up ${powerUps.orb.gun()}
choose a gun
use the left mouse button to shoot the mobs `)
} else if (instruction === 2 && mob.length === 0) {
instruction++
- level.trainingText(`use your field to pick up the gun power up
+ level.trainingText(`use your field to pick up ${powerUps.orb.gun()}
choose a gun
use the left mouse button to shoot the mobs
drop a block on the red button to open the door`)
} else if (instruction === 3 && !door.isClosing) {
instruction++
- level.trainingText(`use your field to pick up the gun power up
+ level.trainingText(`use your field to pick up ${powerUps.orb.gun()}
choose a gun
use the left mouse button to shoot the mobs
put a block on the red button to open the door `)
@@ -32448,16 +35305,15 @@ const level = {
spawn.mapRect(1375, -16, 50, 50);
spawn.mapRect(1400, -8, 50, 25);
spawn.mapRect(750, -24, 650, 100);
- powerUps.directSpawn(875, -40, "heal", false, null, 15);
- powerUps.directSpawn(1075, -50, "heal", false, null, 25);
- powerUps.directSpawn(1275, -65, "heal", false, null, 35);
+ powerUps.directSpawn(875, -40, "heal", false, 15);
+ powerUps.directSpawn(1075, -50, "heal", false, 25);
+ powerUps.directSpawn(1275, -65, "heal", false, 35);
const door = level.door(1612.5, -175, 25, 190, 185, 3)
spawn.mapRect(1600, -1200, 500, 850); //exit roof
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
nailGun() {
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32467,7 +35323,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("nail gun")
b.guns[b.activeGun].ammo = 0
simulation.updateGunHUD();
@@ -32552,7 +35408,6 @@ const level = {
spawn.mapRect(1600, -600, 425, 250);
},
shotGun() {
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32562,7 +35417,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("shotgun")
// b.guns[b.activeGun].ammo = 0
// simulation.updateGunHUD();
@@ -32634,7 +35489,6 @@ const level = {
spawn.mapRect(1600, -600, 425, 250);
},
superBall() {
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32644,7 +35498,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("super balls")
// b.guns[b.activeGun].ammo = 0
// simulation.updateGunHUD();
@@ -32718,7 +35572,6 @@ const level = {
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
matterWave() { //fire wave through the map to kill mosb
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32728,7 +35581,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("wave")
// b.guns[b.activeGun].ammo = 0
// simulation.updateGunHUD();
@@ -32805,7 +35658,6 @@ const level = {
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
missile() { //fire a missile to kill mobs and trigger button
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32815,7 +35667,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("missiles")
// b.guns[b.activeGun].ammo = 0
// simulation.updateGunHUD();
@@ -32894,7 +35746,6 @@ const level = {
spawn.mapRect(2025, -2800, 1075, 2450);
},
stack() { //stack blocks to get to exit
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32904,7 +35755,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
let instruction = 0
level.trainingText(`use your field to stack the blocks `)
@@ -32946,7 +35797,6 @@ const level = {
spawn.mapVertex(1300, 0, "400 0 -500 0 -300 -125 400 -125"); //base
},
mine() { //kill mobs and tack their bodies
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(300, -50); //normal spawn
spawn.mapRect(250, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -32956,7 +35806,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("mine")
let instruction = 0
@@ -33030,7 +35880,6 @@ const level = {
spawn.mapVertex(1300, 0, "400 0 -600 0 -300 -125 400 -125"); //base
},
grenades() { //jump at the top of the elevator's path to go extra high
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(-50, -10, 100, 20); //small platform for player
level.exit.x = 1900;
@@ -33040,7 +35889,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("grenades")
const elevator1 = level.elevator(550, -100, 180, 25, -840, 0.003, {
@@ -33150,7 +35999,6 @@ const level = {
spawn.nodeGroup(1200, -1500, "grenadier", 7);
},
harpoon() { //jump at the top of the elevator's path to go extra high
- level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(-50, -10, 100, 20); //small platform for player
level.exit.x = 1900;
@@ -33160,7 +36008,7 @@ const level = {
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
- b.removeAllGuns();
+ b.resetAllGuns();
b.giveGuns("harpoon")
let instruction = 0
diff --git a/js/lore.js b/js/lore.js
index ff5372e5..16bccb33 100644
--- a/js/lore.js
+++ b/js/lore.js
@@ -38,7 +38,7 @@ const lore = {
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
// document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
- simulation.makeTextLog(`lore .unlockTesting()`, Infinity);
+ simulation.inGameConsole(`lore .unlockTesting()`, Infinity);
sound.portamento(50)
sound.portamento(83.333)
@@ -48,7 +48,7 @@ const lore = {
color: "#f20",
voice: undefined,
text: function (say) {
- simulation.makeTextLog(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
+ simulation.inGameConsole(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
lore.talkingColor = this.color
const utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-AU" //"en-IN"; //de-DE en-GB fr-FR en-US en-AU
@@ -61,7 +61,7 @@ const lore = {
voice: undefined,
text: function (say) {
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
- simulation.makeTextLog(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
+ simulation.inGameConsole(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
lore.talkingColor = this.color
if (lore.isSpeech) {
const utterance = new SpeechSynthesisUtterance(say);
@@ -95,7 +95,7 @@ const lore = {
color: "#f20",
text: function (say) {
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
- simulation.makeTextLog(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
+ simulation.inGameConsole(`input.audio(${(Date.now() / 1000).toFixed(0)} s ): "${say} "`, Infinity);
lore.talkingColor = this.color
if (lore.isSpeech) {
utterance = new SpeechSynthesisUtterance(say);
@@ -358,7 +358,7 @@ const lore = {
setInterval(() => {
if (Math.random() < 0.5) {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
- level.difficultyIncrease(simulation.difficultyMode)
+ // level.difficultyIncrease(simulation.difficultyMode)
} else {
spawn.randomLevelBoss(500 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5))
}
@@ -622,8 +622,8 @@ const lore = {
console.log(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`)
console.log(`Latitude: ${latitude} °, Longitude: ${longitude} °`)
lore.miriam.text("We tracked the location down to this Latitude and Longitude:")
- simulation.makeTextLog(`Latitude: ${latitude} °, Longitude: ${longitude} °`, Infinity);
- simulation.makeTextLog(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`, Infinity);
+ simulation.inGameConsole(`Latitude: ${latitude} °, Longitude: ${longitude} °`, Infinity);
+ simulation.inGameConsole(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`, Infinity);
}
function error() {
@@ -693,9 +693,9 @@ const lore = {
setInterval(() => {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
}, 500); //every 1/2 seconds
- setInterval(() => {
- level.difficultyIncrease(simulation.difficultyMode)
- }, 5000); //every 5 seconds
+ // setInterval(() => {
+ // level.difficultyIncrease(simulation.difficultyMode)
+ // }, 5000); //every 5 seconds
},
() => {
lore.talkingColor = "#dff";
@@ -769,13 +769,13 @@ const lore = {
},
() => {
lore.miriam.text("We can spawn power ups with this command:")
- simulation.makeTextLog(`powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
+ simulation.inGameConsole(`powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
powerUps.spawn(player.position.x, player.position.y - 100, "heal")
},
() => {
setTimeout(() => {
lore.miriam.text("or we can make a bunch of them:")
- simulation.makeTextLog(`for (let i = 0; i < 100; i++) powerUps.spawn(0, 500, "coupling")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 100; i++) powerUps.spawn(0, 500, "coupling")`, Infinity);
for (let i = 0; i < 100; i++) powerUps.spawn(5 - 10 * Math.random(), -500 * Math.random(), "coupling")
}, 2000);
},
@@ -798,9 +798,9 @@ const lore = {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("I'll spawn some more power ups for you.")
- simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
- simulation.makeTextLog(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "ammo")
spawn.dragonFlyBoss(-1400, -300);
spawn.dragonFlyBoss(1400, -300);
@@ -820,9 +820,9 @@ const lore = {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.anand.text("DragonFlyBoss is my favorite.")
- simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
- simulation.makeTextLog(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "ammo")
spawn.historyBoss(0, -400);
spawn.powerUpBossBaby(-1500, -100);
@@ -841,7 +841,7 @@ const lore = {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("Here are some extra tech.")
- simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "tech")`, Infinity);
+ simulation.inGameConsole(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "tech")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(0, -200 - i * 40, "tech")
spawn.historyBoss(0, -400);
spawn.blinkBoss(-1400, -300);
@@ -902,7 +902,7 @@ const lore = {
x: 0,
y: -500
})
- simulation.makeTextLog(`Matter.Body.setPosition(player, { x: 0, y: -500 })`, 180);
+ simulation.inGameConsole(`Matter.Body.setPosition(player, { x: 0, y: -500 })`, 180);
}, 1500);
} else if (m.alive) {
@@ -1180,7 +1180,7 @@ const lore = {
// return product_Range(r + 1, n) / product_Range(1, n - r);
// }
// }
- // simulation.makeTextLog(`n = ${combinations(tech.tech.length + b.guns.length + m.fieldUpgrades.length, 50).toExponential(10)}`, Infinity);
+ // simulation.inGameConsole(`n = ${combinations(tech.tech.length + b.guns.length + m.fieldUpgrades.length, 50).toExponential(10)}`, Infinity);
// lore.miriam.text(`There are roughly 5 times 10 to the 60 possible combinations. `)
// },
// () => { lore.miriam.text("Even if each simulation took 1 nano-second,") },
diff --git a/js/mob.js b/js/mob.js
index 349d6875..01a7f049 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -794,27 +794,6 @@ const mobs = {
}
}
},
- // invulnerability() {
- // if (this.isInvulnerable) {
- // if (this.invulnerabilityCountDown > 0) {
- // this.invulnerabilityCountDown--
- // //graphics //draw a super shield?
- // 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.fillStyle = `rgba(${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},0.5)`
- // // ctx.fill();
- // ctx.strokeStyle = "rgba(255,255,255,0.4)";
- // ctx.stroke();
- // } else {
- // this.isInvulnerable = false
- // this.damageReduction = this.startingDamageReduction
- // }
- // }
- // },
grow() {
if (this.seePlayer.recall) {
if (this.radius < 80) {
@@ -926,10 +905,7 @@ const mobs = {
spawn.bomb(this.position.x, this.position.y + this.radius * 0.7, 9 + Math.ceil(this.radius / 15), 5);
//add spin and speed
Matter.Body.setAngularVelocity(mob[mob.length - 1], (Math.random() - 0.5) * 0.5);
- Matter.Body.setVelocity(mob[mob.length - 1], {
- x: this.velocity.x,
- y: this.velocity.y
- });
+ Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x, y: this.velocity.y });
//spin for mob as well
Matter.Body.setAngularVelocity(this, (Math.random() - 0.5) * 0.25);
}
@@ -1078,7 +1054,7 @@ const mobs = {
})
}
} else if (tech.isMobLowHealth && this.health < 0.25) {
- dmg *= 3.22
+ dmg *= 3
simulation.ephemera.push({
name: "damage outline",
@@ -1109,7 +1085,7 @@ const mobs = {
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000
dmg *= this.damageReduction
//energy and heal drain should be calculated after damage boosts
- if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon
+ if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon * level.isReducedRegen
dmg /= Math.sqrt(this.mass)
}
@@ -1161,13 +1137,26 @@ const mobs = {
this.onDeath(this); //custom death effects
this.removeConsBB();
this.alive = false; //triggers mob removal in mob[i].replace(i)
+ // console.log(this.shieldCount)
if (this.isDropPowerUp) {
- // if (true) {
- // //killing a mob heals for the last damage you took
-
-
- // }
+ if (level.isMobDeathHeal) {
+ for (let i = 0; i < mob.length; i++) {
+ if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 && mob[i].alive) { //700
+ if (mob[i].health < 1) {
+ mob[i].health += 0.33 + this.isBoss
+ if (mob[i].health > 1) mob[i].health = 1
+ simulation.drawList.push({
+ x: mob[i].position.x,
+ y: mob[i].position.y,
+ radius: mob[i].radius + 20,
+ color: "rgba(0,255,100,0.5)",
+ time: 10
+ });
+ }
+ }
+ }
+ }
if (this.isSoonZombie) { //spawn zombie on death
this.leaveBody = false;
let count = 5 //delay spawn cycles
@@ -1197,6 +1186,34 @@ const mobs = {
});
}
}
+ if (level.isMobRespawn && !this.isBoss && 0.33 > Math.random()) {
+ simulation.drawList.push({
+ x: this.position.x,
+ y: this.position.y,
+ radius: 30,
+ color: `#fff`,
+ time: 20
+ });
+ simulation.drawList.push({
+ x: this.position.x,
+ y: this.position.y,
+ radius: 20,
+ color: `#fff`,
+ time: 40
+ });
+ simulation.drawList.push({
+ x: this.position.x,
+ y: this.position.y,
+ radius: 10,
+ color: `#fff`,
+ time: 60
+ });
+ setTimeout(() => {
+ const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
+ const size = 16 + Math.ceil(Math.random() * 15)
+ spawn[pick](this.position.x, this.position.y, size);
+ }, 1000);
+ }
if (tech.healSpawn && Math.random() < tech.healSpawn) {
powerUps.spawn(this.position.x + 20 * (Math.random() - 0.5), this.position.y + 20 * (Math.random() - 0.5), "heal");
simulation.drawList.push({
@@ -1222,13 +1239,16 @@ const mobs = {
});
}
- if (tech.deathSkipTime && !m.isBodiesAsleep) {
+ if (tech.isVerlet && !m.isBodiesAsleep) {
requestAnimationFrame(() => {
- simulation.timePlayerSkip((this.isBoss ? 45 : 25) * tech.deathSkipTime)
+ simulation.timePlayerSkip(this.isBoss ? 60 : 30)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
}); //wrapping in animation frame prevents errors, probably
}
- if (tech.isEnergyLoss) m.energy *= 0.8;
+ if (tech.isEnergyLoss) {
+ m.energy -= 0.05;
+ if (m.energy < 0) m.energy = 0
+ }
powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
mobs.mobDeaths++
@@ -1263,6 +1283,10 @@ const mobs = {
bullet[bullet.length - 1].endCycle = simulation.cycle + 900 //15 seconds
this.leaveBody = false; // no body since it turned into the bot
}
+ if (tech.isMobDeathImmunity) {
+ const immuneTime = 360
+ if (m.immuneCycle < m.cycle + immuneTime) m.immuneCycle = m.cycle + immuneTime; //player is immune to damage
+ }
if (tech.isAddRemoveMaxHealth) {
if (!this.isBoss) {
const amount = 0.0025
@@ -1276,34 +1300,12 @@ const mobs = {
m.setMaxHealth();
}
}
-
- // if (this.isBoss && this.isDropPowerUp) {
- // powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
- // powerUps.spawn(this.position.x - 20, this.position.y, "research", false)
- // powerUps.spawn(this.position.x - 40, this.position.y, "research", false)
- // powerUps.spawn(this.position.x + 40, this.position.y, "research", false)
- // powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
- // powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
- // powerUps.spawn(this.position.x, this.position.y + 40, "heal", false)
- // powerUps.spawn(this.position.x, this.position.y - 40, "heal", false)
- // } else {
- // const amount = 0.005
- // if (tech.isEnergyHealth) {
- // if (m.maxEnergy > amount) {
- // tech.healMaxEnergyBonus -= amount
- // m.setMaxEnergy();
- // }
- // } else if (m.maxHealth > amount) {
- // tech.extraMaxHealth -= amount //decrease max health
- // m.setMaxHealth();
- // }
- // }
}
if (tech.cloakDuplication && !this.isBoss) {
tech.cloakDuplication -= 0.01
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
- } else if (tech.isShieldAmmo && this.shield && !this.isExtraShield && this.isDropPowerUp) {
+ } else if (tech.isShieldAmmo && this.shield && this.shieldCount === 1) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) {
type = "heal"
diff --git a/js/player.js b/js/player.js
index e65d5af4..9bd7a427 100644
--- a/js/player.js
+++ b/js/player.js
@@ -8,7 +8,7 @@ const m = {
// let vector = Vertices.fromPath("0 40 50 40 50 115 0 115 30 130 20 130"); //player as a series of vertices
let vertices = Vertices.fromPath("0,40, 50,40, 50,115, 30,130, 20,130, 0,115, 0,40"); //player as a series of vertices
playerBody = Bodies.fromVertices(0, 0, vertices);
- jumpSensor = Bodies.rectangle(0, 46, 36, 6, {
+ jumpSensor = Bodies.rectangle(0, 46, 36, 6, { //(0, 46, 50, 6, { //for wall jumping
//this sensor check if the player is on the ground to enable jumping
sleepThreshold: 99999999999,
isSensor: true
@@ -83,16 +83,21 @@ const m = {
Fx: 0.016, //run Force on ground //
jumpForce: 0.42,
setMovement() {
- // m.Fx = 0.08 / mass * tech.squirrelFx
+ // console.log(player.mass)
// m.FxAir = 0.4 / mass / mass
- m.Fx = tech.baseFx * m.fieldFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
- m.jumpForce = tech.baseJumpForce * m.fieldJump * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
+ m.Fx = tech.baseFx * m.fieldFx * m.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
+ m.jumpForce = tech.baseJumpForce * m.fieldJump * m.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
},
FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70,
yOffGoal: 70,
onGround: false, //checks if on ground or in air
lastOnGroundCycle: 0, //use to calculate coyote time
+ coyoteCycles: 5,
+ hardLanding: 130,
+ squirrelFx: 1,
+ squirrelJump: 1,
+ velocitySmooth: { x: 0, y: 0 },//use for drawing skin's velocity gel tail
standingOn: undefined,
numTouching: 0,
crouch: false,
@@ -210,10 +215,7 @@ const m = {
m.crouch = true;
m.yOffGoal = m.yOffWhen.crouch;
if ((playerHead.position.y - player.position.y) < 0) {
- Matter.Body.setPosition(playerHead, {
- x: player.position.x,
- y: player.position.y + 9.1740767
- })
+ Matter.Body.setPosition(playerHead, { x: player.position.x, y: player.position.y + 9.1740767 })
}
}
},
@@ -222,14 +224,12 @@ const m = {
m.crouch = false;
m.yOffGoal = m.yOffWhen.stand;
if ((playerHead.position.y - player.position.y) > 0) {
- Matter.Body.setPosition(playerHead, {
- x: player.position.x,
- y: player.position.y - 30.28592321
- })
+ Matter.Body.setPosition(playerHead, { x: player.position.x, y: player.position.y - 30.28592321 })
}
}
},
hardLandCD: 0,
+ hardLandCDScale: 1,
checkHeadClear() {
if (Matter.Query.collides(headSensor, map).length > 0) {
return false
@@ -239,14 +239,9 @@ const m = {
},
buttonCD_jump: 0, //cool down for player buttons
jump() {
- // if (!m.onGround) m.lastOnGroundCycle = 0 //m.cycle - tech.coyoteTime
m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
//apply a fraction of the jump force to the body the player is jumping off of
- Matter.Body.applyForce(m.standingOn, m.pos, {
- x: 0,
- y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5)
- });
-
+ Matter.Body.applyForce(m.standingOn, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
player.force.y = -m.jumpForce; //player jump force
Matter.Body.setVelocity(player, { //zero player y-velocity for consistent jumps
x: player.velocity.x,
@@ -260,7 +255,7 @@ const m = {
if (!(input.down) && m.checkHeadClear() && m.hardLandCD < m.cycle) m.undoCrouch();
} else if (input.down || m.hardLandCD > m.cycle) {
m.doCrouch(); //on ground && not crouched and pressing s or down
- } else if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
+ } else if (input.up && m.buttonCD_jump + 20 < m.cycle) {
m.jump()
}
const moveX = player.velocity.x - m.moverX //account for mover platforms
@@ -290,8 +285,7 @@ const m = {
},
airControl() {
//check for coyote time jump
- // if (input.up && m.buttonCD_jump + 20 + tech.coyoteTime < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + tech.coyoteTime > m.cycle) m.jump()
- if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + 5 > m.cycle) m.jump()
+ if (input.up && m.buttonCD_jump + 20 < m.cycle && m.lastOnGroundCycle + m.coyoteCycles > m.cycle) m.jump()
//check for short jumps //moving up //recently pressed jump //but not pressing jump key now
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {
@@ -348,7 +342,7 @@ const m = {
}
if (
!tech.tech[i].isNonRefundable &&
- !tech.tech[i].isFromAppliedScience &&
+ // !tech.tech[i].isFromAppliedScience &&
!tech.tech[i].isAltRealityTech
) {
totalTech += tech.tech[i].count
@@ -366,6 +360,7 @@ const m = {
tech.duplication = 0;
tech.extraMaxHealth = 0;
tech.totalCount = 0;
+ tech.removeCount = 0;
const randomBotCount = b.totalBots()
b.zeroBotCount()
//remove all bullets, respawn bots
@@ -384,14 +379,17 @@ const m = {
b.inventoryGun = 0;
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].have = false;
- if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
+ if (b.guns[i].ammo !== Infinity) {
+ b.guns[i].ammo = 0;
+ b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
+ }
}
//give random guns
for (let i = 0; i < totalGuns; i++) b.giveGuns()
//randomize ammo based on ammo/ammoPack count
for (let i = 0, len = b.inventory.length; i < len; i++) {
- if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.15 + 0.3 * (Math.random() - 0.5))))
+ if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (2.5 + 0.3 * (Math.random() - 0.5))))
}
// console.log(b.activeGun)
//randomize tech
@@ -414,7 +412,7 @@ const m = {
m.drop();
if (simulation.paused) build.pauseGrid() //update the build when paused
},
- dmgScale: null, //scales all damage, but not raw .dmg //set in levels.setDifficulty
+ dmgScale: null, //scales all damage, but not raw .dmg
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
//remove immortality tech
@@ -445,7 +443,7 @@ const m = {
simulation.clearNow = true; //triggers a map reset
m.switchWorlds()
simulation.isTextLogOpen = true;
- simulation.makeTextLog(`simulation.amplitude = 0.${len - i - 1}`, swapPeriod);
+ simulation.inGameConsole(`simulation.amplitude = 0.${len - i - 1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i + 1) * (i + 1) * 0.006})`;
@@ -458,7 +456,7 @@ const m = {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
simulation.isTextLogOpen = true;
- simulation.makeTextLog("simulation.amplitude = null");
+ simulation.inGameConsole("simulation.amplitude = null");
tech.isImmortal = false //disable future immortality
}, 6 * swapPeriod);
} else if (m.alive) { //normal death code here
@@ -472,13 +470,10 @@ const m = {
m.displayHealth();
document.getElementById("text-log").style.display = "none"
document.getElementById("fade-out").style.opacity = 0.9; //slowly fade to 90% white on top of canvas
- // build.shareURL(false)
setTimeout(function () {
Composite.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
- //if you die after clearing fewer than 4 levels the difficulty settings automatically opens
- if ((level.levelsCleared < 4 || level.levelsCleared > 12) && !simulation.isTraining && !simulation.isCheating) document.getElementById("settings-details").open = true;
}, 5000);
}
},
@@ -488,7 +483,7 @@ const m = {
for (i = 0, len = b.inventory.length; i < len; i++) gunList.push(b.inventory[i])
const techList = [] //store tech names
for (let i = 0; i < tech.tech.length; i++) {
- if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) techList.push(i)
+ if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) techList.push(tech.tech[i].name)
}
if (techList.length) {
localSettings.entanglement = {
@@ -541,9 +536,15 @@ const m = {
},
baseHealth: 1,
setMaxHealth(isMessage) {
- m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
+ m.maxHealth = m.baseHealth + tech.extraMaxHealth + 4 * tech.isFallingDamage
+ if (level.isReducedHealth) {
+ level.reducedHealthLost = Math.max(0, m.health - m.maxHealth * 0.5)
+ m.maxHealth *= 0.5
+ }
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
- if (isMessage) simulation.makeTextLog(`m .maxHealth = ${m.maxHealth.toFixed(2)}`)
+ document.getElementById("defense-bar").style.width = Math.floor(300 * m.maxHealth * (1 - m.defense())) + "px";
+
+ if (isMessage) simulation.inGameConsole(`m .maxHealth = ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
},
@@ -553,29 +554,29 @@ const m = {
lastCalculatedDefense: 0, //used to decided if defense bar needs to be redrawn (in simulation.checks)
defense() {
let dmg = 1
- dmg *= m.fieldHarmReduction
- // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5
- // 1.25 + Math.sin(m.cycle * 0.01)
- if (tech.isDiaphragm) dmg *= 0.56 + 0.36 * Math.sin(m.cycle * 0.0075);
+ if (powerUps.boost.isDefense && powerUps.boost.endCycle > simulation.cycle) dmg *= 0.3
+ if (tech.isMaxHealthDefense && m.health === m.maxHealth) dmg *= 0.3
+ if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075);
if (tech.isZeno) dmg *= 0.15
- if (tech.isFieldHarmReduction) dmg *= 0.65
- if (tech.isHarmMACHO) dmg *= 0.4
+ if (tech.isFieldHarmReduction) dmg *= 0.6
+ if (tech.isHarmDarkMatter) dmg *= (tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 0.25 : 0.4
if (tech.isImmortal) dmg *= 0.7
- if (tech.energyRegen === 0) dmg *= 0.34
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
- if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
- if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.26
- if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
+ if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
- if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55
- if (tech.isHarmReduce && input.field) dmg *= 0.12
+ if (tech.isSpeedHarm && (tech.speedAdded + player.speed) > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.01583, 0.95) //capped at speed of 55
+ if (tech.isHarmReduce && input.field) dmg *= 0.1
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
- if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
- if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
- if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.27
- if (tech.isTurret && m.crouch) dmg *= 0.34;
+ if (tech.isBotArmor) dmg *= 0.96 ** b.totalBots()
+ if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3;
+ if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
+ if (tech.isTurret && m.crouch) dmg *= 0.3;
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
- return tech.isEnergyHealth ? Math.pow(dmg, 0.5) : dmg //defense has less effect
+ // if (tech.isLowHealthDefense) dmg *= Math.pow(0.3, Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health)))
+ if (tech.isLowHealthDefense) dmg *= Math.pow(0.2, Math.max(0, 1 - (tech.isEnergyHealth ? m.energy / m.maxEnergy : m.health / m.maxHealth)))
+ // return tech.isEnergyHealth ? Math.pow(dmg, 0.7) : dmg //defense has less effect
+ // dmg *= m.fieldHarmReduction
+ return dmg * m.fieldHarmReduction
},
rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy)))
if (tech.isRewindGrenade) {
@@ -685,13 +686,13 @@ const m = {
damage(dmg) {
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(0.95, m.maxEnergy) && dmg > 0.01) {
const steps = Math.floor(Math.min(299, 150 * m.energy))
- simulation.makeTextLog(`m .rewind(${steps})`)
+ simulation.inGameConsole(`m .rewind(${steps})`)
m.rewind(steps)
return
}
m.lastHarmCycle = m.cycle
if (tech.isDroneOnDamage && bullet.length < 150) { //chance to build a drone on damage from tech
- const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) / tech.droneEnergyReduction * (tech.isEnergyHealth ? 0.5 : 1)
+ const len = Math.min((dmg - 0.06 * Math.random()) * 80, 60) / tech.droneEnergyReduction * (tech.isEnergyHealth ? 0.5 : 1)
for (let i = 0; i < len; i++) {
if (Math.random() < 0.5) b.drone({
x: m.pos.x + 30 * Math.cos(m.angle) + 100 * (Math.random() - 0.5),
@@ -705,8 +706,8 @@ const m = {
if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) {
tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1)
- simulation.makeTextLog(`m .research -- ${powerUps.research.count}`)
- for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
+ simulation.inGameConsole(`m .research -- ${powerUps.research.count}`)
+ for (let i = 0; i < 22; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
m.energy = m.maxEnergy + 0.1
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function () { //set wipe to have trails
@@ -714,7 +715,6 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
- tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
@@ -734,7 +734,7 @@ const m = {
tech.isDeathAvoidedThisLevel = true
m.health = 0.05
powerUps.research.changeRerolls(-1)
- simulation.makeTextLog(`m .research --
+ simulation.inGameConsole(`m .research --
${powerUps.research.count}`)
for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
@@ -743,7 +743,6 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
- tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
@@ -787,6 +786,21 @@ const m = {
simulation.fpsInterval = 1000 / simulation.fpsCap;
}
m.defaultFPSCycle = m.cycle
+ if (level.isMobHealPlayerDamage) {
+ for (let i = 0; i < mob.length; i++) {
+ if (mob[i].health < 1 && mob[i].isDropPowerUp && mob[i].alive) {
+ simulation.drawList.push({
+ x: mob[i].position.x,
+ y: mob[i].position.y,
+ radius: mob[i].radius + 20,
+ color: "rgba(0,255,100,0.5)",
+ time: 10
+ });
+ mob[i].health += dmg * 7
+ if (mob[i].health > 1) mob[i].health = 1
+ }
+ }
+ }
// if (tech.isSlowFPS) { // slow game
// simulation.fpsCap = 30 //new fps
// simulation.fpsInterval = 1000 / simulation.fpsCap;
@@ -839,12 +853,22 @@ const m = {
},
draw() { },
isAltSkin: false,
+ drawBoost() {
+
+ },
resetSkin() {
simulation.isAutoZoom = true;
+ m.hardLandCDScale = 1
m.yOffWhen.jump = 70
m.yOffWhen.stand = 49
m.yOffWhen.crouch = 22
m.isAltSkin = false
+ m.coyoteCycles = 5
+ m.hardLanding = 130
+ m.squirrelFx = 1;
+ m.squirrelJump = 1;
+ m.velocitySmooth = { x: 0, y: 0 }
+ requestAnimationFrame(() => { m.setMovement() })
m.color = {
hue: 0,
sat: 0,
@@ -888,15 +912,21 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6;
+ ctx.lineWidth = 5;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 12, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 12, m.foot.y + 8);
+ }
ctx.lineWidth = 4;
ctx.stroke();
@@ -925,11 +955,6 @@ const m = {
m.yOffWhen.stand = 49
m.yOffWhen.crouch = 22
m.isAltSkin = false
- m.color = {
- hue: 0,
- sat: 0,
- light: 100,
- }
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 10}%)`
@@ -966,14 +991,38 @@ const m = {
m.isAltSkin = true
m.yOffWhen.stand = 52
m.yOffWhen.jump = 72
- // m.yOffWhen.crouch = 22
- // m.color = {
- // hue: 184,
- // sat: 0,
- // light: 55,
- // }
- // m.setFillColors();
+ m.coyoteCycles = 11
+ m.hardLandCDScale = 0.5
+ m.hardLanding = 160
+ m.squirrelFx = 1.4;
+ m.squirrelJump = 1.16;
+ m.setMovement()
+
m.draw = function () {
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 39
+ const mag = 14 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+
+ // const time = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ ctx.fillStyle = `rgba(0,0,0,${0.04 + 0.3 * time})`
+ ctx.fill()
+ // ctx.strokeStyle = "#333"
+ // ctx.lineWidth = 1
+ // ctx.stroke();
+ ctx.restore();
+ }
+
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
@@ -992,8 +1041,7 @@ const m = {
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
- m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
+ m.yOff = m.yOff * 0.75 + m.yOffGoal * 0.25; //smoothly move leg height towards height goal
}
m.drawLeg = function (stroke) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
@@ -1052,11 +1100,6 @@ const m = {
},
polar() {
m.isAltSkin = true
- m.color = {
- hue: 0,
- sat: 0,
- light: 100,
- }
// m.setFillColors();
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`
@@ -1074,12 +1117,10 @@ const m = {
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
-
const diff = (m.lastKillCycle - m.cycle + tech.isDamageCooldownTime) / tech.isDamageCooldownTime
const color = diff < 0 ? "#fff" : "#aaa"
const hue = 220 + 20 * Math.sin(0.01 * m.cycle)
const colorInverse = diff < 0 ? `hsl(${hue}, 80%, 40%)` : "#fff"
- // const colorInverseFade = diff < 0 ? "#ccc" : "#fff"
m.drawLeg(color, colorInverse);
m.calcLeg(0, 0);
m.drawLeg(color, colorInverse);
@@ -1093,21 +1134,14 @@ const m = {
ctx.beginPath();
ctx.moveTo(15, 0)
ctx.lineTo(28, 0)
- // ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = colorInverse;
ctx.lineWidth = 4;
ctx.stroke();
ctx.restore();
-
- // const scale = diff>0.3
- // console.log(diff.toFixed(3), scale.toFixed(3))
ctx.beginPath();
ctx.ellipse(m.pos.x, m.pos.y, 24, 18, 3.14 * Math.random(), 0, 2 * Math.PI)
- // `rgba(0,0,${100 + 30 * Math.sin(0.1 * m.cycle)},0.8)`
ctx.fillStyle = diff < 0 ? `hsl(${hue}, 80%, 40%)` : `rgba(255,255,255,${Math.min(Math.max(0, diff + 0.3), 1)})`
- // ctx.fillStyle = colorInverse
- // ctx.fillStyle = `rgba(0,0,0,${scale})`
ctx.fill();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
@@ -1127,15 +1161,21 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6;
+ ctx.lineWidth = 5;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
ctx.lineWidth = 3;
ctx.stroke();
@@ -1159,23 +1199,46 @@ const m = {
m.isAltSkin = true
m.yOffWhen.stand = 52
m.yOffWhen.jump = 72
- // m.yOffWhen.crouch = 22
- // m.color = {
- // hue: 184,
- // sat: 0,
- // light: 55,
- // }
- // m.setFillColors();
+ // m.speedSmooth = 0
+ // m.smoothAngle = 0
m.draw = function () {
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 40
+ const mag = 9 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+
+ // const time = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ // ctx.fillStyle = `rgba(255,0,200,${0.4 * time})`
+ // ctx.fill()
+ // ctx.strokeStyle = "#f09"
+
+ ctx.fillStyle = `rgba(255,255,255,${0.3 + time})`;
+ ctx.fill()
+ ctx.strokeStyle = "#446"
+ ctx.lineWidth = 0.2 + 4 * time
+ // ctx.lineWidth = 1
+ ctx.stroke();
+ ctx.restore();
+ }
+
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -1.25);
- m.drawLeg("#606070");
+ m.drawLeg("#606080");
m.calcLeg(0, 0);
- m.drawLeg("#445");
-
+ m.drawLeg("#446");
ctx.rotate(m.angle);
ctx.beginPath();
@@ -1186,22 +1249,27 @@ const m = {
ctx.beginPath();
const arc = 0.7 + 0.17 * Math.sin(m.cycle * 0.012)
ctx.arc(0, 0, 30, -arc, arc, true); //- Math.PI / 2
- ctx.strokeStyle = "#445";
+ ctx.strokeStyle = "#446";
ctx.lineWidth = 2;
ctx.stroke();
+ //fire outline directed opposite player look direction
+ // ctx.beginPath();
+ // const radius = 40
+ // const extend = -50
+ // ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ // ctx.bezierCurveTo(extend, radius, extend, 0, -100, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ // ctx.bezierCurveTo(extend, 0, extend, -radius, 0, -radius);
+ // ctx.fillStyle = "rgba(255,0,255,0.3)";
+ // ctx.fill()
ctx.beginPath();
ctx.moveTo(13, 0)
ctx.lineTo(20, 0)
- // ctx.beginPath();
- // ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.lineWidth = 5;
- ctx.strokeStyle = "#445";
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
@@ -1223,9 +1291,15 @@ const m = {
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 12, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 12, m.foot.y + 8);
+ }
ctx.lineWidth = 4;
ctx.stroke();
@@ -1254,6 +1328,30 @@ const m = {
}
m.setFillColors();
m.draw = function () {
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 40
+ const mag = 10 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+
+ // const time = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ ctx.fillStyle = `hsla(184,100%,70%,${0.1 + 1.5 * time})`
+ ctx.fill()
+ ctx.strokeStyle = "#035"//"hsl(184,100%,70%)"
+ ctx.lineWidth = 0.2 + 3 * time
+ ctx.stroke();
+ ctx.restore();
+ }
+
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -1266,8 +1364,8 @@ const m = {
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
- ctx.strokeStyle = "rgba(0,255,255,0.22)";
- ctx.lineWidth = 12;
+ ctx.strokeStyle = "rgba(0,255,255,0.25)";
+ ctx.lineWidth = 15;
ctx.stroke();
ctx.fillStyle = 'hsl(184,100%,85%)' //m.fillColor; //"#9ff" //m.bodyGradient
ctx.fill();
@@ -1276,10 +1374,9 @@ const m = {
ctx.arc(17, 0, 5.5, 0, 2 * Math.PI);
ctx.fillStyle = "#357"
ctx.fill();
-
ctx.restore();
+
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
@@ -1295,16 +1392,22 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6;
+ ctx.lineWidth = 5;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 14, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 14, m.foot.y + 5);
- ctx.lineWidth = 4;
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
+ ctx.lineWidth = 3;
ctx.stroke();
//hip joint
@@ -1317,7 +1420,7 @@ const m = {
ctx.moveTo(m.foot.x + 5, m.foot.y);
ctx.arc(m.foot.x, m.foot.y + 1, 5, 0, 2 * Math.PI);
ctx.strokeStyle = "rgba(0,255,255,0.25)";
- ctx.lineWidth = 5;
+ ctx.lineWidth = 6;
ctx.stroke();
ctx.fillStyle = m.fillColor;
ctx.fill();
@@ -1325,6 +1428,9 @@ const m = {
}
},
tungsten() {
+ m.hardLandCDScale = 2
+ m.hardLanding = 60
+ m.coyoteCycles = 0
m.isAltSkin = true
m.color = {
hue: 210,
@@ -1384,7 +1490,7 @@ const m = {
ctx.fill();
ctx.restore();
- m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ m.yOff = m.yOff * 0.9 + m.yOffGoal * 0.1; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
@@ -1469,6 +1575,26 @@ const m = {
m.bodyGradient = grd
m.draw = function () {
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 40
+ const mag = 12 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+ // const time = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ ctx.fillStyle = `hsla(${simulation.cycle},100%,70%,${0.1 + 2 * time})`
+ ctx.fill()
+ ctx.restore();
+ }
+
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -1489,7 +1615,6 @@ const m = {
// ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
@@ -1511,9 +1636,15 @@ const m = {
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
ctx.lineWidth = 4;
ctx.stroke();
@@ -1542,7 +1673,7 @@ const m = {
m.isAltSkin = true
simulation.isAutoZoom = false;
m.draw = function () {
- const amplitude = 8 + 4 * Math.sin(m.cycle * 0.0075)
+ const amplitude = 8 + 4 * Math.sin(m.cycle * 0.01)
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -1568,18 +1699,38 @@ const m = {
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
- //zoom camera in and out
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 39
+ const mag = 6 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+ // ctx.fillStyle = `hsla(${simulation.cycle * 0.5},100%,70%,0.4)`
+ // ctx.fill()
+ ctx.strokeStyle = "#345"
+ // const time = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ ctx.lineWidth = 0.2 + 4 * time
+ ctx.stroke();
+ ctx.restore();
+ }
- // console.log(simulation.zoomScale)
- simulation.setZoom(1800 + 400 * Math.sin(m.cycle * 0.0075))
+ //zoom camera in and out
+ simulation.setZoom(1800 + 400 * Math.sin(m.cycle * 0.01))
}
},
dilate2() {
m.isAltSkin = true
m.draw = function () {
- const amplitude = Math.sin(m.cycle * 0.0075)
+ const amplitude = Math.sin(m.cycle * 0.01)
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -1596,7 +1747,7 @@ const m = {
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.strokeStyle = "#345";
- ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.0075 + Math.PI);
+ ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.01 + Math.PI);
ctx.stroke();
// ctx.arc(12, 0, 8 + 4 * amplitude, 0, 2 * Math.PI); //big eye
ctx.beginPath();
@@ -1608,8 +1759,31 @@ const m = {
// ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
- powerUps.boost.draw()
- simulation.setZoom(1800 + 400 * Math.sin(m.cycle * 0.0075))
+
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
+ ctx.beginPath();
+ const radius = 39
+ const mag = 6 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+ // ctx.fillStyle = `hsla(${simulation.cycle * 0.5},100%,70%,0.4)`
+ // ctx.fill()
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+
+ ctx.strokeStyle = "#345"
+ ctx.lineWidth = 0.2 + 7 * time
+ // ctx.lineWidth = (4 + 3 * Math.sin(m.cycle * 0.01 + Math.PI)) * time;
+ ctx.stroke();
+ ctx.restore();
+ }
+
+ simulation.setZoom(1800 + 400 * amplitude)
}
m.drawLeg = function (stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
@@ -1625,15 +1799,21 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6 + 2 * Math.sin(m.cycle * 0.0075 + Math.PI);
+ ctx.lineWidth = 6 + 2 * Math.sin(m.cycle * 0.01 + Math.PI);
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
ctx.lineWidth = 4;
ctx.stroke();
@@ -1648,19 +1828,14 @@ const m = {
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = "#345";
ctx.fill();
- ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.0075 + Math.PI);
+ ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.01 + Math.PI);
ctx.stroke();
ctx.restore();
}
},
CPT() {
m.isAltSkin = true
- m.color = {
- hue: 0,
- sat: 0,
- light: 100,
- }
- // m.setFillColors();
+
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`
let grd = ctx.createLinearGradient(-20, 0, 15, 0);
@@ -1668,7 +1843,6 @@ const m = {
grd.addColorStop(1, m.fillColor);
// grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
-
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -1708,15 +1882,21 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6;
+ ctx.lineWidth = 5;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
- ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
ctx.lineWidth = 3;
ctx.stroke();
@@ -1736,50 +1916,44 @@ const m = {
ctx.restore();
}
},
- hexagon() {
+ verlet() {
m.isAltSkin = true
- m.color = {
- hue: 0,
- sat: 0,
- light: 100,
- }
- // m.setFillColors();
- m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
- m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`
- let grd = ctx.createLinearGradient(-30, 0, 30, 0);
- grd.addColorStop(0, m.fillColorDark);
- grd.addColorStop(0.7, m.fillColor);
- // grd.addColorStop(1, m.fillColor);
- m.bodyGradient = grd
-
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
- m.calcLeg(Math.PI, -3);
+ m.calcLeg(Math.PI, -2);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
- ctx.rotate(m.angle);
- const size = 32
ctx.beginPath();
- ctx.lineTo(size * 1, size * 0)
- ctx.lineTo(size * 0.5, size * 0.866)
- ctx.lineTo(size * -0.5, size * 0.866)
- ctx.lineTo(size * -1, size * 0)
- ctx.lineTo(size * -0.5, size * -0.866)
- ctx.lineTo(size * 0.5, size * -0.866)
- ctx.lineTo(size * 1, size * 0)
+ ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
- ctx.arc(15, 0, 4, 0, 2 * Math.PI);
- ctx.strokeStyle = "#333";
- ctx.lineWidth = 2;
+ const rate = 0.09
+ ctx.strokeStyle = "#000";
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.arc(0, 0, rate * (simulation.cycle + 0) % 30, 0, 2 * Math.PI);
ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, rate * (simulation.cycle + 15 / rate) % 30, 0, 2 * Math.PI);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 30, 0, 2 * Math.PI);
+ ctx.stroke();
+
+ ctx.globalCompositeOperation = "difference";
+ ctx.rotate(m.angle);
+ ctx.beginPath();
+ ctx.arc(21, 0, 8, 0, 2 * Math.PI);
+ ctx.fillStyle = input.fire ? "#0ff" : input.field ? "#d30" : `#fff`
+ ctx.fill();
ctx.restore();
+
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
@@ -1797,27 +1971,28 @@ const m = {
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
- ctx.lineWidth = 6;
+ ctx.lineWidth = 1;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ const footDrop = m.onGround ? 5 : 10
+ ctx.lineTo(m.foot.x - 15, m.foot.y + footDrop);
ctx.moveTo(m.foot.x, m.foot.y);
- ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
- ctx.lineWidth = 3;
+ ctx.lineTo(m.foot.x + 15, m.foot.y + footDrop);
+ ctx.lineWidth = 1;
ctx.stroke();
//hip joint
ctx.beginPath();
- ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
+ ctx.arc(m.hip.x, m.hip.y, 9, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 5, m.knee.y);
- ctx.arc(m.knee.x, m.knee.y, 5, 0, 2 * Math.PI);
+ ctx.arc(m.knee.x, m.knee.y, 3, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 5, m.foot.y);
- ctx.arc(m.foot.x, m.foot.y, 5, 0, 2 * Math.PI);
+ ctx.arc(m.foot.x, m.foot.y, 4, 0, 2 * Math.PI);
ctx.fillStyle = "#000";
ctx.fill();
// ctx.lineWidth = 2;
@@ -1892,6 +2067,7 @@ const m = {
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ powerUps.boost.draw()
}
},
diegesis() {
@@ -1919,10 +2095,12 @@ const m = {
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ powerUps.boost.draw()
}
},
cat() {
m.isAltSkin = true
+ m.coyoteCycles = 10
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -1931,8 +2109,6 @@ const m = {
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
-
-
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
ctx.scale(1, -1);
ctx.rotate(Math.PI);
@@ -1987,6 +2163,7 @@ const m = {
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ powerUps.boost.draw()
}
},
pareidolia() {
@@ -2042,6 +2219,7 @@ const m = {
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15;
+ powerUps.boost.draw()
}
},
flipFlop() {
@@ -2079,7 +2257,97 @@ const m = {
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
- }
+ },
+ hexagon() {
+ m.isAltSkin = true
+
+ m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
+ m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`
+ let grd = ctx.createLinearGradient(-30, 0, 30, 0);
+ grd.addColorStop(0, m.fillColorDark);
+ grd.addColorStop(0.7, m.fillColor);
+ // grd.addColorStop(1, m.fillColor);
+ m.bodyGradient = grd
+
+ m.draw = function () {
+ ctx.fillStyle = m.fillColor;
+ m.walk_cycle += m.flipLegs * m.Vx;
+ ctx.save();
+ ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
+ ctx.translate(m.pos.x, m.pos.y);
+ m.calcLeg(Math.PI, -3);
+ m.drawLeg("#4a4a4a");
+ m.calcLeg(0, 0);
+ m.drawLeg("#333");
+ ctx.rotate(m.angle);
+
+ const size = 32
+ ctx.beginPath();
+ ctx.lineTo(size * 1, size * 0)
+ ctx.lineTo(size * 0.5, size * 0.866)
+ ctx.lineTo(size * -0.5, size * 0.866)
+ ctx.lineTo(size * -1, size * 0)
+ ctx.lineTo(size * -0.5, size * -0.866)
+ ctx.lineTo(size * 0.5, size * -0.866)
+ ctx.lineTo(size * 1, size * 0)
+ ctx.fillStyle = m.bodyGradient
+ ctx.fill();
+ ctx.arc(15, 0, 4, 0, 2 * Math.PI);
+ ctx.strokeStyle = "#333";
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.restore();
+ m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
+ powerUps.boost.draw()
+ }
+ m.drawLeg = function (stroke) {
+ // if (simulation.mouseInGame.x > m.pos.x) {
+ if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
+ m.flipLegs = 1;
+ } else {
+ m.flipLegs = -1;
+ }
+ ctx.save();
+ ctx.scale(m.flipLegs, 1); //leg lines
+ ctx.beginPath();
+ ctx.moveTo(m.hip.x, m.hip.y);
+ ctx.lineTo(m.knee.x, m.knee.y);
+ ctx.lineTo(m.foot.x, m.foot.y);
+ ctx.strokeStyle = stroke;
+ ctx.lineWidth = 6;
+ ctx.stroke();
+
+ //toe lines
+ ctx.beginPath();
+ ctx.moveTo(m.foot.x, m.foot.y);
+ if (m.onGround) {
+ ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
+ } else {
+ ctx.lineTo(m.foot.x - 13, m.foot.y + 8);
+ ctx.moveTo(m.foot.x, m.foot.y);
+ ctx.lineTo(m.foot.x + 13, m.foot.y + 8);
+ }
+ ctx.lineWidth = 3;
+ ctx.stroke();
+
+ //hip joint
+ ctx.beginPath();
+ ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
+ //knee joint
+ ctx.moveTo(m.knee.x + 5, m.knee.y);
+ ctx.arc(m.knee.x, m.knee.y, 5, 0, 2 * Math.PI);
+ //foot joint
+ ctx.moveTo(m.foot.x + 5, m.foot.y);
+ ctx.arc(m.foot.x, m.foot.y, 5, 0, 2 * Math.PI);
+ ctx.fillStyle = "#000";
+ ctx.fill();
+ // ctx.lineWidth = 2;
+ // ctx.stroke();
+ ctx.restore();
+ }
+ },
},
// *********************************************
// **************** fields *********************
@@ -2106,7 +2374,7 @@ const m = {
isFieldActive: false,
fieldRange: 155,
fieldShieldingScale: 1,
- // fieldDamage: 1,
+ fieldDamage: 1,
isSneakAttack: false,
lastHit: 0, //stores value of last damage player took above a threshold, in m.damage
sneakAttackCycle: 0,
@@ -2143,8 +2411,8 @@ const m = {
m.eyeFillColor = m.fieldMeterColor
m.fieldShieldingScale = 1;
m.fieldBlockCD = 10;
+ m.fieldDamage = 1
m.fieldHarmReduction = 1;
- m.lastHit = 0
m.isSneakAttack = false
m.duplicateChance = 0
m.grabPowerUpRange2 = 200000;
@@ -2176,8 +2444,9 @@ const m = {
}
},
setMaxEnergy(isMessage = true) {
- m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
- if (isMessage) simulation.makeTextLog(`m .maxEnergy = ${(m.maxEnergy.toFixed(2))}`)
+ m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 3 * tech.isGroundState + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
+ if (level.isReducedEnergy) m.maxEnergy *= 0.5
+ if (isMessage) simulation.inGameConsole(`m .maxEnergy = ${(m.maxEnergy.toFixed(2))}`)
},
fieldMeterColor: "#0cf",
drawRegenEnergy(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
@@ -2227,12 +2496,14 @@ const m = {
m.fieldRegen = 0.001667 //10 energy per second plasma torch
} else if (m.fieldMode === 8) {
m.fieldRegen = 0.001667 //10 energy per second pilot wave
+ } else if (m.fieldMode === 9) {
+ m.fieldRegen = 0.00117 //7 energy per second wormhole
} else if (m.fieldMode === 10) {
m.fieldRegen = 0.0015 //9 energy per second grappling hook
} else {
m.fieldRegen = 0.001 //6 energy per second
}
- if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling //return `generate ${(6*couple).toFixed(0)} energy per second`
+ if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.0001 * m.coupling
if (tech.isTimeCrystals) {
m.fieldRegen *= 2.5
} else if (tech.isGroundState) {
@@ -2240,21 +2511,18 @@ const m = {
}
},
regenEnergy() { //used in drawRegenEnergy // rewritten by some tech
- if (m.immuneCycle < m.cycle && m.fieldCDcycle < m.cycle) m.energy += m.fieldRegen;
+ if (m.immuneCycle < m.cycle && m.fieldCDcycle < m.cycle) m.energy += m.fieldRegen * level.isReducedRegen;
if (m.energy < 0) m.energy = 0
},
regenEnergyDefault() {
- if (m.immuneCycle < m.cycle && m.fieldCDcycle < m.cycle) m.energy += m.fieldRegen;
+ if (m.immuneCycle < m.cycle && m.fieldCDcycle < m.cycle) m.energy += m.fieldRegen * level.isReducedRegen;
if (m.energy < 0) m.energy = 0
},
lookingAt(who) {
//calculate a vector from body to player and make it length 1
const diff = Vector.normalise(Vector.sub(who.position, m.pos));
//make a vector for the player's direction of length 1
- const dir = {
- x: Math.cos(m.angle),
- y: Math.sin(m.angle)
- };
+ const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) };
//the dot product of diff and dir will return how much over lap between the vectors
if (Vector.dot(dir, diff) > m.fieldThreshold) {
return true;
@@ -2278,8 +2546,6 @@ const m = {
Matter.Body.setMass(player, mass);
//reduce air and ground move forces
m.setMovement()
- // m.Fx = 0.08 / mass * tech.squirrelFx //base player mass is 5
- // m.FxAir = 0.4 / mass / mass //base player mass is 5
//make player stand a bit lower when holding heavy masses
m.yOffWhen.stand = Math.max(m.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6))
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand;
@@ -2358,6 +2624,30 @@ const m = {
ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y);
ctx.fill();
}
+ if (tech.isTokamakFly && m.throwCharge > 4 && m.energy > 0.01) {
+ player.force.y -= 0.5 * player.mass * simulation.g; //add some reduced gravity
+ // const mass = (player.mass + 10) / 3 * simulation.g //this makes it so you fly slower with larger blocks
+ let isDrain = false
+ const thrust = player.mass * simulation.g * Math.pow(5 / player.mass, 0.1)
+ if (input.down) {
+ isDrain = true
+ player.force.y += 0.9 * thrust;
+ } else if (input.up) {
+ isDrain = true
+ player.force.y -= 0.9 * thrust
+ }
+ if (!m.onGround) {
+ if (input.left) {
+ isDrain = true
+ player.force.x -= 0.4 * thrust
+ } else if (input.right) {
+ isDrain = true
+ player.force.x += 0.4 * thrust
+ }
+ if (isDrain) m.energy -= 0.0017;
+ }
+
+ }
} else {
//draw charge
const x = m.pos.x + 15 * Math.cos(m.angle);
@@ -2408,7 +2698,7 @@ const m = {
if (tech.isTokamak && m.throwCharge > 4) { //remove the block body and pulse in the direction you are facing
//m.throwCharge > 5 seems to be when the field full colors in a block you are holding
m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds
- if (m.immuneCycle < m.cycle) m.energy += 0.25 * Math.sqrt(m.holdingTarget.mass) * Math.min(5, m.throwCharge)
+ if (m.immuneCycle < m.cycle) m.energy += 0.25 * Math.sqrt(m.holdingTarget.mass) * Math.min(5, m.throwCharge) * level.isReducedRegen
m.throwCharge = 0;
m.definePlayerMass() //return to normal player mass
//remove block before pulse, so it doesn't get in the way
@@ -2419,6 +2709,12 @@ const m = {
}
}
b.pulse(60 * Math.pow(m.holdingTarget.mass, 0.25), m.angle)
+ if (tech.isTokamakHeal && tech.tokamakHealCount < 5) {
+ tech.tokamakHealCount++
+ let massScale = Math.min(65 * Math.sqrt(m.maxHealth), 14 * Math.pow(m.holdingTarget.mass, 0.4))
+ if (powerUps.healGiveMaxEnergy) massScale = powerUps["heal"].size()
+ powerUps.spawn(m.pos.x, m.pos.y, "heal", true, massScale * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1))) // spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
+ }
} else { //normal throw
//bullet-like collisions
m.holdingTarget.collisionFilter.category = cat.bullet
@@ -2462,6 +2758,7 @@ const m = {
});
m.definePlayerMass() //return to normal player mass
+ if (tech.isStaticBlock) m.holdingTarget.isStatic = true
if (tech.isAddBlockMass) {
const expand = function (that, massLimit) {
if (that.mass < massLimit) {
@@ -2756,7 +3053,7 @@ const m = {
m.pushMass(mob[i]);
if (tech.deflectEnergy && !mob[i].isInvulnerable && !mob[i].isShielded) {
- m.energy += tech.deflectEnergy
+ m.energy += tech.deflectEnergy * level.isReducedRegen
}
}
}
@@ -2853,7 +3150,7 @@ const m = {
couplingDescription(couple = m.coupling) {
switch (m.fieldMode) {
case 0: //field emitter
- return `all other field effects`
+ return `all effects`
case 1: //standing wave
// return `deflecting condenses +${couple.toFixed(1)} ice IX `
return `+${(couple * 5).toFixed(0)} maximum energy `
@@ -2861,25 +3158,25 @@ const m = {
return `deflecting condenses ${(0.1 * couple).toFixed(2)} ice IX `
// return `invulnerable +${2*couple} seconds post collision `
case 3: //negative mass
- return `+${(100 * (1 - 0.973 ** couple)).toFixed(1)}% defense `
+ return `${(0.973 ** couple).toFixed(2)}x damage taken `
case 4: //assembler
- return `generate ${(0.8 * couple).toFixed(1)} energy per second`
+ return `+${(0.6 * couple).toFixed(1)} energy per second`
case 5: //plasma
- return `+${(1.5 * couple).toFixed(1)}% damage `
+ return `${(1 + 0.015 * couple).toFixed(3)}x damage `
case 6: //time dilation
- return `+${(5 * couple).toFixed(0)}% longer stopped time ` //movement , jumping , and
+ return `+${(1 + 0.05 * couple).toFixed(2)}x longer stopped time ` //movement , jumping , and
case 7: //cloaking
- return `+${(3.3 * couple).toFixed(1)}% ambush damage `
+ return `${(1 + 3.3 * couple).toFixed(3)}x ambush damage `
case 8: //pilot wave
- return `+${(4 * couple).toFixed(0)}% block collision damage `
+ return `${(1 + 0.05 * couple).toFixed(2)}x block collision damage `
case 9: //wormhole
return `after eating blocks +${(2 * couple).toFixed(0)} energy `
case 10: //grappling hook
- return `${powerUps.orb.ammo(1)} give ${(4 * couple).toFixed(0)}% more ammo`
+ return `${powerUps.orb.ammo(1)} give ${(4 * couple).toFixed(0)}% more ammo`
}
},
couplingChange(change = 0) {
- if (change > 0 && level.onLevel !== -1) simulation.makeTextLog(`m.coupling += ${change}`, 60); //level.onLevel !== -1 means not on lore level
+ if (change > 0 && level.onLevel !== -1) simulation.inGameConsole(`
m.coupling += ${change}`, 60); //level.onLevel !== -1 means not on lore level
m.coupling += change
if (m.coupling < 0) {
//look for coupling power ups on this level and remove them to prevent exploiting tech ejections
@@ -2917,13 +3214,13 @@ const m = {
document.getElementById("field").innerHTML = m.fieldUpgrades[index].name
m.setHoldDefaults();
m.fieldUpgrades[index].effect();
- simulation.makeTextLog(`m .setField("${m.fieldUpgrades[m.fieldMode].name} ")`);
+ simulation.inGameConsole(`
m .setField("${m.fieldUpgrades[m.fieldMode].name} ") input.key.field: ["MouseRight "]`);
},
fieldUpgrades: [{
name: "field emitter",
imageNumber: Math.floor(Math.random() * 26), //pick one of the 25 field emitter image files at random
description: `initial field use energy to deflect mobs and throw blocks
- generate 4 energy per second`, // 100 max energy
+ 4 energy per second`, // 100 max energy
effect: () => {
m.hold = function () {
if (m.isHolding) {
@@ -2952,11 +3249,11 @@ const m = {
//deflecting protects you in every direction
description: `3 oscillating shields are permanently active
+150 max energy
- generate 6 energy per second`,
+ 6 energy per second`,
drainCD: 0,
effect: () => {
m.fieldBlockCD = 0;
- m.blockingRecoil = 1.5 //4 is normal
+ m.blockingRecoil = 1 //4 is normal
m.fieldRange = 185
m.fieldShieldingScale = 1.6 * Math.pow(0.5, (tech.harmonics - 2))
// m.fieldHarmReduction = 0.66; //33% reduction
@@ -3054,10 +3351,7 @@ const m = {
},
{
name: "perfect diamagnetism",
- description: "deflecting does not drain energy maintains functionality while inactive generate 5 energy per second",
- // attract power ups from far away
- // description: "attract power ups from far away deflecting doesn't drain energy thrown blocks have",
- // description: "gain energy when blocking no recoil when blocking ",
+ description: `deflecting does not drain energy shield maintains functionality while inactive5 energy per second`,
effect: () => {
m.fieldMeterColor = "#48f" //"#0c5"
m.eyeFillColor = m.fieldMeterColor
@@ -3292,14 +3586,14 @@ const m = {
{
name: "negative mass",
// hold blocks as if they have a lower mass
- description: "use energy to nullify gravity +55% defense generate 6 energy per second",
+ description: `use energy to nullify gravity 0.4x damage taken 6 energy per second`,
fieldDrawRadius: 0,
effect: () => {
m.fieldFire = true;
m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
m.fieldMeterColor = "#333"
m.eyeFillColor = m.fieldMeterColor
- m.fieldHarmReduction = 0.45; //55% reduction
+ m.fieldHarmReduction = 0.4;
m.fieldDrawRadius = 0;
m.hold = function () {
@@ -3480,11 +3774,11 @@ const m = {
},
{
name: "molecular assembler",
- description: `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"} use energy to deflect mobs generate 12 energy per second`,
- // simulation.molecularMode: Math.floor(4 * Math.random()), //0 spores, 1 missile, 2 ice IX, 3 drones
+ description: `use energy to deflect mobs excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"} 12 energy per second`,
setDescription() {
- return `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"} use energy to deflect mobs generate 12 energy per second`
+ return `use energy to deflect mobs excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"} 12 energy per second`
},
+
effect: () => {
m.fieldMeterColor = "#ff0"
m.eyeFillColor = m.fieldMeterColor
@@ -3538,7 +3832,7 @@ const m = {
bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5)
// b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
} else if (simulation.molecularMode === 2) {
- m.energy -= 0.045;
+ m.energy -= 0.044;
b.iceIX(1)
} else if (simulation.molecularMode === 3) {
if (tech.isDroneRadioactive) {
@@ -3600,9 +3894,10 @@ const m = {
},
{
name: "plasma torch",
- description: "use energy to emit short range plasma damages and pushes mobs away generate 10 energy per second",
+ description: "use energy to emit short range plasma 1.5x damage 10 energy per second",
set() {
b.isExtruderOn = false
+ m.fieldDamage = 1.5
// m.fieldCDcycleAlternate = 0
if (m.plasmaBall) {
@@ -4056,7 +4351,7 @@ const m = {
},
{
name: "time dilation",
- description: "use energy to stop time +20% movement and fire rate generate 12 energy per second",
+ description: `use energy to stop time 1.2x movement and fire rate 12 energy per second`,
set() {
// m.fieldMeterColor = "#0fc"
// m.fieldMeterColor = "#ff0"
@@ -4067,7 +4362,7 @@ const m = {
m.setMovement();
b.setFireCD()
const timeStop = () => {
- m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
+ m.immuneCycle = m.cycle + 10; //invulnerable to harm while time is stopped, this also disables regen
//draw field everywhere
ctx.globalCompositeOperation = "saturation"
ctx.fillStyle = "#ccc";
@@ -4246,7 +4541,7 @@ const m = {
},
effect() {
if (tech.isTimeStop) {
- m.fieldHarmReduction = 0.66; //33% reduction
+ m.fieldHarmReduction = 0.6;
} else {
m.fieldHarmReduction = 1;
}
@@ -4255,7 +4550,7 @@ const m = {
},
{
name: "metamaterial cloaking",
- description: "+66% defense while cloaked after decloaking +333% damage for 2 s generate 6 energy per second",
+ description: `0.3x damage taken while cloaked after decloaking 4.5x damage for 2 s6 energy per second`,
effect: () => {
m.fieldFire = true;
m.fieldMeterColor = "#333";
@@ -4306,7 +4601,7 @@ const m = {
if (!m.isCloak) { //&& m.energy > drain + 0.03
// m.energy -= drain
m.isCloak = true //enter cloak
- m.fieldHarmReduction = 0.33; //66% reduction
+ m.fieldHarmReduction = 0.3;
m.enterCloakCycle = m.cycle
if (tech.isCloakHealLastHit && m.lastHit > 0) {
const heal = Math.min(0.75 * m.lastHit, m.energy)
@@ -4398,26 +4693,25 @@ const m = {
}
this.drawRegenEnergyCloaking()
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
+ m.fieldDamage = 4.5 * (1 + 0.033 * m.coupling)
const timeLeft = (m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) - m.cycle) * 0.5
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 32, 0, 2 * Math.PI);
ctx.strokeStyle = "rgba(180,30,70,0.5)";//"rgba(0,0,0,0.7)";//"rgba(255,255,255,0.7)";//"rgba(255,0,100,0.7)";
ctx.lineWidth = Math.max(Math.min(10, timeLeft), 3);
ctx.stroke();
-
// ctx.globalCompositeOperation = "multiply";
// m.drawCloakedM()
// ctx.globalCompositeOperation = "source-over";
+ } else {
+ m.fieldDamage = 1
}
}
}
},
{
name: "pilot wave",
- //blocks can't collide with intangible mobs
- //field radius decreases out of line of sight
- //unlock tech from other fields
- description: "use energy to guide blocks tech , fields , and guns have +2 choices generate 10 energy per second",
+ description: `use energy to guide blocks
,
, and
have +3 ch oi ces 10 energy per second`,
effect: () => {
m.fieldMeterColor = "#333"
m.eyeFillColor = m.fieldMeterColor
@@ -4646,7 +4940,7 @@ const m = {
{
name: "wormhole",
//wormholes attract blocks and power ups
- description: "use energy to tunnel through a wormhole +7% chance to duplicate spawned power ups generate 6 energy per second", // bullets may also traverse wormholes
+ description: "use energy to tunnel through a wormhole +7% chance to duplicate spawned power ups 7 energy per second", // bullets may also traverse wormholes
drain: 0,
effect: function () {
m.fieldMeterColor = "#bbf" //"#0c5"
@@ -4757,7 +5051,7 @@ const m = {
Matter.Composite.remove(engine.world, body[i]);
body.splice(i, 1);
m.fieldRange *= 0.8
- if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling
+ if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling * level.isReducedRegen
if (tech.isWormholeWorms) { //pandimensional spermia
b.worm(Vector.add(m.hole.pos2, Vector.rotate({ x: m.fieldRange * 0.4, y: 0 }, 2 * Math.PI * Math.random())))
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -10));
@@ -4779,10 +5073,8 @@ const m = {
Matter.Composite.remove(engine.world, body[i]);
body.splice(i, 1);
m.fieldRange *= 0.8
- // if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
- // if (tech.isWormholeEnergy && m.immuneCycle < m.cycle) m.energy += 0.5
- if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling
- if (m.fieldMode === 0 || m.fieldMode === 9) m.energy += 0.02 * m.coupling
+ if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling * level.isReducedRegen
+ if (m.fieldMode === 0 || m.fieldMode === 9) m.energy += 0.02 * m.coupling * level.isReducedRegen
if (tech.isWormholeWorms) { //pandimensional spermia
b.worm(Vector.add(m.hole.pos1, Vector.rotate({
x: m.fieldRange * 0.4,
@@ -5194,15 +5486,14 @@ const m = {
},
{
name: "grappling hook",
- // description: `use energy to pull yourself towards the map generate 6 energy per second`,
- description: `use energy to fire a hook that pulls playerdamages mobs and grabs blocks generate 9 energy per second`,
+ description: `use energy to fire a hook that pulls you0.5x damage taken 9 energy per second`,
effect: () => {
m.fieldFire = true;
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
// m.fieldMeterColor = "#789"//"#456"
m.eyeFillColor = m.fieldMeterColor
+ m.fieldHarmReduction = 0.5; //40% reduction
m.grabPowerUpRange2 = 300000 //m.grabPowerUpRange2 = 200000;
- // m.fieldHarmReduction = 0.45; //55% reduction
m.hold = function () {
if (m.isHolding) {
@@ -5379,8 +5670,8 @@ const m = {
y: drag * player.velocity.y
});
if (input.up) { //forward thrust
- player.force.x += thrust * Math.cos(m.angle) * tech.squirrelJump
- player.force.y += thrust * Math.sin(m.angle) * tech.squirrelJump
+ player.force.x += thrust * Math.cos(m.angle) * m.squirrelJump
+ player.force.y += thrust * Math.sin(m.angle) * m.squirrelJump
} else if (input.down) {
player.force.x -= 0.6 * thrust * Math.cos(m.angle)
player.force.y -= 0.6 * thrust * Math.sin(m.angle)
@@ -5534,7 +5825,7 @@ const m = {
return
}
m.damage(dmg);
- if (tech.isPiezo) m.energy += 20.48;
+ if (tech.isPiezo) m.energy += 20.48 * level.isReducedRegen;
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
@@ -5597,7 +5888,7 @@ const m = {
let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2 : 1);
if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true);
- if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && m.throwCycle > m.cycle) {
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && Math.random() < 0.5) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) {
type = "heal"
diff --git a/js/powerup.js b/js/powerup.js
index d70b30ae..4f3af638 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -34,48 +34,10 @@ const powerUps = {
healGiveMaxEnergy: false, //for tech 1st ionization energy
orb: {
research(num = 1) {
- switch (num) {
- case 1:
- return `
`
- case 2:
- return `
-
-
- `
- case 3:
- return `
-
-
-
- `
- case 4:
- return `
-
-
-
-
- `
- case 5:
- return `
-
-
-
-
-
- `
- case 6:
- return `
-
-
-
-
-
-
- `
- }
+ if (num === 1) return `
`
let text = ''
for (let i = 0; i < num; i++) {
- text += `
`
+ text += `
`
}
text += ' '
for (let i = 0; i < num; i++) {
@@ -90,7 +52,7 @@ const powerUps = {
}
let text = ''
for (let i = 0; i < num; i++) {
- text += `
`
+ text += `
`
}
text += ' '
for (let i = 0; i < num; i++) {
@@ -100,37 +62,43 @@ const powerUps = {
},
heal(num = 1) {
if (powerUps.healGiveMaxEnergy) {
- switch (num) {
- case 1:
- return `
`
- }
+ if (num === 1) return `
`
+
let text = ''
for (let i = 0; i < num; i++) {
- text += `
`
+ text += `
`
}
text += ' '
- for (let i = 0; i < num; i++) {
- text += ' '
- }
+ for (let i = 0; i < num; i++) text += ' '
return text
} else {
- switch (num) {
- case 1:
- return `
`
- }
+ if (num === 1) return `
`
+
let text = ''
for (let i = 0; i < num; i++) {
- text += `
`
+ text += `
`
}
text += ' '
- for (let i = 0; i < num; i++) {
- text += ' '
- }
+ for (let i = 0; i < num; i++) text += ' '
return text
}
},
tech(num = 1) {
- return `
`
+ return `tech
`
+ },
+ field(num = 1) {
+ return `field
`
+ },
+ gun(num = 1) {
+ return `gun
`
+ },
+ gunTech(num = 1) {
+ return `gun tech
+ gun tech
`
+ },
+ fieldTech(num = 1) {
+ return `field tech
+ field tech
`
},
coupling(num = 1) {
switch (num) {
@@ -139,7 +107,7 @@ const powerUps = {
}
let text = ''
for (let i = 0; i < num; i++) {
- text += `
`
+ text += `
`
}
text += ' '
for (let i = 0; i < num; i++) {
@@ -189,7 +157,6 @@ const powerUps = {
} else {
powerUps.do = () => powerUps.draw();
}
- tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else {
powerUps.draw = powerUps.drawCircle
if (tech.isHealAttract) {
@@ -247,12 +214,14 @@ const powerUps = {
if (powerUp[i].isDuplicated) {
if (Math.random() < 0.003 && !m.isBodiesAsleep) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
b.explosion(powerUp[i].position, 175 + (11 + 3 * Math.random()) * powerUp[i].size);
- Matter.Composite.remove(engine.world, powerUp[i]);
- powerUp.splice(i, 1);
+ if (powerUp[i]) {
+ Matter.Composite.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1);
+ }
break
}
if (Math.random() < 0.3) { //draw electricity
- const mag = 4 + powerUp[i].size / 5
+ const mag = Math.max(1, 4 + powerUp[i].size / 5)
let unit = Vector.rotate({ x: mag, y: mag }, 2 * Math.PI * Math.random())
let path = { x: powerUp[i].position.x + unit.x, y: powerUp[i].position.y + unit.y }
ctx.beginPath();
@@ -272,17 +241,17 @@ const powerUps = {
choose(type, index) {
if (type === "gun") {
b.giveGuns(index)
- let text = `b.giveGuns("${b.guns[index].name} ")`
+ let text = `
b.giveGuns("${b.guns[index].name} ")`
if (b.inventory.length === 1) text += ` input.key.gun: ["MouseLeft "]`
if (b.inventory.length === 2) text += `
input.key.nextGun: ["${input.key.nextGun} ","MouseWheel "]
input.key.previousGun: ["${input.key.previousGun} ","MouseWheel "]`
- simulation.makeTextLog(text);
+ simulation.inGameConsole(text);
} else if (type === "field") {
m.setField(index)
} else if (type === "tech") {
- // if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
- simulation.makeTextLog(`tech .giveTech("${tech.tech[index].name} ")`);
+ // if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
+ simulation.inGameConsole(`
tech .giveTech("${tech.tech[index].name} ")`);
tech.giveTech(index)
}
powerUps.endDraft(type);
@@ -313,26 +282,18 @@ const powerUps = {
ctx.fillStyle = `rgba(150,150,150,0.9)`; //`rgba(221,221,221,0.6)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
- // document.getElementById("pause-grid-right").style.opacity = "0.7"
- // document.getElementById("pause-grid-left").style.opacity = "0.7"
}
- // build.pauseGrid()
},
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
- if (tech.isCancelTech && Math.random() < 0.85 && type !== "entanglement") {
- // powerUps.research.use('tech')
- powerUps[type].effect();
- return
- }
if (tech.isCancelDuplication) {
- tech.duplication += 0.05
- tech.maxDuplicationEvent()
- simulation.makeTextLog(`tech.duplicationChance() += ${0.043}`)
- simulation.circleFlare(0.043);
+ const value = 0.05
+ tech.duplication += value
+ simulation.inGameConsole(`tech.duplicationChance() += ${value}`)
+ simulation.circleFlare(value);
}
if (tech.isCancelRerolls) {
- for (let i = 0, len = 10 + 4 * Math.random(); i < len; i++) {
+ for (let i = 0, len = 8 + 4 * Math.random(); i < len; i++) {
let spawnType
if (Math.random() < 0.4 && !tech.isEnergyNoAmmo) {
spawnType = "ammo"
@@ -345,21 +306,14 @@ const powerUps = {
}
}
if (tech.isCancelCouple) powerUps.spawnDelay("coupling", 8)
- // if (tech.isCancelTech && Math.random() < 0.3) {
- // powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false);
- // simulation.makeTextLog(`options exchange : returns 1 tech `)
- // }
- // if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
- // const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
- // for (let i = 0; i < banishLength; i++) {
- // const index = powerUps.tech.choiceLog.length - i - 1
- // if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
- // tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
- // }
- // }
- // simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
- // }
+ if (tech.isCancelTech && tech.cancelTechCount === 0 && type !== "entanglement") {
+ tech.cancelTechCount++
+ // powerUps.research.use('tech')
+ powerUps[type].effect();
+ return
+ }
}
+
if (tech.isAnsatz && powerUps.research.count < 1) {
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
}
@@ -386,7 +340,7 @@ const powerUps = {
if (this.count < 5) simulation.removeEphemera(this.name)
ctx.beginPath();
- ctx.arc(m.pos.x, m.pos.y, this.count, 0, 2 * Math.PI);
+ ctx.arc(m.pos.x, m.pos.y, Math.max(3, this.count), 0, 2 * Math.PI);
ctx.fillStyle = color
ctx.fill();
// ctx.strokeStyle = "hsla(200,50%,61%,0.18)";
@@ -395,6 +349,125 @@ const powerUps = {
})
},
+ difficulty: {
+ name: "difficulty",
+ color: "#000",
+ size() {
+ return 80 / Math.pow(localSettings.difficultyMode, 1.5);
+ },
+ effect() {
+ const initialDifficultyMode = simulation.difficultyMode
+ requestAnimationFrame(() => { //add a background behind the power up menu
+ ctx.fillStyle = `rgba(150,150,150,0.9)`;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ });
+ powerUps.animatePowerUpGrab('rgba(0, 0, 0,0.6)')
+
+ if (!simulation.paused) {
+ simulation.paused = true;
+ simulation.isChoosing = true; //stops p from un pausing on key down
+ document.body.style.cursor = "auto";
+ document.getElementById("choose-grid").style.pointerEvents = "auto";
+ document.getElementById("choose-grid").style.transitionDuration = "0s";
+ }
+ //build level info
+ document.getElementById("choose-grid").classList.add('choose-grid-no-images');
+ document.getElementById("choose-grid").classList.remove('choose-grid');
+ document.getElementById("choose-grid").style.gridTemplateColumns = "505px" //adjust this to increase the width of the whole menu, but mostly the center column
+
+ let text = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
0.87x damage , 1.22x damage taken per level+1 boss on each level
+
more mob per levelfaster mobs per level
+
0.87x damage , 1.22x damage taken per level+1 random constraint on each level
+
+1 boss on each level bosses spawn 1 fewer ${powerUps.orb.tech()}
+
0.87x damage , 1.22x damage taken per level+1 random constraint on each level
+
0.5x initial damage 2x initial damage taken
+
+
+
${localSettings.difficultyCompleted[1] ? "⚆" : " "}
+
${localSettings.difficultyCompleted[2] ? "⚆" : " "}
+
${localSettings.difficultyCompleted[3] ? "⚆" : " "}
+
${localSettings.difficultyCompleted[4] ? "⚆" : " "}
+
${localSettings.difficultyCompleted[5] ? "⚇" : " "}
+
${localSettings.difficultyCompleted[6] ? "⚇" : " "}
+
+
+
+ confirm difficulty parameters
+
+
`
+ document.getElementById("choose-grid").innerHTML = text
+ //show level info
+ document.getElementById("choose-grid").style.opacity = "1"
+ document.getElementById("choose-grid").style.transitionDuration = "0.3s"; //how long is the fade in on
+ document.getElementById("choose-grid").style.visibility = "visible"
+ document.getElementById("choose-difficulty").addEventListener("click", () => {
+ level.unPause()
+ document.body.style.cursor = "none";
+ //reset hide image style
+ if (localSettings.isHideImages) {
+ document.getElementById("choose-grid").classList.add('choose-grid-no-images');
+ document.getElementById("choose-grid").classList.remove('choose-grid');
+ } else {
+ document.getElementById("choose-grid").classList.add('choose-grid');
+ document.getElementById("choose-grid").classList.remove('choose-grid-no-images');
+ }
+ if (level.levelsCleared === 0 && initialDifficultyMode !== simulation.difficultyMode) {
+ //remove and respawn all power ups if difficulty mode was changed
+ for (let i = 0; i < powerUp.length; ++i) Matter.Composite.remove(engine.world, powerUp[i]);
+ powerUp = [];
+ level.initialPowerUps()
+ simulation.trails(30)
+ }
+ });
+
+ let setDifficultyText = function (isReset = true) {
+ for (let i = 1; i < 7; i++) {
+ const id = document.getElementById("constraint-" + i)
+ if (simulation.difficultyMode < i) {
+ id.style.opacity = "0.15"
+ } else {
+ id.style.opacity = "1"
+ }
+ }
+ if (isReset) {
+ lore.setTechGoal()
+ localSettings.difficultyMode = simulation.difficultyMode
+ localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
+ localSettings.entanglement = undefined //after changing difficulty, reset stored tech
+ if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
+ }
+ }
+ setDifficultyText(false)
+ document.getElementById("difficulty-slider").value = simulation.difficultyMode
+ document.getElementById("difficulty-slider").addEventListener("input", () => {
+ simulation.difficultyMode = document.getElementById("difficulty-slider").value
+ setDifficultyText()
+ level.setConstraints()
+ });
+ for (let i = 1; i < 7; i++) {
+ document.getElementById("constraint-" + i).addEventListener("click", () => {
+ simulation.difficultyMode = i
+ document.getElementById("difficulty-slider").value = simulation.difficultyMode
+ setDifficultyText()
+ level.setConstraints()
+ });
+ }
+ },
+ },
coupling: {
name: "coupling",
color: "#0ae", //"#0cf",
@@ -430,19 +503,41 @@ const powerUps = {
endCycle: 0,
duration: null, //set by "tech: band gap"
damage: null, //set by "tech: band gap"
+ isDefense: false,
effect() {
powerUps.animatePowerUpGrab('rgba(255, 0, 0, 0.5)')
- powerUps.boost.endCycle = m.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - m.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
+ powerUps.boost.endCycle = simulation.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - simulation.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
},
draw() {
// console.log(this.endCycle)
- if (powerUps.boost.endCycle > m.cycle) {
- ctx.strokeStyle = "rgba(255,0,0,0.8)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
+ // if (powerUps.boost.endCycle > m.cycle) {
+ // ctx.strokeStyle = "rgba(255,0,0,0.8)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
+ // ctx.beginPath();
+ // const arc = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ // ctx.arc(m.pos.x, m.pos.y, 28, m.angle - Math.PI * arc, m.angle + Math.PI * arc); //- Math.PI / 2
+ // ctx.lineWidth = 4
+ // ctx.stroke();
+ // }
+
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
ctx.beginPath();
- const arc = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
- ctx.arc(m.pos.x, m.pos.y, 28, m.angle - Math.PI * arc, m.angle + Math.PI * arc); //- Math.PI / 2
- ctx.lineWidth = 4
+ const radius = 40
+ const mag = 8 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+ ctx.fillStyle = `rgba(255,0,200,${time})`
+ ctx.fill()
+ ctx.strokeStyle = "#f09"
+ ctx.lineWidth = 0.3 + 4 * time
ctx.stroke();
+ ctx.restore();
}
},
},
@@ -462,7 +557,7 @@ const powerUps = {
if (amount !== 0) powerUps.research.count += amount
if (tech.isRerollBots && !this.isMakingBots) {
let cycle = () => {
- const cost = 2 + Math.floor(0.2 * b.totalBots())
+ const cost = 2 + Math.floor(0.25 * b.totalBots())
if (m.alive && powerUps.research.count >= cost) {
requestAnimationFrame(cycle);
this.isMakingBots = true
@@ -494,7 +589,7 @@ const powerUps = {
}
if (tech.isRerollHaste) {
if (powerUps.research.count === 0) {
- tech.researchHaste = 0.66;
+ tech.researchHaste = 0.5;
b.setFireCD();
} else {
tech.researchHaste = 1;
@@ -504,11 +599,16 @@ const powerUps = {
},
currentRerollCount: 0,
use(type) { //runs when you actually research a list of selections, type can be field, gun, or tech
- if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
- tech.addJunkTechToPool(tech.junkResearchNumber * 0.01)
+ if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
+ tech.addJunkTechToPool(0.01)
} else {
powerUps.research.changeRerolls(-1)
}
+ if (tech.isResearchDamage) {
+ tech.damage *= 1.05
+ simulation.inGameConsole(`tech .damage *= ${1.05} //peer review`);
+ tech.addJunkTechToPool(0.01)
+ }
powerUps.research.currentRerollCount++
// if (tech.isBanish && type === 'tech') { // banish researched tech
// const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
@@ -516,12 +616,12 @@ const powerUps = {
// const index = powerUps.tech.choiceLog.length - i - 1
// if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
// }
- // simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
+ // simulation.inGameConsole(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
// }
if (tech.isResearchReality) {
m.switchWorlds()
simulation.trails()
- simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
+ simulation.inGameConsole(`simulation.amplitude = ${Math.random()}`);
}
powerUps[type].effect();
},
@@ -530,7 +630,7 @@ const powerUps = {
name: "heal",
color: "#0eb",
size() {
- return Math.sqrt(0.1 + 0.25) * 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)) * (tech.isFlipFlopOn && tech.isFlipFlopHealth ? Math.sqrt(2) : 1); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
+ return Math.sqrt(0.1 + 0.25) * 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
},
effect() {
if (!tech.isEnergyHealth && m.alive) {
@@ -540,30 +640,42 @@ const powerUps = {
let overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal
const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale
m.addHealth(heal);
- if (healOutput > 0) simulation.makeTextLog(`m .health += ${(healOutput).toFixed(3)}`) // ${m.health.toFixed(3)}
+ if (healOutput > 0) simulation.inGameConsole(`
m .health += ${(healOutput).toFixed(3)}`) // ${m.health.toFixed(3)}
if (tech.isOverHeal && overHeal > 0) { //tech quenching
- overHeal *= 2 //double the over heal converted to max health
- //make sure overHeal doesn't kill player
- if (m.health - overHeal * m.defense() < 0) overHeal = m.health - 0.01
- tech.extraMaxHealth += overHeal //increase max health
+ tech.extraMaxHealth += 0.3 * overHeal //increase max health
m.setMaxHealth();
- m.damage(overHeal);
- overHeal *= m.defense() // account for defense after m.damage() so the text log is accurate
- simulation.makeTextLog(`m .health -= ${(overHeal).toFixed(3)}`) // ${m.health.toFixed(3)}
+ simulation.inGameConsole(`
m .maxHealth += ${(0.3 * overHeal).toFixed(3)}`)
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,
- radius: overHeal * 500 * simulation.healScale,
- color: simulation.mobDmgColor,
+ radius: overHeal * 100 * simulation.healScale,
+ color: "#0eb",
time: simulation.drawTime
});
+
+ // overHeal *= 2 //double the over heal converted to max health
+ // //make sure overHeal doesn't kill player
+ // if (m.health - overHeal * m.defense() < 0) overHeal = m.health - 0.01
+ // if (overHeal > m.maxHealth) overHeal = m.maxHealth //just in case overHeal gets too big
+ // tech.extraMaxHealth += overHeal //increase max health
+ // m.setMaxHealth();
+ // m.damage(overHeal);
+ // overHeal *= m.defense() // account for defense after m.damage() so the text log is accurate
+ // simulation.inGameConsole(`
m .health -= ${(overHeal).toFixed(3)}`) // ${m.health.toFixed(3)}
+ // simulation.drawList.push({ //add dmg to draw queue
+ // x: m.pos.x,
+ // y: m.pos.y,
+ // radius: overHeal * 500 * simulation.healScale,
+ // color: simulation.mobDmgColor,
+ // time: simulation.drawTime
+ // });
} else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up
requestAnimationFrame(() => {
- powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
+ powerUps.directSpawn(this.position.x, this.position.y, "heal", true, Math.min(1, overHeal) * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, name, moving = true, mode = null, size = powerUps[name].size()) {
});
}
if (tech.isHealBrake) {
- const totalTime = 900
+ const totalTime = 1020
//check if you already have this effect
let foundActiveEffect = false
for (let i = 0; i < simulation.ephemera.length; i++) {
@@ -606,14 +718,14 @@ const powerUps = {
}
}
if (powerUps.healGiveMaxEnergy) {
- tech.healMaxEnergyBonus += 0.11 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)
+ tech.healMaxEnergyBonus += 0.14 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)
m.setMaxEnergy();
}
},
spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used
- powerUps.directSpawn(x, y, "heal", false, null, size)
- if (Math.random() < tech.duplicationChance()) {
- powerUps.directSpawn(x, y, "heal", false, null, size)
+ powerUps.directSpawn(x, y, "heal", false, size)
+ if (!level.isNextLevelPowerUps && Math.random() < tech.duplicationChance()) {
+ powerUps.directSpawn(x, y, "heal", false, size)
powerUp[powerUp.length - 1].isDuplicated = true
}
}
@@ -629,64 +741,35 @@ const powerUps = {
if (b.inventory.length > 0) {
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
- const target = b.guns[b.activeGun]
- if (target.ammo !== Infinity) {
+ const name = b.guns[b.activeGun]
+ if (name.ammo !== Infinity) {
if (tech.ammoCap) {
- const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap * 0.8 * couplingExtraAmmo) //0.7 is average
- target.ammo = ammoAdded
- // simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`)
+ name.ammo = Math.ceil(2 * name.ammoPack * tech.ammoCap * couplingExtraAmmo)
} else {
- const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack * 0.8 * couplingExtraAmmo)
- target.ammo += ammoAdded
- // simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`)
+ name.ammo += Math.ceil(2 * (Math.random() + Math.random()) * name.ammoPack * couplingExtraAmmo)
}
}
} else { //give ammo to all guns in inventory
- // let textLog = ""
for (let i = 0, len = b.inventory.length; i < len; i++) {
- const target = b.guns[b.inventory[i]]
- if (target.ammo !== Infinity) {
+ const name = b.guns[b.inventory[i]]
+ if (name.ammo !== Infinity) {
if (tech.ammoCap) {
- const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap * couplingExtraAmmo) //0.45 is average
- target.ammo = ammoAdded
- // textLog += `${target.name}.ammo = ${ammoAdded} `
+ name.ammo = Math.ceil(name.ammoPack * tech.ammoCap * couplingExtraAmmo)
} else { //default ammo behavior
- const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack * couplingExtraAmmo) //Math.ceil(Math.random() * target.ammoPack)
- // console.log(ammoAdded, Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack))
- target.ammo += ammoAdded
- // textLog += `${target.name}.ammo += ${ammoAdded} `
+ name.ammo += Math.ceil((Math.random() + Math.random()) * name.ammoPack * couplingExtraAmmo)
}
}
}
- // simulation.makeTextLog(textLog)
}
- // } else { //give ammo to all guns in inventory
- // for (let i = 0, len = b.inventory.length; i < len; i++) {
- // const target = b.guns[b.inventory[i]]
- // if (target.ammo !== Infinity) {
- // if (tech.ammoCap) {
- // const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average
- // target.ammo = ammoAdded
- // simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`)
- // } else {
- // const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack)
- // target.ammo += ammoAdded
- // simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`)
- // }
- // }
- // }
- // }
simulation.updateGunHUD();
}
}
},
cancelText(type) {
- // if (localSettings.isHideImages) { }
-
if (tech.isSuperDeterminism) {
return `
`
- } else if (tech.isCancelTech) {
- return `randomize
`
+ } else if (tech.isCancelTech && tech.cancelTechCount === 0) {
+ return `randomize
`
} else if (level.levelsCleared === 0 && localSettings.isTrainingNotAttempted && b.inventory.length === 0) { //don't show cancel if on initial level and haven't done tutorial
return `
`
} else {
@@ -697,13 +780,10 @@ const powerUps = {
let text = ""
if (type === "entanglement") {
text += `entanglement
`
- } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
text += `` // style = "margin-left: 192px; margin-right: -192px;"
- tech.junkResearchNumber = Math.ceil(3 * Math.random())
text += `
`
- for (let i = 0; i < tech.junkResearchNumber; i++) {
- text += `
`
- }
+ text += `
`
text += ` pseudoscience `
} else if (powerUps.research.count > 0) {
text += `` // style = "margin-left: 192px; margin-right: -192px;"
@@ -719,19 +799,16 @@ const powerUps = {
let text = `
`
if (type === "entanglement") {
text += `
entanglement ` //
- } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
text += `
` // style = "margin-left: 192px; margin-right: -192px;"
- tech.junkResearchNumber = Math.ceil(3 * Math.random())
text += ``
- for (let i = 0, len = tech.junkResearchNumber; i < len; i++) {
- text += `
`
- }
+ text += `
`
text += ` ${tech.isResearchReality ? "alternate reality " : "research"} `
} else if (powerUps.research.count > 0) {
text += `
` // style = "margin-left: 192px; margin-right: -192px;"
text += ``
let researchCap = 18
- if (tech.isCancelTech) researchCap -= 2
+ if (tech.isCancelTech && tech.cancelTechCount === 0) researchCap -= 2
if (canvas.width < 1951) researchCap -= 3
if (canvas.width < 1711) researchCap -= 4
for (let i = 0, len = Math.min(powerUps.research.count, researchCap); i < len; i++) {
@@ -743,8 +820,8 @@ const powerUps = {
}
if (tech.isSuperDeterminism) {
text += `cancel `
- } else if (tech.isCancelTech) {
- text += `randomize `
+ } else if (tech.isCancelTech && tech.cancelTechCount === 0) {
+ text += `randomize `
} else if (level.levelsCleared === 0 && localSettings.isTrainingNotAttempted && b.inventory.length === 0) {
text += `cancel ` //don't show cancel if on initial level and haven't done tutorial
} else {
@@ -787,31 +864,13 @@ const powerUps = {
}
return text
},
- // researchAndCancelText(type) {
- // let text = ""
- // if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
- // text += `
` // style = "margin-left: 192px; margin-right: -192px;"
- // tech.junkResearchNumber = Math.ceil(4 * Math.random())
- // text += `
`
- // for (let i = 0; i < tech.junkResearchNumber; i++) text += `
`
- // text += ` pseudoscience `
- // } else if (powerUps.research.count > 0) {
- // text += `
` // style = "margin-left: 192px; margin-right: -192px;"
- // text += `
`
- // for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `
`
- // text += ` ${tech.isResearchReality?"alternate reality ": "research"} `
- // } else {
- // text += `
`
- // }
- // return text + '
'
- // },
hideStyle: `style="height:auto; border: none; background-color: transparent;"`,
gunText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"`
return `
-
-
- ${b.guns[choose].descriptionFunction()}
`
+
+
+ ${b.guns[choose].descriptionFunction()}
`
},
fieldText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[choose].name}${choose === 0 ? Math.floor(Math.random() * 10) : ""}.webp');"`
@@ -828,6 +887,15 @@ const powerUps = {
${tech.tech[choose].name} ${techCountText}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
},
+ instantTechText(choose, click) {
+ const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
+ const style = localSettings.isHideImages || tech.tech[choose].isLore ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
+ //
+ return `
+
+
${tech.tech[choose].name} ${techCountText}
+ ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
+ },
skinTechText(choose, click) {
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
@@ -838,7 +906,7 @@ const powerUps = {
- ${tech.tech[choose].name} ${techCountText}
+ ${tech.tech[choose].name} ${techCountText}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}