electrostatic induction

tech: electrostatic induction - foam bullets are attracted to nearby mobs

portals on perplex map, now remove blocks that fall in
new community map! coliseum by iNoobBoi

a few more tech can be refunded properly
nonRefundable tech don't show up in the list of tech you have
This commit is contained in:
landgreen
2021-03-13 06:22:05 -08:00
parent 3d04e61a04
commit 862a0ae9d0
10 changed files with 396 additions and 193 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -307,23 +307,25 @@ const b = {
explosionRange() {
return tech.explosiveRadius * (tech.isExplosionHarm ? 1.8 : 1) * (tech.isSmallExplosion ? 0.8 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
},
explosion(where, radius) { // typically explode is used for some bullets with .onEnd
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius
let dist, sub, knock;
let dmg = radius * 0.013;
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) {
color = "rgba(255,0,30,0.7)"
radius *= 0.8
dmg *= 1.6
}
if (tech.isExplodeRadio) { //radiation explosion
radius *= 1.25; //alert range
color = "rgba(25,139,170,0.25)"
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: radius,
color: "rgba(25,139,170,0.25)",
color: color,
time: simulation.drawTime * 2
});
@@ -360,7 +362,7 @@ const b = {
x: where.x,
y: where.y,
radius: radius,
color: "rgba(255,25,0,0.6)",
color: color,
time: simulation.drawTime
});
const alertRange = 100 + radius * 2; //alert range
@@ -2246,7 +2248,7 @@ const b = {
this.target = null
this.collisionFilter.category = cat.bullet;
this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
if (tech.isFoamGrowOnDeath && bullet.length < 300) {
if (tech.isFoamGrowOnDeath && bullet.length < 250) {
let targets = []
for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
@@ -2290,6 +2292,20 @@ const b = {
this.radius *= SCALE;
} else {
this.force.y += this.mass * 0.00008; //gravity
if (tech.isFoamAttract) {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].dropPowerUp && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * 0.004)
const slow = 0.9
Matter.Body.setVelocity(this, {
x: this.velocity.x * slow,
y: this.velocity.y * slow
});
break
}
}
}
}
}
}
@@ -4063,7 +4079,7 @@ const b = {
setTimeout(() => {
if (!simulation.paused) {
b.foam(position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius)
bullet[bullet.length - 1].damage = (1 + 1.43 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
bullet[bullet.length - 1].damage = (1 + 1.27 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
}
}, 250 * tech.foamFutureFire);
} else {

View File

@@ -217,7 +217,7 @@ const build = {
text += `<div class="pause-grid-module" id ="pause-field"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>`
let countTech = 0
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) {
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isFieldTech) {
text += `<div class="pause-grid-module"><div class="grid-title">
@@ -235,8 +235,8 @@ const build = {
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isLore) {
text += `<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isJunk) {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
// } else if (tech.tech[i].isJunk) {
// text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
}
@@ -756,10 +756,6 @@ window.addEventListener("keydown", function(event) {
document.getElementById("pause-field").innerHTML = `<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}`
});
}
if (simulation.testing) {
}
}
}
break

View File

