propagator
tech: propagator - 67% damage, lose 1/2 second of time when a mob dies timeSkipBoss is back, maybe it will not cause bugs this time immune to harm unless player is inside horizon player loses time when inside horizon snake bosses are immune to harm until your remove their tail mob shields are 30% stronger time dilation: retrocausality automatically grabs power ups eternalism 50->40% damage paradigm shift 10->16% chance to get a research when ejecting tech reaction inhibitor 11->13% mob health reduction recycling 1->0.5% health for 5 seconds up to 2.5% per mob kill at normal max health bug fixes
This commit is contained in:
14
js/bullet.js
14
js/bullet.js
@@ -2109,10 +2109,10 @@ const b = {
|
||||
onEnd() {},
|
||||
do() {
|
||||
if (this.endCycle < simulation.cycle + 1) this.isWave = false
|
||||
if (Matter.Query.point(map, this.position).length) { //check if inside map
|
||||
if (Matter.Query.point(map, this.position).length) { //check if inside map //|| Matter.Query.point(body, this.position).length
|
||||
this.isBranch = true;
|
||||
this.do = () => { if (this.endCycle < simulation.cycle + 1) this.isWave = false }
|
||||
} else { //check if inside a body
|
||||
} else { //check if inside a mob
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position))
|
||||
const radius = mob[i].radius + tech.extruderRange / 2
|
||||
@@ -2387,14 +2387,14 @@ const b = {
|
||||
}
|
||||
if (tech.isLaserPush) { //push mobs away
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.94, y: best.who.velocity.y * 0.94 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.95, y: best.who.velocity.y * 0.95 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.005 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
} else if (tech.isLaserPush && best.who.classType === "body") {
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.94, y: best.who.velocity.y * 0.94 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.95, y: best.who.velocity.y * 0.95 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.005 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
};
|
||||
@@ -6996,7 +6996,7 @@ const b = {
|
||||
x: 7.5 * Math.cos(m.angle - Math.PI / 2),
|
||||
y: 7.5 * Math.sin(m.angle - Math.PI / 2)
|
||||
}
|
||||
const dmg = 0.66 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
|
||||
const dmg = 0.70 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
|
||||
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||
const eye = {
|
||||
x: m.pos.x + 15 * Math.cos(m.angle),
|
||||
|
||||
@@ -198,7 +198,7 @@ function collisionChecks(event) {
|
||||
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
|
||||
if (v > 9) {
|
||||
if (tech.blockDmg) { //electricity
|
||||
console.log("hi")
|
||||
// console.log("hi")
|
||||
Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y });
|
||||
if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) {
|
||||
mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12
|
||||
|
||||
@@ -187,7 +187,7 @@ window.addEventListener('load', () => {
|
||||
const canvas = document.getElementById("canvas");
|
||||
//using "const" causes problems in safari when an ID shares the same name.
|
||||
const ctx = canvas.getContext("2d");
|
||||
// const ctx = canvas.getContext('2d', { alpha: false }); //optimization, but doesn't work
|
||||
// const ctx = canvas.getContext('2d', { alpha: false }); //optimization, this works if you wipe with the background color of each level
|
||||
|
||||
document.body.style.backgroundColor = "#fff";
|
||||
|
||||
@@ -278,7 +278,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
||||
if (tech.tech[i].count > 0) {
|
||||
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||
if (tech.tech[i].isNonRefundable) {
|
||||
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||
} else if (tech.tech[i].isFieldTech) {
|
||||
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title">
|
||||
<span style="position:relative;">
|
||||
|
||||
18
js/level.js
18
js/level.js
@@ -17,10 +17,10 @@ const level = {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// // simulation.isHorizontalFlipped = true
|
||||
// m.addHealth(Infinity)
|
||||
// m.setField("standing wave")
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("nail gun")
|
||||
// tech.giveTech("closed timelike curve")
|
||||
// tech.giveTech("irradiated nails")
|
||||
// tech.giveTech("retrocausality")
|
||||
// tech.giveTech("pneumatic actuator")
|
||||
// tech.giveTech("6s half-life")
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
||||
@@ -36,8 +36,8 @@ const level = {
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.testing();
|
||||
// level.reactor(); //not in rotation, used for testing
|
||||
// spawn.timeBoss(1900, -500)
|
||||
// spawn.snakeSpitBoss(1900, -500)
|
||||
// level.reservoir(); //not in rotation, used for testing
|
||||
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||
// powerUps.research.changeRerolls(3000)
|
||||
@@ -2681,7 +2681,7 @@ const level = {
|
||||
// spawn.shieldingBoss(1700, -500)
|
||||
|
||||
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
|
||||
// for (let i = 0; i < 4; i++) spawn.starter(1900, -500)
|
||||
for (let i = 0; i < 4; i++) spawn.starter(1900, -500)
|
||||
// spawn.pulsar(1900, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1900, -500, 1);
|
||||
// mob[mob.length - 1].isShielded = true
|
||||
@@ -3294,8 +3294,8 @@ const level = {
|
||||
}
|
||||
|
||||
//2nd floor
|
||||
spawn.mapVertex(855, -1936, "-612 50 0 100 612 50 612 -50 -612 -50");
|
||||
spawn.mapVertex(-687, -1936, "-612 50 0 100 612 50 612 -50 -612 -50");
|
||||
spawn.mapVertex(-687, -1936, "-625 50 0 100 625 50 625 -50 -625 -50");
|
||||
spawn.mapVertex(855, -1936, "-625 50 0 100 625 50 625 -50 -625 -50");
|
||||
|
||||
//2nd floor right building
|
||||
// spawn.mapRect(550, -3050, 600, 175);
|
||||
@@ -3328,11 +3328,11 @@ const level = {
|
||||
spawn.randomMob(950, -1725, 0.1);
|
||||
spawn.randomMob(-725, -1775, 0.1);
|
||||
spawn.randomMob(-200, -2075, 0);
|
||||
spawn.randomMob(-550, -3500, -0.2);
|
||||
spawn.randomMob(375, -2125, 0);
|
||||
spawn.randomMob(1025, -3200, 0);
|
||||
spawn.randomMob(-550, -3500, 0);
|
||||
spawn.randomMob(-700, -2450, -0.1);
|
||||
spawn.randomMob(-1175, -2775, -0.1);
|
||||
spawn.randomMob(1025, -3200, -0.2);
|
||||
spawn.randomMob(-525, -3750, -0.2);
|
||||
spawn.randomMob(1350, -2075, -0.3);
|
||||
spawn.randomMob(1775, 1000, -0.4);
|
||||
|
||||
18
js/mob.js
18
js/mob.js
@@ -1119,7 +1119,7 @@ const mobs = {
|
||||
if (tech.iceIXOnDeath && this.isSlowed) {
|
||||
for (let i = 0, len = 2 * Math.sqrt(Math.min(this.mass, 25)) * tech.iceIXOnDeath; i < len; i++) b.iceIX(3, Math.random() * 2 * Math.PI, this.position)
|
||||
}
|
||||
if (tech.deathSpawnsFromBoss || (tech.deathSpawns && this.isDropPowerUp)) {
|
||||
if (tech.deathSpawnsFromBoss || tech.deathSpawns) {
|
||||
const spawns = tech.deathSpawns + tech.deathSpawnsFromBoss
|
||||
const len = Math.min(12, spawns * Math.ceil(Math.random() * simulation.difficulty * spawns))
|
||||
for (let i = 0; i < len; i++) {
|
||||
@@ -1130,6 +1130,22 @@ const mobs = {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (tech.isDeathSkipTime && !m.isBodiesAsleep) {
|
||||
requestAnimationFrame(() => {
|
||||
simulation.timePlayerSkip(this.isBoss ? 45 : 25)
|
||||
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
|
||||
}); //wrapping in animation frame prevents errors, probably
|
||||
|
||||
// if (tech.isFlipFlopOn) {
|
||||
// m.rewind(this.isBoss ? 45 : 25)
|
||||
// } else {
|
||||
// requestAnimationFrame(() => {
|
||||
// simulation.timePlayerSkip(this.isBoss ? 45 : 25)
|
||||
// simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
|
||||
// }); //wrapping in animation frame prevents errors, probably
|
||||
// }
|
||||
}
|
||||
if (tech.isEnergyLoss) m.energy *= 0.75;
|
||||
powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
|
||||
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
|
||||
|
||||
37
js/player.js
37
js/player.js
@@ -2529,6 +2529,25 @@ const m = {
|
||||
this.rewindCount = 0
|
||||
m.grabPowerUpRange2 = 300000
|
||||
m.hold = function() {
|
||||
|
||||
m.grabPowerUp();
|
||||
|
||||
// //grab power ups
|
||||
// for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
// if (
|
||||
// Vector.magnitudeSquared(Vector.sub(m.pos, powerUp[i].position)) < 100000 &&
|
||||
// !simulation.isChoosing &&
|
||||
// (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
|
||||
// ) {
|
||||
// powerUps.onPickUp(powerUp[i]);
|
||||
// powerUp[i].effect();
|
||||
// Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
// powerUp.splice(i, 1);
|
||||
// break; //because the array order is messed up after splice
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if (m.isHolding) {
|
||||
m.drawHold(m.holdingTarget);
|
||||
m.holding();
|
||||
@@ -2568,20 +2587,6 @@ const m = {
|
||||
} else {
|
||||
m.undoCrouch()
|
||||
}
|
||||
//grab power ups
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
Vector.magnitudeSquared(Vector.sub(m.pos, powerUp[i].position)) < 100000 &&
|
||||
!simulation.isChoosing &&
|
||||
(powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
|
||||
) {
|
||||
powerUps.onPickUp(powerUp[i]);
|
||||
powerUp[i].effect();
|
||||
Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
break; //because the array order is messed up after splice
|
||||
}
|
||||
}
|
||||
if (!(this.rewindCount % 30)) {
|
||||
if (tech.isRewindBot) {
|
||||
for (let i = 0; i < tech.isRewindBot; i++) {
|
||||
@@ -2594,8 +2599,6 @@ const m = {
|
||||
const who = bullet[bullet.length - 1]
|
||||
who.endCycle = simulation.cycle + 60
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2612,7 +2615,7 @@ const m = {
|
||||
} else {
|
||||
m.fieldFire = true;
|
||||
m.isBodiesAsleep = false;
|
||||
m.drain = 0.003
|
||||
m.drain = 0.0025
|
||||
m.hold = function() {
|
||||
if (m.isHolding) {
|
||||
m.wakeCheck();
|
||||
|
||||
@@ -137,7 +137,7 @@ const powerUps = {
|
||||
},
|
||||
doDefault() {
|
||||
//draw power ups
|
||||
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
|
||||
ctx.globalAlpha = 0.4 * Math.sin(simulation.cycle * 0.15) + 0.6;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
|
||||
@@ -237,7 +237,6 @@ const powerUps = {
|
||||
}
|
||||
},
|
||||
choose(type, index) {
|
||||
console.log('choose')
|
||||
if (type === "gun") {
|
||||
b.giveGuns(index)
|
||||
let text = `b.giveGuns("<span class='color-text'>${b.guns[index].name}</span>")`
|
||||
@@ -356,7 +355,7 @@ const powerUps = {
|
||||
// document.body.style.overflow = "hidden"
|
||||
// if (m.alive){}
|
||||
if (simulation.paused) requestAnimationFrame(cycle);
|
||||
simulation.paused = false;
|
||||
if (m.alive) simulation.paused = false;
|
||||
simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
build.unPauseGrid()
|
||||
if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 30 cycles
|
||||
@@ -1080,7 +1079,7 @@ const powerUps = {
|
||||
},
|
||||
pauseEjectTech(index) {
|
||||
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isNonRefundable) {
|
||||
if (Math.random() < 0.1 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
||||
if (Math.random() < 0.16 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
||||
tech.removeTech(index)
|
||||
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
} else {
|
||||
|
||||
@@ -521,9 +521,7 @@ const simulation = {
|
||||
}
|
||||
}, len * swapPeriod);
|
||||
},
|
||||
wipe() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
},
|
||||
wipe() {}, //set in simulation.startGame
|
||||
gravity() {
|
||||
function addGravity(bodies, magnitude) {
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
@@ -1049,7 +1047,7 @@ const simulation = {
|
||||
|
||||
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
|
||||
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05
|
||||
if (tech.isHealthRecovery) m.addHealth(0.01 * m.maxHealth)
|
||||
if (tech.isHealthRecovery) m.addHealth(0.005 * m.maxHealth)
|
||||
}
|
||||
|
||||
if (!(m.cycle % 420)) { //once every 7 seconds
|
||||
|
||||
330
js/spawn.js
330
js/spawn.js
@@ -1,10 +1,11 @@
|
||||
//main object for spawning things in a level
|
||||
const spawn = {
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, mantisBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
|
||||
randomBossList: ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||
"powerUpBoss", "powerUpBossBaby", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
||||
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss"
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
|
||||
randomBossList: [
|
||||
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
||||
"snakeBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss"
|
||||
],
|
||||
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
|
||||
bossTypeSpawnIndex: 0, //increases as the boss type cycles
|
||||
@@ -19,7 +20,7 @@ const spawn = {
|
||||
pickList: ["starter", "starter"],
|
||||
fullPickList: [
|
||||
"hopper", "hopper", "hopper",
|
||||
"slasher", "slasher", "hopper",
|
||||
"slasher", "slasher", "slasher",
|
||||
"stabber", "stabber", "stabber",
|
||||
"springer", "springer", "springer",
|
||||
"shooter", "shooter",
|
||||
@@ -2028,7 +2029,6 @@ const spawn = {
|
||||
me.seePlayerFreq = 300;
|
||||
const springStiffness = 0.00008; //simulation.difficulty
|
||||
const springDampening = 0.01;
|
||||
|
||||
me.springTarget = {
|
||||
x: me.position.x,
|
||||
y: me.position.y
|
||||
@@ -2055,11 +2055,9 @@ const spawn = {
|
||||
Composite.add(engine.world, cons[cons.length - 1]);
|
||||
cons[len2].length = 100 + 1.5 * radius;
|
||||
me.cons2 = cons[len2];
|
||||
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.invulnerabilityCountDown = 0
|
||||
|
||||
me.do = function() {
|
||||
this.checkStatus();
|
||||
this.gravity();
|
||||
@@ -2069,7 +2067,6 @@ const spawn = {
|
||||
ctx.arc(this.cons2.pointA.x, this.cons2.pointA.y, 6, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#222";
|
||||
ctx.fill();
|
||||
|
||||
this.seePlayerCheck()
|
||||
// this.seePlayerByHistory()
|
||||
if (this.isInvulnerable) {
|
||||
@@ -2202,7 +2199,6 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
me.onDeath = function() {
|
||||
this.removeCons();
|
||||
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
@@ -2215,7 +2211,6 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const sideLength = 80 // distance between each node mob
|
||||
const nodes = 3
|
||||
const angle = 2 * Math.PI / nodes
|
||||
@@ -2255,7 +2250,6 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const stiffness = 0.01
|
||||
const damping = 0.1
|
||||
for (let i = 1; i < nodes; ++i) { //attach to center mob
|
||||
@@ -2287,88 +2281,86 @@ const spawn = {
|
||||
}
|
||||
spawn.allowShields = true;
|
||||
},
|
||||
timeSkipBoss(x, y, radius = 55) {
|
||||
mobs.spawn(x, y, 6, radius, '#000');
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
// me.stroke = "transparent"; //used for drawSneaker
|
||||
me.timeSkipLastCycle = 0
|
||||
me.eventHorizon = 1800; //required for black hole
|
||||
me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
|
||||
me.accelMag = 0.0004 * simulation.accelScale;
|
||||
// me.frictionAir = 0.005;
|
||||
// me.memory = 1600;
|
||||
// Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
Matter.Body.setDensity(me, 0.0005 + 0.00018 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
spawn.shield(me, x, y, 1);
|
||||
// timeSkipBoss(x, y, radius = 55) {
|
||||
// mobs.spawn(x, y, 6, radius, '#000');
|
||||
// let me = mob[mob.length - 1];
|
||||
// me.isBoss = true;
|
||||
// // me.stroke = "transparent"; //used for drawSneaker
|
||||
// me.timeSkipLastCycle = 0
|
||||
// me.eventHorizon = 1800; //required for black hole
|
||||
// me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
|
||||
// me.accelMag = 0.0004 * simulation.accelScale;
|
||||
// // me.frictionAir = 0.005;
|
||||
// // me.memory = 1600;
|
||||
// // Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// Matter.Body.setDensity(me, 0.0005 + 0.00018 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// spawn.shield(me, x, y, 1);
|
||||
// me.onDeath = function() {
|
||||
// //applying forces to player doesn't seem to work inside this method, not sure why
|
||||
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
// };
|
||||
// me.do = function() {
|
||||
// //keep it slow, to stop issues from explosion knock backs
|
||||
// if (this.speed > 8) {
|
||||
// Matter.Body.setVelocity(this, {
|
||||
// x: this.velocity.x * 0.99,
|
||||
// y: this.velocity.y * 0.99
|
||||
// });
|
||||
// }
|
||||
// this.seePlayerCheck();
|
||||
// this.checkStatus();
|
||||
// this.attraction()
|
||||
// if (!simulation.isTimeSkipping) {
|
||||
// const compress = 1
|
||||
// if (this.timeSkipLastCycle < simulation.cycle - compress &&
|
||||
// Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
|
||||
// this.timeSkipLastCycle = simulation.cycle
|
||||
// simulation.timeSkip(compress)
|
||||
|
||||
// this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
|
||||
// this.stroke = "#014"
|
||||
// this.isShielded = false;
|
||||
// this.isDropPowerUp = true;
|
||||
// this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can't touch bullets
|
||||
|
||||
me.onDeath = function() {
|
||||
//applying forces to player doesn't seem to work inside this method, not sure why
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
};
|
||||
me.do = function() {
|
||||
//keep it slow, to stop issues from explosion knock backs
|
||||
if (this.speed > 8) {
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: this.velocity.x * 0.99,
|
||||
y: this.velocity.y * 0.99
|
||||
});
|
||||
}
|
||||
this.seePlayerCheck();
|
||||
this.checkStatus();
|
||||
this.attraction()
|
||||
if (!simulation.isTimeSkipping) {
|
||||
const compress = 1
|
||||
if (this.timeSkipLastCycle < simulation.cycle - compress &&
|
||||
Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
|
||||
this.timeSkipLastCycle = simulation.cycle
|
||||
simulation.timeSkip(compress)
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = "#fff";
|
||||
// ctx.globalCompositeOperation = "destination-in"; //in or atop
|
||||
// ctx.fill();
|
||||
// ctx.globalCompositeOperation = "source-over";
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// ctx.clip();
|
||||
|
||||
this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
|
||||
this.stroke = "#014"
|
||||
this.isShielded = false;
|
||||
this.isDropPowerUp = true;
|
||||
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can't touch bullets
|
||||
// // ctx.beginPath();
|
||||
// // ctx.arc(this.position.x, this.position.y, 9999, 0, 2 * Math.PI);
|
||||
// // ctx.fillStyle = "#000";
|
||||
// // ctx.fill();
|
||||
// // ctx.strokeStyle = "#000";
|
||||
// // ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.globalCompositeOperation = "destination-in"; //in or atop
|
||||
ctx.fill();
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
ctx.clip();
|
||||
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, 9999, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = "#000";
|
||||
// ctx.fill();
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke();
|
||||
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||
// ctx.fill();
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke();
|
||||
} else {
|
||||
this.isShielded = true;
|
||||
this.isDropPowerUp = false;
|
||||
this.seePlayer.recall = false
|
||||
this.fill = "transparent"
|
||||
this.stroke = "transparent"
|
||||
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob; //can't touch bullets
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// // ctx.beginPath();
|
||||
// // ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// // ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||
// // ctx.fill();
|
||||
// // ctx.strokeStyle = "#000";
|
||||
// // ctx.stroke();
|
||||
// } else {
|
||||
// this.isShielded = true;
|
||||
// this.isDropPowerUp = false;
|
||||
// this.seePlayer.recall = false
|
||||
// this.fill = "transparent"
|
||||
// this.stroke = "transparent"
|
||||
// this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob; //can't touch bullets
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||
// ctx.fill();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) {
|
||||
mobs.spawn(x, y, 4, radius, "rgb(255,0,190)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -3931,7 +3923,7 @@ const spawn = {
|
||||
me.isBoss = true;
|
||||
Matter.Body.setDensity(me, 0.001); //normal is 0.001
|
||||
me.inertia = Infinity;
|
||||
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0.06 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.frictionAir = 0.01
|
||||
@@ -3974,8 +3966,8 @@ const spawn = {
|
||||
const unit = Vector.sub(player.position, this.position)
|
||||
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(unit), 0.1));
|
||||
} else {
|
||||
if (Math.abs(this.velocity.y) < 9) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.02 });
|
||||
if (Math.abs(this.velocity.x) < 6.5) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.02, y: this.velocity.y });
|
||||
if (Math.abs(this.velocity.y) < 10) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.02 });
|
||||
if (Math.abs(this.velocity.x) < 7) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.02, y: this.velocity.y });
|
||||
}
|
||||
|
||||
if (this.isInvulnerable) {
|
||||
@@ -5138,7 +5130,7 @@ const spawn = {
|
||||
me.maxCycles = 110;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.5;
|
||||
me.frictionAir = 1;
|
||||
// me.homePosition = { x: x, y: y };
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
|
||||
@@ -5153,7 +5145,7 @@ const spawn = {
|
||||
};
|
||||
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
Matter.Body.rotate(this, 0.003) //gently spin around
|
||||
this.checkStatus();
|
||||
ctx.beginPath(); //draw cycle timer
|
||||
ctx.moveTo(this.vertices[this.vertices.length - 1].x, this.vertices[this.vertices.length - 1].y)
|
||||
@@ -5186,6 +5178,73 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
},
|
||||
timeSkipBoss(x, y, radius = 50) {
|
||||
mobs.spawn(x, y, 15, radius, "rgb(150, 150, 255)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.eventHorizon = 0; //set in mob loop
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.004;
|
||||
me.accelMag = 0.0001 + 0.00003 * simulation.accelScale
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random(), true)
|
||||
|
||||
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
// requestAnimationFrame(() => { simulation.timePlayerSkip(120) }); //wrapping in animation frame prevents errors, probably
|
||||
};
|
||||
me.onDamage = function() {
|
||||
//find side of mob closest to player
|
||||
//causes lag for foam,laser too many seekers //maybe scale chance with dmg
|
||||
// const where = Vector.add(this.position, Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.radius + 10))
|
||||
// spawn.seeker(where.x, where.y); //give the bullet a rotational velocity as if they were attached to a vertex
|
||||
};
|
||||
me.do = function() {
|
||||
this.seePlayerByHistory();
|
||||
this.attraction();
|
||||
this.checkStatus();
|
||||
this.eventHorizon = 950 + 170 * Math.sin(simulation.cycle * 0.005)
|
||||
if (!simulation.isTimeSkipping) {
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < this.eventHorizon) {
|
||||
this.attraction();
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
this.isInvulnerable = false
|
||||
if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
|
||||
simulation.timePlayerSkip(8)
|
||||
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
|
||||
}); //wrapping in animation frame prevents errors, probably
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.globalCompositeOperation = "destination-in"; //in or atop
|
||||
ctx.fill();
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||
// ctx.stroke();
|
||||
ctx.clip();
|
||||
} else {
|
||||
this.damageReduction = 0
|
||||
this.isInvulnerable = true
|
||||
//prevents other things from being drawn later on in the draw cycle
|
||||
requestAnimationFrame(() => {
|
||||
simulation.camera();
|
||||
ctx.beginPath(); //gets rid of already draw shapes
|
||||
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI, false); //part you can't see
|
||||
ctx.fillStyle = color.background;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
streamBoss(x, y, radius = 110) {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(245,180,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -5412,10 +5471,14 @@ const spawn = {
|
||||
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.accelMag = 0.0001 + 0.0002 * Math.sqrt(simulation.accelScale)
|
||||
me.accelMag = 0.0003 + 0.0002 * Math.sqrt(simulation.accelScale)
|
||||
me.memory = 250;
|
||||
me.laserRange = 500;
|
||||
Matter.Body.setDensity(me, 0.0022 + 0.00022 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.startingDamageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0
|
||||
me.isInvulnerable = true
|
||||
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
for (let i = 0; i < mob.length; i++) { //wake up tail mobs
|
||||
@@ -5428,9 +5491,7 @@ const spawn = {
|
||||
};
|
||||
me.canFire = false;
|
||||
me.closestVertex1 = 0;
|
||||
// me.closestVertex2 = 1;
|
||||
me.cycle = 0
|
||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
this.seePlayerByHistory()
|
||||
@@ -5439,7 +5500,7 @@ const spawn = {
|
||||
this.cycle++
|
||||
if (this.seePlayer.recall && ((this.cycle % 10) === 0)) {
|
||||
if (this.canFire) {
|
||||
if (this.cycle > 120) {
|
||||
if (this.cycle > 100) {
|
||||
this.cycle = 0
|
||||
this.canFire = false
|
||||
// Matter.Body.setAngularVelocity(this, 0.1)
|
||||
@@ -5450,7 +5511,7 @@ const spawn = {
|
||||
}
|
||||
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6)
|
||||
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
|
||||
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -10)
|
||||
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -13)
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||
x: this.velocity.x + velocity.x,
|
||||
y: this.velocity.y + velocity.y
|
||||
@@ -5482,14 +5543,29 @@ const spawn = {
|
||||
// }
|
||||
}
|
||||
}
|
||||
if (this.isInvulnerable) {
|
||||
ctx.beginPath();
|
||||
let vertices = this.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 20;
|
||||
ctx.strokeStyle = "rgba(255,255,255,0.7)";
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
//extra space to give head room
|
||||
angle -= 0.1
|
||||
mag -= 10
|
||||
let previousTailID = 0
|
||||
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
angle -= 0.15 + i * 0.008
|
||||
mag -= 5
|
||||
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 20);
|
||||
if (i === 0) mob[mob.length - 1].snakeHeadID = me.id
|
||||
mob[mob.length - 1].previousTailID = previousTailID
|
||||
previousTailID = mob[mob.length - 1].id
|
||||
}
|
||||
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
|
||||
|
||||
@@ -5530,36 +5606,46 @@ const spawn = {
|
||||
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.accelMag = 0.00077 * simulation.accelScale;
|
||||
me.accelMag = 0.0004 + 0.0003 * Math.sqrt(simulation.accelScale)
|
||||
me.memory = 250;
|
||||
me.laserRange = 500;
|
||||
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.startingDamageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0
|
||||
me.isInvulnerable = true
|
||||
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
for (let i = 0; i < mob.length; i++) { //wake up tail mobs
|
||||
if (mob[i].isSnakeTail && mob[i].alive) {
|
||||
mob[i].isSnakeTail = false;
|
||||
mob[i].do = mob[i].doActive
|
||||
// mob[i].removeConsBB();
|
||||
}
|
||||
}
|
||||
};
|
||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
this.seePlayerByHistory()
|
||||
this.checkStatus();
|
||||
this.attraction();
|
||||
this.harmZone();
|
||||
if (this.isInvulnerable) {
|
||||
ctx.beginPath();
|
||||
let vertices = this.vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
ctx.lineWidth = 20;
|
||||
ctx.strokeStyle = "rgba(255,255,255,0.7)";
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
//extra space to give head room
|
||||
angle -= 0.1
|
||||
mag -= 10
|
||||
let previousTailID = 0
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
angle -= 0.15 + i * 0.008
|
||||
mag -= 5
|
||||
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 20);
|
||||
if (i === 0) mob[mob.length - 1].snakeHeadID = me.id
|
||||
mob[mob.length - 1].previousTailID = previousTailID
|
||||
previousTailID = mob[mob.length - 1].id
|
||||
}
|
||||
|
||||
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
|
||||
|
||||
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
||||
@@ -5595,23 +5681,23 @@ const spawn = {
|
||||
let me = mob[mob.length - 1];
|
||||
me.collisionFilter.mask = cat.bullet | cat.player | cat.mob //| cat.body
|
||||
me.accelMag = 0.0006 * simulation.accelScale;
|
||||
me.leaveBody = false;
|
||||
me.leaveBody = Math.random() < 0.33 ? true : false;
|
||||
me.showHealthBar = false;
|
||||
me.isDropPowerUp = false;
|
||||
// Matter.Body.setDensity(me, 0.00004); //normal is 0.001
|
||||
Matter.Body.setDensity(me, 0.003); //normal is 0.001
|
||||
me.frictionAir = 0.015;
|
||||
me.isSnakeTail = true;
|
||||
me.stroke = "transparent"
|
||||
me.onDeath = function() {
|
||||
// if (this.isSnakeTail) { //wake up tail mobs
|
||||
// for (let i = 0; i < mob.length; i++) {
|
||||
// if (mob[i].isSnakeTail && mob[i].alive) {
|
||||
// mob[i].isSnakeTail = false;
|
||||
// mob[i].do = mob[i].doActive
|
||||
// mob[i].removeConsBB();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
setTimeout(() => {
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (this.id === mob[i].previousTailID && mob[i].alive) mob[i].death()
|
||||
if (this.snakeHeadID === mob[i].id) {
|
||||
mob[i].isInvulnerable = false
|
||||
mob[i].damageReduction = mob[i].startingDamageReduction
|
||||
}
|
||||
}
|
||||
}, 150);
|
||||
};
|
||||
me.do = function() {
|
||||
this.checkStatus();
|
||||
@@ -5666,7 +5752,7 @@ const spawn = {
|
||||
me.stroke = "rgb(220,220,255)";
|
||||
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||
me.shield = true;
|
||||
me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.isUnblockable = true
|
||||
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
|
||||
121
js/tech.js
121
js/tech.js
@@ -221,7 +221,8 @@ const tech = {
|
||||
},
|
||||
damageFromTech() {
|
||||
let dmg = 1 //m.fieldDamage
|
||||
if (tech.isNoDraftPause) dmg *= 1.5
|
||||
if (tech.isDeathSkipTime) dmg *= 1.67
|
||||
if (tech.isNoDraftPause) dmg *= 1.4
|
||||
if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount)
|
||||
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
|
||||
if (tech.OccamDamage) dmg *= tech.OccamDamage
|
||||
@@ -556,7 +557,7 @@ const tech = {
|
||||
{
|
||||
name: "cache",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Cache_(computing)' class="link">cache</a>`,
|
||||
description: `${powerUps.orb.ammo()} give <strong>16x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
|
||||
description: `${powerUps.orb.ammo()} give <strong>1600%</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
|
||||
// ammo powerups always max out your gun,
|
||||
// but the maximum ammo ti limited
|
||||
// description: `${powerUps.orb.ammo()} give <strong>13x</strong> more <strong class='color-ammo'>ammo</strong>, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`,
|
||||
@@ -936,7 +937,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "reaction inhibitor",
|
||||
description: "mobs spawn with <strong>11%</strong> less <strong>health</strong>",
|
||||
description: "mobs spawn with <strong>13%</strong> less <strong>health</strong>",
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -946,7 +947,7 @@ const tech = {
|
||||
},
|
||||
requires: "", //"any mob death tech",
|
||||
effect: () => {
|
||||
tech.mobSpawnWithHealth *= 0.89
|
||||
tech.mobSpawnWithHealth *= 0.87
|
||||
|
||||
//set all mobs at full health to 0.85
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
@@ -957,6 +958,24 @@ const tech = {
|
||||
tech.mobSpawnWithHealth = 1;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "propagator",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>67%</strong>, but after<br>mobs <strong>die</strong> lose <strong>0.5</strong> seconds of <strong>time</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isDeathSkipTime = true
|
||||
},
|
||||
remove() {
|
||||
tech.isDeathSkipTime = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "decorrelation",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>70%</strong> after not <strong>activating</strong><br>your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
|
||||
@@ -1772,6 +1791,24 @@ const tech = {
|
||||
m.eyeFillColor = 'transparent'
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "spacetime interval",
|
||||
// description: "increase <strong class='color-d'>damage</strong> by <strong>93%</strong>, but after mobs <strong>die</strong><br>move into the <strong>past</strong> / <strong>future</strong> while <strong class='color-flop'>ON</strong> / <strong class='color-flop'>OFF</strong>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 4,
|
||||
// frequencyDefault: 4,
|
||||
// allowed() {
|
||||
// return tech.isFlipFlop || tech.isRelay
|
||||
// },
|
||||
// requires: "ON/OFF tech",
|
||||
// effect() {
|
||||
// tech.isDeathSkipTime = true
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isDeathSkipTime = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "NAND gate",
|
||||
description: "if in the <strong class='color-flop'>ON</strong> state<br>do <strong>55.5%</strong> more <strong class='color-d'>damage</strong>",
|
||||
@@ -2479,7 +2516,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "recycling",
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>regain <strong>1%</strong> of max <strong class='color-h'>health</strong> every second",
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>regain <strong>0.5%</strong> of max <strong class='color-h'>health</strong> every second",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3172,7 +3209,7 @@ const tech = {
|
||||
|
||||
{
|
||||
name: "paradigm shift",
|
||||
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>10%</strong> chance to convert that <strong class='color-m'>tech</strong> into ${powerUps.orb.research(1)}`,
|
||||
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>16%</strong> chance to convert that <strong class='color-m'>tech</strong> into ${powerUps.orb.research(1)}`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3191,7 +3228,7 @@ const tech = {
|
||||
{
|
||||
name: "eternalism",
|
||||
// description: `increase <strong class='color-d'>damage</strong> by <strong>60%</strong>, but <strong>time</strong> doesn't <strong>pause</strong><br>while choosing a choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>`, //${powerUps.orb.heal()} or
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong>, but<br><strong>time</strong> can't be <strong>paused</strong> <em>(time dilation still works)</em>",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>40%</strong>, but<br><strong>time</strong> can't be <strong>paused</strong> <em>(time dilation still works)</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3556,19 +3593,19 @@ const tech = {
|
||||
// return `randomly remove <strong>${this.removePercent * 100}%</strong> of your <strong class='color-m'>tech</strong><br>for each removed gain <strong>${this.damagePerRemoved * 100}%</strong> <strong class='color-d'>damage</strong>`
|
||||
// },
|
||||
descriptionFunction() {
|
||||
return `randomly remove <strong>half</strong> your <strong class='color-m'>tech</strong><br>for each removed gain <strong>${this.damagePerRemoved * 100}%</strong> <strong class='color-d'>damage</strong> <em>(~${this.damagePerRemoved * 50 * tech.totalCount}%)</em>`
|
||||
return `randomly remove <strong>half</strong> your <strong class='color-m'>tech</strong><br>for each removed gain <strong>${this.damagePerRemoved * 100 }%</strong> <strong class='color-d'>damage</strong> <em>(~${(this.count === 0) ? this.damagePerRemoved * 50 * tech.totalCount : tech.OccamDamage*100}%)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequency: 199,
|
||||
frequencyDefault: 1,
|
||||
isNonRefundable: true,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return (tech.totalCount > 6)
|
||||
},
|
||||
requires: "NOT EXPERIMENT MODE, more than 6 tech",
|
||||
removePercent: 0.5,
|
||||
requires: "more than 6 tech",
|
||||
// removePercent: 0.5,
|
||||
damagePerRemoved: 0.5,
|
||||
effect() {
|
||||
let pool = []
|
||||
@@ -3577,7 +3614,7 @@ const tech = {
|
||||
}
|
||||
pool = shuffle(pool); //shuffles order of maps
|
||||
let removeCount = 0
|
||||
for (let i = 0, len = pool.length * this.removePercent; i < len; i++) removeCount += tech.removeTech(pool[i])
|
||||
for (let i = 0, len = pool.length * this.damagePerRemoved; i < len; i++) removeCount += tech.removeTech(pool[i])
|
||||
tech.OccamDamage = 1 + this.damagePerRemoved * removeCount
|
||||
// tech.OccamDamage = Math.pow(1.25, removeCount)
|
||||
},
|
||||
@@ -5713,8 +5750,8 @@ const tech = {
|
||||
simulation.updateGunHUD()
|
||||
},
|
||||
remove() {
|
||||
b.guns[8].ammoPack = 24
|
||||
if (this.count) {
|
||||
b.guns[8].ammoPack = 24
|
||||
b.guns[8].ammo += this.ammoLost
|
||||
simulation.updateGunHUD()
|
||||
}
|
||||
@@ -6110,7 +6147,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.17
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.18
|
||||
},
|
||||
requires: "laser, not free-electron",
|
||||
effect() {
|
||||
@@ -6138,13 +6175,13 @@ const tech = {
|
||||
requires: "laser, not pulse, diodes",
|
||||
effect() {
|
||||
tech.laserFieldDrain = 0.007 //base is 0.002
|
||||
tech.laserDamage = 0.51; //base is 0.16
|
||||
tech.laserDamage = 0.54; //base is 0.18
|
||||
tech.laserColor = "#83f"
|
||||
tech.laserColorAlpha = "rgba(136, 51, 255,0.5)"
|
||||
},
|
||||
remove() {
|
||||
tech.laserFieldDrain = 0.002;
|
||||
tech.laserDamage = 0.17; //used in check on pulse and diode: tech.laserDamage === 0.16
|
||||
tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.16
|
||||
tech.laserColor = "#f00"
|
||||
tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)"
|
||||
}
|
||||
@@ -6217,7 +6254,7 @@ const tech = {
|
||||
{
|
||||
name: "diffuse beam",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Diffuser_(optics)' class="link">diffuse beam</a>`,
|
||||
description: "<strong class='color-laser'>laser</strong> beam is <strong>wider</strong> and doesn't <strong>reflect</strong><br>increase full beam <strong class='color-d'>damage</strong> by <strong>200%</strong>",
|
||||
description: "<strong class='color-laser'>laser</strong> beam is <strong>wider</strong> and doesn't <strong>reflect</strong><br>increase full beam <strong class='color-d'>damage</strong> by <strong>220%</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -6311,7 +6348,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.17 && !tech.isStuckOn
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.18 && !tech.isStuckOn
|
||||
},
|
||||
requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier",
|
||||
effect() {
|
||||
@@ -7049,7 +7086,7 @@ const tech = {
|
||||
},
|
||||
requires: "extruder",
|
||||
effect() {
|
||||
tech.extruderRange += 60
|
||||
tech.extruderRange += 55
|
||||
},
|
||||
remove() {
|
||||
tech.extruderRange = 15
|
||||
@@ -7895,6 +7932,51 @@ const tech = {
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "translate",
|
||||
description: "translate n-gon into a random language",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
isNonRefundable: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
// generate a container
|
||||
const gtElem = document.createElement('div')
|
||||
gtElem.id = "gtElem"
|
||||
gtElem.style.visibility = 'hidden' // make it invisible
|
||||
document.body.append(gtElem)
|
||||
|
||||
// generate a script to run after creation
|
||||
function initGT() {
|
||||
// create a new translate element
|
||||
new google.translate.TranslateElement({ pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL }, 'gtElem')
|
||||
// ok now since it's loaded perform a funny hack to make it work
|
||||
const langSelect = document.getElementsByClassName("goog-te-combo")[0]
|
||||
// select a random language. It takes a second for all langauges to load, so wait a second.
|
||||
setTimeout(() => {
|
||||
langSelect.selectedIndex = Math.round(langSelect.options.length * Math.random())
|
||||
// simulate a click
|
||||
langSelect.dispatchEvent(new Event('change'))
|
||||
// now make it go away
|
||||
const bar = document.getElementById(':1.container')
|
||||
bar.style.display = 'none'
|
||||
bar.style.visibility = 'hidden'
|
||||
}, 1000)
|
||||
|
||||
}
|
||||
|
||||
// add the google translate script
|
||||
const translateScript = document.createElement('script')
|
||||
translateScript.src = '//translate.google.com/translate_a/element.js?cb=initGT'
|
||||
document.body.append(translateScript)
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "discount",
|
||||
description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!",
|
||||
@@ -10223,4 +10305,5 @@ const tech = {
|
||||
isClusterExplode: null,
|
||||
isCircleExplode: null,
|
||||
isPetalsExplode: null,
|
||||
isDeathSkipTime: null
|
||||
}
|
||||
Reference in New Issue
Block a user