gravityObservatory
new level: gravityObservatory
level: testChamber2 renamed gravityInterferometer
it has been added to the levels that are extra hard and only show up late game
it also got a bit hard with the addition of 1 more laser
deflected mob bullets are converted into small blocks
ablative drones is now a gun tech for drones
it makes ~33% more drones
1.033->1.05x sneak attack damage per coupling for cloaking field
bug fixes
extended vertical flip to edge cases:
trail left by snakeBoss
laser array from boss and mobs
springer,spiderBoss,mantisBoss constraints
subway: dark matter no longer removed if it gets too far from the player
training: fixed potential lock out from running out of ammo
training: fixed accidental difficulty increase
This commit is contained in:
@@ -474,13 +474,14 @@ const build = {
|
|||||||
|
|
||||||
// <strong class='color-g'>${b.activeGun === null || b.activeGun === undefined ? "undefined" : b.guns[b.activeGun].name}</strong> (${b.activeGun === null || b.activeGun === undefined ? "0" : b.guns[b.activeGun].ammo})
|
// <strong class='color-g'>${b.activeGun === null || b.activeGun === undefined ? "undefined" : b.guns[b.activeGun].name}</strong> (${b.activeGun === null || b.activeGun === undefined ? "0" : b.guns[b.activeGun].ammo})
|
||||||
|
|
||||||
|
// <br>
|
||||||
|
// <input onclick="build.showImages('pause')" type="checkbox" id="hide-images-pause" name="hide-images-pause" ${localSettings.isHideImages ? "checked" : ""}>
|
||||||
|
// <label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.15em;" >hide images</label>
|
||||||
|
|
||||||
let text = `<div class="pause-grid-module" style="padding: 8px;">
|
let text = `<div class="pause-grid-module" style="padding: 8px;">
|
||||||
<span style="font-size:1.4em;font-weight: 600; float: left;">PAUSED</span>
|
<span style="font-size:1.4em;font-weight: 600; float: left;">PAUSED</span>
|
||||||
<em style="float: right;color:#ccc;">press ${input.key.pause} to resume</em>
|
<em style="float: right;color:#ccc;">press ${input.key.pause} to resume</em>
|
||||||
<br>
|
<br>
|
||||||
<input onclick="build.showImages('pause')" type="checkbox" id="hide-images-pause" name="hide-images-pause" ${localSettings.isHideImages ? "checked" : ""}>
|
|
||||||
<label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.15em;" >hide images</label>
|
|
||||||
<br>
|
|
||||||
<button onclick="build.shareURL(false)" class='sort-button' style="font-size:1em;float: right;">copy build URL</button>
|
<button onclick="build.shareURL(false)" class='sort-button' style="font-size:1em;float: right;">copy build URL</button>
|
||||||
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" ${localSettings.isHideHUD ? "checked" : ""}>
|
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" ${localSettings.isHideHUD ? "checked" : ""}>
|
||||||
<label for="hide-hud" title="hide: tech, damage taken, damage, in game console" style="font-size:1.15em;">minimal HUD</label>
|
<label for="hide-hud" title="hide: tech, damage taken, damage, in game console" style="font-size:1.15em;">minimal HUD</label>
|
||||||
|
|||||||
491
js/level.js
491
js/level.js
@@ -8,8 +8,8 @@ const level = {
|
|||||||
defaultZoom: 1400,
|
defaultZoom: 1400,
|
||||||
onLevel: -1,
|
onLevel: -1,
|
||||||
levelsCleared: 0,
|
levelsCleared: 0,
|
||||||
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
|
//see level.populateLevels: (initial, ... , (reservoir, factory, or gravityInterferometer), reactor, ... , subway, final) added later
|
||||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers", "flocculation", "testChamber2"],
|
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock", "towers", "flocculation", "gravityObservatory"],
|
||||||
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"],
|
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"],
|
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
|
||||||
levels: [],
|
levels: [],
|
||||||
@@ -30,14 +30,14 @@ const level = {
|
|||||||
// tech.tech[297].frequency = 100
|
// tech.tech[297].frequency = 100
|
||||||
// tech.addJunkTechToPool(0.5)
|
// tech.addJunkTechToPool(0.5)
|
||||||
// m.couplingChange(10)
|
// m.couplingChange(10)
|
||||||
// m.setField("time dilation") //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("standing wave") //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
|
// m.energy = 0
|
||||||
// powerUps.research.count = 3
|
// powerUps.research.count = 3
|
||||||
// tech.isHookWire = true
|
// tech.isHookWire = true
|
||||||
// m.energy = 0
|
// m.energy = 0
|
||||||
// simulation.molecularMode = 2
|
// simulation.molecularMode = 2
|
||||||
// m.damage(0.1);
|
// m.damage(0.1);
|
||||||
// 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("nail gun") //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("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
|
// 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.laserColor = "#fff"
|
||||||
@@ -45,9 +45,9 @@ const level = {
|
|||||||
|
|
||||||
// b.guns[8].ammo = 100000000
|
// b.guns[8].ammo = 100000000
|
||||||
// requestAnimationFrame(() => { tech.giveTech("stimulated emission") });
|
// requestAnimationFrame(() => { tech.giveTech("stimulated emission") });
|
||||||
// tech.giveTech("mass-energy equivalence")
|
// tech.giveTech("dark matter")
|
||||||
// tech.addJunkTechToPool(0.5)
|
// tech.addJunkTechToPool(0.5)
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("the upside down")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("entropic gravity")
|
||||||
// for (let i = 0; i < 1; ++i) tech.giveTech("nitinol")
|
// for (let i = 0; i < 1; ++i) tech.giveTech("nitinol")
|
||||||
// m.skin.egg();
|
// m.skin.egg();
|
||||||
|
|
||||||
@@ -59,13 +59,13 @@ const level = {
|
|||||||
// for (let i = 0; i < 4; i++) powerUps.directSpawn(450, -50, "tech");
|
// for (let i = 0; i < 4; i++) powerUps.directSpawn(450, -50, "tech");
|
||||||
// for (let i = 0; i < 7; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 250, "research", false);
|
// for (let i = 0; i < 7; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 250, "research", false);
|
||||||
// spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
|
// spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
|
||||||
// level.testChamber2();
|
// level.gravityInterferometer();
|
||||||
|
|
||||||
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
||||||
|
|
||||||
|
|
||||||
// for (let i = 0; i < 1; ++i) spawn.revolutionBoss(1900, -500)
|
// for (let i = 0; i < 1; ++i) spawn.snakeBoss(1900, -500)
|
||||||
// for (let i = 0; i < 1; i++) spawn.starter(1900, -500, 20)
|
// for (let i = 0; i < 1; i++) spawn.mantisBoss(1900, -500)
|
||||||
|
|
||||||
// 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 < 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 < 2; ++i) powerUps.directSpawn(m.pos.x + 450, m.pos.y + 50 * Math.random(), "boost");
|
||||||
@@ -137,7 +137,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
level.newLevelOrPhase()
|
level.newLevelOrPhase()
|
||||||
if (simulation.isTraining) {
|
if (simulation.isTraining) {
|
||||||
simulation.difficultyMode = 2
|
simulation.difficultyMode = 1
|
||||||
} else {
|
} else {
|
||||||
simulation.inGameConsole(`<span class='color-var'>level</span>.onLevel <span class='color-symbol'>=</span> "<span class='color-text'>${level.levels[level.onLevel]}</span>"`);
|
simulation.inGameConsole(`<span class='color-var'>level</span>.onLevel <span class='color-symbol'>=</span> "<span class='color-text'>${level.levels[level.onLevel]}</span>"`);
|
||||||
document.title = "n-gon: " + level.levelAnnounce();
|
document.title = "n-gon: " + level.levelAnnounce();
|
||||||
@@ -256,7 +256,12 @@ const level = {
|
|||||||
customTopLayer() { },
|
customTopLayer() { },
|
||||||
updateDifficulty() {
|
updateDifficulty() {
|
||||||
simulation.difficulty = level.levelsCleared * simulation.difficultyMode
|
simulation.difficulty = level.levelsCleared * simulation.difficultyMode
|
||||||
if (simulation.isTraining) simulation.difficulty = 1
|
if (simulation.isTraining) {
|
||||||
|
simulation.difficulty = 1
|
||||||
|
simulation.difficultyMode = 1
|
||||||
|
m.dmgScale = 1
|
||||||
|
simulation.dmgScale = 1//Math.max(0.1, 0.25 * level.levelsCleared * scale) //damage done by mobs scales with total levels //a bigger number means the player takes more damage
|
||||||
|
} else {
|
||||||
const scale = simulation.difficultyMode > 3 ? 2 : 1
|
const scale = simulation.difficultyMode > 3 ? 2 : 1
|
||||||
m.dmgScale = Math.pow(0.85, level.levelsCleared * scale)
|
m.dmgScale = Math.pow(0.85, level.levelsCleared * scale)
|
||||||
simulation.dmgScale = Math.max(0.1, 0.25 * level.levelsCleared * scale) //damage done by mobs scales with total levels //a bigger number means the player takes more damage
|
simulation.dmgScale = Math.max(0.1, 0.25 * level.levelsCleared * scale) //damage done by mobs scales with total levels //a bigger number means the player takes more damage
|
||||||
@@ -264,6 +269,7 @@ const level = {
|
|||||||
m.dmgScale *= 0.5
|
m.dmgScale *= 0.5
|
||||||
simulation.dmgScale *= 2
|
simulation.dmgScale *= 2
|
||||||
}
|
}
|
||||||
|
}
|
||||||
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
|
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
|
||||||
if (simulation.difficultyMode === 1) {
|
if (simulation.difficultyMode === 1) {
|
||||||
simulation.accelScale = 1.1
|
simulation.accelScale = 1.1
|
||||||
@@ -772,7 +778,8 @@ const level = {
|
|||||||
}
|
}
|
||||||
level.levels = shuffle(level.levels); //shuffles order of maps with seeded random
|
level.levels = shuffle(level.levels); //shuffles order of maps with seeded random
|
||||||
level.levels.length = 9 //remove any extra levels past 9
|
level.levels.length = 9 //remove any extra levels past 9
|
||||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, Math.random() < 0.5 ? "factory" : "reservoir"); //add level to the back half of the randomized levels list
|
pick = ["gravityInterferometer", "factory", "reservoir"]
|
||||||
|
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, pick[Math.floor(Math.random() * pick.length)]); //add level to the back half of the randomized levels list
|
||||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||||
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
|
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
|
||||||
level.levels.unshift("initial"); //add level to the start of the randomized levels list
|
level.levels.unshift("initial"); //add level to the start of the randomized levels list
|
||||||
@@ -1548,7 +1555,7 @@ const level = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
button(x, y, width = 126, isSpawnBase = true, isInvertedVertical = false) {
|
button(x, y, width = 126, isSpawnBase = true, isInvertedVertical = false, color = "hsl(0, 100%, 70%)") {
|
||||||
if (isSpawnBase) {
|
if (isSpawnBase) {
|
||||||
if (isInvertedVertical) {
|
if (isInvertedVertical) {
|
||||||
spawn.mapVertex(x + 65, y - 3, "100 -10 -100 -10 -70 10 70 10");
|
spawn.mapVertex(x + 65, y - 3, "100 -10 -100 -10 -70 10 70 10");
|
||||||
@@ -1594,18 +1601,19 @@ const level = {
|
|||||||
this.isUp = false;
|
this.isUp = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
query() {
|
queryRemove() {
|
||||||
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
|
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
|
||||||
this.isUp = true;
|
this.isUp = true;
|
||||||
} else {
|
} else {
|
||||||
if (this.isUp === true) {
|
if (this.isUp === true) {
|
||||||
const list = Matter.Query.region(body, this) //are any blocks colliding with this
|
const list = Matter.Query.region(body, this) //are any blocks colliding with this
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
if (list[0].bounds.max.x - list[0].bounds.min.x < 150 && list[0].bounds.max.y - list[0].bounds.min.y < 150) { //not too big of a block
|
Matter.Composite.remove(engine.world, list[0]);
|
||||||
Matter.Body.setPosition(list[0], { //teleport block to the center of the button
|
for (let i = 0; i < body.length; i++) {
|
||||||
x: this.min.x + width / 2,
|
if (body[i] === list[0]) {
|
||||||
y: list[0].position.y
|
body.splice(i, 1);
|
||||||
})
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Matter.Body.setVelocity(list[0], { x: 0, y: 0 });
|
Matter.Body.setVelocity(list[0], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
@@ -1613,8 +1621,15 @@ const level = {
|
|||||||
this.isUp = false;
|
this.isUp = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
queryPlayer() {
|
||||||
|
if (Matter.Query.region([player], this).length === 0) {
|
||||||
|
this.isUp = true;
|
||||||
|
} else {
|
||||||
|
this.isUp = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
draw() {
|
draw() {
|
||||||
ctx.fillStyle = "hsl(0, 100%, 70%)"
|
ctx.fillStyle = color
|
||||||
if (this.isUp) {
|
if (this.isUp) {
|
||||||
ctx.fillRect(this.min.x, this.min.y, this.width, 20)
|
ctx.fillRect(this.min.x, this.min.y, this.width, 20)
|
||||||
} else {
|
} else {
|
||||||
@@ -1654,18 +1669,20 @@ const level = {
|
|||||||
this.isUp = false;
|
this.isUp = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
query() {
|
queryRemove() {
|
||||||
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
|
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
|
||||||
this.isUp = true;
|
this.isUp = true;
|
||||||
} else {
|
} else {
|
||||||
if (this.isUp === true) {
|
if (this.isUp === true) {
|
||||||
const list = Matter.Query.region(body, this) //are any blocks colliding with this
|
const list = Matter.Query.region(body, this) //are any blocks colliding with this
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
if (list[0].bounds.max.x - list[0].bounds.min.x < 150 && list[0].bounds.max.y - list[0].bounds.min.y < 150) { //not too big of a block
|
//delete triggering block
|
||||||
Matter.Body.setPosition(list[0], { //teleport block to the center of the button
|
Matter.Composite.remove(engine.world, list[0]);
|
||||||
x: this.min.x + width / 2,
|
for (let i = 0; i < body.length; i++) {
|
||||||
y: list[0].position.y
|
if (body[i] === list[0]) {
|
||||||
})
|
body.splice(i, 1);
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Matter.Body.setVelocity(list[0], { x: 0, y: 0 });
|
Matter.Body.setVelocity(list[0], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
@@ -1673,8 +1690,15 @@ const level = {
|
|||||||
this.isUp = false;
|
this.isUp = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
queryPlayer() {
|
||||||
|
if (Matter.Query.region([player], this).length === 0) {
|
||||||
|
this.isUp = true;
|
||||||
|
} else {
|
||||||
|
this.isUp = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
draw() {
|
draw() {
|
||||||
ctx.fillStyle = "hsl(0, 100%, 70%)"
|
ctx.fillStyle = color
|
||||||
if (this.isUp) {
|
if (this.isUp) {
|
||||||
ctx.fillRect(this.min.x, this.min.y - 10, this.width, 20)
|
ctx.fillRect(this.min.x, this.min.y - 10, this.width, 20)
|
||||||
} else {
|
} else {
|
||||||
@@ -3376,7 +3400,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
//remove any mob that is too far from player
|
//remove any mob that is too far from player
|
||||||
for (let i = 0; i < mob.length; ++i) {
|
for (let i = 0; i < mob.length; ++i) {
|
||||||
if (Vector.magnitudeSquared(Vector.sub(player.position, mob[i].position)) > 4000000) { //remove any mob farther then 2000 pixels from player
|
if (Vector.magnitudeSquared(Vector.sub(player.position, mob[i].position)) > 4000000 && !mob[i].isDarkMatter) { //remove any mob farther then 2000 pixels from player
|
||||||
mob[i].removeConsBB()
|
mob[i].removeConsBB()
|
||||||
mob[i].removeCons()
|
mob[i].removeCons()
|
||||||
mob[i].leaveBody = false
|
mob[i].leaveBody = false
|
||||||
@@ -7025,7 +7049,8 @@ const level = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
testChamber2() {
|
gravityInterferometer() {
|
||||||
|
level.isVerticalFLipLevel = true
|
||||||
mobs.maxMobBody = 20 //normally 40, but set to 10 to avoid too much clutter
|
mobs.maxMobBody = 20 //normally 40, but set to 10 to avoid too much clutter
|
||||||
simulation.fallHeight = 4000
|
simulation.fallHeight = 4000
|
||||||
level.announceMobTypes()
|
level.announceMobTypes()
|
||||||
@@ -7133,13 +7158,13 @@ const level = {
|
|||||||
spawn.mapRect(-4000, 2000, 8000, 3000); //floor
|
spawn.mapRect(-4000, 2000, 8000, 3000); //floor
|
||||||
}
|
}
|
||||||
let buildNormalMap = function () {
|
let buildNormalMap = function () {
|
||||||
buttons.push(level.button(-1895, -1600))
|
buttons.push(level.button(-1895, -1600, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
buttons[buttons.length - 1].isUp = false
|
buttons[buttons.length - 1].isUp = false
|
||||||
spawn.mapRect(-1675, -2025, 50, 250);
|
spawn.mapRect(-1675, -2025, 50, 250);
|
||||||
|
|
||||||
simulation.ephemera.push({
|
simulation.ephemera.push({
|
||||||
name: "buttons up",
|
name: "buttons up",
|
||||||
count: flipAnimationCycles,
|
count: flipAnimationCycles + 30,
|
||||||
do() {
|
do() {
|
||||||
this.count--
|
this.count--
|
||||||
if (this.count < 0) {
|
if (this.count < 0) {
|
||||||
@@ -7161,6 +7186,10 @@ const level = {
|
|||||||
balance.push(level.rotor(-750, 1700, 400, 25, 0.01, Math.PI / 2, 0.5))
|
balance.push(level.rotor(-750, 1700, 400, 25, 0.01, Math.PI / 2, 0.5))
|
||||||
balance.push(level.rotor(-275, 1650, 550, 32, 0.01, 0, 0.5))
|
balance.push(level.rotor(-275, 1650, 550, 32, 0.01, 0, 0.5))
|
||||||
|
|
||||||
|
lasers.push(level.laser({ x: -1625, y: -850 }, { x: 1980, y: -850 })) ////x, y, width, height, damage = 0.002)
|
||||||
|
spawn.mapRect(1980, -862, 25, 25); //laser entrance
|
||||||
|
balance.push(level.rotor(1000, -910, 550, 32, 0.01, 0, 0.5))
|
||||||
|
|
||||||
//left side
|
//left side
|
||||||
//level entrance
|
//level entrance
|
||||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||||
@@ -7214,13 +7243,13 @@ const level = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
let buildVerticalFLippedMap = function () { // flip Y with this -> spawn.mapRect(x, -y - h, w, h);
|
let buildVerticalFLippedMap = function () { // flip Y with this -> spawn.mapRect(x, -y - h, w, h);
|
||||||
buttons.push(level.button(-1895, 1600, 126, true, true))
|
buttons.push(level.button(-1895, 1600, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
buttons[buttons.length - 1].isUp = false
|
buttons[buttons.length - 1].isUp = false
|
||||||
spawn.mapRect(-1675, 2025 - 250, 50, 250);
|
spawn.mapRect(-1675, 2025 - 250, 50, 250);
|
||||||
|
|
||||||
simulation.ephemera.push({
|
simulation.ephemera.push({
|
||||||
name: "buttons up",
|
name: "buttons up",
|
||||||
count: flipAnimationCycles,
|
count: flipAnimationCycles + 30,
|
||||||
do() {
|
do() {
|
||||||
this.count--
|
this.count--
|
||||||
if (this.count < 0) {
|
if (this.count < 0) {
|
||||||
@@ -7242,6 +7271,11 @@ const level = {
|
|||||||
balance.push(level.rotor(-750, -1700 - 25, 400, 25, 0.01, Math.PI / 2, 0.5))
|
balance.push(level.rotor(-750, -1700 - 25, 400, 25, 0.01, Math.PI / 2, 0.5))
|
||||||
balance.push(level.rotor(-250, -1650 - 32, 500, 32, 0.01, 0, 0.5))
|
balance.push(level.rotor(-250, -1650 - 32, 500, 32, 0.01, 0, 0.5))
|
||||||
|
|
||||||
|
lasers.push(level.laser({ x: -1625, y: 850 }, { x: 1980, y: 850 })) ////x, y, width, height, damage = 0.002)
|
||||||
|
spawn.mapRect(1980, 862 - 25, 25, 25); //laser entrance
|
||||||
|
balance.push(level.rotor(1000, 910 - 32, 550, 32, 0.01, 0, 0.5))
|
||||||
|
|
||||||
|
|
||||||
//left side
|
//left side
|
||||||
//level entrance
|
//level entrance
|
||||||
spawn.mapRect(level.enter.x, level.enter.y - 20 - 20, 100, 20);
|
spawn.mapRect(level.enter.x, level.enter.y - 20 - 20, 100, 20);
|
||||||
@@ -7329,8 +7363,24 @@ const level = {
|
|||||||
m.history[i].angle *= -1
|
m.history[i].angle *= -1
|
||||||
m.history[i].velocity.y *= -1
|
m.history[i].velocity.y *= -1
|
||||||
}
|
}
|
||||||
|
for (let i = 0; i < mob.length; i++) {
|
||||||
//stun to wipe history of all mobs, so they don't get confused about player position vertical swap
|
//stun to wipe history of all mobs, so they don't get confused about player position vertical swap
|
||||||
for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 1)
|
mobs.statusStun(mob[i], 1)
|
||||||
|
//edge cases
|
||||||
|
if (mob[i].history) {
|
||||||
|
for (let j = 0; j < mob[i].history.length; j++) mob[i].history[j].y *= -1
|
||||||
|
}
|
||||||
|
if (mob[i].laserArray) {
|
||||||
|
for (let j = 0; j < mob[i].laserArray.length; j++) {
|
||||||
|
mob[i].laserArray[j].a.y *= -1
|
||||||
|
mob[i].laserArray[j].b.y *= -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mob[i].springTarget2) {
|
||||||
|
mob[i].springTarget.y *= -1
|
||||||
|
mob[i].springTarget2.y *= -1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buildMapOutline()
|
buildMapOutline()
|
||||||
buildNormalMap()
|
buildNormalMap()
|
||||||
@@ -7339,7 +7389,8 @@ const level = {
|
|||||||
for (let i = 0; i < buttons.length; i++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
buttons[i].draw()
|
buttons[i].draw()
|
||||||
if (buttons[i].isUp && !isFlipping) {
|
if (buttons[i].isUp && !isFlipping) {
|
||||||
buttons[i].query();
|
// buttons[i].query();
|
||||||
|
buttons[i].queryPlayer();
|
||||||
if (!buttons[i].isUp) {
|
if (!buttons[i].isUp) {
|
||||||
isFlipping = true
|
isFlipping = true
|
||||||
if (isFlipped) {
|
if (isFlipped) {
|
||||||
@@ -7444,7 +7495,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.fillStyle = `rgba(255,255,255,${0 + 0.3 * Math.random()})` //balances center dot
|
ctx.fillStyle = `rgba(255,255,255,${0 + 0.3 * Math.random()})`
|
||||||
if (isFlipped) {
|
if (isFlipped) {
|
||||||
ctx.fillRect(-2025, 2025 - 450, 400, 450);
|
ctx.fillRect(-2025, 2025 - 450, 400, 450);
|
||||||
//shadows
|
//shadows
|
||||||
@@ -7518,6 +7569,351 @@ const level = {
|
|||||||
spawn.randomLevelBoss(-875, -200);
|
spawn.randomLevelBoss(-875, -200);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
},
|
},
|
||||||
|
gravityObservatory() {
|
||||||
|
mobs.maxMobBody = 25 //normally 40, but set lower to avoid too much clutter
|
||||||
|
level.isVerticalFLipLevel = true
|
||||||
|
simulation.fallHeight = 4000
|
||||||
|
level.announceMobTypes()
|
||||||
|
level.setPosToSpawn(-2375, 950);
|
||||||
|
level.exit.x = 3750
|
||||||
|
level.exit.y = 165
|
||||||
|
level.defaultZoom = 2600
|
||||||
|
simulation.zoomTransition(level.defaultZoom)
|
||||||
|
document.body.style.backgroundColor = "#c3d6e1";
|
||||||
|
color.map = "#444"
|
||||||
|
|
||||||
|
let buttons = []
|
||||||
|
let isFlipped = false;
|
||||||
|
let isFlipping = false;
|
||||||
|
const flipAnimationCycles = 60
|
||||||
|
|
||||||
|
let buildMapOutline = function () {
|
||||||
|
//boxes center on zero,zero with deep walls to hide background
|
||||||
|
spawn.mapRect(4000, -2000, 2000, 4000); //right map wall
|
||||||
|
spawn.mapRect(-6000, -2000, 2000, 4000); //left map wall
|
||||||
|
spawn.mapRect(-6000, -4000, 12000, 3000); //map ceiling
|
||||||
|
spawn.mapRect(-6000, 1000, 12000, 3000); //floor
|
||||||
|
}
|
||||||
|
let buildNormalMap = function () {
|
||||||
|
buttons.push(level.button(-3350, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(-3350, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(150, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(150, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(3725, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(3725, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
for (let i = 0; i < buttons.length; i++) buttons[i].isUp = false
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "buttons up",
|
||||||
|
count: flipAnimationCycles,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) {
|
||||||
|
for (let i = 0; i < buttons.length; i++) buttons[i].isUp = true
|
||||||
|
simulation.removeEphemera(this.name);
|
||||||
|
isFlipping = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
//far left zone
|
||||||
|
spawn.mapRect(-2575, 987, 375, 100);
|
||||||
|
spawn.mapRect(-2575, -600, 600, 1325);
|
||||||
|
spawn.mapRect(-2200, 650, 225, 475);
|
||||||
|
spawn.mapRect(-2575, 700, 35, 125);
|
||||||
|
spawn.mapRect(-3500, -1050, 425, 63);
|
||||||
|
spawn.mapRect(-3500, 987, 425, 50);
|
||||||
|
spawn.mapVertex(-2275, -1000, "-400 0 -300 150 300 150 400 0");
|
||||||
|
|
||||||
|
spawn.mapVertex(-3287, 0, "-213 -500 0 -550 213 -500 213 500 0 550 -213 500");
|
||||||
|
spawn.mapVertex(-3750, -100, "-100 -200 -50 -250 50 -250 100 -200 100 200 50 250 -50 250 -100 200");
|
||||||
|
spawn.mapVertex(-2825, 0, "-100 -400 -50 -450 50 -450 100 -400 100 400 50 450 -50 450 -100 400");
|
||||||
|
|
||||||
|
//dense center left zone
|
||||||
|
spawn.mapVertex(-1150, -750, "400 -75 425 0 400 75 -400 75 -425 0 -400 -75");
|
||||||
|
spawn.mapVertex(-550, -450, "400 -75 425 0 400 75 -400 75 -425 0 -400 -75");
|
||||||
|
|
||||||
|
spawn.mapVertex(-1685, 153, "-150 -500 0 -550 150 -500 150 750 -150 450");
|
||||||
|
spawn.mapVertex(-1106, 707, "500 -150 550 0 500 150 -500 150 -800 -150");
|
||||||
|
spawn.mapRect(-1645, 470, 200, 200);
|
||||||
|
Matter.Body.setAngle(map[map.length - 1], Math.PI / 4)
|
||||||
|
spawn.mapRect(-2085, 910, 200, 200);
|
||||||
|
Matter.Body.setAngle(map[map.length - 1], Math.PI / 4)
|
||||||
|
|
||||||
|
//open center right area with both bosses
|
||||||
|
// spawn.mapRect(0, -450, 425, 1100);
|
||||||
|
spawn.mapVertex(213, 0, "-213 -700 0 -650 213 -600 213 700 0 650 -213 600");
|
||||||
|
spawn.mapRect(0, -1050, 425, 63);
|
||||||
|
spawn.mapRect(0, 987, 425, 50);
|
||||||
|
spawn.mapVertex(1700, -1000, "-600 0 -400 400 400 400 600 0");
|
||||||
|
spawn.mapVertex(2800, -1000, "-500 0 -400 150 400 150 500 0");
|
||||||
|
spawn.mapVertex(1700, 700, "-400 -100 -450 0 -400 100 400 100 450 0 400 -100");
|
||||||
|
spawn.mapVertex(2800, 375, "-400 -100 -450 0 -400 100 400 100 450 0 400 -100");
|
||||||
|
|
||||||
|
//far right exit structure
|
||||||
|
spawn.mapRect(3575, -1050, 425, 63);
|
||||||
|
spawn.mapRect(3575, 987, 425, 50);
|
||||||
|
spawn.mapVertex(3840, 450, "-250 -300 250 -300 250 300 -250 100");
|
||||||
|
spawn.mapVertex(3840, -450, "-250 300 250 300 250 -300 -250 -100");
|
||||||
|
spawn.mapRect(3750, 185, 100, 25);
|
||||||
|
}
|
||||||
|
let buildVerticalFLippedMap = function () { // flip Y with this -> spawn.mapRect(x, -y - h, w, h);
|
||||||
|
buttons.push(level.button(-3350, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(-3350, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(150, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(150, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(3725, 985, 126, true, false, "hsl(330, 100%, 50%)"))
|
||||||
|
buttons.push(level.button(3725, -985, 126, true, true, "hsl(330, 100%, 50%)"))
|
||||||
|
for (let i = 0; i < buttons.length; i++) buttons[i].isUp = false
|
||||||
|
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "buttons up",
|
||||||
|
count: flipAnimationCycles,
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) {
|
||||||
|
for (let i = 0; i < buttons.length; i++) buttons[i].isUp = true
|
||||||
|
simulation.removeEphemera(this.name);
|
||||||
|
isFlipping = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//far left zone
|
||||||
|
spawn.mapRect(-2575, -1087, 375, 100);
|
||||||
|
spawn.mapRect(-2575, 600 - 1325, 600, 1325);
|
||||||
|
spawn.mapRect(-2200, -650 - 475, 225, 475);
|
||||||
|
spawn.mapRect(-2575, -700 - 125, 35, 125);
|
||||||
|
spawn.mapRect(-3500, 1050 - 63, 425, 63);
|
||||||
|
spawn.mapRect(-3500, -987 - 50, 425, 50);
|
||||||
|
spawn.mapVertex(-2275, 1000, "-300 0 -400 150 400 150 300 0");
|
||||||
|
|
||||||
|
spawn.mapVertex(-3287, 0, "-213 -500 0 -550 213 -500 213 500 0 550 -213 500");
|
||||||
|
spawn.mapVertex(-3750, 100, "-100 -200 -50 -250 50 -250 100 -200 100 200 50 250 -50 250 -100 200");
|
||||||
|
spawn.mapVertex(-2825, 0, "-100 -400 -50 -450 50 -450 100 -400 100 400 50 450 -50 450 -100 400");
|
||||||
|
|
||||||
|
//dense center left zone
|
||||||
|
spawn.mapVertex(-1150, 750, "400 -75 425 0 400 75 -400 75 -425 0 -400 -75");
|
||||||
|
spawn.mapVertex(-550, 450, "400 -75 425 0 400 75 -400 75 -425 0 -400 -75");
|
||||||
|
|
||||||
|
spawn.mapVertex(-1685, -153, "-150 500 0 550 150 500 150 -750 -150 -450");
|
||||||
|
spawn.mapVertex(-1106, -707, "500 150 550 0 500 -150 -500 -150 -800 150");
|
||||||
|
spawn.mapRect(-1645, -470 - 200, 200, 200);
|
||||||
|
Matter.Body.setAngle(map[map.length - 1], Math.PI / 4)
|
||||||
|
spawn.mapRect(-2085, -910 - 200, 200, 200);
|
||||||
|
Matter.Body.setAngle(map[map.length - 1], Math.PI / 4)
|
||||||
|
|
||||||
|
//open center right area with both bosses
|
||||||
|
spawn.mapVertex(213, 0, "-213 -600 0 -650 213 -700 213 600 0 650 -213 700");
|
||||||
|
spawn.mapRect(0, 1050 - 63, 425, 63);
|
||||||
|
spawn.mapRect(0, -987 - 50, 425, 50);
|
||||||
|
spawn.mapVertex(1700, 1000, "-400 0 -600 400 600 400 400 0");
|
||||||
|
spawn.mapVertex(2800, 1000, "-400 0 -500 150 500 150 400 0");
|
||||||
|
spawn.mapVertex(1700, -700, "-400 -100 -450 0 -400 100 400 100 450 0 400 -100");
|
||||||
|
spawn.mapVertex(2800, -375, "-400 -100 -450 0 -400 100 400 100 450 0 400 -100");
|
||||||
|
//far right building like exit structure
|
||||||
|
spawn.mapRect(3575, 1050 - 63, 425, 63);
|
||||||
|
spawn.mapRect(3575, -987 - 50, 425, 50);
|
||||||
|
spawn.mapVertex(3840, 450, "-250 -300 250 -300 250 300 -250 100");
|
||||||
|
spawn.mapVertex(3840, -450, "-250 300 250 300 250 -300 -250 -100");
|
||||||
|
spawn.mapRect(3750, -210, 100, 25);
|
||||||
|
}
|
||||||
|
let flipAndRemove = function () {
|
||||||
|
simulation.translatePlayerAndCamera({ x: player.position.x, y: -player.position.y })
|
||||||
|
level.enter.y = -level.enter.y
|
||||||
|
level.exit.y = -level.exit.y
|
||||||
|
for (let i = body.length - 1; i > -1; i--) {
|
||||||
|
if (body[i].isRotor) body.splice(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAll(array) {
|
||||||
|
for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
|
||||||
|
}
|
||||||
|
removeAll(map);
|
||||||
|
map = [];
|
||||||
|
removeAll(buttons);
|
||||||
|
buttons = []
|
||||||
|
|
||||||
|
function invertVertical(array) {
|
||||||
|
for (let i = 0; i < array.length; ++i) {
|
||||||
|
Matter.Body.setPosition(array[i], { x: array[i].position.x, y: -array[i].position.y })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invertVertical(body);
|
||||||
|
invertVertical(powerUp);
|
||||||
|
invertVertical(bullet);
|
||||||
|
invertVertical(mob);
|
||||||
|
//fields
|
||||||
|
if (m.fieldMode === 9 && m.hole.isOn) {
|
||||||
|
m.hole.pos1.y *= -1
|
||||||
|
m.hole.pos2.y *= -1
|
||||||
|
} else if (m.fieldMode === 2) {
|
||||||
|
m.fieldPosition.y *= -1
|
||||||
|
m.fieldAngle *= -1
|
||||||
|
}
|
||||||
|
//history
|
||||||
|
for (let i = 0; i < m.history.length; i++) {
|
||||||
|
m.history[i].position.y *= -1
|
||||||
|
m.history[i].angle *= -1
|
||||||
|
m.history[i].velocity.y *= -1
|
||||||
|
}
|
||||||
|
for (let i = 0; i < mob.length; i++) {
|
||||||
|
//stun to wipe history of all mobs, so they don't get confused about player position vertical swap
|
||||||
|
mobs.statusStun(mob[i], 1)
|
||||||
|
//edge cases
|
||||||
|
if (mob[i].history) {
|
||||||
|
for (let j = 0; j < mob[i].history.length; j++) mob[i].history[j].y *= -1
|
||||||
|
}
|
||||||
|
if (mob[i].laserArray) {
|
||||||
|
for (let j = 0; j < mob[i].laserArray.length; j++) {
|
||||||
|
mob[i].laserArray[j].a.y *= -1
|
||||||
|
mob[i].laserArray[j].b.y *= -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mob[i].springTarget2) {
|
||||||
|
mob[i].springTarget.y *= -1
|
||||||
|
mob[i].springTarget2.y *= -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildMapOutline()
|
||||||
|
buildNormalMap()
|
||||||
|
level.custom = () => {
|
||||||
|
//stuff floats near buttons
|
||||||
|
if ((player.position.x > -3505 && player.position.x < -3075) ||
|
||||||
|
(player.position.x > 0 && player.position.x < 425) ||
|
||||||
|
(player.position.x > 3575)) {
|
||||||
|
if (player.position.y > 0) {
|
||||||
|
player.force.y -= 0.8 * simulation.g * player.mass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < body.length; i++) {
|
||||||
|
if ((body[i].position.x > -3505 && body[i].position.x < -3075) ||
|
||||||
|
(body[i].position.x > 0 && body[i].position.x < 425) ||
|
||||||
|
(body[i].position.x > 3575)
|
||||||
|
) {
|
||||||
|
if (body[i].position.y > 0) {
|
||||||
|
body[i].force.y -= 1.04 * simulation.g * body[i].mass
|
||||||
|
} else {
|
||||||
|
body[i].force.y += 1.04 * simulation.g * body[i].mass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < powerUp.length; i++) {
|
||||||
|
if ((powerUp[i].position.x > -3505 && powerUp[i].position.x < -3075) ||
|
||||||
|
(powerUp[i].position.x > 0 && powerUp[i].position.x < 425) ||
|
||||||
|
(powerUp[i].position.x > 3575)
|
||||||
|
) {
|
||||||
|
if (powerUp[i].position.y > 0) {
|
||||||
|
powerUp[i].force.y -= 1.04 * simulation.g * powerUp[i].mass
|
||||||
|
} else {
|
||||||
|
powerUp[i].force.y += 1.04 * simulation.g * powerUp[i].mass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
|
buttons[i].draw()
|
||||||
|
if (buttons[i].isUp && !isFlipping) {
|
||||||
|
// buttons[i].query();
|
||||||
|
buttons[i].queryPlayer();
|
||||||
|
if (!buttons[i].isUp) {
|
||||||
|
isFlipping = true
|
||||||
|
if (isFlipped) {
|
||||||
|
const normalMap = function () {
|
||||||
|
isFlipped = false
|
||||||
|
flipAndRemove()
|
||||||
|
buildMapOutline()
|
||||||
|
buildNormalMap(); //rewrite flipped version of map
|
||||||
|
simulation.draw.setPaths() //update map graphics
|
||||||
|
level.addToWorld()
|
||||||
|
}
|
||||||
|
simulation.unFlipCameraVertical(flipAnimationCycles, normalMap)
|
||||||
|
} else {
|
||||||
|
const flipMap = function () {
|
||||||
|
isFlipped = true
|
||||||
|
flipAndRemove()
|
||||||
|
buildMapOutline()
|
||||||
|
buildVerticalFLippedMap(); //rewrite flipped version of map
|
||||||
|
simulation.draw.setPaths() //update map graphics
|
||||||
|
level.addToWorld()
|
||||||
|
}
|
||||||
|
simulation.flipCameraVertical(flipAnimationCycles, flipMap)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.fillStyle = "#d4f4f4"
|
||||||
|
ctx.fillRect(3575, -300, 475, 575);
|
||||||
|
if (isFlipped) {
|
||||||
|
//draw flipped entrance
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(level.enter.x, level.enter.y - 30);
|
||||||
|
ctx.lineTo(level.enter.x, level.enter.y + 80);
|
||||||
|
ctx.bezierCurveTo(level.enter.x, level.enter.y + 170, level.enter.x + 100, level.enter.y + 170, level.enter.x + 100, level.enter.y + 80);
|
||||||
|
ctx.lineTo(level.enter.x + 100, level.enter.y - 30);
|
||||||
|
ctx.lineTo(level.enter.x, level.enter.y - 30);
|
||||||
|
ctx.fillStyle = "#ccc";
|
||||||
|
ctx.fill();
|
||||||
|
//draw flipped exit
|
||||||
|
ctx.fillStyle = "#d4f4f4"
|
||||||
|
// ctx.fillRect(-2000, 1325, 375, 350)
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(level.exit.x, level.exit.y - 30);
|
||||||
|
ctx.lineTo(level.exit.x, level.exit.y + 80);
|
||||||
|
ctx.bezierCurveTo(level.exit.x, level.exit.y + 170, level.exit.x + 100, level.exit.y + 170, level.exit.x + 100, level.exit.y + 80);
|
||||||
|
ctx.lineTo(level.exit.x + 100, level.exit.y - 30);
|
||||||
|
ctx.lineTo(level.exit.x, level.exit.y - 30);
|
||||||
|
ctx.fillStyle = "#0ff";
|
||||||
|
ctx.fill();
|
||||||
|
} else {
|
||||||
|
level.exit.drawAndCheck();
|
||||||
|
level.enter.draw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
level.customTopLayer = () => {
|
||||||
|
ctx.fillStyle = `rgba(255,255,255,${0 + 0.3 * Math.random()})`
|
||||||
|
ctx.fillRect(-3500, -1075, 425, 2100);
|
||||||
|
ctx.fillRect(0, -1075, 425, 2100);
|
||||||
|
ctx.fillRect(3575, -1075, 425, 2100);
|
||||||
|
ctx.fillStyle = "rgba(0,0,0,0.08)"
|
||||||
|
ctx.fillRect(-2575, -1025, 600, 2050);
|
||||||
|
ctx.fillRect(1300, -1050, 800, 2100);
|
||||||
|
ctx.fillRect(2400, -1050, 800, 2100);
|
||||||
|
};
|
||||||
|
|
||||||
|
// spawn.bodyRect(1900, 1875, 100, 125, 0.5);
|
||||||
|
spawn.bodyRect(-2569, 825, 25, 165);
|
||||||
|
|
||||||
|
spawn.randomMob(-3750, -400, 0.2);
|
||||||
|
spawn.randomMob(-3425, -600, 0.2);
|
||||||
|
spawn.randomMob(-3225, -625, 0.3);
|
||||||
|
spawn.randomMob(-2850, -500, 0.3);
|
||||||
|
spawn.randomMob(-2450, -675, 0.3);
|
||||||
|
spawn.randomMob(-2150, -650, 0.4);
|
||||||
|
spawn.randomMob(-1650, -500, 0.4);
|
||||||
|
spawn.randomMob(-1325, 275, 0.4);
|
||||||
|
spawn.randomMob(-825, 425, 0.5);
|
||||||
|
spawn.randomMob(-400, -575, 0.5);
|
||||||
|
spawn.randomMob(-1275, -900, 0.5);
|
||||||
|
spawn.randomMob(-675, -775, 0.6);
|
||||||
|
spawn.randomMob(150, -725, 0.6);
|
||||||
|
spawn.randomMob(475, 925, 0.7);
|
||||||
|
spawn.randomMob(1500, 550, 0.7);
|
||||||
|
spawn.randomMob(1850, 500, 0.7);
|
||||||
|
spawn.randomMob(2025, 925, 0.8);
|
||||||
|
spawn.randomMob(1575, 875, 0.8);
|
||||||
|
spawn.randomMob(2650, 650, 0.9);
|
||||||
|
spawn.randomMob(3100, 700, 0.9);
|
||||||
|
spawn.randomMob(3050, 100, 1);
|
||||||
|
spawn.randomMob(2350, 100, 1);
|
||||||
|
spawn.randomMob(3400, 875, 1);
|
||||||
|
spawn.randomMob(3375, -725, 1);
|
||||||
|
spawn.randomMob(3925, 100, 1);
|
||||||
|
|
||||||
|
powerUps.spawnStartingPowerUps(-825, -600);
|
||||||
|
spawn.randomLevelBoss(1550, 200);
|
||||||
|
spawn.secondaryBossChance(2675, -125)
|
||||||
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
|
},
|
||||||
lock() {
|
lock() {
|
||||||
level.announceMobTypes()
|
level.announceMobTypes()
|
||||||
level.setPosToSpawn(0, -65); //lower start
|
level.setPosToSpawn(0, -65); //lower start
|
||||||
@@ -18624,7 +19020,7 @@ const level = {
|
|||||||
const door3 = level.door(20238, -781.4, 88, 452, 412)
|
const door3 = level.door(20238, -781.4, 88, 452, 412)
|
||||||
const hazard2 = level.hazard(2550, -150, 10, 0.4) //y=-1485
|
const hazard2 = level.hazard(2550, -150, 10, 0.4) //y=-1485
|
||||||
|
|
||||||
simulation.enableConstructMode()
|
// simulation.enableConstructMode()
|
||||||
level.setPosToSpawn(0, -50); //normal spawn
|
level.setPosToSpawn(0, -50); //normal spawn
|
||||||
level.exit.x = 15316;
|
level.exit.x = 15316;
|
||||||
level.exit.y = -30;
|
level.exit.y = -30;
|
||||||
@@ -21089,7 +21485,7 @@ const level = {
|
|||||||
ctx.fillRect(1675, -2325, 250, 75);
|
ctx.fillRect(1675, -2325, 250, 75);
|
||||||
ctx.fillRect(2700, -2525, 25, 150);
|
ctx.fillRect(2700, -2525, 25, 150);
|
||||||
};
|
};
|
||||||
simulation.enableConstructMode()
|
// simulation.enableConstructMode()
|
||||||
level.setPosToSpawn(0, -50); //normal spawn
|
level.setPosToSpawn(0, -50); //normal spawn
|
||||||
level.exit.x = 23885;
|
level.exit.x = 23885;
|
||||||
level.exit.y = 800;
|
level.exit.y = 800;
|
||||||
@@ -21221,7 +21617,7 @@ const level = {
|
|||||||
const slime2 = level.hazard(2400, -2100, 200, 2100);
|
const slime2 = level.hazard(2400, -2100, 200, 2100);
|
||||||
const slime3 = level.hazard(2600, -2100, 3600, 200);
|
const slime3 = level.hazard(2600, -2100, 3600, 200);
|
||||||
const slime4 = level.hazard(6400, -2100, 3600, 200);
|
const slime4 = level.hazard(6400, -2100, 3600, 200);
|
||||||
simulation.enableConstructMode()
|
// simulation.enableConstructMode()
|
||||||
level.setPosToSpawn(0, -50); //normal spawn
|
level.setPosToSpawn(0, -50); //normal spawn
|
||||||
level.exit.x = 13130.3;
|
level.exit.x = 13130.3;
|
||||||
let rainCount = 1
|
let rainCount = 1
|
||||||
@@ -24060,7 +24456,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
simulation.enableConstructMode() //landgreen if you see this can you remove im probably gonna forget
|
// simulation.enableConstructMode() //landgreen if you see this can you remove im probably gonna forget
|
||||||
for (let i = 0; i < spawn.bossTypeSpawnOrder.length * Math.random(); i++) {
|
for (let i = 0; i < spawn.bossTypeSpawnOrder.length * Math.random(); i++) {
|
||||||
spawn.bossTypeSpawnOrder.splice(i * Math.floor(Math.random() * spawn.bossTypeSpawnOrder.length), 1, "restoreBoss") //meh good enough
|
spawn.bossTypeSpawnOrder.splice(i * Math.floor(Math.random() * spawn.bossTypeSpawnOrder.length), 1, "restoreBoss") //meh good enough
|
||||||
}
|
}
|
||||||
@@ -24212,7 +24608,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
Composite.add(engine.world, me.constraint);
|
Composite.add(engine.world, me.constraint);
|
||||||
}
|
}
|
||||||
simulation.enableConstructMode()
|
// simulation.enableConstructMode()
|
||||||
let firstMobsSpawned = 1
|
let firstMobsSpawned = 1
|
||||||
let secondMobsSpawned = 0
|
let secondMobsSpawned = 0
|
||||||
let thirdMobsSpawned = 0
|
let thirdMobsSpawned = 0
|
||||||
@@ -27153,7 +27549,7 @@ const level = {
|
|||||||
const door3 = level.door(20238, -781.4, 88, 452, 412)
|
const door3 = level.door(20238, -781.4, 88, 452, 412)
|
||||||
//y=-1485
|
//y=-1485
|
||||||
|
|
||||||
simulation.enableConstructMode()
|
// simulation.enableConstructMode()
|
||||||
level.setPosToSpawn(0, -50); //normal spawn
|
level.setPosToSpawn(0, -50); //normal spawn
|
||||||
level.exit.x = 15316;
|
level.exit.x = 15316;
|
||||||
level.exit.y = -84;
|
level.exit.y = -84;
|
||||||
@@ -36285,10 +36681,9 @@ const level = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
spawn.spinner(1300 + i, -3000 - 200 * i, 25 + 5 * i)
|
spawn.spinner(1300 + i, -3000 - 200 * i, 25 + 5 * i)
|
||||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
const who = mob[mob.length - 1]
|
||||||
x: 0,
|
Matter.Body.setVelocity(who, { x: 0, y: 62 });
|
||||||
y: 62
|
who.isDropPowerUp = false
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
|
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
|
||||||
@@ -36373,6 +36768,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
spawn.hopper(1300 + i, -3000 - 2000 * i, 25 + 5 * i)
|
spawn.hopper(1300 + i, -3000 - 2000 * i, 25 + 5 * i)
|
||||||
|
mob[mob.length - 1].isDropPowerUp = false
|
||||||
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
|
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
|
||||||
@@ -36455,6 +36851,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
spawn.spawner(i * 230, -800)
|
spawn.spawner(i * 230, -800)
|
||||||
|
mob[mob.length - 1].isDropPowerUp = false
|
||||||
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
spawn.mapVertex(510, -430, "725 0 725 80 -650 80 -650 -80 650 -80"); //upper room with mobs
|
spawn.mapVertex(510, -430, "725 0 725 80 -650 80 -650 -80 650 -80"); //upper room with mobs
|
||||||
@@ -36538,6 +36935,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
spawn.springer(i * 200, -800)
|
spawn.springer(i * 200, -800)
|
||||||
|
mob[mob.length - 1].isDropPowerUp = false
|
||||||
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
spawn.springer(1825, -330, 20);
|
spawn.springer(1825, -330, 20);
|
||||||
@@ -36627,6 +37025,7 @@ const level = {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
spawn.springer(2100 + i * 100, -250)
|
spawn.springer(2100 + i * 100, -250)
|
||||||
|
mob[mob.length - 1].isDropPowerUp = false
|
||||||
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
// Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
js/mob.js
23
js/mob.js
@@ -658,29 +658,6 @@ const mobs = {
|
|||||||
this.cons.length = 100 + 1.5 * this.radius;
|
this.cons.length = 100 + 1.5 * this.radius;
|
||||||
this.cons2.length = 100 + 1.5 * this.radius;
|
this.cons2.length = 100 + 1.5 * this.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// if (!(simulation.cycle % (this.seePlayerFreq * 2))) {
|
|
||||||
// const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
|
|
||||||
// const goal = Vector.add(this.position, Vector.mult(unit, stepRange))
|
|
||||||
// this.springTarget.x = goal.x;
|
|
||||||
// this.springTarget.y = goal.y;
|
|
||||||
// // this.springTarget.x = this.seePlayer.position.x;
|
|
||||||
// // this.springTarget.y = this.seePlayer.position.y;
|
|
||||||
// this.cons.length = -200;
|
|
||||||
// this.cons2.length = 100 + 1.5 * this.radius;
|
|
||||||
// } else if (!(simulation.cycle % this.seePlayerFreq)) {
|
|
||||||
// const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
|
|
||||||
// const goal = Vector.add(this.position, Vector.mult(unit, stepRange))
|
|
||||||
// this.springTarget2.x = goal.x;
|
|
||||||
// this.springTarget2.y = goal.y;
|
|
||||||
// // this.springTarget2.x = this.seePlayer.position.x;
|
|
||||||
// // this.springTarget2.y = this.seePlayer.position.y;
|
|
||||||
// this.cons.length = 100 + 1.5 * this.radius;
|
|
||||||
// this.cons2.length = -200;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
js/player.js
56
js/player.js
@@ -691,8 +691,8 @@ const m = {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.lastHarmCycle = m.cycle
|
m.lastHarmCycle = m.cycle
|
||||||
if (tech.isDroneOnDamage && bullet.length < 150) { //chance to build a drone on damage from tech
|
if (tech.isDroneOnDamage && bullet.length < 180) { //chance to build a drone on damage from tech
|
||||||
const len = Math.min((dmg - 0.06 * Math.random()) * 80, 60) / tech.droneEnergyReduction * (tech.isEnergyHealth ? 0.5 : 1)
|
const len = Math.min((dmg - 0.045 * Math.random()) * 95, 65) / tech.droneEnergyReduction * (tech.isEnergyHealth ? 0.5 : 1)
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
if (Math.random() < 0.5) b.drone({
|
if (Math.random() < 0.5) b.drone({
|
||||||
x: m.pos.x + 30 * Math.cos(m.angle) + 100 * (Math.random() - 0.5),
|
x: m.pos.x + 30 * Math.cos(m.angle) + 100 * (Math.random() - 0.5),
|
||||||
@@ -3074,6 +3074,51 @@ const m = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
minEnergyToDeflect: 0.05,
|
minEnergyToDeflect: 0.05,
|
||||||
|
bulletsToBlocks(who) {
|
||||||
|
if (who.isMobBullet && !who.isInvulnerable && who.mass < 10 && body.length < mobs.maxMobBody) {
|
||||||
|
// spawn block
|
||||||
|
body[body.length] = Matter.Bodies.polygon(who.position.x, who.position.y, who.vertices.length, who.radius, {
|
||||||
|
friction: 0.05,
|
||||||
|
frictionAir: 0.001,
|
||||||
|
collisionFilter: {
|
||||||
|
category: cat.bullet,
|
||||||
|
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
|
||||||
|
},
|
||||||
|
classType: "body",
|
||||||
|
isPrinted: true,
|
||||||
|
radius: 10, //used to grow and warp the shape of the block
|
||||||
|
density: 0.002, //double density for 2x damage
|
||||||
|
});
|
||||||
|
const block = body[body.length - 1]
|
||||||
|
Composite.add(engine.world, block); //add to world
|
||||||
|
//reverse velocity and make sure it's above 40
|
||||||
|
const unit = Vector.mult(Vector.normalise(who.velocity), -Math.max(40, who.speed))
|
||||||
|
Matter.Body.setVelocity(block, unit);
|
||||||
|
|
||||||
|
simulation.ephemera.push({
|
||||||
|
name: "remove block",
|
||||||
|
count: 120, //cycles before it self removes
|
||||||
|
do() {
|
||||||
|
this.count--
|
||||||
|
if (this.count < 0) {
|
||||||
|
simulation.removeEphemera(this.name)
|
||||||
|
Matter.Composite.remove(engine.world, block);
|
||||||
|
//find block
|
||||||
|
for (let i = 0; i < body.length; i++) {
|
||||||
|
if (body[i] === block) {
|
||||||
|
body.splice(i, 1);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
//remove mob bullet
|
||||||
|
Matter.Composite.remove(engine.world, who); //remove from physics early to avoid collisions with block
|
||||||
|
who.alive = false
|
||||||
|
}
|
||||||
|
},
|
||||||
pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) {
|
pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) {
|
||||||
if (m.energy > m.minEnergyToDeflect) { //shield needs at least some of the cost to block
|
if (m.energy > m.minEnergyToDeflect) { //shield needs at least some of the cost to block
|
||||||
if (who.isShielded) fieldBlockCost *= 2; //shielded mobs take more energy to block
|
if (who.isShielded) fieldBlockCost *= 2; //shielded mobs take more energy to block
|
||||||
@@ -3108,6 +3153,7 @@ const m = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m.bulletsToBlocks(who)
|
||||||
const unit = Vector.normalise(Vector.sub(player.position, who.position))
|
const unit = Vector.normalise(Vector.sub(player.position, who.position))
|
||||||
if (tech.blockDmg) {
|
if (tech.blockDmg) {
|
||||||
Matter.Body.setVelocity(who, { x: 0.5 * who.velocity.x, y: 0.5 * who.velocity.y });
|
Matter.Body.setVelocity(who, { x: 0.5 * who.velocity.x, y: 0.5 * who.velocity.y });
|
||||||
@@ -3282,7 +3328,8 @@ const m = {
|
|||||||
case 6: //time dilation
|
case 6: //time dilation
|
||||||
return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
|
return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
|
||||||
case 7: //cloaking
|
case 7: //cloaking
|
||||||
return `<strong>${(1 + 3.3 * couple).toFixed(3)}x</strong> ambush <strong class='color-d'>damage</strong>`
|
// return `<strong>${(1 + 3.3 * couple).toFixed(3)}x</strong> ambush <strong class='color-d'>damage</strong>`
|
||||||
|
return `<strong>${(1 + 0.05 * couple).toFixed(3)}x</strong> ambush <strong class='color-d'>damage</strong>`
|
||||||
case 8: //pilot wave
|
case 8: //pilot wave
|
||||||
return `<strong>${(1 + 0.05 * couple).toFixed(2)}x</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
return `<strong>${(1 + 0.05 * couple).toFixed(2)}x</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
||||||
case 9: //wormhole
|
case 9: //wormhole
|
||||||
@@ -3577,6 +3624,7 @@ const m = {
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m.bulletsToBlocks(mob[i])
|
||||||
if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField)
|
if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField)
|
||||||
//mob knock backs
|
//mob knock backs
|
||||||
const massRoot = Math.sqrt(Math.max(1, mob[i].mass));
|
const massRoot = Math.sqrt(Math.max(1, mob[i].mass));
|
||||||
@@ -4809,7 +4857,7 @@ const m = {
|
|||||||
}
|
}
|
||||||
this.drawRegenEnergyCloaking()
|
this.drawRegenEnergyCloaking()
|
||||||
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
|
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)
|
m.fieldDamage = 4.5 * (1 + 0.05 * m.coupling)
|
||||||
const timeLeft = (m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) - m.cycle) * 0.5
|
const timeLeft = (m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) - m.cycle) * 0.5
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(m.pos.x, m.pos.y, 32, 0, 2 * Math.PI);
|
ctx.arc(m.pos.x, m.pos.y, 32, 0, 2 * Math.PI);
|
||||||
|
|||||||
@@ -351,9 +351,10 @@ const powerUps = {
|
|||||||
name: "instructions",
|
name: "instructions",
|
||||||
color: "rgba(100,125,140,0.35)",
|
color: "rgba(100,125,140,0.35)",
|
||||||
size() {
|
size() {
|
||||||
return 150
|
return 130
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
|
Matter.Body.setVelocity(player, { x: 0, y: 0 });//power up is so big it launches the player, this stops that
|
||||||
requestAnimationFrame(() => { //add a background behind the power up menu
|
requestAnimationFrame(() => { //add a background behind the power up menu
|
||||||
ctx.fillStyle = `rgba(150,150,150,0.9)`;
|
ctx.fillStyle = `rgba(150,150,150,0.9)`;
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
@@ -372,7 +373,7 @@ const powerUps = {
|
|||||||
document.getElementById("choose-grid").classList.remove('choose-grid');
|
document.getElementById("choose-grid").classList.remove('choose-grid');
|
||||||
document.getElementById("choose-grid").style.gridTemplateColumns = "800px"//adjust this to increase the width of the whole menu, but mostly the center column
|
document.getElementById("choose-grid").style.gridTemplateColumns = "800px"//adjust this to increase the width of the whole menu, but mostly the center column
|
||||||
let lore = localSettings.loreCount > 0 ? "lore.unlockTesting() //press T to enter testing" : ""
|
let lore = localSettings.loreCount > 0 ? "lore.unlockTesting() //press T to enter testing" : ""
|
||||||
let text = `<div class="grid-container"><pre> <strong>//console commands</strong>
|
let text = `<div class="grid-container" style = "font-size:1rem;"><pre> <strong>//console commands</strong>
|
||||||
powerUps.instructions.effect() //reproduce this message
|
powerUps.instructions.effect() //reproduce this message
|
||||||
tech.giveTech("name") //replace "name" with tech name
|
tech.giveTech("name") //replace "name" with tech name
|
||||||
m.setField("name") //standing wave perfect diamagnetism negative mass molecular assembler plasma torch time dilation metamaterial cloaking pilot wave wormhole grappling hook
|
m.setField("name") //standing wave perfect diamagnetism negative mass molecular assembler plasma torch time dilation metamaterial cloaking pilot wave wormhole grappling hook
|
||||||
@@ -382,17 +383,13 @@ const powerUps = {
|
|||||||
m.energy = 0 //set energy
|
m.energy = 0 //set energy
|
||||||
m.health = 1 //set health
|
m.health = 1 //set health
|
||||||
m.maxHealth = 1 //set max health
|
m.maxHealth = 1 //set max health
|
||||||
m.energy = 1 //set energy
|
|
||||||
m.maxEnergy = 1 //set max energy
|
m.maxEnergy = 1 //set max energy
|
||||||
simulation.enableConstructMode() //press T to build with mouse
|
simulation.enableConstructMode() //press T to build with mouse
|
||||||
${lore}
|
${lore}
|
||||||
|
powerUps.spawn(m.pos.x, m.pos.y, "name") //tech gun field heal ammo research coupling boost instructions entanglement
|
||||||
//tech gun field heal ammo research coupling boost instructions entanglement
|
|
||||||
powerUps.spawn(m.pos.x, m.pos.y, "name")
|
|
||||||
Matter.Body.setPosition(player, simulation.mouseInGame);
|
Matter.Body.setPosition(player, simulation.mouseInGame);
|
||||||
spawn.bodyRect(simulation.mouseInGame.x, simulation.mouseInGame.y, 50, 50)
|
spawn.bodyRect(simulation.mouseInGame.x, simulation.mouseInGame.y, 50, 50)
|
||||||
spawn.randomLevelBoss(simulation.mouseInGame.x, simulation.mouseInGame.y)
|
spawn.randomLevelBoss(simulation.mouseInGame.x, simulation.mouseInGame.y)
|
||||||
|
|
||||||
<strong>chrome</strong> <strong>firefox</strong>
|
<strong>chrome</strong> <strong>firefox</strong>
|
||||||
<strong>Win/Linux:</strong> Ctrl + Shift + J Ctrl + Shift + J
|
<strong>Win/Linux:</strong> Ctrl + Shift + J Ctrl + Shift + J
|
||||||
<strong>Mac:</strong> Cmd + Option + J Cmd + Shift + J</pre></div>
|
<strong>Mac:</strong> Cmd + Option + J Cmd + Shift + J</pre></div>
|
||||||
|
|||||||
@@ -935,6 +935,7 @@ const simulation = {
|
|||||||
m.onGround = false
|
m.onGround = false
|
||||||
m.lastOnGroundCycle = 0
|
m.lastOnGroundCycle = 0
|
||||||
m.health = 0;
|
m.health = 0;
|
||||||
|
level.isNoHeal = false
|
||||||
m.addHealth(0.25)
|
m.addHealth(0.25)
|
||||||
m.drop();
|
m.drop();
|
||||||
m.holdingTarget = null
|
m.holdingTarget = null
|
||||||
@@ -1185,6 +1186,7 @@ const simulation = {
|
|||||||
},
|
},
|
||||||
clearNow: false,
|
clearNow: false,
|
||||||
clearMap() {
|
clearMap() {
|
||||||
|
level.isVerticalFLipLevel = false
|
||||||
level.isProcedural = false;
|
level.isProcedural = false;
|
||||||
level.fallMode = "";
|
level.fallMode = "";
|
||||||
simulation.unFlipCameraVertical()
|
simulation.unFlipCameraVertical()
|
||||||
@@ -1957,6 +1959,7 @@ const simulation = {
|
|||||||
},
|
},
|
||||||
enableConstructMode() {
|
enableConstructMode() {
|
||||||
level.isProcedural = false //this is set to be true in levels like labs that need x+ and y+ in front of positions
|
level.isProcedural = false //this is set to be true in levels like labs that need x+ and y+ in front of positions
|
||||||
|
level.isVerticalFLipLevel = false
|
||||||
simulation.isConstructionMode = true;
|
simulation.isConstructionMode = true;
|
||||||
simulation.isHorizontalFlipped = false;
|
simulation.isHorizontalFlipped = false;
|
||||||
simulation.isAutoZoom = false;
|
simulation.isAutoZoom = false;
|
||||||
@@ -1983,8 +1986,17 @@ const simulation = {
|
|||||||
simulation.outputMapString(`${Math.floor(simulation.constructMouseDownPosition.x)}, ${Math.floor(simulation.constructMouseDownPosition.y)}`);
|
simulation.outputMapString(`${Math.floor(simulation.constructMouseDownPosition.x)}, ${Math.floor(simulation.constructMouseDownPosition.y)}`);
|
||||||
} else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive
|
} else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive
|
||||||
if (e.button === 0) { //add map
|
if (e.button === 0) { //add map
|
||||||
|
// if (level.isProcedural) {
|
||||||
|
// simulation.outputMapString(`spawn.mapRect(x+${x}, ${y}, ${dx}, ${dy});\n`);
|
||||||
|
// } else {
|
||||||
|
// simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
|
||||||
|
// }
|
||||||
if (level.isProcedural) {
|
if (level.isProcedural) {
|
||||||
simulation.outputMapString(`spawn.mapRect(x+${x}, ${y}, ${dx}, ${dy});\n`);
|
simulation.outputMapString(`spawn.mapRect(x+${x}, ${y}, ${dx}, ${dy});\n`);
|
||||||
|
} else if (level.isVerticalFLipLevel) {
|
||||||
|
console.log('hi')
|
||||||
|
simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
|
||||||
|
simulation.outputMapString(`//spawn.mapRect(${x}, ${-y - dy}, ${dx}, ${dy});\n`);
|
||||||
} else {
|
} else {
|
||||||
simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
|
simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
|
||||||
}
|
}
|
||||||
|
|||||||
77
js/spawn.js
77
js/spawn.js
@@ -2559,10 +2559,7 @@ const spawn = {
|
|||||||
const springStiffness = 0.00014;
|
const springStiffness = 0.00014;
|
||||||
const springDampening = 0.0005;
|
const springDampening = 0.0005;
|
||||||
|
|
||||||
me.springTarget = {
|
me.springTarget = { x: me.position.x, y: me.position.y };
|
||||||
x: me.position.x,
|
|
||||||
y: me.position.y
|
|
||||||
};
|
|
||||||
const len = cons.length;
|
const len = cons.length;
|
||||||
cons[len] = Constraint.create({
|
cons[len] = Constraint.create({
|
||||||
pointA: me.springTarget,
|
pointA: me.springTarget,
|
||||||
@@ -4322,7 +4319,7 @@ const spawn = {
|
|||||||
me.accelMag = 0.0002 * simulation.accelScale;
|
me.accelMag = 0.0002 * simulation.accelScale;
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
|
|
||||||
me.lasers = [] //keeps track of static laser beams
|
me.laserArray = [] //keeps track of static laser beams
|
||||||
me.laserLimit = simulation.difficultyMode < 3 ? 1 : 2
|
me.laserLimit = simulation.difficultyMode < 3 ? 1 : 2
|
||||||
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
|
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
|
||||||
me.cycle = 0
|
me.cycle = 0
|
||||||
@@ -4354,14 +4351,14 @@ const spawn = {
|
|||||||
best2.y = save1Y
|
best2.y = save1Y
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lasers.push({ a: { x: best1.x, y: best1.y }, b: { x: best2.x, y: best2.y }, fade: 0 })
|
this.laserArray.push({ a: { x: best1.x, y: best1.y }, b: { x: best2.x, y: best2.y }, fade: 0 })
|
||||||
//friction to animate the mob dropping something
|
//friction to animate the mob dropping something
|
||||||
Matter.Body.setVelocity(this, Vector.mult(this.velocity, 0.05));
|
Matter.Body.setVelocity(this, Vector.mult(this.velocity, 0.05));
|
||||||
Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.05)
|
Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.05)
|
||||||
// simulation.drawList.push({ x: best1.x, y: best1.y, radius: 10, color: "rgba(255,0,100,0.3)", time: simulation.drawTime * 2 });
|
// simulation.drawList.push({ x: best1.x, y: best1.y, radius: 10, color: "rgba(255,0,100,0.3)", time: simulation.drawTime * 2 });
|
||||||
// simulation.drawList.push({ x: best2.x, y: best2.y, radius: 10, color: "rgba(255,0,100,0.3)", time: simulation.drawTime * 2 });
|
// simulation.drawList.push({ x: best2.x, y: best2.y, radius: 10, color: "rgba(255,0,100,0.3)", time: simulation.drawTime * 2 });
|
||||||
|
|
||||||
if (this.lasers.length > this.laserLimit) this.lasers.shift() //cap total lasers
|
if (this.laserArray.length > this.laserLimit) this.laserArray.shift() //cap total laserArray
|
||||||
if (!this.seePlayer.recall && (Vector.magnitude(Vector.sub(this.position, this.driftGoal)) < 200 || 0.3 > Math.random())) {
|
if (!this.seePlayer.recall && (Vector.magnitude(Vector.sub(this.position, this.driftGoal)) < 200 || 0.3 > Math.random())) {
|
||||||
//used in drift when can't find player
|
//used in drift when can't find player
|
||||||
const radius = Math.random() * 1000;
|
const radius = Math.random() * 1000;
|
||||||
@@ -4371,9 +4368,9 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
me.fireLaser = function () {
|
me.fireLaser = function () {
|
||||||
for (let i = 0; i < this.lasers.length; i++) { //fire all lasers in the array
|
for (let i = 0; i < this.laserArray.length; i++) { //fire all lasers in the array
|
||||||
let best = vertexCollision(this.lasers[i].a, this.lasers[i].b, m.isCloak ? [body] : [body, [playerBody, playerHead]]); //not checking map to fix not hitting player bug, this might make some lasers look strange when the map changes
|
let best = vertexCollision(this.laserArray[i].a, this.laserArray[i].b, m.isCloak ? [body] : [body, [playerBody, playerHead]]); //not checking map to fix not hitting player bug, this might make some lasers look strange when the map changes
|
||||||
if (this.lasers[i].fade > 0.99) {
|
if (this.laserArray[i].fade > 0.99) {
|
||||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
|
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
|
||||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
|
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
|
||||||
const dmg = 0.03 * simulation.dmgScale;
|
const dmg = 0.03 * simulation.dmgScale;
|
||||||
@@ -4385,7 +4382,7 @@ const spawn = {
|
|||||||
color: "rgba(255,0,100,0.5)",
|
color: "rgba(255,0,100,0.5)",
|
||||||
time: 20
|
time: 20
|
||||||
});
|
});
|
||||||
this.lasers.splice(i, 1) //remove this laser node
|
this.laserArray.splice(i, 1) //remove this laser node
|
||||||
if (this.distanceToPlayer < 1000) { //mob jumps away from player
|
if (this.distanceToPlayer < 1000) { //mob jumps away from player
|
||||||
const forceMag = 0.03 * this.mass;
|
const forceMag = 0.03 * this.mass;
|
||||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||||
@@ -4395,7 +4392,7 @@ const spawn = {
|
|||||||
} else if (best.who && best.who.classType === "body") { //hitting block
|
} else if (best.who && best.who.classType === "body") { //hitting block
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(best.x, best.y);
|
ctx.moveTo(best.x, best.y);
|
||||||
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.lineTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.strokeStyle = `rgb(255,0,100)`;
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
@@ -4403,8 +4400,8 @@ const spawn = {
|
|||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
} else { //hitting nothing
|
} else { //hitting nothing
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
ctx.moveTo(this.laserArray[i].b.x, this.laserArray[i].b.y);
|
||||||
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.lineTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.strokeStyle = `rgb(255,0,100)`;
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
@@ -4412,12 +4409,12 @@ const spawn = {
|
|||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
}
|
}
|
||||||
} else {//fade in warning
|
} else {//fade in warning
|
||||||
this.lasers[i].fade += 0.01
|
this.laserArray[i].fade += 0.01
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.moveTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.lineTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
ctx.lineTo(this.laserArray[i].b.x, this.laserArray[i].b.y);
|
||||||
ctx.lineWidth = 2 + 40 - 40 * this.lasers[i].fade;
|
ctx.lineWidth = 2 + 40 - 40 * this.laserArray[i].fade;
|
||||||
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.lasers[i].fade})`;
|
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.laserArray[i].fade})`;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4486,7 +4483,7 @@ const spawn = {
|
|||||||
this.laserDelay = 130
|
this.laserDelay = 130
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
me.lasers = [] //keeps track of static laser beams
|
me.laserArray = [] //keeps track of static laser beams
|
||||||
me.laserLimit = 2 + (simulation.difficultyMode > 2) + (simulation.difficultyMode > 4)
|
me.laserLimit = 2 + (simulation.difficultyMode > 2) + (simulation.difficultyMode > 4)
|
||||||
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
|
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
|
||||||
me.cycle = 0
|
me.cycle = 0
|
||||||
@@ -4517,7 +4514,7 @@ const spawn = {
|
|||||||
best2.x = save1X
|
best2.x = save1X
|
||||||
best2.y = save1Y
|
best2.y = save1Y
|
||||||
}
|
}
|
||||||
this.lasers.push({ a: { x: best1.x, y: best1.y }, b: { x: best2.x, y: best2.y }, fade: 0 })
|
this.laserArray.push({ a: { x: best1.x, y: best1.y }, b: { x: best2.x, y: best2.y }, fade: 0 })
|
||||||
}
|
}
|
||||||
// add(m.pos, m.angle)
|
// add(m.pos, m.angle)
|
||||||
add(m.pos, this.angle + Math.PI / 4 + Math.PI / 2)
|
add(m.pos, this.angle + Math.PI / 4 + Math.PI / 2)
|
||||||
@@ -4534,9 +4531,9 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
me.fireLaser = function () {
|
me.fireLaser = function () {
|
||||||
for (let i = 0; i < this.lasers.length; i++) { //fire all lasers in the array
|
for (let i = 0; i < this.laserArray.length; i++) { //fire all laserArray in the array
|
||||||
let best = vertexCollision(this.lasers[i].a, this.lasers[i].b, m.isCloak ? [body] : [body, [playerBody, playerHead]]); //not checking map to fix not hitting player bug, this might make some lasers look strange when the map changes
|
let best = vertexCollision(this.laserArray[i].a, this.laserArray[i].b, m.isCloak ? [body] : [body, [playerBody, playerHead]]); //not checking map to fix not hitting player bug, this might make some lasers look strange when the map changes
|
||||||
if (this.lasers[i].fade > 0.99) {
|
if (this.laserArray[i].fade > 0.99) {
|
||||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
|
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
|
||||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
|
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
|
||||||
const dmg = 0.03 * simulation.dmgScale;
|
const dmg = 0.03 * simulation.dmgScale;
|
||||||
@@ -4548,7 +4545,7 @@ const spawn = {
|
|||||||
color: "rgba(255,0,100,0.5)",
|
color: "rgba(255,0,100,0.5)",
|
||||||
time: 20
|
time: 20
|
||||||
});
|
});
|
||||||
this.lasers.splice(i, 1) //remove this laser node
|
this.laserArray.splice(i, 1) //remove this laser node
|
||||||
if (this.distanceToPlayer < 1000) { //mob jumps away from player
|
if (this.distanceToPlayer < 1000) { //mob jumps away from player
|
||||||
const forceMag = 0.03 * this.mass;
|
const forceMag = 0.03 * this.mass;
|
||||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||||
@@ -4558,7 +4555,7 @@ const spawn = {
|
|||||||
} else if (best.who && best.who.classType === "body") { //hitting block
|
} else if (best.who && best.who.classType === "body") { //hitting block
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(best.x, best.y);
|
ctx.moveTo(best.x, best.y);
|
||||||
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.lineTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.strokeStyle = `rgb(255,0,100)`;
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
@@ -4566,8 +4563,8 @@ const spawn = {
|
|||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
} else { //hitting nothing
|
} else { //hitting nothing
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
ctx.moveTo(this.laserArray[i].b.x, this.laserArray[i].b.y);
|
||||||
ctx.lineTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.lineTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.strokeStyle = `rgb(255,0,100)`;
|
ctx.strokeStyle = `rgb(255,0,100)`;
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||||
@@ -4575,16 +4572,16 @@ const spawn = {
|
|||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
}
|
}
|
||||||
} else {//fade in warning
|
} else {//fade in warning
|
||||||
this.lasers[i].fade += 0.007
|
this.laserArray[i].fade += 0.007
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.lasers[i].a.x, this.lasers[i].a.y);
|
ctx.moveTo(this.laserArray[i].a.x, this.laserArray[i].a.y);
|
||||||
ctx.lineTo(this.lasers[i].b.x, this.lasers[i].b.y);
|
ctx.lineTo(this.laserArray[i].b.x, this.laserArray[i].b.y);
|
||||||
ctx.lineWidth = 2 + 40 - 40 * this.lasers[i].fade;
|
ctx.lineWidth = 2 + 40 - 40 * this.laserArray[i].fade;
|
||||||
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.lasers[i].fade})`;
|
ctx.strokeStyle = `rgba(255,0,100,${0.02 + 0.1 * this.laserArray[i].fade})`;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
if (this.lasers[i].fade > 0.99) {
|
if (this.laserArray[i].fade > 0.99) {
|
||||||
this.lasers[i].fade = 1;
|
this.laserArray[i].fade = 1;
|
||||||
if (this.lasers.length > this.laserLimit) this.lasers.shift() //cap total lasers
|
if (this.laserArray.length > this.laserLimit) this.laserArray.shift() //cap total lasers
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4744,9 +4741,9 @@ const spawn = {
|
|||||||
Matter.Body.setAngularVelocity(this, 0)
|
Matter.Body.setAngularVelocity(this, 0)
|
||||||
}
|
}
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
this.lasers(this.vertices[0], this.angle + Math.PI / 3);
|
this.laserArray(this.vertices[0], this.angle + Math.PI / 3);
|
||||||
this.lasers(this.vertices[1], this.angle + Math.PI);
|
this.laserArray(this.vertices[1], this.angle + Math.PI);
|
||||||
this.lasers(this.vertices[2], this.angle - Math.PI / 3);
|
this.laserArray(this.vertices[2], this.angle - Math.PI / 3);
|
||||||
ctx.strokeStyle = "#50f";
|
ctx.strokeStyle = "#50f";
|
||||||
ctx.lineWidth = 1.5;
|
ctx.lineWidth = 1.5;
|
||||||
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
||||||
@@ -4757,7 +4754,7 @@ const spawn = {
|
|||||||
ctx.stroke(); // Draw it
|
ctx.stroke(); // Draw it
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
me.lasers = function (where, angle) {
|
me.laserArray = function (where, angle) {
|
||||||
const seeRange = 7000;
|
const seeRange = 7000;
|
||||||
best = {
|
best = {
|
||||||
x: null,
|
x: null,
|
||||||
|
|||||||
44
js/tech.js
44
js/tech.js
@@ -2634,25 +2634,6 @@ const tech = {
|
|||||||
tech.isDarkStar = false
|
tech.isDarkStar = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "ablative drones",
|
|
||||||
descriptionFunction() {
|
|
||||||
return `after losing ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} there is a chance<br>to rebuild your broken parts as <strong>drones</strong>`
|
|
||||||
},
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
frequencyDefault: 1,
|
|
||||||
allowed: () => true,
|
|
||||||
requires: "",
|
|
||||||
effect() {
|
|
||||||
tech.isDroneOnDamage = true;
|
|
||||||
// for (let i = 0; i < 4; i++) b.drone()
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isDroneOnDamage = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "non-Newtonian armor",
|
name: "non-Newtonian armor",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Non-Newtonian_fluid' class="link">non-Newtonian armor</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Non-Newtonian_fluid' class="link">non-Newtonian armor</a>`,
|
||||||
@@ -4574,7 +4555,7 @@ const tech = {
|
|||||||
name: "deprecated",
|
name: "deprecated",
|
||||||
scale: 0.08,
|
scale: 0.08,
|
||||||
descriptionFunction() {
|
descriptionFunction() {
|
||||||
return `after <span class='color-remove'>removing</span> this gain<br><strong>${1 + this.scale}x</strong> <strong class='color-d'>damage</strong> per <span class='color-remove'>removed</span> ${powerUps.orb.tech()}<em style ="float: right;">(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)</em>`
|
return `after <span class='color-remove'>removing</span> this gain <strong>${1 + this.scale}x</strong> <strong class='color-d'>damage</strong><br>per ${powerUps.orb.tech()} <span class='color-remove'>removed</span> this game<em style ="float: right;">(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)</em>`
|
||||||
},
|
},
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -6607,7 +6588,7 @@ const tech = {
|
|||||||
allowed() {
|
allowed() {
|
||||||
return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.bulletsLastLonger === 1 && !tech.isDronesTravel && (build.isExperimentSelection || powerUps.research.count > 1)
|
return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.bulletsLastLonger === 1 && !tech.isDronesTravel && (build.isExperimentSelection || powerUps.research.count > 1)
|
||||||
},
|
},
|
||||||
requires: "drones, not drone repair, anti-shear topology, autonomous navigation",
|
requires: "drones, not drone repair, anti-shear topology, autonomous navigation, ",
|
||||||
effect() {
|
effect() {
|
||||||
const num = 5
|
const num = 5
|
||||||
tech.isForeverDrones += num
|
tech.isForeverDrones += num
|
||||||
@@ -6640,6 +6621,27 @@ const tech = {
|
|||||||
// if (this.count > 0) powerUps.research.changeRerolls(2)
|
// if (this.count > 0) powerUps.research.changeRerolls(2)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ablative drones",
|
||||||
|
descriptionFunction() {
|
||||||
|
return `after losing ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} there is a chance<br>to rebuild your broken parts as <strong>drones</strong>`
|
||||||
|
},
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
frequencyDefault: 1,
|
||||||
|
allowed() {
|
||||||
|
return (tech.haveGunCheck("drones") && !tech.isForeverDrones) || (m.fieldMode === 4 && simulation.molecularMode === 3)
|
||||||
|
},
|
||||||
|
requires: "drones, not fault tolerance",
|
||||||
|
effect() {
|
||||||
|
tech.isDroneOnDamage = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isDroneOnDamage = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "reduced tolerances",
|
name: "reduced tolerances",
|
||||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Engineering_tolerance' class="link">reduced tolerances</a>`,
|
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Engineering_tolerance' class="link">reduced tolerances</a>`,
|
||||||
|
|||||||
80
todo.txt
80
todo.txt
@@ -1,32 +1,27 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
new level testChamber2
|
new level: gravityObservatory
|
||||||
New camera flip effect
|
|
||||||
new laser level element now has collisions with blocks
|
|
||||||
elevators are less deadly to mobs at low speeds
|
|
||||||
|
|
||||||
difficulty level progression reworked
|
level: testChamber2 renamed gravityInterferometer
|
||||||
no constraints on final boss
|
it has been added to the levels that are extra hard and only show up late game
|
||||||
new constraint - healing disabled
|
it also got a bit hard with the addition of 1 more laser
|
||||||
|
|
||||||
quenching 0.3->0.4x overheal converted to max health
|
deflected mob bullets are converted into small blocks
|
||||||
tungsten carbide 400->500 extra max health
|
ablative drones is now a gun tech for drones
|
||||||
paradigm shift's health loss is no longer reduced by damage taken reduction
|
it makes ~33% more drones
|
||||||
coherence no longer remembers tech that is set to zero frequency, like removed tech
|
1.033->1.05x sneak attack damage per coupling for cloaking field
|
||||||
|
|
||||||
JUNK tech: pet the bot - lets you pet your bots
|
bug fixes
|
||||||
JUNK tech: the upside down - flip everything
|
extended vertical flip to edge cases:
|
||||||
|
trail left by snakeBoss
|
||||||
bug
|
laser array from boss and mobs
|
||||||
prevented possible duplicate choices with coherence tech
|
springer,spiderBoss,mantisBoss constraints
|
||||||
fixed issues with showing and hiding health bars on that constraint
|
subway: dark matter no longer removed if it gets too far from the player
|
||||||
fixed crash from autonomous defense
|
training: fixed potential lock out from running out of ammo
|
||||||
mass-energy mode wasn't getting any benefit from damage taken reduction
|
training: fixed accidental difficulty increase
|
||||||
it now gets square root of damage taken reduction
|
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
|
|
||||||
figure out why seeded random isn't making runs the same:
|
figure out why seeded random isn't making runs the same:
|
||||||
shuffle is being used for a wide variety of things that don't need a seeded random
|
shuffle is being used for a wide variety of things that don't need a seeded random
|
||||||
make two shuffle functions?
|
make two shuffle functions?
|
||||||
@@ -55,26 +50,37 @@ player can become crouched while not touching the ground if they exit the ground
|
|||||||
|
|
||||||
*********************************************************** TODO *****************************************************
|
*********************************************************** TODO *****************************************************
|
||||||
|
|
||||||
|
considering removing generative AI images from n-gon
|
||||||
|
pros: (of removing images)
|
||||||
|
the novelty of the images has worn off
|
||||||
|
cleaner UI without them
|
||||||
|
reduce the total size of n-gon by about 1/3
|
||||||
|
reduce the complexity of the code
|
||||||
|
avoid ire of people that hate generative AI
|
||||||
|
cons: (of removing images)
|
||||||
|
some people might like them
|
||||||
|
|
||||||
|
make a level selector power up
|
||||||
|
it shows up when you enter testing mode on the initial level
|
||||||
|
check box for community maps?
|
||||||
|
|
||||||
|
deflecting with field converts mob bullets to blocks that despawn after a few seconds
|
||||||
|
default for all fields that can deflect
|
||||||
|
|
||||||
|
add more tips:
|
||||||
|
download latest version of n-gon
|
||||||
|
https://codeload.github.com/landgreen/n-gon/zip/refs/heads/master
|
||||||
|
|
||||||
|
|
||||||
new level based laser element
|
new level based laser element
|
||||||
!!update new version into other levels
|
!!update new version into other levels
|
||||||
|
|
||||||
level technique: pairs of touch activated elevators jump on one to get high enough to jump on the next one
|
level technique: pairs of touch activated elevators jump on one to get high enough to jump on the next one
|
||||||
|
|
||||||
flip player upside down
|
new vertical flip level
|
||||||
fieldTech: negative mass?
|
long horizontal
|
||||||
JUNK tech?
|
several buttons
|
||||||
final boss effect
|
shorten flip time?
|
||||||
maybe just flip player camera and mouse
|
|
||||||
level effect flip map vertically also
|
|
||||||
new subway station
|
|
||||||
new full level
|
|
||||||
needs a device that will flip gravity
|
|
||||||
update to old level so it is more surreal
|
|
||||||
levels with few effects, just blocks and map
|
|
||||||
levels with a roof or infinite fall
|
|
||||||
towers, lab
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1343,6 +1349,8 @@ possible names for tech
|
|||||||
cork - used as a heat shield for rockets
|
cork - used as a heat shield for rockets
|
||||||
P = NP - something with speeding up calculation times
|
P = NP - something with speeding up calculation times
|
||||||
transistivity - something where a>b and b>c -> a>c
|
transistivity - something where a>b and b>c -> a>c
|
||||||
|
lenticular - looks different from different angles (lasers?)
|
||||||
|
De Sitter space - simple model of universe related to general relativity (mass-energy?)
|
||||||
|
|
||||||
******************************************************* DESIGN ******************************************************
|
******************************************************* DESIGN ******************************************************
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user