@@ -16,7 +16,7 @@ const level = {
// simulation.zoomScale = 1000;
// simulation.setZoom();
// m.setField("nano-scale manufacturing")
// b.giveGuns("shotgun")
// b.giveGuns("foam")
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission")
@@ -50,21 +50,20 @@ const level = {
// level.warehouse();
// level.highrise();
// level.office();
// level.gauntlet(); //only fighting, very simple map
// level.house() //fan level
// level.detours() //fan level
// level.basement(); //fan level
// level.stronghold() //fan level
// level.testChamber2() //fan level
// level.gauntlet(); //only fighting, very simple map, before final boss
// level.house() //community level
// level.detours() //community level
// level.basement(); //community level
// level.stronghold() //community level
// level.perplex() //community level
// level.coliseum() //community level
// powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "tech");
// tech.giveTech("undefined")
// lore.techCount = 7
// localSettings.loreCount = 1;
// simulation.isCheating = false //true;
// lore.techCount = 6
// localSettings.loreCount = 1;
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// simulation.isCheating = false //true;
// level.null()
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
@@ -622,7 +621,7 @@ const level = {
ctx.fillStyle = this.color
ctx.fill();
}
query = function() {
query = function(isRemoveBlocks = false) {
if (Matter.Query.collides(this, [player]).length === 0) { //not touching player
if (player.isInPortal === this) player.isInPortal = null
} else if (player.isInPortal !== this) { //touching player
@@ -666,6 +665,11 @@ const level = {
if (Matter.Query.collides(this, [body[i]]).length === 0) {
if (body[i].isInPortal === this) body[i].isInPortal = null
} else if (body[i].isInPortal !== this) { //touching this portal, but for the first time
if (isRemoveBlocks) {
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
break
}
body[i].isInPortal = this.portalPair
//teleport
if (this.portalPair.angle % (Math.PI / 2)) { //if left, right up or down
@@ -683,11 +687,6 @@ const level = {
let v = Vector.mult(this.portalPair.unit, mag)
Matter.Body.setVelocity(body[i], v);
}
// else if (body[i].speed < 0.1) { //touching this portal and very slow
// Matter.World.remove(engine.world, body[i]);
// body.splice(i, 1);
// break
// }
}
}
// }
@@ -4673,7 +4672,7 @@ const level = {
}
}
},
testChamber2() {
perplex() {
level.setPosToSpawn(-600, 400);
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = 550;
@@ -4699,10 +4698,10 @@ const level = {
level.custom = () => {
level.playerExitCheck();
portal[2].query()
portal[3].query()
portal2[2].query()
portal2[3].query()
portal[2].query(true)
portal[3].query(true)
portal2[2].query(true)
portal2[3].query(true)
rotor.rotate();
};
@@ -4739,19 +4738,33 @@ const level = {
y: -250,
width: 1500,
height: 700,
color: "rgba(0,0,0,0.1)"
color: "rgba(0,0,0,0.03)"
});
level.fill.push({
x: -925,
y: -505,
width: 930,
height: 255,
color: "rgba(0,0,0,0.1)"
color: "rgba(0,0,0,0.03)"
});
// level.fill.push({
// x: -1280,
// y: -700,
// width: 355,
// height: 800,
// color: "rgba(0,0,0,0.03)"
// });
//section 2: lower central room (gone through main portals 1 time)
spawn.mapRect(920, 245, 160, 455); //below right portal
spawn.mapRect(1075, -300, 500, 1000); //2-1 right floor
spawn.bodyRect(100, -1000, 50, 350);
spawn.bodyRect(100, -1015, 250, 15);
spawn.mapRect(-925, -1600, 100, 1000); //2-2 left wall
spawn.mapRect(725, -2150, 200, 750); //2-2 right wall
spawn.mapRect(725, -1200, 200, 200); //2-2 right wall 2
spawn.mapRect(300, -1000, 625, 50); //2 central ledge
//shute
spawn.mapRect(1075, -2005, 550, 1055); //shute right wall
spawn.mapRect(875, -1000, 50, 300); //shute left 1
spawn.mapRect(860, -1030, 50, 300); //shute left 2
@@ -4761,12 +4774,21 @@ const level = {
spawn.mapRect(1090, -1030, 50, 300); //shute right 2
spawn.mapRect(1100, -1100, 50, 300); //shute right 3
spawn.mapRect(1120, -980, 50, 50); //shute right 4
spawn.bodyRect(100, -1000, 50, 350);
spawn.bodyRect(100, -1015, 250, 15);
spawn.mapRect(-925, -1600, 100, 1000); //2-2 left wall
spawn.mapRect(725, -2150, 200, 750); //2-2 right wall
spawn.mapRect(725, -1200, 200, 200); //2-2 right wall 2
spawn.mapRect(300, -1000, 625, 50); //2 central ledge
spawn.mapRect(1850, -650, 400, 50); //drop from 4-1
// level.fill.push({
// x: 150,
// y: -1000,
// width: 775,
// height: 700,
// color: "rgba(0,0,0,0.03)"
// });
// level.fill.push({
// x: 1075,
// y: -1000,
// width: 500,
// height: 700,
// color: "rgba(0,0,0,0.03)"
// });
level.fill.push({
x: 725,
y: -1400,
@@ -4774,91 +4796,100 @@ const level = {
height: 200,
color: "rgba(0,0,0,0.1)"
});
level.fill.push({
level.fill.push({ //lower shute
x: 925,
y: -2150,
width: 150,
height: 2175,
color: "rgba(0,0,0,0.1)"
});
level.fill.push({
level.fill.push({ //upper shute
x: 925,
y: -3450,
y: -3400,
width: 150,
height: 900,
height: 850,
color: "rgba(0,0,0,0.1)"
});
//section 3: upper left room and upper central room (gone through main portals 2 times)
//3-2 is just the upper part of 2-2
spawn.mapRect(-1775, -1000, 700, 300); //3-1 floor
spawn.mapRect(-1900, -2300, 175, 1600); //3-1 left wall
spawn.mapRect(-1375, -1300, 300, 50); //3-1 platform 1
spawn.mapRect(-1600, -1650, 300, 50); //3-1 platform 2
spawn.mapRect(-1775, -2300, 700, 300); //3-1 ceiling
spawn.mapRect(-830, -1600, 300, 50); //2 upper left ledge
spawn.mapRect(250, -2150, 675, 50); //2 upper right ledge
spawn.mapRect(-925, -2300, 100, 400); //3-2 left wall
spawn.mapRect(-830, -1600, 300, 50); //3-2 left ledge
spawn.mapRect(250, -2150, 675, 50); //3-2 right ledge
spawn.mapRect(-925, -2300, 100, 300); //3-2 left wall
spawn.mapRect(-600, -2700, 1525, 150); //3-2 ceiling
spawn.mapRect(1075, -2150, 250, 150); //next to upper portal
level.fill.push({
x: -1730,
y: -2300,
width: 870,
height: 1600,
color: "rgba(0,0,0,0.1)"
});
// level.fill.push({
// x: -1730,
// y: -2300,
// width: 870,
// height: 1600,
// color: "rgba(0,0,0,0.03)"
// });
//section 4: upper right portals
spawn.mapRect(1475, -2700, 150, 700); //4-1 left wall
spawn.mapRect(1775, -1650, 250, 150); //4-1 floor-ish
spawn.mapRect(1575, -1505, 450, 555); //below upper right portal
spawn.mapRect(1800, -2250, 400, 50); //4-1 platform 2
spawn.bodyRect(2200, -2250, 25, 300);
spawn.bodyRect(2200, -2250, 15, 300);
spawn.mapRect(2200, -1950, 400, 50); //4-1 platform 1
//spawn.bodyRect(2575, -2600, 25, 650);
spawn.mapRect(2600, -1650, 400, 50); //4-1 platform 0
spawn.mapRect(2200, -1350, 400, 50); //4-1 platform -1
spawn.bodyRect(2200, -1900, 25, 550);
spawn.bodyRect(2575, -1650, 25, 300);
spawn.bodyRect(2200, -1900, 15, 550);
spawn.bodyRect(2585, -1650, 15, 300);
spawn.mapRect(1780, -4200, 820, 1600); //top right corner
spawn.mapRect(1800, -4200, 800, 1600); //4-2 right wall
spawn.mapRect(800, -4200, 1800, -500); //4-2 ceiling
spawn.mapRect(1075, -3450, 250, 900); //4-2 center block
spawn.mapRect(800, -3450, 125, 900); //4-2 left wall
spawn.mapRect(1550, -4200, 310, 600); //4-2 upper right wall
level.fill.push({
x: 1800,
y: -2200,
width: 225,
height: 550,
color: "rgba(0,0,0,0.1)"
});
spawn.mapRect(1075, -3400, 225, 850); //upper shute right wall
spawn.mapRect(800, -3400, 125, 850); //upper shute left wall
// level.fill.push({
// x: 1800,
// y: -2200,
// width: 225,
// height: 550,
// color: "rgba(0,0,0,0.1)"
// });
level.fill.push({
x: 1800,
y: -2600,
width: 400,
height: 400,
color: "rgba(0,0,0,0.1)"
color: "rgba(0,0,0,0.03)"
});
level.fill.push({
x: 2200,
y: -2600,
width: 400,
height: 1250,
color: "rgba(0,0,0,0.1)"
color: "rgba(0,0,0,0.03)"
});
//section 5: after portals (gone through main portals 3 times)
spawn.mapRect(-700, -2700, 100, 450); //5-1 right wall
spawn.mapRect(-1450, -2700, 900, 50); //5-1 ceiling
spawn.mapRect(-925, -2300, 325, 50); //5-1 right floor
level.fill.push({
x: -1450,
y: -2655,
width: 755,
height: 355,
color: "rgba(0,0,0,0.1)"
});
spawn.mapRect(-1900, -3000, 450, 50); //stair cover
spawn.bodyRect(-1150, -2950, 200, 250); //5-2 block
// level.fill.push({
// x: -1450,
// y: -2655,
// width: 755,
// height: 355,
// color: "rgba(0,0,0,0.03)"
// });
// level.fill.push({
// x: -1900,
// y: -3000,
// width: 450,
// height: 700,
// color: "rgba(0,0,0,0.03)"
// });
//top left corner stuff
if (true) {
@@ -4872,10 +4903,10 @@ const level = {
//exit room
spawn.mapRect(350, -3000, 50, 100); //exit room left wall
spawn.mapRect(350, -3000, 450, -1700); //exit room ceiling
spawn.bodyRect(350, -2900, 50, 50); //door
spawn.bodyRect(350, -2850, 50, 50); //door
spawn.bodyRect(350, -2800, 50, 50); //door
spawn.bodyRect(350, -2750, 50, 50); //door
spawn.bodyRect(350, -2900, 50, 50.5); //door
spawn.bodyRect(350, -2850, 50, 50.5); //door
spawn.bodyRect(350, -2800, 50, 50.5); //door
spawn.bodyRect(350, -2750, 50, 50.5); //door
level.fillBG.push({
x: 375,
y: -3000,
@@ -4884,9 +4915,9 @@ const level = {
color: "#d4f4f4"
});
spawn.debris(-800, -50, 400, 6); //16 debris per level
spawn.debris(-400, 450, 400, 5); //16 debris per level
spawn.debris(-1650, -2300, 250, 4); //16 debris per level
spawn.debris(-750, -650, 750, 6); //16 debris per level
spawn.debris(-750, -650, 750, 3); //16 debris per level
//mobs
spawn.randomMob(-650, -100, 0.7); //1-2 left
@@ -4895,7 +4926,7 @@ const level = {
//spawn.randomMob(-1500, -300, 0.3); //1-4 platform
spawn.randomMob(1450, -450, 0); //2-1 right
spawn.randomMob(1700, -800, 1); //2-1 off the edge. chance is 1 because some enemies just fall
spawn.randomGroup(-550, -1000, -0.3); //2-2
spawn.randomGroup(-550, -900, -0.3); //2-2
spawn.randomMob(-1550, -1800, 0.7); //3-1 upper platform
//spawn.randomMob(-1225, -1400, 0.3); //3-1 lower platform
spawn.randomMob(450, -2350, 0.3); //3-2 right ledge
@@ -4903,8 +4934,8 @@ const level = {
spawn.randomGroup(2400, -2300, -0.3); //4-1 floating
spawn.randomMob(2400, -1450, 0); //4-1 platform -1
spawn.randomMob(2800, -1800, 0.5); //4-1 platform 0
spawn.randomMob(-1100, -2800, 0.5); //5-2 left
spawn.randomMob(-550, -2800, 0.5); //5-2 middle
spawn.randomMob(-1700, -3200, 0.7); //5-2 left platform
spawn.randomMob(-550, -2800, 0.3); //5-2 middle
if (simulation.difficulty > 3) {
if (Math.random() < 0.5) {
spawn.randomLevelBoss(450, -1350, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss", "pulsarBoss", "laserBoss"]);
@@ -4915,4 +4946,153 @@ const level = {
powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
},
coliseum() {
level.custom = () => {
level.playerExitCheck();
};
level.customTopLayer = () => {};
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
//Level
level.setPosToSpawn(200, 50);
level.exit.x = 8950;
level.exit.y = 200;
//Map
spawn.mapRect(150, 90, 100, 100);
spawn.mapRect(8950, 190, 100, 100);
spawn.mapRect(-100, -400, 100, 600);
spawn.mapRect(-100, 100, 700, 100);
spawn.mapRect(500, 100, 100, 1700);
spawn.mapRect(500, 1700, 4000, 100);
spawn.mapRect(4100, 600, 400, 100);
spawn.mapRect(4400, 600, 100, 1600);
spawn.mapRect(4400, 2100, 4300, 100);
spawn.mapRect(8600, 200, 100, 2000);
spawn.mapRect(8600, 200, 700, 100);
spawn.mapRect(9200, -300, 100, 600);
spawn.mapRect(8600, -300, 700, 100);
spawn.mapRect(8600, -700, 100, 500);
spawn.mapRect(4400, -700, 4300, 100);
spawn.mapRect(4400, -700, 100, 900);
spawn.mapRect(-100, -400, 4600, 100);
//Platforms
spawn.mapRect(1100, 400, 300, 100);
spawn.mapRect(500, 500, 300, 100);
spawn.mapRect(1050, 800, 300, 100);
spawn.mapRect(1770, 1050, 300, 100);
spawn.mapRect(1800, 500, 300, 100);
spawn.mapRect(2550, 900, 300, 100);
spawn.mapRect(2800, 1400, 300, 100);
spawn.mapRect(1250, 1350, 300, 100);
spawn.mapRect(4750, 850, 300, 100);
spawn.mapRect(3200, 1050, 300, 100);
spawn.mapRect(4700, 100, 300, 100);
spawn.mapRect(5350, 0, 300, 100);
spawn.mapRect(3800, 900, 300, 100);
spawn.mapRect(5100, 500, 300, 100);
spawn.mapRect(5900, -300, 300, 100);
spawn.mapRect(6500, -700, 300, 1300);
spawn.mapRect(7900, 0, 300, 100);
spawn.mapRect(8050, 800, 300, 100);
spawn.mapRect(7800, 1900, 300, 100);
spawn.mapRect(8300, 450, 300, 100);
spawn.mapRect(8400, 1200, 300, 100);
spawn.mapRect(7570, 1100, 300, 100);
spawn.mapRect(6700, 1850, 300, 100);
spawn.mapRect(8000, 1500, 300, 100);
spawn.mapRect(7120, -100, 300, 100);
spawn.mapRect(7000, 1500, 300, 100);
spawn.mapRect(6500, 1000, 300, 2100);
spawn.mapRect(5800, 1100, 300, 100);
spawn.mapRect(5900, 1700, 300, 100);
spawn.mapRect(5300, 1400, 300, 100);
spawn.mapRect(5200, 1100, 300, 100);
spawn.mapRect(6700, 1100, 300, 100);
spawn.mapRect(4800, 1650, 300, 100);
//Room 1 Spawning
spawn.randomMob(1000, 700, 0.7);
spawn.randomGroup(1100, 700, 0.5);
spawn.randomMob(1900, 400, 0.7);
spawn.randomGroup(2000, 400, 0.4);
spawn.randomGroup(1800, 1100, 0.4);
spawn.randomGroup(2700, 700, 0.5);
spawn.randomMob(2900, 1200, 0.7);
spawn.randomSmallMob(3200, 300, 0.9);
spawn.randomSmallMob(3700, 800, 0.9);
spawn.randomMob(1100, 700, 0.6);
spawn.randomGroup(1200, 700, 0.5);
spawn.randomMob(2000, 400, 0.8);
spawn.randomGroup(2100, 400, 0.5);
spawn.randomGroup(1900, 1100, 0.5);
spawn.randomGroup(2800, 700, 0.5);
spawn.randomMob(3000, 1200, 0.7);
spawn.randomSmallMob(3200, 300, 0.9);
spawn.randomSmallMob(3700, 800, 0.9);
spawn.randomMob(800, 1500, 0.9);
spawn.randomMob(1500, 1500, 0.7);
spawn.randomMob(2200, 1500, 0.6);
spawn.randomMob(2500, 1500, 0.7);
spawn.randomMob(2800, 1500, 0.7);
spawn.randomMob(3300, 1500, 0.6);
//Room 2 Spawning
spawn.randomGroup(4700, 2000, 0.9);
spawn.randomMob(5000, 2000, 0.5);
spawn.randomSmallMob(5700, 1500, 0.9);
spawn.randomMob(8500, 2000, 0.6);
spawn.randomGroup(8000, 1300, 0.9);
spawn.randomMob(8300, -300, 0.4);
spawn.randomSmallMob(7600, -200, 0.9);
spawn.randomMob(5200, -300, 0.5);
spawn.randomSmallMob(4700, -200, 0.5);
spawn.randomGroup(4700, 2000, 0.8);
spawn.randomMob(5000, 2000, 0.5);
spawn.randomSmallMob(5700, 1500, 0.9);
spawn.randomGroup(8500, 2000, 0.3);
spawn.randomSmallMob(8000, 1300, 0.4);
spawn.randomMob(8300, -300, 0.3);
spawn.randomGroup(7600, -200, 0.5);
spawn.randomMob(5200, -300, 0.3);
spawn.randomGroup(4700, -200, 0.4);
spawn.randomGroup(8650, -200, 0.9); //end guards
spawn.randomMob(8650, -200, 0.9); //end guards
//Boss Spawning
spawn.randomLevelBoss(6000, 700, ["pulsarBoss", "laserTargetingBoss", "powerUpBoss", "bomberBoss", "historyBoss", "orbitalBoss"]);
spawn.shieldingBoss(7200, 500);
if (simulation.difficulty > 20) {
spawn.randomLevelBoss(2000, 300, ["historyBoss", "shooterBoss"]);
}
//Blocks
spawn.bodyRect(550, -300, 50, 400); //spawn door
spawn.bodyRect(4400, 200, 100, 400); //boss door
spawn.bodyRect(6600, 600, 50, 400); //boss 2 door
spawn.debris(400, 800, 400, 2);
spawn.debris(3800, 1600, 1200, 6);
spawn.debris(7500, 2000, 800, 4);
spawn.debris(5500, 2000, 800, 4);
//Powerups
powerUps.spawnStartingPowerUps(1250, 1500);
powerUps.spawnStartingPowerUps(1500, 1500);
powerUps.spawn(8650, -200, "ammo");
powerUps.spawn(8650, -200, "ammo");
powerUps.spawn(8650, -200, "ammo");
powerUps.spawn(8650, -200, "ammo");
powerUps.spawn(200, 50, "heal");
powerUps.spawn(200, 50, "ammo");
powerUps.spawn(200, 50, "ammo");
powerUps.spawn(200, 50, "ammo");
powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(6600, 600, ["historyBoss", "powerUpBoss", "pulsarBoss", "orbitalBoss"]);
},
};

View File

@@ -380,13 +380,7 @@ const m = {
//find what tech I could get
let options = [];
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (
tech.tech[i].count < tech.tech[i].maxCount &&
tech.tech[i].allowed() &&
!tech.tech[i].isBadRandomOption &&
!tech.tech[i].isLore &&
(!tech.tech[i].isJunk || Math.random() < 0.15)
) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
}
}

View File

@@ -630,6 +630,23 @@ const powerUps = {
m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
}
},
removeRandomTech() {
const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0) have.push(i)
}
if (have.length) {
const choose = have[Math.floor(Math.random() * have.length)]
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
const totalRemoved = tech.tech[choose].count
tech.tech[choose].count = 0;
tech.tech[choose].remove(); // remove a random tech form the list of tech you have
tech.tech[choose].isLost = true
simulation.updateTechHUD();
return totalRemoved
}
return 0
},
directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
let index = powerUp.length;
target = powerUps[target];

View File

@@ -307,7 +307,7 @@ const simulation = {
if (tech.tech[i].isLost) {
if (text) text += "<br>" //add a new line, but not on the first line
text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
} else if (tech.tech[i].count > 0) {
} else if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) {
if (text) text += "<br>" //add a new line, but not on the first line
text += tech.tech[i].name
if (tech.tech[i].nameInfo) {
@@ -521,13 +521,24 @@ const simulation = {
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
if (simulation.isCommunityMaps) {
level.levels.push("stronghold");
level.levels.push("basement");
level.levels.push("detours");
// level.levels.push("detours");
level.levels.push("house");
level.levels.push("testChamber2");
level.levels.push("perplex");
level.levels.push("coliseum");
// level.levels.push("vats");
level.levels.splice(0, 5); //remove some random levels to make up for adding the community levels
//remove undefined tech for community maps
lore.techCount = 0;
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0;
tech.tech[i].count = 0;
}
}
}
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("intro"); //add level to the start of the randomized levels list

View File

@@ -1491,9 +1491,10 @@ const spawn = {
me.fireCycle = 0
me.fireTarget = { x: 0, y: 0 }
me.pulseRadius = Math.min(500, 230 + simulation.difficulty * 3)
me.fireDelay = Math.max(60, 190 - simulation.difficulty * 2)
me.fireDelay = Math.max(60, 140 - simulation.difficulty * 2)
me.isFiring = false
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 200 + 300 * Math.random(), 1)
me.onDeath = function() {
@@ -1560,11 +1561,11 @@ const spawn = {
//rotate towards fireAngle
const angle = this.angle + Math.PI / 2;
const c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
const threshold = 0.03;
const threshold = 0.04;
if (c > threshold) {
this.torque += 0.000001 * this.inertia;
this.torque += 0.0000015 * this.inertia;
} else if (c < -threshold) {
this.torque -= 0.000001 * this.inertia;
this.torque -= 0.0000015 * this.inertia;
} else if (this.fireCycle > 45) { //fire
unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100)
this.fireTarget = Vector.add(this.vertices[1], unit)
@@ -1590,8 +1591,8 @@ const spawn = {
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.fireCycle = Infinity
me.fireTarget = { x: 0, y: 0 }
me.pulseRadius = Math.min(400, 165 + simulation.difficulty * 3)
me.fireDelay = Math.max(75, 150 - simulation.difficulty * 0.5)
me.pulseRadius = Math.min(400, 170 + simulation.difficulty * 3)
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
me.isFiring = false
me.onHit = function() {};
me.canSeeTarget = function() {
@@ -1677,11 +1678,11 @@ const spawn = {
x: Math.cos(angle),
y: Math.sin(angle)
}, this.fireDir)
const threshold = 0.03;
const threshold = 0.04;
if (dot > threshold) { //rotate towards fireAngle
this.torque += 0.000001 * this.inertia;
this.torque += 0.0000015 * this.inertia;
} else if (dot < -threshold) {
this.torque -= 0.000001 * this.inertia;
this.torque -= 0.0000015 * this.inertia;
} else if (this.fireCycle > 60) { // aim
unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100)
this.fireTarget = Vector.add(this.vertices[1], unit)

View File

@@ -87,7 +87,7 @@
if (!found) return //if name not found don't give any tech
}
if (tech.isMetaAnalysis && tech.tech[index].isJunk) {
tech.giveTech('random', true)
tech.giveTech('random')
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "research");
return
}
@@ -252,7 +252,6 @@
maxCount: 1,
count: 0,
frequency: 1,
isNonRefundable: true,
allowed() {
return (tech.isDamageForGuns || tech.isFireRateForGuns) && (b.inventory.length + 5) < b.guns.length
},
@@ -262,8 +261,13 @@
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
},
remove() {
if (tech.isGunCycle) {
for (let i = 0; i < 6; i++) {
if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun
}
tech.isGunCycle = false;
}
}
},
{
name: "gun technology",
@@ -573,7 +577,7 @@
}
},
{
name: "electrostatic discharge",
name: "simulated annealing",
description: "increase <strong class='color-d'>damage</strong> by <strong>20%</strong><br><strong>20%</strong> increased <strong><em>delay</em></strong> after firing",
maxCount: 1,
count: 0,
@@ -1126,7 +1130,6 @@
count: 0,
frequency: 1,
isBotTech: true,
// isNonRefundable: true,
allowed() {
return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection
},
@@ -1189,7 +1192,6 @@
frequency: 1,
isBotTech: true,
isNonRefundable: true,
// isExperimentHide: true,
isBadRandomOption: true,
allowed() {
return b.totalBots() > 3
@@ -2040,8 +2042,6 @@
count: 0,
frequency: 1,
isNonRefundable: true,
// isExperimentHide: true,
// isBadRandomOption: true,
allowed() {
return true
},
@@ -2080,7 +2080,7 @@
powerUps.research.changeRerolls(0)
}, 1000);
},
description: "once per level use <strong>1</strong> <strong class='color-r'>research</strong> to avoid <strong>dying</strong><br>and spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups",
description: "use <strong>1</strong> <strong class='color-r'>research</strong> to avoid <strong>dying</strong><br>and spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups once per level",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2258,9 +2258,8 @@
maxCount: 1,
count: 0,
frequency: 1,
// isNonRefundable: true,
isNonRefundable: true,
isBadRandomOption: true,
// isExperimentHide: true,
allowed() {
return (tech.totalCount > 6)
},
@@ -2269,19 +2268,17 @@
//remove active bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
let count = 0 //count tech
let count = 1 //count tech
for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups
if (!tech.tech[i].isNonRefundable) count += tech.tech[i].count
}
if (tech.isDeterminism) count -= 3 //remove the bonus tech
if (tech.isSuperDeterminism) count -= 2 //remove the bonus tech
if (tech.isDeterminism) count -= 4 //remove the bonus tech
if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech
tech.setupAllTech(); // remove all tech
lore.techCount = 0;
// tech.addLoreTechToPool();
for (let i = 0; i < count; i++) { // spawn new tech power ups
powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
}
for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups
//have state is checked in m.death()
},
remove() {}
@@ -2343,7 +2340,6 @@
maxCount: 9,
count: 0,
frequency: 1,
// isNonRefundable: true,
allowed() {
return tech.duplicationChance() < 1
},
@@ -2472,7 +2468,6 @@
count: 0,
frequency: 1,
isNonRefundable: true,
// isExperimentHide: true,
allowed() {
return (tech.totalCount > 3) && !tech.isSuperDeterminism
},
@@ -2502,24 +2497,13 @@
count: 0,
frequency: 1,
isNonRefundable: true,
// isExperimentHide: true,
allowed() {
return (tech.totalCount > 3) && !tech.isSuperDeterminism && tech.duplicationChance() > 0
},
requires: "at least 1 tech, a chance to duplicate power ups",
effect: () => {
const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0) have.push(i)
}
const choose = have[Math.floor(Math.random() * have.length)]
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
for (let i = 0; i < tech.tech[choose].count; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech");
powerUps.spawn(m.pos.x, m.pos.y, "tech");
tech.tech[choose].count = 0;
tech.tech[choose].remove(); // remove a random tech form the list of tech you have
tech.tech[choose].isLost = true
simulation.updateTechHUD();
const removeTotal = powerUps.removeRandomTech()
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
},
remove() {}
}, {
@@ -2529,7 +2513,6 @@
count: 0,
frequency: 1,
isNonRefundable: true,
// isExperimentHide: true,
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
@@ -2565,8 +2548,6 @@
name: "dark patterns",
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>18</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
maxCount: 1,
// isNonRefundable: true,
// isExperimentHide: true,
count: 0,
frequency: 1,
allowed() {
@@ -2608,9 +2589,7 @@
maxCount: 1,
count: 0,
frequency: 1,
// isNonRefundable: true,
// isExperimentHide: true,
// isBadRandomOption: true,
isNonRefundable: true,
allowed() {
return !tech.isSuperDeterminism
},
@@ -2622,11 +2601,11 @@
}
},
remove() {
if (this.count > 1) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isFieldTech) tech.tech[i].frequency /= 2
}
}
// if (this.count > 1) {
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isFieldTech) tech.tech[i].frequency /= 2
// }
// }
}
},
{
@@ -2635,7 +2614,6 @@
maxCount: 1,
count: 0,
frequency: 1,
isNonRefundable: true,
allowed() {
return tech.totalCount > 9
},
@@ -2647,7 +2625,7 @@
},
remove() {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) tech.tech[i].frequency /= 100
if (tech.tech[i].count > 0 && tech.tech[i].frequency > 1) tech.tech[i].frequency /= 100
}
}
}, {
@@ -2672,7 +2650,6 @@
maxCount: 1,
count: 0,
frequency: 1,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
return !tech.isExtraChoice && !tech.isCancelDuplication && !tech.isCancelRerolls
@@ -2680,11 +2657,12 @@
requires: "not cardinality, not futures or commodities exchanges",
effect: () => {
tech.isDeterminism = true;
//if you change the six also change it in Born rule
//if you change the number spawned also change it in Born rule
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
},
remove() {
tech.isDeterminism = false;
for (let i = 0; i < 5; i++) powerUps.removeRandomTech()
}
}, {
name: "superdeterminism",
@@ -2693,7 +2671,6 @@
count: 0,
frequency: 3,
frequencyDefault: 3,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
return tech.isDeterminism && !tech.manyWorlds && !tech.isGunSwitchField
@@ -2701,11 +2678,12 @@
requires: "determinism, not unified field theory",
effect: () => {
tech.isSuperDeterminism = true;
//if you change the six also change it in Born rule
for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
//if you change the number spawned also change it in Born rule
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
},
remove() {
tech.isSuperDeterminism = false;
for (let i = 0; i < 5; i++) powerUps.removeRandomTech()
}
},
//**************************************************
@@ -3656,6 +3634,41 @@
remove() {
tech.isFastFoam = false;
}
},
{
name: "electrostatic induction",
description: "<strong>foam</strong> bullets are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 1,
allowed() {
return tech.haveGunCheck("foam") || tech.foamBotCount > 1
},
requires: "foam",
effect() {
tech.isFoamAttract = true
},
remove() {
tech.isFoamAttract = false
}
}, {
name: "quantum foam",
description: "<strong>foam</strong> gun fires <strong>0.25</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>127%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 1,
allowed() {
return tech.haveGunCheck("foam")
},
requires: "foam",
effect() {
tech.foamFutureFire++
},
remove() {
tech.foamFutureFire = 0;
}
}, {
name: "foam fractionation",
description: "<strong>foam</strong> gun bubbles are <strong>100%</strong> larger<br>when you have below <strong>300</strong> <strong class='color-g'>ammo</strong>",
@@ -3673,23 +3686,6 @@
remove() {
tech.isAmmoFoamSize = false;
}
}, {
name: "quantum foam",
description: "<strong>foam</strong> gun fires <strong>0.25</strong> seconds into the <strong>future</strong><br>increase <strong>foam</strong> gun <strong class='color-d'>damage</strong> by <strong>143%</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 1,
allowed() {
return tech.haveGunCheck("foam")
},
requires: "foam",
effect() {
tech.foamFutureFire++
},
remove() {
tech.foamFutureFire = 0;
}
},
// {
@@ -5522,7 +5518,7 @@
count: 0,
frequency: 1,
isLore: true,
isNonRefundable: true,
// isNonRefundable: true,
isExperimentHide: true,
allowed() {
return true
@@ -5798,5 +5794,6 @@
isFlipFlopLevelReset: null,
isFlipFlopDamage: null,
isFlipFlopEnergy: null,
isMetaAnalysis: null
isMetaAnalysis: null,
isFoamAttract: null
}

