pulsar
new mob: pulsar - aims at player and does damage in an circle (set to 3x chance to show up until the next patch) several tech that were nonrefundable now can be removed and refunded added several bug fixes
This commit is contained in:
128
js/bullet.js
128
js/bullet.js
@@ -574,6 +574,121 @@ const b = {
|
||||
});
|
||||
}
|
||||
},
|
||||
photon(where, angle = m.angle) {
|
||||
let best;
|
||||
const path = [{
|
||||
x: m.pos.x + 20 * Math.cos(angle),
|
||||
y: m.pos.y + 20 * Math.sin(angle)
|
||||
},
|
||||
{
|
||||
x: m.pos.x + range * Math.cos(angle),
|
||||
y: m.pos.y + range * Math.sin(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 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//check for collisions
|
||||
best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
if (tech.isPulseAim) { //find mobs in line of sight
|
||||
let dist = 2200
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
|
||||
if (explosionRadius < newDist &&
|
||||
newDist < dist &&
|
||||
Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
|
||||
dist = newDist
|
||||
best.who = mob[i]
|
||||
path[path.length - 1] = mob[i].position
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!best.who) {
|
||||
vertexCollision(path[0], path[1], mob);
|
||||
vertexCollision(path[0], path[1], map);
|
||||
vertexCollision(path[0], path[1], body);
|
||||
if (best.dist2 != Infinity) { //if hitting something
|
||||
path[path.length - 1] = {
|
||||
x: best.x,
|
||||
y: best.y
|
||||
};
|
||||
}
|
||||
}
|
||||
if (best.who) b.explosion(path[1], explosionRadius, true)
|
||||
|
||||
//draw laser beam
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path[0].x, path[0].y);
|
||||
ctx.lineTo(path[1].x, path[1].y);
|
||||
ctx.strokeStyle = "rgba(255,0,0,0.13)"
|
||||
ctx.lineWidth = 60 * energy / 0.2
|
||||
ctx.stroke();
|
||||
ctx.strokeStyle = "rgba(255,0,0,0.2)"
|
||||
ctx.lineWidth = 18
|
||||
ctx.stroke();
|
||||
ctx.strokeStyle = "#f00";
|
||||
ctx.lineWidth = 4
|
||||
ctx.stroke();
|
||||
|
||||
//draw little dots along the laser path
|
||||
const sub = Vector.sub(path[1], path[0])
|
||||
const mag = Vector.magnitude(sub)
|
||||
for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
|
||||
const dist = Math.random()
|
||||
simulation.drawList.push({
|
||||
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
|
||||
y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
|
||||
radius: 1 + 4 * Math.random(),
|
||||
color: "rgba(255,0,0,0.5)",
|
||||
time: Math.floor(2 + 33 * Math.random() * Math.random())
|
||||
});
|
||||
}
|
||||
},
|
||||
grenade() {
|
||||
|
||||
},
|
||||
@@ -3266,11 +3381,11 @@ const b = {
|
||||
if (m.crouch) {
|
||||
spread = 0.75
|
||||
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCD); // cool down
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to damage for 30 cycles
|
||||
knock = 0.01
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCD); // cool down
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCD); //player is immune to damage for 30 cycles
|
||||
spread = 1.3
|
||||
knock = 0.1
|
||||
}
|
||||
@@ -4319,6 +4434,12 @@ const b = {
|
||||
} else {
|
||||
this.fire = this.fireLaser
|
||||
}
|
||||
|
||||
// this.fire = this.firePhoton
|
||||
},
|
||||
firePhoton() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCD); // cool down
|
||||
b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle)
|
||||
},
|
||||
fireLaser() {
|
||||
if (m.energy < tech.laserFieldDrain) {
|
||||
@@ -4329,7 +4450,6 @@ const b = {
|
||||
b.laser();
|
||||
}
|
||||
},
|
||||
|
||||
// laser(where = {
|
||||
// x: m.pos.x + 20 * Math.cos(m.angle),
|
||||
// y: m.pos.y + 20 * Math.sin(m.angle)
|
||||
@@ -4501,7 +4621,7 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + Math.floor(120 * b.fireCD); // cool down
|
||||
} else {
|
||||
m.energy -= DRAIN
|
||||
if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to collision damage for 5 cycles
|
||||
if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 5 cycles
|
||||
Matter.Body.setPosition(player, history.position);
|
||||
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||
if (m.health !== history.health) {
|
||||
|
||||
@@ -126,7 +126,7 @@ function collisionChecks(event) {
|
||||
if (tech.isPiezo) m.energy += 20.48;
|
||||
if (tech.isBayesian) powerUps.ejectTech()
|
||||
if (mob[k].onHit) mob[k].onHit(k);
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
//extra kick between player and mob //this section would be better with forces but they don't work...
|
||||
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
||||
Matter.Body.setVelocity(player, {
|
||||
|
||||
@@ -241,6 +241,8 @@ const build = {
|
||||
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
|
||||
}
|
||||
countTech++
|
||||
} else if (tech.tech[i].isLost) {
|
||||
text += `<div class="pause-grid-module" style="text-decoration: line-through;"><div class="grid-title">${tech.tech[i].name}</div>${tech.tech[i].description}</div></div>`
|
||||
}
|
||||
}
|
||||
el = document.getElementById("pause-grid-right")
|
||||
|
||||
10
js/level.js
10
js/level.js
@@ -16,7 +16,7 @@ const level = {
|
||||
// simulation.zoomScale = 1000;
|
||||
// simulation.setZoom();
|
||||
// m.setField("nano-scale manufacturing")
|
||||
// b.giveGuns("nail gun")
|
||||
// b.giveGuns("laser")
|
||||
// tech.isExplodeRadio = true
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
||||
// tech.giveTech("supercritical fission")
|
||||
@@ -1087,19 +1087,19 @@ const level = {
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
// spawn.boost(1500, 0, 900);
|
||||
|
||||
// simulation.difficulty = 30
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
// spawn.starter(1900, -500)
|
||||
spawn.pulsar(1900, -500)
|
||||
// spawn.historyBoss(1900, -500)
|
||||
// spawn.ghoster(2900, -500)
|
||||
// spawn.launcherBoss(1200, -500)
|
||||
// spawn.laserTargetingBoss(1600, -400)
|
||||
// spawn.striker(1600, -500)
|
||||
// spawn.shooter(1700, -120)
|
||||
// spawn.laserTargetingBoss(1700, -120)
|
||||
// spawn.bomberBoss(1400, -500)
|
||||
// spawn.sniper(1800, -120)
|
||||
// spawn.streamBoss(1600, -500)
|
||||
simulation.difficulty = 30
|
||||
spawn.orbitalBoss(1600, -500)
|
||||
// spawn.orbitalBoss(1600, -500)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.shieldingBoss(1600, -500)
|
||||
// spawn.beamer(1200, -500)
|
||||
|
||||
64
js/player.js
64
js/player.js
@@ -321,7 +321,7 @@ const m = {
|
||||
if (
|
||||
!tech.tech[i].isNonRefundable &&
|
||||
tech.tech[i].name !== "many-worlds" &&
|
||||
tech.tech[i].name !== "decoherence"
|
||||
tech.tech[i].name !== "Ψ(t) collapse"
|
||||
) {
|
||||
totalTech += tech.tech[i].count
|
||||
tech.tech[i].remove();
|
||||
@@ -509,7 +509,7 @@ const m = {
|
||||
if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
|
||||
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
|
||||
if (tech.isBlockHarm && m.isHolding) dmg *= 0.15
|
||||
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
|
||||
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.019, 0.60)
|
||||
if (tech.isSlowFPS) dmg *= 0.8
|
||||
// if (tech.isPiezo) dmg *= 0.85
|
||||
if (tech.isHarmReduce && m.fieldUpgrades[m.fieldMode].name === "negative mass field" && m.isFieldActive) dmg *= 0.5
|
||||
@@ -581,7 +581,7 @@ const m = {
|
||||
}
|
||||
}
|
||||
m.energy = Math.max(m.energy - steps / 136, 0.01)
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
|
||||
let isDrawPlayer = true
|
||||
const shortPause = function() {
|
||||
@@ -834,7 +834,42 @@ const m = {
|
||||
ctx.stroke();
|
||||
// draw eye; used in flip-flop
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(15, 0, 3, 0, 2 * Math.PI);
|
||||
// ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = m.eyeFillColor;
|
||||
// ctx.fill()
|
||||
|
||||
ctx.restore();
|
||||
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
|
||||
},
|
||||
drawDefault() {
|
||||
ctx.fillStyle = m.fillColor;
|
||||
m.walk_cycle += m.flipLegs * m.Vx;
|
||||
|
||||
//draw body
|
||||
ctx.save();
|
||||
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
|
||||
ctx.translate(m.pos.x, m.pos.y);
|
||||
|
||||
m.calcLeg(Math.PI, -3);
|
||||
m.drawLeg("#4a4a4a");
|
||||
m.calcLeg(0, 0);
|
||||
m.drawLeg("#333");
|
||||
|
||||
ctx.rotate(m.angle);
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
||||
grd.addColorStop(0, m.fillColorDark);
|
||||
grd.addColorStop(1, m.fillColor);
|
||||
ctx.fillStyle = grd;
|
||||
ctx.fill();
|
||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||
ctx.strokeStyle = "#333";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
// draw eye; used in flip-flop
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = m.eyeFillColor;
|
||||
// ctx.fill()
|
||||
|
||||
@@ -1571,7 +1606,7 @@ const m = {
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
||||
m.fieldMeterColor = "#000"
|
||||
m.fieldMeterColor = "#333"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.fieldHarmReduction = 0.5;
|
||||
m.fieldDrawRadius = 0;
|
||||
@@ -1834,8 +1869,9 @@ const m = {
|
||||
description: "<strong class='color-cloaked'>cloak</strong> after not using your gun or field<br>while <strong class='color-cloaked'>cloaked</strong> mobs can't see you<br>increase <strong class='color-d'>damage</strong> by <strong>133%</strong>",
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.fieldMeterColor = "#000";
|
||||
m.fieldMeterColor = "#333";
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
// m.eyeFillColor = '#333'
|
||||
m.fieldPhase = 0;
|
||||
m.isCloak = false
|
||||
m.fieldDamage = 2.33 // 1 + 111/100
|
||||
@@ -2344,7 +2380,7 @@ const m = {
|
||||
// break; //because the array order is messed up after splice
|
||||
// }
|
||||
// }
|
||||
// m.immuneCycle = m.cycle + 5; //player is immune to collision damage for 30 cycles
|
||||
// m.immuneCycle = m.cycle + 5; //player is immune to damage for 30 cycles
|
||||
// } else {
|
||||
// m.fieldCDcycle = m.cycle + 30;
|
||||
// // m.resetHistory();
|
||||
@@ -2447,7 +2483,7 @@ const m = {
|
||||
Matter.World.remove(engine.world, body[i]);
|
||||
body.splice(i, 1);
|
||||
m.fieldRange *= 0.8
|
||||
if (tech.isWormholeEnergy) m.energy += 0.5
|
||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||
if (tech.isWormSpores) { //pandimensionalspermia
|
||||
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
||||
b.spore(Vector.add(m.hole.pos2, Vector.rotate({
|
||||
@@ -2473,7 +2509,7 @@ const m = {
|
||||
body.splice(i, 1);
|
||||
m.fieldRange *= 0.8
|
||||
// if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
|
||||
if (tech.isWormholeEnergy) m.energy += 0.5
|
||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||
if (tech.isWormSpores) { //pandimensionalspermia
|
||||
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
||||
b.spore(Vector.add(m.hole.pos1, Vector.rotate({
|
||||
@@ -2554,7 +2590,7 @@ const m = {
|
||||
x: velocity.x,
|
||||
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
|
||||
});
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
@@ -2579,11 +2615,11 @@ const m = {
|
||||
m.hole.unit = Vector.perp(Vector.normalise(sub))
|
||||
|
||||
if (tech.isWormholeDamage) {
|
||||
who = Matter.Query.ray(mob, m.pos, simulation.mouseInGame, 80)
|
||||
who = Matter.Query.ray(mob, m.pos, simulation.mouseInGame, 100)
|
||||
for (let i = 0; i < who.length; i++) {
|
||||
if (who[i].body.alive) {
|
||||
mobs.statusDoT(who[i].body, 0.6, 420)
|
||||
mobs.statusStun(who[i].body, 240)
|
||||
mobs.statusDoT(who[i].body, 1, 420)
|
||||
mobs.statusStun(who[i].body, 360)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2830,7 +2866,7 @@ const m = {
|
||||
if (tech.isPiezo) m.energy += 20.48;
|
||||
if (tech.isBayesian) powerUps.ejectTech()
|
||||
if (mob[k].onHit) mob[k].onHit(k);
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
//extra kick between player and mob //this section would be better with forces but they don't work...
|
||||
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
||||
Matter.Body.setVelocity(player, {
|
||||
|
||||
@@ -70,7 +70,7 @@ const powerUps = {
|
||||
document.body.style.overflow = "hidden"
|
||||
simulation.paused = false;
|
||||
simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
build.unPauseGrid()
|
||||
requestAnimationFrame(cycle);
|
||||
if (m.holdingTarget) m.drop();
|
||||
@@ -379,11 +379,11 @@ const powerUps = {
|
||||
} else {
|
||||
if (tech.isBanish) {
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].name === "erase") powerUps.ejectTech(i)
|
||||
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
|
||||
}
|
||||
// simulation.makeTextLog(`No <strong class='color-m'>tech</strong> left<br>erased <strong class='color-m'>tech</strong> have been recovered`)
|
||||
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`)
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "tech");
|
||||
// powerUps.spawn(m.pos.x, m.pos.y, "tech");
|
||||
powerUps.endDraft("tech");
|
||||
} else {
|
||||
powerUps.giveRandomAmmo()
|
||||
|
||||
@@ -509,7 +509,11 @@ const simulation = {
|
||||
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
|
||||
document.getElementById("dmg").style.display = "inline";
|
||||
document.getElementById("health-bg").style.display = "inline";
|
||||
ctx.globalCompositeOperation = "source-over"
|
||||
ctx.shadowBlur = 0;
|
||||
// ctx.shadowColor = '#000';
|
||||
if (!m.isShipMode) {
|
||||
m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech
|
||||
m.spawn(); //spawns the player
|
||||
} else {
|
||||
World.add(engine.world, [player])
|
||||
@@ -828,7 +832,7 @@ const simulation = {
|
||||
|
||||
if (!(simulation.cycle % 420)) { //once every 7 seconds
|
||||
|
||||
if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to collision damage for 60 cycles
|
||||
if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to damage for 60 cycles
|
||||
|
||||
fallCheck = function(who, save = false) {
|
||||
let i = who.length;
|
||||
|
||||
119
js/spawn.js
119
js/spawn.js
@@ -11,6 +11,7 @@ const spawn = {
|
||||
"launcher", "launcher",
|
||||
"springer", "springer",
|
||||
"sucker", "sucker",
|
||||
"pulsar", "pulsar", "pulsar", "pulsar", "pulsar", //briefly high chance to show from a few days
|
||||
"chaser",
|
||||
"sniper",
|
||||
"spinner",
|
||||
@@ -21,7 +22,7 @@ const spawn = {
|
||||
"ghoster",
|
||||
"sneaker",
|
||||
],
|
||||
allowedGroupList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper"],
|
||||
allowedGroupList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper", "pulsar"],
|
||||
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||
//each level has 2 mobs: one new mob and one from the last level
|
||||
spawn.pickList.splice(0, 1);
|
||||
@@ -100,16 +101,21 @@ const spawn = {
|
||||
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// spawn.shield(me, x, y, 1);
|
||||
me.onDeath = function() {
|
||||
//add lore level as next level if player took lore tech earlier in the game
|
||||
if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) {
|
||||
level.levels.push("null")
|
||||
|
||||
function unlockExit() {
|
||||
level.exit.x = 5500;
|
||||
level.exit.y = -330;
|
||||
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}<br>level.levels.push("<span class='lore-text'>null</span>")`);
|
||||
//remove block map element so exit is clear
|
||||
Matter.World.remove(engine.world, map[map.length - 1]);
|
||||
map.splice(map.length - 1, 1);
|
||||
simulation.draw.setPaths(); //redraw map draw path
|
||||
}
|
||||
|
||||
//add lore level as next level if player took lore tech earlier in the game
|
||||
if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) {
|
||||
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}<br>level.levels.push("<span class='lore-text'>null</span>")`);
|
||||
level.levels.push("null")
|
||||
//remove block map element so exit is clear
|
||||
unlockExit()
|
||||
} else { //reset game
|
||||
let count = 0
|
||||
|
||||
@@ -130,7 +136,12 @@ const spawn = {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!simulation.testing) requestAnimationFrame(loop);
|
||||
if (simulation.testing) {
|
||||
simulation.makeTextLog(`level.levels.length <span class='color-symbol'>=</span> <strong>Infinite</strong>`);
|
||||
unlockExit()
|
||||
} else {
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
@@ -419,7 +430,7 @@ const spawn = {
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [player]);
|
||||
if (best.who && best.who === player && m.immuneCycle < m.cycle) {
|
||||
if (m.immuneCycle < m.cycle + 60 + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + 60 + tech.collisionImmuneCycles; //player is immune to collision damage extra time
|
||||
if (m.immuneCycle < m.cycle + 60 + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + 60 + tech.collisionImmuneCycles; //player is immune to damage extra time
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: best.x,
|
||||
@@ -1470,6 +1481,93 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
},
|
||||
pulsar(x, y, radius = 30) {
|
||||
mobs.spawn(x, y, 3, radius, "#f08");
|
||||
let me = mob[mob.length - 1];
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||
me.radius *= 2
|
||||
me.vertices[1].x = me.position.x + Math.cos(me.angle) * me.radius; //make one end of the triangle longer
|
||||
me.vertices[1].y = me.position.y + Math.sin(me.angle) * me.radius;
|
||||
me.fireCycle = 0
|
||||
me.fireTarget = { x: 0, y: 0 }
|
||||
me.pulseRadius = Math.min(500, 300 + simulation.difficulty)
|
||||
me.frictionAir = 0.01;
|
||||
me.fireDelay = Math.min(90, 210 - simulation.difficulty)
|
||||
me.isFiring = false
|
||||
me.onHit = function() {};
|
||||
me.canSeeTarget = function() {
|
||||
const diff = Vector.normalise(Vector.sub(this.fireTarget, this.position)); //make a vector for the mob's direction of length 1
|
||||
const dot = Vector.dot({
|
||||
x: Math.cos(this.angle),
|
||||
y: Math.sin(this.angle)
|
||||
}, diff); //the dot product of diff and dir will return how much over lap between the vectors
|
||||
if (dot < 0.97 || Matter.Query.ray(map, this.fireTarget, this.position).length !== 0) { //if not looking at target
|
||||
this.isFiring = false
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
me.do = function() {
|
||||
this.seePlayerByLookingAt();
|
||||
this.checkStatus();
|
||||
if (!m.isBodiesAsleep && this.seePlayer.recall) {
|
||||
|
||||
if (this.isFiring) {
|
||||
if (this.fireCycle > this.fireDelay) { //fire
|
||||
if (!this.canSeeTarget()) return
|
||||
this.isFiring = false
|
||||
//damage player if in range
|
||||
if (Vector.magnitude(Vector.sub(player.position, this.fireTarget)) < this.pulseRadius && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
|
||||
m.damage(0.03 * simulation.dmgScale);
|
||||
}
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.fireTarget.x,
|
||||
y: this.fireTarget.y,
|
||||
radius: this.pulseRadius,
|
||||
color: "rgba(255,0,100,0.8)",
|
||||
time: simulation.drawTime
|
||||
});
|
||||
} else { //delay before firing
|
||||
this.fireCycle++
|
||||
if (!(simulation.cycle % 3)) {
|
||||
if (!this.canSeeTarget()) return //if can't see stop firing
|
||||
|
||||
//draw explosion outline
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "rgba(255,0,100,0.05)";
|
||||
ctx.fill();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "rgba(255,0,100,0.5)";
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
} else { //aim at player
|
||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position)); //set direction to turn to fire
|
||||
//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;
|
||||
if (c > threshold) {
|
||||
this.torque += 0.000001 * this.inertia;
|
||||
} else if (c < -threshold) {
|
||||
this.torque -= 0.000001 * this.inertia;
|
||||
} else { //fire
|
||||
this.fireTarget = { x: player.position.x, y: player.position.y }
|
||||
if (!this.canSeeTarget()) return
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
this.fireLockCount = 0
|
||||
this.isFiring = true
|
||||
this.fireCycle = 0
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
laser(x, y, radius = 30) {
|
||||
mobs.spawn(x, y, 3, radius, "#f00");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -1603,7 +1701,7 @@ const spawn = {
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [player]);
|
||||
if (best.who && best.who === player && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to collision damage for an extra second
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
const dmg = 0.14 * simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -2758,7 +2856,8 @@ const spawn = {
|
||||
}
|
||||
Matter.Body.setPosition(this, Vector.add(who.position, Vector.mult(orbit, radius))) //bullets move with player
|
||||
//damage player
|
||||
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible)) {
|
||||
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
m.damage(0.035 * simulation.dmgScale);
|
||||
this.death();
|
||||
}
|
||||
|
||||
259
js/tech.js
259
js/tech.js
@@ -47,21 +47,16 @@
|
||||
if (options.length) {
|
||||
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++
|
||||
}
|
||||
// for (let i = 0; i < num; i++) {
|
||||
// // find an index that doesn't have dups first
|
||||
// let index = null
|
||||
// for (let i = 0; i < tech.junk.length; i++) {
|
||||
// if (tech.junk[i].numberInPool === 0) {
|
||||
// index = i
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if (index === null) index = Math.floor(Math.random() * tech.junk.length) //or just pick a random junk tech to add
|
||||
|
||||
// tech.junk[index].numberInPool++
|
||||
// tech.tech.push(Object.assign({}, tech.junk[index])) // push a "clone" of the tech.junk into the pool
|
||||
// if (tech.junk[index].numberInPool > 1) tech.tech[tech.tech.length - 1].name += ` - ${(tech.junk[index].numberInPool + 9).toString(36)}` //give it a unique name so it can be found
|
||||
// }
|
||||
},
|
||||
removeJunkTechFromPool(num = 1) {
|
||||
for (let j = 0; j < num; j++) {
|
||||
for (let i = 0; i < tech.tech.length; i++) {
|
||||
if (tech.tech[i].isJunk && tech.tech[i].frequency > 0 && tech.tech[i].count < tech.tech[i].maxCount) {
|
||||
tech.tech[i].frequency--
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// removeJunkTechFromPool() {
|
||||
// for (let i = tech.tech.length - 1; i > 0; i--) {
|
||||
@@ -141,7 +136,7 @@
|
||||
if (tech.isRerollDamage) dmg *= 1 + 0.039 * powerUps.research.count
|
||||
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.4, player.speed * 0.013)
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015)
|
||||
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
|
||||
return dmg * tech.slowFire * tech.aimDamage
|
||||
},
|
||||
@@ -264,6 +259,28 @@
|
||||
tech.isGunCycle = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "gun technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "gun");
|
||||
// this.count--
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "specialist",
|
||||
description: "for every <strong class='color-g'>gun</strong> in your inventory spawn a<br><strong class='color-h'>heal</strong>, <strong class='color-r'>research</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-m'>tech</strong>",
|
||||
@@ -483,7 +500,7 @@
|
||||
},
|
||||
{
|
||||
name: "Newton's 1st law",
|
||||
description: "moving at high <strong>speeds</strong> reduces <strong class='color-harm'>harm</strong><br>by up to <strong>50%</strong>",
|
||||
description: "moving at high <strong>speeds</strong> reduces <strong class='color-harm'>harm</strong><br>by up to <strong>60%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -500,7 +517,7 @@
|
||||
},
|
||||
{
|
||||
name: "Newton's 2nd law",
|
||||
description: "moving at high <strong>speeds</strong> increases <strong class='color-d'>damage</strong><br> by up to <strong>33%</strong>",
|
||||
description: "moving at high <strong>speeds</strong> increases <strong class='color-d'>damage</strong><br> by up to <strong>43%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1103,19 +1120,27 @@
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isBotTech: true,
|
||||
isNonRefundable: true,
|
||||
// isNonRefundable: true,
|
||||
allowed() {
|
||||
return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection
|
||||
},
|
||||
requires: "at least 2 bots, 1 research",
|
||||
effect: () => {
|
||||
powerUps.research.changeRerolls(-1)
|
||||
b.randomBot()
|
||||
if (powerUps.research.count > 0) {
|
||||
powerUps.research.changeRerolls(-1)
|
||||
b.randomBot()
|
||||
}
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 4
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
remove() {
|
||||
if (this.count > 0) {
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isBotTech) tech.tech[i].frequency /= 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "perimeter defense",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>6%</strong><br>for each of your permanent <strong class='color-bot'>bots</strong>",
|
||||
@@ -1248,7 +1273,7 @@
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.collisionImmuneCycles += 45;
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||
},
|
||||
remove() {
|
||||
tech.collisionImmuneCycles = 30;
|
||||
@@ -1328,7 +1353,7 @@
|
||||
ctx.stroke();
|
||||
//draw eye
|
||||
ctx.beginPath();
|
||||
ctx.arc(15, 0, 3, 0, 2 * Math.PI);
|
||||
ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = m.eyeFillColor;
|
||||
ctx.fill()
|
||||
ctx.restore();
|
||||
@@ -2002,6 +2027,27 @@
|
||||
tech.largerHeals = 1;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "healing technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-h'>healing</strong> <strong class='color-m'>tech</strong><br>spawn <strong>12</strong> <strong class='color-h'>heals</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0; i < 12; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isHealTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
// {
|
||||
// name: "perpetual heals",
|
||||
// description: "find <strong>3</strong> <strong class='color-h'>heals</strong> at the start of each <strong>level</strong>",
|
||||
@@ -2225,6 +2271,7 @@
|
||||
if (tech.isSuperDeterminism) count -= 2 //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");
|
||||
@@ -2268,7 +2315,7 @@
|
||||
}
|
||||
}, {
|
||||
name: "stimulated emission",
|
||||
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>but, after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2291,20 +2338,21 @@
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isNonRefundable: true,
|
||||
allowed() {
|
||||
return tech.duplicationChance() < 1
|
||||
},
|
||||
requires: "below 100% duplication chance",
|
||||
effect() {
|
||||
tech.duplicateChance += 0.075
|
||||
tech.maxDuplicationEvent()
|
||||
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
|
||||
tech.addJunkTechToPool(12)
|
||||
tech.maxDuplicationEvent()
|
||||
},
|
||||
remove() {
|
||||
tech.duplicateChance = 0
|
||||
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
|
||||
if (this.count > 1) tech.removeJunkTechFromPool(12)
|
||||
}
|
||||
}, {
|
||||
name: "futures exchange",
|
||||
@@ -2491,7 +2539,7 @@
|
||||
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,
|
||||
// isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2505,7 +2553,12 @@
|
||||
tech.addJunkTechToPool(18)
|
||||
// for (let i = 0; i < tech.junk.length; i++) tech.tech.push(tech.junk[i])
|
||||
},
|
||||
remove() {}
|
||||
remove() {
|
||||
if (this.count > 0) {
|
||||
tech.removeJunkTechFromPool(18)
|
||||
level.difficultyIncrease(simulation.difficultyMode)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "unified field theory",
|
||||
description: `in the <strong>pause</strong> menu, change your <strong class='color-f'>field</strong><br>by <strong>clicking</strong> on your <strong class='color-f'>field's</strong> box`,
|
||||
@@ -2522,8 +2575,36 @@
|
||||
remove() {
|
||||
tech.isGunSwitchField = false;
|
||||
}
|
||||
}, {
|
||||
name: "statistical ensemble",
|
||||
},
|
||||
{
|
||||
name: "field technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
// isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "field");
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isFieldTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "reinforcement learning",
|
||||
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>recursive <strong class='color-m'>tech</strong> you already have by <strong>10000%</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -2535,10 +2616,14 @@
|
||||
requires: "at least 10 tech",
|
||||
effect: () => {
|
||||
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 *= 100
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
remove() {
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].count > 0) tech.tech[i].frequency /= 100
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: "cardinality",
|
||||
description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>5</strong> <strong>choices</strong>",
|
||||
@@ -2596,88 +2681,28 @@
|
||||
remove() {
|
||||
tech.isSuperDeterminism = false;
|
||||
}
|
||||
}, {
|
||||
name: "gun technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "gun");
|
||||
// this.count--
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
}, {
|
||||
name: "ammo technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong> <strong class='color-m'>tech</strong><br>spawn <strong>6</strong> <strong class='color-g'>ammo</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isEnergyNoAmmo
|
||||
},
|
||||
requires: "not exciton lattice",
|
||||
effect() {
|
||||
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "ammo");
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
}, {
|
||||
name: "field technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "field");
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isFieldTech) tech.tech[i].frequency *= 2
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
}, {
|
||||
name: "healing technology",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-h'>healing</strong> <strong class='color-m'>tech</strong><br>spawn <strong>12</strong> <strong class='color-h'>heals</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
isNonRefundable: true,
|
||||
// isExperimentHide: true,
|
||||
// isBadRandomOption: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0; i < 12; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].isHealTech) tech.tech[i].frequency *= 200
|
||||
}
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
// {
|
||||
// name: "ammo technology",
|
||||
// description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong> <strong class='color-m'>tech</strong><br>spawn <strong>6</strong> <strong class='color-g'>ammo</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// isNonRefundable: true,
|
||||
// // isExperimentHide: true,
|
||||
// // isBadRandomOption: true,
|
||||
// allowed() {
|
||||
// return !tech.isEnergyNoAmmo
|
||||
// },
|
||||
// requires: "not exciton lattice",
|
||||
// effect() {
|
||||
// for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "ammo");
|
||||
// for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
// if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
|
||||
// }
|
||||
// },
|
||||
// remove() {}
|
||||
// },
|
||||
//**************************************************
|
||||
//************************************************** gun
|
||||
//************************************************** tech
|
||||
@@ -2834,7 +2859,7 @@
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("nail gun") && !tech.nailFireRate && !tech.isIceCrystals && !tech.isRivets && !tech.isNailRadiation
|
||||
return tech.haveGunCheck("nail gun") && !tech.nailFireRate && !tech.isIceCrystals && !tech.isRivets
|
||||
},
|
||||
requires: "nail gun, not ice crystal, rivets, or pneumatic actuator",
|
||||
effect() {
|
||||
@@ -4513,7 +4538,7 @@
|
||||
}
|
||||
}, {
|
||||
name: "Penrose process",
|
||||
description: "after a <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>you gain <strong>50</strong> <strong class='color-f'>energy</strong>",
|
||||
description: "after a <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>you gain <strong>63</strong> <strong class='color-f'>energy</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4959,7 +4984,7 @@
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0, len = Math.floor(m.energy * 40); i < len; i++) {
|
||||
for (let i = 0, len = 40; i < len; i++) {
|
||||
setTimeout(() => {
|
||||
m.energy -= 1 / len
|
||||
const index = body.length
|
||||
|
||||
22
todo.txt
22
todo.txt
@@ -1,8 +1,15 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
new mob: pulsar - aims at player and does damage in an circle
|
||||
(set to 3x chance to show up until the next patch)
|
||||
|
||||
several tech that were nonrefundable now can be removed and refunded
|
||||
added several bug fixes
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
micro-extruder is laggy?
|
||||
|
||||
mouse event e.which is deprecated
|
||||
|
||||
fix door.isOpen actually meaning isClosed?
|
||||
@@ -45,6 +52,16 @@ use the floor of portal sensor on the player? to unstuck player
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
remove pulsar from high chance to show on next patch
|
||||
|
||||
mob bullets that blow up
|
||||
draw outline of exploded region, 2 seconds later damage player in region and remove bullet
|
||||
|
||||
|
||||
mob sniper: draw aim graphics before fire
|
||||
|
||||
tech laser: photon - laser, but it can only move 100 pixels a cycle
|
||||
|
||||
mob - grows after taking damage
|
||||
mob - attack outwardly after taking damage
|
||||
|
||||
@@ -328,7 +345,10 @@ possible names for tech
|
||||
holonomy - parallel transport of a vector leads to movement (applies to curved space)
|
||||
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
||||
uncertainty principle
|
||||
|
||||
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
|
||||
|
||||
plot script:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user