% converted to x
text rework
most numbers converted from "+50%" to "1.5x"
renamed defense -> damage taken
adjusted about 20 tech to round down or up their values to less decimals
for a few I added research cost or JUNK chance to balance rounding
new community map soft by Richard0820
tech: peer review - gain +damage each time you research
self-assembly scales with health not health percent
matter.js engine reverted back to 0.18 (to fix an issue with time dilation)
This commit is contained in:
BIN
img/peer review.webp
Normal file
BIN
img/peer review.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
@@ -62,7 +62,7 @@
|
||||
<label for="hide-images" title="hide images for fields, guns, and tech">hide images</label>
|
||||
<br>
|
||||
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" style="width:17px; height:17px;">
|
||||
<label for="hide-hud" title="hide: tech, defense, damage, in game console, new level animation">minimal HUD</label>
|
||||
<label for="hide-hud" title="hide: tech, damage taken, damage, in game console, new level animation">minimal HUD</label>
|
||||
<br>
|
||||
<label for="fps-select" title="use this to slow the game down">limit frames per second:</label>
|
||||
<select name="fps-select" id="fps-select">
|
||||
|
||||
@@ -287,8 +287,8 @@ const b = {
|
||||
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
|
||||
if (m.fieldMode === 6) b.fireCDscale *= 0.8
|
||||
if (tech.isFastTime) b.fireCDscale *= 0.5
|
||||
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, Math.max(0, b.inventory.length - 1))
|
||||
if (tech.isFireMoveLock) b.fireCDscale *= 0.23 // 77% fire rate
|
||||
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.8, Math.max(0, b.inventory.length - 1))
|
||||
if (tech.isFireMoveLock) b.fireCDscale *= 0.2 // 77% fire rate
|
||||
},
|
||||
fireAttributes(dir, rotate = true) {
|
||||
if (rotate) {
|
||||
@@ -1873,7 +1873,7 @@ const b = {
|
||||
if (tech.isHarpoonPowerUp && simulation.cycle - 480 < tech.harpoonPowerUpCycle) {
|
||||
Matter.Body.setDensity(this, 1.8 * tech.harpoonDensity); //+90% damage after pick up power up for 8 seconds
|
||||
} else if (tech.isHarpoonFullHealth && who.health === 1) {
|
||||
Matter.Body.setDensity(this, 2.11 * tech.harpoonDensity); //+90% damage if mob has full health do
|
||||
Matter.Body.setDensity(this, 2.2 * tech.harpoonDensity); //+90% damage if mob has full health do
|
||||
simulation.ephemera.push({
|
||||
name: "harpoon outline",
|
||||
count: 2, //cycles before it self removes
|
||||
@@ -7230,7 +7230,6 @@ const b = {
|
||||
},
|
||||
{
|
||||
name: "foam", //8
|
||||
// description: `spray bubbly foam that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time<br><strong>24</strong> bubbles per ${powerUps.orb.ammo()}`,
|
||||
descriptionFunction() {
|
||||
return `spray bubbly <strong>foam</strong> that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time<br><strong>${this.ammoPack.toFixed(0)}</strong> bubbles per ${powerUps.orb.ammo()}`
|
||||
},
|
||||
|
||||
17
js/index.js
17
js/index.js
@@ -474,11 +474,11 @@ const build = {
|
||||
<label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.15em;" >hide images</label>
|
||||
<br>
|
||||
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" ${localSettings.isHideHUD ? "checked" : ""}>
|
||||
<label for="hide-hud" title="hide: tech, defense, 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>
|
||||
<br>
|
||||
|
||||
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)} difficulty: ${((m.dmgScale)).toPrecision(4)}
|
||||
<br><strong class='color-defense'>defense</strong>: ${(1 - m.defense()).toPrecision(5)} difficulty: ${(1 / simulation.dmgScale).toPrecision(4)}
|
||||
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)} <span style="float: right;"><strong class='color-d'>difficulty:</strong> ${((m.dmgScale)).toPrecision(4)}</span>
|
||||
<br><strong class='color-defense'>damage taken</strong>: ${(m.defense()).toPrecision(4)} <span style="float: right;"><strong class='color-defense'>difficulty:</strong> ${(simulation.dmgScale).toPrecision(4)}</span>
|
||||
<br><strong><em>fire rate</em></strong>: ${((1 - b.fireCDscale) * 100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
|
||||
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""}
|
||||
${m.coupling ? `<br><span style = 'font-size:90%;'>` + m.couplingDescription(m.coupling) + `</span> from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""}
|
||||
@@ -552,7 +552,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
||||
<button onclick="build.sortTech('guntech')" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
|
||||
<button onclick="build.sortTech('fieldtech')" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
|
||||
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
|
||||
<button onclick="build.sortTech('defense')" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">defense</strong></button>
|
||||
<button onclick="build.sortTech('damage taken')" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
|
||||
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
|
||||
<input type="search" id="sort-input" style="width: 8em;font-size: 0.6em;color:#000;" placeholder="sort by"/>
|
||||
<button onclick="build.sortTech('input')" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
|
||||
@@ -876,7 +876,9 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
|
||||
<button onclick="build.sortTech('guntech', true)" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
|
||||
<button onclick="build.sortTech('fieldtech', true)" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
|
||||
<button onclick="build.sortTech('damage', true)" class='sort-button'><strong class='color-d'>damage</strong></button>
|
||||
<button onclick="build.sortTech('defense', true)" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">defense</strong></button>
|
||||
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
|
||||
<button onclick="build.sortTech('damage taken', true)" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
|
||||
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
|
||||
<button onclick="build.sortTech('have', true)" class='sort-button color-m' style="letter-spacing: 1px;font-weight: 800;">have</button>
|
||||
<button onclick="build.sortTech('allowed', true)" class='sort-button' style="letter-spacing: 1px;font-weight: 400;">allowed</button>
|
||||
<input type="search" id="sort-input" style="width: 8.7em;font-size: 0.6em;color:#000;" placeholder="sort by"/>
|
||||
@@ -1602,10 +1604,7 @@ window.addEventListener("keydown", function (event) {
|
||||
case "r":
|
||||
m.resetHistory();
|
||||
Matter.Body.setPosition(player, simulation.mouseInGame);
|
||||
Matter.Body.setVelocity(player, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
Matter.Body.setVelocity(player, { x: 0, y: 0 });
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
|
||||
571
js/level.js
571
js/level.js
@@ -11,7 +11,7 @@ const level = {
|
||||
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
||||
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
|
||||
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", 'arena'],
|
||||
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"],
|
||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
|
||||
levels: [],
|
||||
start() {
|
||||
@@ -51,7 +51,7 @@ const level = {
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
|
||||
// level.testChamber();
|
||||
// level.testing();
|
||||
|
||||
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
|
||||
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
|
||||
@@ -82,9 +82,9 @@ const level = {
|
||||
// localSettings.isTrainingNotAttempted = true
|
||||
// simulation.isCheating = false //true;
|
||||
// for (let i = 0; i < 5; i++) tech.giveTech("undefined")
|
||||
// lore.techCount = 2
|
||||
// lore.techCount = 1
|
||||
// level.levelsCleared = 10
|
||||
// localSettings.loreCount = 5 //this sets what conversation is heard
|
||||
// localSettings.loreCount = 2 //this sets what conversation is heard
|
||||
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
|
||||
// level.null()
|
||||
@@ -98,7 +98,6 @@ const level = {
|
||||
// powerUps.spawn(m.pos.x, m.pos.y, "entanglement", false);
|
||||
} else {
|
||||
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
|
||||
|
||||
// spawn.pickList = ["focuser", "focuser"]
|
||||
level[level.levels[level.onLevel]](); //picks the current map from the the levels array
|
||||
if (!simulation.isCheating && !build.isExperimentRun && !simulation.isTraining) {
|
||||
@@ -160,7 +159,7 @@ const level = {
|
||||
}
|
||||
if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) {
|
||||
var gun = b.guns[b.inventory[tech.buffedGun]].name
|
||||
simulation.makeTextLog(`pigeonhole principle: <strong>+${(31 * Math.max(0, b.inventory.length)).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`, 600);
|
||||
simulation.makeTextLog(`pigeonhole principle: <strong>${(1.3 * Math.max(0, b.inventory.length)).toFixed(2)}x</strong> <strong class='color-d'>damage</strong> for <strong class="highlight">${gun}</strong>`, 600);
|
||||
}
|
||||
if (tech.isSwitchReality && level.levelsCleared !== 0) {
|
||||
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
|
||||
@@ -170,9 +169,9 @@ const level = {
|
||||
}
|
||||
if (tech.isHealLowHealth) {
|
||||
if (tech.isEnergyHealth) {
|
||||
var len = 4 * (1 - m.energy / m.maxEnergy) //as a percent
|
||||
var len = 4 * Math.max(0, m.maxEnergy - m.energy)
|
||||
} else {
|
||||
var len = 4 * (1 - m.health / m.maxHealth) //as a percent
|
||||
var len = 4 * Math.max(0, m.maxHealth - m.health)
|
||||
}
|
||||
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
|
||||
}
|
||||
@@ -31811,6 +31810,562 @@ const level = {
|
||||
}
|
||||
}
|
||||
},
|
||||
soft() {
|
||||
simulation.makeTextLog(`<img src="https://raw.githubusercontent.com/Whyisthisnotavalable/image-yy/main/Hotpot-removed.png" width="100" height="100" style="background-image: radial-gradient(circle, gray, black, transparent)">`);
|
||||
simulation.makeTextLog(`<strong>soft</strong> by <span class='color-var'>Richard0820</span>`);
|
||||
simulation.makeTextLog("<em>The lasers deal less damage the higher level you are</em>")
|
||||
const portals = [];
|
||||
portals.push(level.portal({
|
||||
x: -1525,
|
||||
y: -250
|
||||
}, Math.PI / 2, {
|
||||
x: 1100,
|
||||
y: -1025
|
||||
}, Math.PI / 2))
|
||||
const soft = {
|
||||
createCloth(x, y, radius, width, height, attachToPlayer = false, stayStill = false, options, touchPlayer = true, constrictionStrength = 0.001) {
|
||||
const bodies = [];
|
||||
const constraints = [];
|
||||
const otherCons = [];
|
||||
const bodyWidth = radius;
|
||||
const bodyHeight = radius;
|
||||
const numRows = Math.ceil(height / bodyHeight);
|
||||
const numCols = Math.ceil(width / bodyWidth);
|
||||
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
for (let j = 0; j < numCols; j++) {
|
||||
const posX = x + j * bodyWidth + bodyWidth / 2;
|
||||
const posY = y + i * bodyHeight + bodyHeight / 2;
|
||||
|
||||
const rect = Matter.Bodies.circle(posX, posY, (bodyWidth + bodyHeight) / 4, options);
|
||||
rect.collisionFilter.category = cat.body;
|
||||
rect.collisionFilter.mask = (touchPlayer ? cat.player | cat.body | cat.bullet | cat.mob | cat.mobBullet : cat.body | cat.bullet | cat.mob | cat.mobBullet);
|
||||
rect.classType = "body";
|
||||
|
||||
Composite.add(engine.world, rect);
|
||||
|
||||
bodies.push(rect);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
for (let j = 0; j < numCols; j++) {
|
||||
const bodyIndexA = i * numCols + j;
|
||||
if (j < numCols - 1) {
|
||||
const bodyIndexB = i * numCols + (j + 1);
|
||||
const constraint = Constraint.create({
|
||||
bodyA: bodies[bodyIndexA],
|
||||
bodyB: bodies[bodyIndexB],
|
||||
stiffness: 0.06,
|
||||
damping: 0.001
|
||||
});
|
||||
Composite.add(engine.world, constraint);
|
||||
constraints.push(constraint);
|
||||
}
|
||||
if (i < numRows - 1) {
|
||||
const bodyIndexB = (i + 1) * numCols + j;
|
||||
const constraint = Constraint.create({
|
||||
bodyA: bodies[bodyIndexA],
|
||||
bodyB: bodies[bodyIndexB],
|
||||
stiffness: 0.06,
|
||||
damping: 0.001
|
||||
});
|
||||
Composite.add(engine.world, constraint);
|
||||
constraints.push(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < numRows - 1; i++) {
|
||||
for (let j = 0; j < numCols - 1; j++) {
|
||||
const bodyA = bodies[i * numCols + j];
|
||||
const bodyB = bodies[(i + 1) * numCols + j + 1];
|
||||
const constraint = Constraint.create({
|
||||
bodyA: bodyA,
|
||||
bodyB: bodyB,
|
||||
stiffness: 0.02
|
||||
});
|
||||
constraints.push(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < numRows - 1; i++) {
|
||||
for (let j = 1; j < numCols; j++) {
|
||||
const bodyA = bodies[i * numCols + j];
|
||||
const bodyB = bodies[(i + 1) * numCols + j - 1];
|
||||
const constraint = Constraint.create({
|
||||
bodyA: bodyA,
|
||||
bodyB: bodyB,
|
||||
stiffness: 0.02
|
||||
});
|
||||
constraints.push(constraint);
|
||||
}
|
||||
}
|
||||
if (stayStill) {
|
||||
for (let i = 0; i < bodies.length; i++) {
|
||||
const by = bodies[i];
|
||||
const spawnX = by.position.x + bodyWidth / 2;
|
||||
const spawnY = by.position.y + bodyHeight / 2;
|
||||
const isLastColumn = (i + 1) % numCols === 0;
|
||||
const isFirstColumn = i % numCols === 0;
|
||||
const stiffness = constrictionStrength * (isLastColumn || isFirstColumn ? 100 : 1); // Apply extra stiffness to first and last columns
|
||||
|
||||
const cost = Constraint.create({
|
||||
bodyA: by,
|
||||
pointB: { x: spawnX, y: spawnY },
|
||||
stiffness: stiffness,
|
||||
length: 0
|
||||
});
|
||||
|
||||
Composite.add(engine.world, cost);
|
||||
otherCons.push(cost);
|
||||
}
|
||||
}
|
||||
if (attachToPlayer) {
|
||||
for (let i = 0; i < bodies.length; i++) {
|
||||
const cost = Constraint.create({
|
||||
bodyA: bodies[i],
|
||||
pointB: player.position,
|
||||
stiffness: 0.0005,
|
||||
length: 0
|
||||
});
|
||||
Composite.add(engine.world, cost);
|
||||
}
|
||||
}
|
||||
|
||||
return { bodies, constraints, otherCons };
|
||||
},
|
||||
clothOptions: {
|
||||
frictionAir: 0.005,
|
||||
},
|
||||
isOuterBoundary(body, bodies) { //unused
|
||||
const neighbors = [
|
||||
{ x: body.position.x + 1, y: body.position.y },
|
||||
{ x: body.position.x - 1, y: body.position.y },
|
||||
{ x: body.position.x, y: body.position.y + 1 },
|
||||
{ x: body.position.x, y: body.position.y - 1 }
|
||||
];
|
||||
|
||||
for (let i = 0; i < neighbors.length; i++) {
|
||||
const neighbor = neighbors[i];
|
||||
const isNeighbor = bodies.some(b => b.position.x === neighbor.x && b.position.y === neighbor.y);
|
||||
if (!isNeighbor) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
draw(cloth) {
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.3)";
|
||||
ctx.fillStyle = "black";
|
||||
for (let i = 0, len = cloth.constraints.length; i < len; ++i) {
|
||||
const constraint = cloth.constraints[i];
|
||||
ctx.moveTo(constraint.bodyA.position.x, constraint.bodyA.position.y);
|
||||
ctx.lineTo(constraint.bodyB.position.x, constraint.bodyB.position.y);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
},
|
||||
addGravity(bodies, magnitude) {
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
bodies[i].force.y += bodies[i].mass * magnitude;
|
||||
}
|
||||
},
|
||||
gravity(cloth) {
|
||||
this.addGravity(cloth.bodies, simulation.g);
|
||||
},
|
||||
breaker(cloth, percentage = 0.5) {
|
||||
const totalConstraints = cloth.constraints.length;
|
||||
const constraintsToRemove = Math.ceil(totalConstraints * percentage);
|
||||
|
||||
for (let i = 0; i < constraintsToRemove; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * cloth.constraints.length);
|
||||
|
||||
let removedConstraint = cloth.constraints.splice(randomIndex, 1)[0];
|
||||
Composite.remove(engine.world, removedConstraint);
|
||||
}
|
||||
},
|
||||
destroyer(cloth, percentage = 0.99999) {
|
||||
const otherCons = cloth.otherCons.length;
|
||||
const otherCons2Remove = Math.ceil(otherCons * percentage);
|
||||
|
||||
for (let i = 0; i < otherCons2Remove; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * cloth.otherCons.length);
|
||||
|
||||
let removedConstraint = cloth.otherCons.splice(randomIndex, 1)[0];
|
||||
Composite.remove(engine.world, removedConstraint);
|
||||
}
|
||||
},
|
||||
annihilate(cloth) {
|
||||
const totalBodies = cloth.bodies.length;
|
||||
for (let i = 0; i < totalBodies; i++) {
|
||||
const removeBody = cloth.bodies[i];
|
||||
Composite.remove(engine.world, removeBody);
|
||||
}
|
||||
cloth.bodies.length = 0; // Clear the bodies array after removal
|
||||
}
|
||||
}
|
||||
const clothArray = [];
|
||||
clothArray.push(soft.createCloth(-100, 0, 50, 1000, 300, false, true, soft.clothOptions, true))
|
||||
clothArray.push(soft.createCloth(-2000, 2375, 50, 1525, 200, false, true, soft.clothOptions, true))
|
||||
clothArray.push(soft.createCloth(-3950, 125, 50, 1800, 125, false, true, soft.clothOptions, true))
|
||||
const annoyingStuff = {
|
||||
lasers(where, angle) {
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const seeRange = 7000;
|
||||
best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
const look = {
|
||||
x: where.x + seeRange * Math.cos(angle),
|
||||
y: where.y + seeRange * Math.sin(angle)
|
||||
};
|
||||
// vertexCollision(where, look, mob);
|
||||
vertexCollision(where, look, map);
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
const dmg = 0.5 / simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: best.x,
|
||||
y: best.y,
|
||||
radius: dmg * 1500,
|
||||
color: "rgba(80,0,255,0.5)",
|
||||
time: 20
|
||||
});
|
||||
}
|
||||
//draw beam
|
||||
if (best.dist2 === Infinity) best = look;
|
||||
ctx.moveTo(where.x, where.y);
|
||||
ctx.lineTo(best.x, best.y);
|
||||
},
|
||||
laserBoss(x, y, radius = 30) {
|
||||
mobs.spawn(x, y, 6, radius, "#f00");
|
||||
let me = mob[mob.length - 1];
|
||||
|
||||
setTimeout(() => { //fix mob in place, but allow rotation
|
||||
me.constraint = Constraint.create({
|
||||
pointA: {
|
||||
x: me.position.x,
|
||||
y: me.position.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 1,
|
||||
damping: 1
|
||||
});
|
||||
Composite.add(engine.world, me.constraint);
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
me.count = 0;
|
||||
me.frictionAir = 0.03;
|
||||
// me.torque -= me.inertia * 0.002
|
||||
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
|
||||
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isBoss = true;
|
||||
// spawn.shield(me, x, y, 1); //not working, not sure why
|
||||
me.onDeath = function () {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
};
|
||||
me.rotateVelocity = -Math.min(0.0045, 0.0015 * simulation.accelScale * simulation.accelScale) * (level.levelsCleared > 8 ? 1 : -1)
|
||||
me.do = function () {
|
||||
this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors
|
||||
this.checkStatus();
|
||||
|
||||
if (!this.isStunned) {
|
||||
//check if slowed
|
||||
let slowed = false
|
||||
for (let i = 0; i < this.status.length; i++) {
|
||||
if (this.status[i].type === "slow") {
|
||||
slowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!slowed) {
|
||||
this.count++
|
||||
Matter.Body.setAngle(this, this.count * this.rotateVelocity)
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < this.vertices.length; i++) {
|
||||
if (Math.sin((2 * Math.PI * simulation.cycle) / (50 + i)) > 0) {
|
||||
this.lasers(this.vertices[i], Math.atan2(this.vertices[i].y - this.position.y, this.vertices[i].x - this.position.x));
|
||||
}
|
||||
}
|
||||
ctx.strokeStyle = "#50f";
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
||||
ctx.stroke(); // Draw it
|
||||
ctx.setLineDash([]);
|
||||
ctx.lineWidth = 20;
|
||||
ctx.strokeStyle = "rgba(80,0,255,0.07)";
|
||||
ctx.stroke(); // Draw it
|
||||
}
|
||||
};
|
||||
me.lasers = function (where, angle) {
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const seeRange = 7000;
|
||||
best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
const look = {
|
||||
x: where.x + seeRange * Math.cos(angle),
|
||||
y: where.y + seeRange * Math.sin(angle)
|
||||
};
|
||||
// vertexCollision(where, look, mob);
|
||||
vertexCollision(where, look, map);
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
const dmg = 0.5 / simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: best.x,
|
||||
y: best.y,
|
||||
radius: dmg * 1500,
|
||||
color: "rgba(80,0,255,0.5)",
|
||||
time: 20
|
||||
});
|
||||
}
|
||||
//draw beam
|
||||
if (best.dist2 === Infinity) best = look;
|
||||
ctx.moveTo(where.x, where.y);
|
||||
ctx.lineTo(best.x, best.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
level.setPosToSpawn(-350, 0);
|
||||
level.exit.x = 1075;
|
||||
level.exit.y = 20;
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
|
||||
level.defaultZoom = 1800
|
||||
simulation.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#aaFFFF55";
|
||||
spawn.mapRect(900, 50, 425, 250);
|
||||
// spawn.mapRect(900, -1050, 0.1, 1350);
|
||||
spawn.mapRect(-475, 2375, 1800, 250);
|
||||
spawn.mapRect(-4400, 2375, 2475, 250);
|
||||
spawn.mapRect(-4400, -450, 250, 3075);
|
||||
spawn.mapRect(-4400, -450, 2225, 250);
|
||||
spawn.mapRect(-2425, -1300, 250, 1100);
|
||||
spawn.mapRect(-2425, -1300, 3825, 250);
|
||||
spawn.mapRect(1325, -1300, 250, 3925);
|
||||
spawn.mapRect(-875, -1300, 250, 1375);
|
||||
spawn.mapRect(-725, 50, 675, 250);
|
||||
spawn.mapRect(-875, 175, 175, 125);
|
||||
for (let i = 0; i < 6; i++) {
|
||||
spawn.mapRect(-4175, 2000 - i * 375, 50, 125);
|
||||
}
|
||||
spawn.mapRect(-3925, 162.5, 50, 125);
|
||||
spawn.mapRect(-2175, 162.5, 50, 125);
|
||||
spawn.mapRect(300, 2025, 250, 600);
|
||||
spawn.mapRect(-2150, 175, 50, 25);
|
||||
spawn.mapRect(-2150, 250, 50, 25);
|
||||
spawn.mapRect(-900, 175, 50, 25);
|
||||
spawn.mapRect(-900, 250, 50, 25);
|
||||
spawn.mapRect(-1600, 175, 50, 25);
|
||||
spawn.mapRect(-1500, 175, 50, 25);
|
||||
spawn.mapRect(-1600, 250, 50, 25);
|
||||
spawn.mapRect(-1500, 250, 50, 25);
|
||||
spawn.mapRect(-1925, 175, 50, 25);
|
||||
spawn.mapRect(-1925, 250, 50, 25);
|
||||
spawn.mapRect(-1200, 175, 50, 25);
|
||||
spawn.mapRect(-1200, 250, 50, 25);
|
||||
spawn.bodyRect(-2125, 200, 1250, 50);
|
||||
spawn.debris(425, 200, 50);
|
||||
spawn.debris(-650, 2100, 50);
|
||||
spawn.debris(-3000, 1925, 50);
|
||||
spawn.debris(-3825, 1550, 50);
|
||||
spawn.debris(-2475, -50, 50);
|
||||
|
||||
const bouncyBody = body[body.length - 1];
|
||||
bouncyBody.restitution = 0.9;
|
||||
spawn.mapVertex(-2175 + 1300 / 2, -1050 + 1225 / 2, "0 -400 -100 -300 -100 0 100 0 100 -300");
|
||||
|
||||
spawn.mapVertex(-4150 + 1975 / 2, -200 + 2575 / 2, "0 -800 -200 -600 -200 0 0 200 200 0 200 -600 0 200");
|
||||
const mapWithVertex = map[map.length - 1];
|
||||
let index1 = 0;
|
||||
level.custom = () => {
|
||||
level.exit.drawAndCheck();
|
||||
|
||||
level.enter.draw();
|
||||
|
||||
if (player.position.x > 425 && index1 === 0) {
|
||||
soft.breaker(clothArray[0], 0.7);
|
||||
soft.destroyer(clothArray[0]);
|
||||
index1++;
|
||||
}
|
||||
if (player.position.y > 1300 && index1 === 1) {
|
||||
setTimeout(() => {
|
||||
soft.breaker(clothArray[0], 1);
|
||||
soft.annihilate(clothArray[0]);
|
||||
clothArray.splice(0, 1);
|
||||
}, 1000); //prevents bugs
|
||||
simulation.makeTextLog("Couldn't be so simple, could it?", 2000 * Math.random());
|
||||
index1++;
|
||||
}
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
for (let i = 0; i < portals.length; i++) {
|
||||
portals[i][2].query();
|
||||
portals[i][3].query();
|
||||
portals[i][0].draw();
|
||||
portals[i][1].draw();
|
||||
portals[i][2].draw();
|
||||
portals[i][3].draw();
|
||||
}
|
||||
ctx.beginPath();
|
||||
if (Math.sin((2 * Math.PI * simulation.cycle) / (50)) > 0) {
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[0], Math.atan2(mapWithVertex.vertices[0].y - mapWithVertex.position.y, mapWithVertex.vertices[0].x - mapWithVertex.position.x));
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[3], Math.atan2(mapWithVertex.vertices[3].y - mapWithVertex.position.y, mapWithVertex.vertices[3].x - mapWithVertex.position.x));
|
||||
}
|
||||
if (Math.sin((2 * Math.PI * simulation.cycle) / (51)) > 0) {
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[1], Math.atan2(mapWithVertex.vertices[1].y - mapWithVertex.position.y, mapWithVertex.vertices[1].x - mapWithVertex.position.x));
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[4], Math.atan2(mapWithVertex.vertices[4].y - mapWithVertex.position.y, mapWithVertex.vertices[4].x - mapWithVertex.position.x));
|
||||
}
|
||||
if (Math.sin((2 * Math.PI * simulation.cycle) / (52)) > 0) {
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[2], Math.atan2(mapWithVertex.vertices[2].y - mapWithVertex.position.y, mapWithVertex.vertices[2].x - mapWithVertex.position.x));
|
||||
annoyingStuff.lasers(mapWithVertex.vertices[5], Math.atan2(mapWithVertex.vertices[5].y - mapWithVertex.position.y, mapWithVertex.vertices[5].x - mapWithVertex.position.x));
|
||||
}
|
||||
|
||||
ctx.strokeStyle = "#000";
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
|
||||
ctx.stroke(); // Draw it
|
||||
ctx.setLineDash([]);
|
||||
ctx.lineWidth = 20;
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.07)";
|
||||
ctx.stroke(); // Draw it
|
||||
|
||||
for (let i = 0; i < clothArray.length; i++) {
|
||||
soft.draw(clothArray[i]);
|
||||
soft.gravity(clothArray[i]);
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = "rgba(69, 69, 69, 0.1)";
|
||||
ctx.rect(-475, 175, 425, 2300);
|
||||
ctx.rect(900, 175, 425, 2300);
|
||||
ctx.rect(-875, 175, 400, 10000);
|
||||
ctx.rect(-4200, -250, 2025, 2775);
|
||||
ctx.fill();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = (m.pos.x < -725 && m.pos.y < 175) ? `rgba(68, 68, 68, ${Math.max(0.3, Math.min((-775 - m.pos.x) / 100, 0.99))})` : color.map;
|
||||
ctx.rect(-875, 50, 175, 150);
|
||||
ctx.fill();
|
||||
|
||||
};
|
||||
annoyingStuff.laserBoss(-1525, 1025);
|
||||
spawn.pulsar(-1525, -850);
|
||||
spawn.pulsar(1125, 1600);
|
||||
spawn.pulsar(-250, 1600);
|
||||
spawn.pulsar(-1450, 1600);
|
||||
spawn.pulsar(-2950, 1750);
|
||||
spawn.pulsar(-3375, 1750);
|
||||
spawn.pulsar(-3825, 1300);
|
||||
spawn.pulsar(-3825, 850);
|
||||
spawn.pulsar(-3450, 50);
|
||||
spawn.pulsar(-2925, 50);
|
||||
spawn.pulsar(-1900, -400);
|
||||
spawn.pulsar(-1200, -400);
|
||||
|
||||
powerUps.addResearchToLevel()
|
||||
powerUps.directSpawn(-775, 125, "tech");
|
||||
powerUp[powerUp.length - 1].collisionFilter.mask = cat.map | cat.body | cat.powerUp
|
||||
spawn.bodyRect(-875, 75, 25, 100);
|
||||
let hardBody = body[body.length - 1];
|
||||
hardBody.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.powerUp
|
||||
},
|
||||
// ********************************************************************************************************
|
||||
// ********************************************************************************************************
|
||||
// ***************************************** training levels **********************************************
|
||||
|
||||
@@ -1078,7 +1078,7 @@ const mobs = {
|
||||
})
|
||||
}
|
||||
} else if (tech.isMobLowHealth && this.health < 0.25) {
|
||||
dmg *= 3.22
|
||||
dmg *= 3
|
||||
|
||||
simulation.ephemera.push({
|
||||
name: "damage outline",
|
||||
|
||||
67
js/player.js
67
js/player.js
@@ -556,24 +556,23 @@ const m = {
|
||||
dmg *= m.fieldHarmReduction
|
||||
// if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5
|
||||
// 1.25 + Math.sin(m.cycle * 0.01)
|
||||
if (tech.isDiaphragm) dmg *= 0.56 + 0.36 * Math.sin(m.cycle * 0.0075);
|
||||
if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075);
|
||||
if (tech.isZeno) dmg *= 0.15
|
||||
if (tech.isFieldHarmReduction) dmg *= 0.65
|
||||
if (tech.isFieldHarmReduction) dmg *= 0.6
|
||||
if (tech.isHarmMACHO) dmg *= 0.4
|
||||
if (tech.isImmortal) dmg *= 0.7
|
||||
if (tech.energyRegen === 0) dmg *= 0.34
|
||||
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
|
||||
if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
|
||||
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.26
|
||||
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
||||
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
|
||||
if (tech.squirrelFx !== 1) dmg *= 0.8//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
||||
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55
|
||||
if (tech.isHarmReduce && input.field) dmg *= 0.12
|
||||
if (tech.isHarmReduce && input.field) dmg *= 0.1
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.27
|
||||
if (tech.isTurret && m.crouch) dmg *= 0.34;
|
||||
if (tech.isBotArmor) dmg *= 0.95 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
|
||||
if (tech.isTurret && m.crouch) dmg *= 0.3;
|
||||
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
|
||||
return tech.isEnergyHealth ? Math.pow(dmg, 0.5) : dmg //defense has less effect
|
||||
},
|
||||
@@ -2232,7 +2231,7 @@ const m = {
|
||||
} else {
|
||||
m.fieldRegen = 0.001 //6 energy per second
|
||||
}
|
||||
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
|
||||
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling
|
||||
if (tech.isTimeCrystals) {
|
||||
m.fieldRegen *= 2.5
|
||||
} else if (tech.isGroundState) {
|
||||
@@ -2861,17 +2860,17 @@ const m = {
|
||||
return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses ${(0.1 * couple).toFixed(2)} <strong class='color-s'>ice IX</strong></span>`
|
||||
// return `<span style = 'font-size:89%;'><strong>invulnerable</strong> <strong>+${2*couple}</strong> seconds post collision</span>`
|
||||
case 3: //negative mass
|
||||
return `<strong>+${(100 * (1 - 0.973 ** couple)).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>`
|
||||
return `<strong>${(100 * (1 - 0.973 ** couple)).toFixed(1)}%</strong> <strong class='color-defense'>damage taken</strong>`
|
||||
case 4: //assembler
|
||||
return `generate <strong>${(0.8 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
|
||||
return `<strong>+${(0.8 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
|
||||
case 5: //plasma
|
||||
return `<strong>+${(1.5 * couple).toFixed(1)}%</strong> <strong class='color-d'>damage</strong>`
|
||||
return `<strong>${(1 + 1.5 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
|
||||
case 6: //time dilation
|
||||
return `<strong>+${(5 * couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
|
||||
case 7: //cloaking
|
||||
return `<strong>+${(3.3 * couple).toFixed(1)}%</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>`
|
||||
case 8: //pilot wave
|
||||
return `<strong>+${(4 * couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
||||
return `<strong>+${(1 + 4 * couple).toFixed(2)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
|
||||
case 9: //wormhole
|
||||
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(2 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
|
||||
case 10: //grappling hook
|
||||
@@ -2923,7 +2922,7 @@ const m = {
|
||||
name: "field emitter",
|
||||
imageNumber: Math.floor(Math.random() * 26), //pick one of the 25 field emitter image files at random
|
||||
description: `<em>initial field</em><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong>
|
||||
<br>generate <strong>4</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
|
||||
<br><strong>4</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
|
||||
effect: () => {
|
||||
m.hold = function () {
|
||||
if (m.isHolding) {
|
||||
@@ -2952,7 +2951,7 @@ const m = {
|
||||
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
|
||||
description: `<strong>3</strong> oscillating <strong>shields</strong> are permanently active
|
||||
<br><strong>+150</strong> max <strong class='color-f'>energy</strong>
|
||||
<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
<br><strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
drainCD: 0,
|
||||
effect: () => {
|
||||
m.fieldBlockCD = 0;
|
||||
@@ -3054,10 +3053,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "perfect diamagnetism",
|
||||
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong><br>generate <strong>5</strong> <strong class='color-f'>energy</strong> per second",
|
||||
// <br><strong>attract</strong> power ups from <strong>far away</strong>
|
||||
// description: "<strong>attract</strong> power ups from <strong>far away</strong><br><strong>deflecting</strong> doesn't drain <strong class='color-f'>energy</strong><br>thrown <strong class='color-block'>blocks</strong> have",
|
||||
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
||||
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong><br><strong>5</strong> <strong class='color-f'>energy</strong> per second",
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#48f" //"#0c5"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
@@ -3292,14 +3288,14 @@ const m = {
|
||||
{
|
||||
name: "negative mass",
|
||||
//<br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br><strong>+55%</strong> <strong class='color-defense'>defense</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br><strong>0.4x</strong> <strong class='color-defense'>damage taken</strong><br><strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
||||
fieldDrawRadius: 0,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.fieldHarmReduction = 0.45; //55% reduction
|
||||
m.fieldHarmReduction = 0.4; //55% reduction
|
||||
m.fieldDrawRadius = 0;
|
||||
|
||||
m.hold = function () {
|
||||
@@ -3480,10 +3476,9 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "molecular assembler",
|
||||
description: `excess <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>generate <strong>12</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
// simulation.molecularMode: Math.floor(4 * Math.random()), //0 spores, 1 missile, 2 ice IX, 3 drones
|
||||
description: `excess <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
setDescription() {
|
||||
return `excess <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>generate <strong>12</strong> <strong class='color-f'>energy</strong> per second`
|
||||
return `excess <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`
|
||||
},
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#ff0"
|
||||
@@ -3600,7 +3595,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "plasma torch",
|
||||
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
set() {
|
||||
b.isExtruderOn = false
|
||||
// m.fieldCDcycleAlternate = 0
|
||||
@@ -4056,7 +4051,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "time dilation",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br><strong>+20%</strong> movement and <strong><em>fire rate</em></strong><br>generate <strong>12</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br><strong>1.2x</strong> movement and <strong><em>fire rate</em></strong><br><strong>12</strong> <strong class='color-f'>energy</strong> per second",
|
||||
set() {
|
||||
// m.fieldMeterColor = "#0fc"
|
||||
// m.fieldMeterColor = "#ff0"
|
||||
@@ -4246,7 +4241,7 @@ const m = {
|
||||
},
|
||||
effect() {
|
||||
if (tech.isTimeStop) {
|
||||
m.fieldHarmReduction = 0.66; //33% reduction
|
||||
m.fieldHarmReduction = 0.6;
|
||||
} else {
|
||||
m.fieldHarmReduction = 1;
|
||||
}
|
||||
@@ -4255,7 +4250,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "metamaterial cloaking",
|
||||
description: "<strong>+66%</strong> <strong class='color-defense'>defense</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>+333%</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "<strong>0.3x</strong> <strong class='color-defense'>damage taken</strong> while <strong class='color-cloaked'>cloaked</strong><br>after <strong class='color-cloaked'>decloaking</strong> <strong>4.5x</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> s<br><strong>6</strong> <strong class='color-f'>energy</strong> per second",
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.fieldMeterColor = "#333";
|
||||
@@ -4306,7 +4301,7 @@ const m = {
|
||||
if (!m.isCloak) { //&& m.energy > drain + 0.03
|
||||
// m.energy -= drain
|
||||
m.isCloak = true //enter cloak
|
||||
m.fieldHarmReduction = 0.33; //66% reduction
|
||||
m.fieldHarmReduction = 0.3;
|
||||
m.enterCloakCycle = m.cycle
|
||||
if (tech.isCloakHealLastHit && m.lastHit > 0) {
|
||||
const heal = Math.min(0.75 * m.lastHit, m.energy)
|
||||
@@ -4417,7 +4412,7 @@ const m = {
|
||||
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
|
||||
//field <strong>radius</strong> decreases out of <strong>line of sight</strong>
|
||||
//<strong>unlock</strong> <strong class='color-m'>tech</strong> from other <strong class='color-f'>fields</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choices</strong><br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choices</strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
@@ -4646,7 +4641,7 @@ const m = {
|
||||
{
|
||||
name: "wormhole",
|
||||
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>+7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>6</strong> <strong class='color-f'>energy</strong> per second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
drain: 0,
|
||||
effect: function () {
|
||||
m.fieldMeterColor = "#bbf" //"#0c5"
|
||||
@@ -5194,15 +5189,13 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "grappling hook",
|
||||
// description: `use <strong class='color-f'>energy</strong> to pull yourself towards the <strong>map</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to fire a hook that <strong>pulls</strong> player<br><strong class='color-d'>damages</strong> mobs and grabs <strong class='color-block'>blocks</strong><br>generate <strong>9</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to fire a hook that <strong>pulls</strong> player<br><strong class='color-d'>damages</strong> mobs and grabs <strong class='color-block'>blocks</strong><br><strong>9</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||
// m.fieldMeterColor = "#789"//"#456"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.grabPowerUpRange2 = 300000 //m.grabPowerUpRange2 = 200000;
|
||||
// m.fieldHarmReduction = 0.45; //55% reduction
|
||||
|
||||
m.hold = function () {
|
||||
if (m.isHolding) {
|
||||
|
||||
@@ -505,10 +505,14 @@ const powerUps = {
|
||||
currentRerollCount: 0,
|
||||
use(type) { //runs when you actually research a list of selections, type can be field, gun, or tech
|
||||
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
tech.addJunkTechToPool(tech.junkResearchNumber * 0.01)
|
||||
tech.addJunkTechToPool(0.01)
|
||||
} else {
|
||||
powerUps.research.changeRerolls(-1)
|
||||
}
|
||||
if (tech.isResearchDamage) {
|
||||
tech.damage *= 1.04
|
||||
simulation.makeTextLog(`<strong>1.04x</strong> <strong class='color-d'>damage</strong> from <strong>peer review</strong>`);
|
||||
}
|
||||
powerUps.research.currentRerollCount++
|
||||
// if (tech.isBanish && type === 'tech') { // banish researched tech
|
||||
// const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
|
||||
@@ -699,11 +703,8 @@ const powerUps = {
|
||||
text += `<div class='choose-grid-module entanglement flipX' onclick='powerUps.endDraft("${type}",true)'>entanglement</div>`
|
||||
} else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
text += `<div onclick="powerUps.research.use('${type}')" class='research-card'>` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
tech.junkResearchNumber = Math.ceil(3 * Math.random())
|
||||
text += `<div><div> <span style="position:relative;">`
|
||||
for (let i = 0; i < tech.junkResearchNumber; i++) {
|
||||
text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>`
|
||||
}
|
||||
text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>`
|
||||
text += `</span> <span class='research-select'>pseudoscience</span></div></div></div>`
|
||||
} else if (powerUps.research.count > 0) {
|
||||
text += `<div onclick="powerUps.research.use('${type}')" class='research-card' >` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
@@ -721,11 +722,8 @@ const powerUps = {
|
||||
text += `<span class='research-card entanglement flipX' style="width: 275px;" onclick='powerUps.endDraft("${type}",true)'><span style="letter-spacing: 6px;">entanglement</span></span>` //‌
|
||||
} else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
text += `<span onclick="powerUps.research.use('${type}')" class='research-card' style="width: 275px;float: left;">` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
tech.junkResearchNumber = Math.ceil(3 * Math.random())
|
||||
text += `<div><div><span style="position:relative;">`
|
||||
for (let i = 0, len = tech.junkResearchNumber; i < len; i++) {
|
||||
text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>`
|
||||
}
|
||||
text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>`
|
||||
text += `</span> <span class='research-select'>${tech.isResearchReality ? "<span class='alt'>alternate reality</span>" : "research"}</span></div></div></span>`
|
||||
} else if (powerUps.research.count > 0) {
|
||||
text += `<span onclick="powerUps.research.use('${type}')" class='research-card' style="width: 275px;float: left;">` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
@@ -787,24 +785,6 @@ const powerUps = {
|
||||
}
|
||||
return text
|
||||
},
|
||||
// researchAndCancelText(type) {
|
||||
// let text = "<div class= 'choose-grid-module'>"
|
||||
// if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
// text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module research-card'>` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
// tech.junkResearchNumber = Math.ceil(4 * Math.random())
|
||||
// text += `<div><div> <span style="position:relative;">`
|
||||
// for (let i = 0; i < tech.junkResearchNumber; i++) text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
|
||||
// text += `</span> <span class='research-select'>pseudoscience</span></div></div></div>`
|
||||
// } else if (powerUps.research.count > 0) {
|
||||
// text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module research-card' >` // style = "margin-left: 192px; margin-right: -192px;"
|
||||
// text += `<div><div><span style="position:relative;">`
|
||||
// for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.21)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
|
||||
// text += `</span> <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div></div>`
|
||||
// } else {
|
||||
// text += `<div></div>`
|
||||
// }
|
||||
// return text + '</div>'
|
||||
// },
|
||||
hideStyle: `style="height:auto; border: none; background-color: transparent;"`,
|
||||
gunText(choose, click) {
|
||||
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"`
|
||||
|
||||
@@ -974,7 +974,7 @@ const spawn = {
|
||||
if (!simulation.paused && !simulation.onTitlePage) {
|
||||
count++
|
||||
if (count < 660) {
|
||||
if (count === 1) simulation.makeTextLog(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
|
||||
if (count === 1 && simulation.difficultyMode < 5) simulation.makeTextLog(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
|
||||
if (!(count % 60)) simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${((count / 60 - Math.random()) * 0.1).toFixed(3)}`);
|
||||
} else if (count === 660) {
|
||||
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> 1 <em>//analysis complete</em>`);
|
||||
@@ -1011,7 +1011,7 @@ const spawn = {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (simulation.testing) {
|
||||
if (simulation.testing || simulation.difficultyMode > 4) {
|
||||
unlockExit()
|
||||
setTimeout(function () {
|
||||
simulation.makeTextLog(`level.levels.length <span class='color-symbol'>=</span> <strong>Infinite</strong>`);
|
||||
|
||||
746
js/tech.js
746
js/tech.js
File diff suppressed because it is too large
Load Diff
13
todo.txt
13
todo.txt
@@ -1,9 +1,19 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
bug fix for experiment mode
|
||||
text rework
|
||||
most numbers converted from "+50%" to "1.5x"
|
||||
renamed defense -> damage taken
|
||||
adjusted about 20 tech to round down or up their values to less decimals
|
||||
for a few I added research cost or JUNK chance to balance rounding
|
||||
|
||||
new community map soft by Richard0820
|
||||
tech: peer review - gain +damage each time you research
|
||||
self-assembly scales with health not health percent
|
||||
matter.js engine reverted back to 0.18 (to fix an issue with time dilation)
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
tech - destroys a random tech each new level and gains +damage each time
|
||||
|
||||
List of ways to break the game
|
||||
CPT + high energy regen
|
||||
@@ -1085,7 +1095,6 @@ possible names for tech
|
||||
holographic - 2-D surface can predict the 3-D space behind it? I think
|
||||
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
||||
swarm intelligence - for a drone 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
|
||||
electrostatic discharge
|
||||
|
||||
Reference in New Issue
Block a user