View File

@@ -1,10 +1,12 @@
******************************************************** NEXT PATCH ********************************************************
meta-analysis - if you choose a junk tech you instead get a random tech and spawn 2 research
micro-extruder should have 50% less lag
tech: electrostatic induction - foam bullets are attracted to nearby mobs
new community level testChamber2! by Oranger on n-gon discord
(be sure to enable community levels in settings)
portals on perplex map, now remove blocks that fall in
new community map! coliseum by iNoobBoi
a few more tech can be refunded properly
nonRefundable tech don't show up in the list of tech you have
******************************************************** BUGS ********************************************************
@@ -39,10 +41,6 @@ fix door.isOpen actually meaning isClosed?
******************************************************** TODO ********************************************************
allow levels to adjust the teleport limit in simulation.checks
copy time-like foam to shotgun
mob sniper: draw aim graphics before fire
tech laser: photon - laser, but it can only move 100 pixels a cycle
@@ -52,14 +50,6 @@ mob - after taking damage
grows
teleports
tech- foam is attracted to mobs
use a gravitational attraction model?
could foam be attracted to other foam bullets too?
or foam is only attracted to foam bullets that are stuck to mobs
is this too computationally intense?
name - static cling
could also do bremsstrahlung radiation like damage on attachment
mobile requirements:
detect mobile, flip to landscape
detect no keyboard, no mouse
@@ -88,6 +78,7 @@ map: laboratory
radiation room
portal + rotor + falling blocks = perpetual motion room
a button that spawns a heal.
consider adding canvas path shadows to levels in level.custom for non squared lighting
lore: a tutorial / lore intro
needs to be optional so it doesn't slow experienced players
@@ -320,7 +311,7 @@ possible names for tech
genetic algorithm
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
stochastic optimization
meta-analysis
electrostatic discharge
plot script: