resonance

tech: resonance - when a block gets vibrated by phonon, it has a chance to spin towards mobs
cross disciplinary gives 4% duplication
boson composite lets you move through elevators again

JUNK tech: microtransactions - buy in-game skins for 1 research anytime you choose a tech

bug fixes
This commit is contained in:
landgreen
2022-06-30 07:35:36 -07:00
parent 5f098c3d1e
commit de99a27a29
8 changed files with 255 additions and 192 deletions

View File

@@ -918,54 +918,55 @@ const b = {
Composite.add(engine.world, bullet[me]); //add bullet to world Composite.add(engine.world, bullet[me]); //add bullet to world
bullet[me].endCycle = simulation.cycle + 70; bullet[me].endCycle = simulation.cycle + 70;
bullet[me].frictionAir = 0.07; bullet[me].frictionAir = 0.07;
bullet[me].suckCycles = 40
const MAG = 0.015 const MAG = 0.015
bullet[me].thrust = { bullet[me].thrust = {
x: bullet[me].mass * MAG * Math.cos(angle), x: bullet[me].mass * MAG * Math.cos(angle),
y: bullet[me].mass * MAG * Math.sin(angle) y: bullet[me].mass * MAG * Math.sin(angle)
} }
bullet[me].do = function() { bullet[me].suck = function() {
const suckCycles = 40 const suck = (who, radius = this.explodeRad * 3.2) => {
if (simulation.cycle > this.endCycle - suckCycles || Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) { //suck for (i = 0, len = who.length; i < len; i++) {
const that = this const sub = Vector.sub(this.position, who[i].position);
const dist = Vector.magnitude(sub);
function suck(who, radius = that.explodeRad * 3.2) { if (dist < radius && dist > 150 && !who.isInvulnerable && who[i] !== this) {
for (i = 0, len = who.length; i < len; i++) { knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
const sub = Vector.sub(that.position, who[i].position); who[i].force.x += knock.x;
const dist = Vector.magnitude(sub); who[i].force.y += knock.y;
if (dist < radius && dist > 150 && !who.isInvulnerable) {
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
who[i].force.x += knock.x;
who[i].force.y += knock.y;
}
} }
} }
let mag = 0.1 }
if (simulation.cycle > this.endCycle - 5) { let mag = 0.1
mag = -0.22 if (simulation.cycle > this.endCycle - 5) {
suck(mob, this.explodeRad * 3) mag = -0.22
suck(body, this.explodeRad * 2) suck(mob, this.explodeRad * 3)
suck(powerUp, this.explodeRad * 1.5) suck(body, this.explodeRad * 2)
suck(bullet, this.explodeRad * 1.5) suck(powerUp, this.explodeRad * 1.5)
suck([player], this.explodeRad * 1.3) suck(bullet, this.explodeRad * 1.5)
} else { suck([player], this.explodeRad * 1.3)
mag = 0.11 } else {
suck(mob, this.explodeRad * 3) mag = 0.11
suck(body, this.explodeRad * 2) suck(mob, this.explodeRad * 3)
suck(powerUp, this.explodeRad * 1.5) suck(body, this.explodeRad * 2)
suck(bullet, this.explodeRad * 1.5) suck(powerUp, this.explodeRad * 1.5)
suck([player], this.explodeRad * 1.3) suck(bullet, this.explodeRad * 1.5)
} suck([player], this.explodeRad * 1.3)
//keep bomb in place }
Matter.Body.setVelocity(this, {
x: 0, Matter.Body.setVelocity(this, { x: 0, y: 0 }); //keep bomb in place
y: 0 //draw suck
}); const radius = 2.75 * this.explodeRad * (this.endCycle - simulation.cycle) / this.suckCycles
//draw suck ctx.fillStyle = "rgba(0,0,0,0.1)";
const radius = 2.75 * this.explodeRad * (this.endCycle - simulation.cycle) / suckCycles ctx.beginPath();
ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI);
ctx.beginPath(); ctx.fill();
ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI); }
ctx.fill(); bullet[me].do = function() {
if (simulation.cycle > this.endCycle - this.suckCycles) { //suck
this.do = this.suck
} else if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
Matter.Body.setPosition(this, Vector.sub(this.position, this.velocity)) //undo last movement
this.do = this.suck
} else { } else {
this.force.x += this.thrust.x; this.force.x += this.thrust.x;
this.force.y += this.thrust.y; this.force.y += this.thrust.y;
@@ -3787,7 +3788,7 @@ const b = {
targetedBlock(who, speed = 50 - Math.min(20, who.mass * 2), range = 1600) { targetedBlock(who, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
let closestMob, dist let closestMob, dist
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (who !== mob[i]) { if (who !== mob[i] && !mob[i].isBadTarget) {
dist = Vector.magnitude(Vector.sub(who.position, mob[i].position)); dist = Vector.magnitude(Vector.sub(who.position, mob[i].position));
if (dist < range && Matter.Query.ray(map, who.position, mob[i].position).length === 0) { //&& Matter.Query.ray(body, position, mob[i].position).length === 0 if (dist < range && Matter.Query.ray(map, who.position, mob[i].position).length === 0) { //&& Matter.Query.ray(body, position, mob[i].position).length === 0
closestMob = mob[i] closestMob = mob[i]
@@ -5704,8 +5705,8 @@ const b = {
name: "matter wave", //3 name: "matter wave", //3
description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>", description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>",
ammo: 0, ammo: 0,
ammoPack: 115, ammoPack: 110,
defaultAmmoPack: 115, defaultAmmoPack: 110,
have: false, have: false,
wavePacketCycle: 0, wavePacketCycle: 0,
delay: 40, delay: 40,
@@ -5776,17 +5777,24 @@ const b = {
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position)) const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position))
const r = 20 const r = 20
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) { if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
const who = body[j]
//make them shake around //make them shake around
body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
//draw vibes //draw vibes
let vertices = body[j].vertices; let vertices = who.vertices;
const vibe = 25 const vibe = 25
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
for (let k = 1; k < vertices.length; k++) { for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5)); ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
} }
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
if (tech.isPhononBlock && !who.isNotHoldable && who.speed < 5 && who.angularSpeed < 0.1) {
if (Math.random() < 0.5) b.targetedBlock(who, 50 - Math.min(25, who.mass * 3)) // targetedBlock(who, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
// Matter.Body.setAngularVelocity(who, (0.25 + 0.1 * Math.random()) * (Math.random() < 0.5 ? -1 : 1));
who.torque += who.inertia * 0.001 * (Math.random() - 0.5)
}
} }
} }
this.waves[i].radius += 0.9 * tech.waveBeamSpeed * this.waves[i].expanding //expand / move this.waves[i].radius += 0.9 * tech.waveBeamSpeed * this.waves[i].expanding //expand / move
@@ -5881,6 +5889,12 @@ const b = {
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5)); ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
} }
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
if (tech.isPhononBlock && !who.isNotHoldable && who.speed < 5 && who.angularSpeed < 0.1) {
if (Math.random() < 0.5) b.targetedBlock(who, 50 - Math.min(25, who.mass * 3)) // targetedBlock(who, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
// Matter.Body.setAngularVelocity(who, (0.25 + 0.12 * Math.random()) * (Math.random() < 0.5 ? -1 : 1));
who.torque += who.inertia * 0.001 * (Math.random() - 0.5)
}
} }
// ctx.stroke(); //draw vibes // ctx.stroke(); //draw vibes
@@ -6005,7 +6019,7 @@ const b = {
if (tech.isPhaseVelocity) { if (tech.isPhaseVelocity) {
waveSpeedMap = 3.5 waveSpeedMap = 3.5
waveSpeedBody = 2 waveSpeedBody = 2
bullet[me].dmg *= 1.2 bullet[me].dmg *= 1.4
} }
if (tech.waveReflections) { if (tech.waveReflections) {
bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange

View File

@@ -18,18 +18,18 @@ const level = {
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.addHealth(Infinity) // m.addHealth(Infinity)
// m.setField("metamaterial cloaking") // m.setField("metamaterial cloaking")
// b.giveGuns("harpoon") // b.giveGuns("matter wave")
// b.giveGuns("shotgun") // b.giveGuns("shotgun")
// b.guns[0].ammo = 10000 // b.guns[0].ammo = 10000
// // b.giveGuns("mine") // // b.giveGuns("mine")
// tech.giveTech("boson composite") // tech.giveTech("phonon")
// for (let i = 0; i < 3; ++i) tech.giveTech("smelting") // for (let i = 0; i < 3; ++i) tech.giveTech("smelting")
// for (let i = 0; i < 9; ++i) tech.giveTech("propagator") // for (let i = 0; i < 9; ++i) tech.giveTech("propagator")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot") // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// for (let i = 0; i < 9; ++i) tech.giveTech("emergence") // for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
// tech.giveTech("polyurethane foam") // tech.giveTech("resonance")
// tech.giveTech("quantum eraser") // tech.giveTech("microtransactions")
// tech.giveTech("MACHO") // tech.giveTech("cross disciplinary")
// m.maxHealth = 100 // m.maxHealth = 100
// m.health = m.maxHealth // m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide") // for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -46,13 +46,13 @@ const level = {
// powerUps.research.changeRerolls(100) // powerUps.research.changeRerolls(100)
// spawn.starter(1900, -500, 100) // spawn.starter(1900, -500, 100)
// for (let i = 0; i < 20; ++i) spawn.exploder(1900, -500) // for (let i = 0; i < 20; ++i) spawn.exploder(1900, -500)
// spawn.timeSkipBoss(1900, -500) spawn.slashBoss(1900, -500)
// level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
// level.testing(); //not in rotation, used for testing level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); // for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech"); // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ // if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// powerUps.research.changeRerolls(3000) // powerUps.research.changeRerolls(3000)
// for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); // for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
// for (let i = 0; i < 3; i++) tech.giveTech("undefined") // for (let i = 0; i < 3; i++) tech.giveTech("undefined")
@@ -423,7 +423,7 @@ const level = {
y += height / 2 y += height / 2
const who = body[body.length] = Bodies.rectangle(x, y, width, height, { const who = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.map, category: cat.body,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
}, },
isNoSetCollision: true, isNoSetCollision: true,
@@ -455,7 +455,7 @@ const level = {
y += height / 2 y += height / 2
const who = body[body.length] = Bodies.rectangle(x, y, width, height, { const who = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.map, category: cat.body,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
}, },
isNoSetCollision: true, isNoSetCollision: true,
@@ -581,7 +581,7 @@ const level = {
force += simulation.g force += simulation.g
const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, { const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.map, category: cat.body, //cat.map,
mask: cat.map | cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet mask: cat.map | cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
}, },
isNoSetCollision: true, isNoSetCollision: true,

View File

@@ -1391,8 +1391,11 @@ const mobs = {
mob.splice(i, 1); mob.splice(i, 1);
if (tech.isMobBlockFling) { if (tech.isMobBlockFling) {
const who = body[body.length - 1] const who = body[body.length - 1]
b.targetedBlock(who) if (!who.isNotHoldable) {
Matter.Body.setAngularVelocity(who, (0.5 + 0.2 * Math.random()) * (Math.random() < 0.5 ? -1 : 1)); b.targetedBlock(who)
Matter.Body.setAngularVelocity(who, (0.5 + 0.2 * Math.random()) * (Math.random() < 0.5 ? -1 : 1));
// who.torque += who.inertia * 0.002 * (Math.random() - 0.5)
}
} }
} else { } else {
Matter.Composite.remove(engine.world, this); Matter.Composite.remove(engine.world, this);

View File

@@ -2829,8 +2829,8 @@ const m = {
if (inPlayer.length > 0) { if (inPlayer.length > 0) {
for (let i = 0; i < inPlayer.length; i++) { for (let i = 0; i < inPlayer.length; i++) {
if (m.energy > 0) { if (m.energy > 0) {
if (inPlayer[i].isUnblockable) m.energy -= 0.003; if (!inPlayer[i].isUnblockable) m.energy -= 0.004;
if (inPlayer[i].shield) m.energy -= 0.014; if (inPlayer[i].shield) m.energy -= 0.012;
} }
} }
} }
@@ -3333,7 +3333,7 @@ const m = {
} }
} }
} }
if (tech.isWormBullets) { if (tech.isWormHoleBullets) {
//teleport bullets //teleport bullets
for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2 for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots

View File

@@ -117,7 +117,6 @@ const powerUps = {
} }
}, },
totalPowerUps: 0, //used for tech that count power ups at the end of a level totalPowerUps: 0, //used for tech that count power ups at the end of a level
lastTechIndex: null,
do() {}, do() {},
setDupChance() { setDupChance() {
if (tech.duplicationChance() > 0 || tech.isAnthropicTech) { if (tech.duplicationChance() > 0 || tech.isAnthropicTech) {
@@ -249,8 +248,6 @@ const powerUps = {
m.setField(index) m.setField(index)
} else if (type === "tech") { } else if (type === "tech") {
// if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false // if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
powerUps.tech.banishList
setTimeout(() => { powerUps.lastTechIndex = index }, 10);
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>")`); simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>")`);
tech.giveTech(index) tech.giveTech(index)
} }
@@ -873,7 +870,6 @@ const powerUps = {
for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
// powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available // powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
// console.log(optionLengthNoDuplicates, options.length) // console.log(optionLengthNoDuplicates, options.length)
powerUps.tech.banishList = []
if (options.length > 0) { if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) { for (let i = 0; i < totalChoices; i++) {
if (options.length < 1) break if (options.length < 1) break
@@ -924,10 +920,19 @@ const powerUps = {
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) fieldOptions.push(i); if (i !== m.fieldMode) fieldOptions.push(i);
} }
const pick = options[Math.floor(Math.seededRandom(0, fieldOptions.length))] //pick an element from the array of options const pick = fieldOptions[Math.floor(Math.seededRandom(0, fieldOptions.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${pick})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[pick].name}</div> ${m.fieldUpgrades[pick].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${pick})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[pick].name}</div> ${m.fieldUpgrades[pick].description}</div>`
} }
} }
if (tech.isMicroTransactions && powerUps.research.count > 0) {
const skins = [] //find skins
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isSkin) skins.push(i)
}
const choose = skins[Math.floor(Math.seededRandom(0, skins.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="tech.giveTech(${choose});powerUps.research.changeRerolls(-1);powerUps.endDraft('tech');powerUps.tech.effect();"><div class="grid-title"><div class="circle-grid research"></div> <span style = 'font-size:90%; font-weight: 100; letter-spacing: -1.5px;'>microtransaction:</span> ${tech.tech[choose].name}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) { if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
tech.isBrainstormActive = true tech.isBrainstormActive = true
let count = 0 let count = 0

View File

@@ -50,9 +50,13 @@ const spawn = {
if (tech.isQuantumEraser && tech.quantumEraserCount > 0) { if (tech.isQuantumEraser && tech.quantumEraserCount > 0) {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp && mob[i].alive) { //&& !mob[i].isBoss if (mob[i].isDropPowerUp && mob[i].alive) { //&& !mob[i].isBoss
tech.isQuantumEraserDuplication = true if (mob[i].isFinalBoss) {
mob[i].death() mob[i].health = 0.66
tech.isQuantumEraserDuplication = false } else {
tech.isQuantumEraserDuplication = true
mob[i].death()
tech.isQuantumEraserDuplication = false
}
//graphics //graphics
const color = 'rgba(255,255,255, 0.8)' const color = 'rgba(255,255,255, 0.8)'
@@ -4123,6 +4127,7 @@ const spawn = {
this.seePlayer.recall && this.seePlayer.recall &&
this.cd < simulation.cycle && this.cd < simulation.cycle &&
this.distanceToPlayer2() < seeDistance2 && this.distanceToPlayer2() < seeDistance2 &&
!m.isCloak &&
Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 &&
Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0 Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0
) { ) {

View File

@@ -134,6 +134,7 @@ const tech = {
tech.giveTech(name) tech.giveTech(name)
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${name}</span>")<em>`); simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${name}</span>")<em>`);
}, },
giveTech(index = 'random') { giveTech(index = 'random') {
if (index === 'random') { if (index === 'random') {
let options = []; let options = [];
@@ -255,7 +256,7 @@ const tech = {
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
duplicationChance() { duplicationChance() {
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication) return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication)
}, },
isScaleMobsWithDuplication: false, isScaleMobsWithDuplication: false,
maxDuplicationEvent() { maxDuplicationEvent() {
@@ -2985,15 +2986,15 @@ const tech = {
}, },
{ {
name: "cross disciplinary", name: "cross disciplinary",
description: "<strong class='color-m'>tech</strong> have an extra <strong class='color-f'>field</strong> or <strong class='color-g'>gun</strong> <strong>choice</strong>", description: "<strong class='color-m'>tech</strong> have an extra <strong class='color-f'>field</strong> or <strong class='color-g'>gun</strong> <strong>choice</strong><br><strong>+5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isDeterminism return !tech.isDeterminism && tech.duplicationChance() < 1
}, },
requires: "not determinism", requires: "below 100% duplication chance not determinism",
effect: () => { effect: () => {
tech.isExtraGunField = true; tech.isExtraGunField = true;
}, },
@@ -3360,9 +3361,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.duplicationChance() < 1 && !tech.isSuperDeterminism return tech.duplicationChance() < 1.11 && !tech.isSuperDeterminism
}, },
requires: "below 100% duplication chance, not superdeterminism", requires: "below 111% duplication chance, not superdeterminism",
effect() { effect() {
tech.isCancelDuplication = true //search for tech.cancelCount to balance tech.isCancelDuplication = true //search for tech.cancelCount to balance
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
@@ -3380,9 +3381,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.duplicationChance() < 1 return tech.duplicationChance() < 1.11
}, },
requires: "below 100% duplication chance", requires: "below 111% duplication chance",
effect() { effect() {
tech.duplicateChance += 0.1 tech.duplicateChance += 0.1
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
@@ -3407,9 +3408,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.duplicationChance() < 1 return tech.duplicationChance() < 1.11
}, },
requires: "below 100% duplication chance", requires: "below 111% duplication chance",
effect: () => { effect: () => {
tech.isStimulatedEmission = true tech.isStimulatedEmission = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
@@ -3428,9 +3429,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.duplicationChance() < 1 return tech.duplicationChance() < 1.11
}, },
requires: "below 100% duplication chance", requires: "below 111% duplication chance",
effect: () => { effect: () => {
tech.isPowerUpsVanish = true tech.isPowerUpsVanish = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
@@ -4422,7 +4423,7 @@ const tech = {
// //
{ {
name: "phase velocity", name: "phase velocity",
description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br><strong>+20%</strong> matter wave <strong class='color-d'>damage</strong>", description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br><strong>+40%</strong> matter wave <strong class='color-d'>damage</strong>",
// description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>", // description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
@@ -4518,8 +4519,8 @@ const tech = {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") { if (b.guns[i].name === "matter wave") {
b.guns[i].chooseFireMethod() b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack / 9 b.guns[i].ammoPack = b.guns[i].defaultAmmoPack / 10
b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 9); b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 10);
simulation.updateGunHUD(); simulation.updateGunHUD();
break break
} }
@@ -4532,7 +4533,7 @@ const tech = {
tech.isLongitudinal = false; tech.isLongitudinal = false;
b.guns[i].chooseFireMethod() b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 9); b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 10);
simulation.updateGunHUD(); simulation.updateGunHUD();
break break
} }
@@ -4550,7 +4551,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isLongitudinal return tech.isLongitudinal && tech.haveGunCheck("matter wave")
}, },
requires: "matter wave, phonon", requires: "matter wave, phonon",
effect() { effect() {
@@ -4572,6 +4573,25 @@ const tech = {
} }
} }
}, },
{
name: "resonance",
description: "after a <strong class='color-block'>block</strong> gets vibrated by a <strong>phonon</strong><br>there is a chance it's <strong>flung</strong> at nearby mobs",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isLongitudinal && tech.haveGunCheck("matter wave")
},
requires: "matter wave, phonon",
effect() {
tech.isPhononBlock = true
},
remove() {
tech.isPhononBlock = false
}
},
{ {
name: "cruise missile", name: "cruise missile",
description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missiles</strong> speed", description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missiles</strong> speed",
@@ -7428,7 +7448,7 @@ const tech = {
}, },
{ {
name: "geodesics", name: "geodesics",
description: `your <strong>projectiles</strong> can traverse <strong class='color-worm'>wormholes</strong><br>spawn 2 <strong class='color-g'>guns</strong> and ${powerUps.orb.ammo(2)}`, description: `your <strong>projectiles</strong> can traverse <strong class='color-worm'>wormholes</strong><br>spawn 2 <strong class='color-g'>guns</strong> and ${powerUps.orb.ammo(4)}`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7439,18 +7459,16 @@ const tech = {
}, },
requires: "wormhole", requires: "wormhole",
effect() { effect() {
tech.isWormBullets = true tech.isWormHoleBullets = true
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "gun");
powerUps.spawn(m.pos.x, m.pos.y, "gun"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "ammo");
powerUps.spawn(m.pos.x, m.pos.y, "ammo");
}
}, },
remove() { remove() {
if (tech.isWormBullets) { if (tech.isWormHoleBullets) {
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) {
if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun
} }
tech.isWormBullets = false; tech.isWormHoleBullets = false;
} }
} }
}, },
@@ -8564,44 +8582,6 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "posture",
description: "stand a bit taller",
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.yOffWhen.stand = 70
},
remove() {
m.yOffWhen.stand = 49
}
},
{
name: "rhythm",
description: "you oscillate up and down",
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
isNonRefundable: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
setInterval(() => {
m.yOffWhen.stand = 53 + 28 * Math.sin(simulation.cycle * 0.2)
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand
}, 100);
},
remove() {}
},
{ {
name: "spinor", name: "spinor",
description: "the direction you aim is determined by your position", description: "the direction you aim is determined by your position",
@@ -8798,21 +8778,6 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "transparency",
description: "become invisible to yourself<br><em>mobs can still see you</em>",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
m.draw = () => {}
},
remove() {}
},
{ {
name: "quantum leap", name: "quantum leap",
description: "become an <strong class='alt'>alternate</strong> version of yourself<br>every <strong>20</strong> seconds", description: "become an <strong class='alt'>alternate</strong> version of yourself<br>every <strong>20</strong> seconds",
@@ -8950,24 +8915,6 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "ship",
description: "fly around with no legs<br>reduce combat <strong>difficulty</strong> by <strong>1 level</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
},
requires: "",
effect() {
m.shipMode()
level.difficultyDecrease(simulation.difficultyMode)
},
remove() {}
},
// { // {
// name: "lubrication", // name: "lubrication",
// description: "reduce block density and friction for this level", // description: "reduce block density and friction for this level",
@@ -9258,11 +9205,10 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isSkin: true,
isNonRefundable: true, isNonRefundable: true,
isJunk: true, isJunk: true,
allowed() { allowed() { return !m.isShipMode },
return !m.isShipMode
},
requires: "", requires: "",
effect() { effect() {
m.draw = function() { m.draw = function() {
@@ -9303,11 +9249,10 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isSkin: true,
isNonRefundable: true, isNonRefundable: true,
isJunk: true, isJunk: true,
allowed() { allowed() { return !m.isShipMode },
return !m.isShipMode
},
requires: "", requires: "",
effect() { effect() {
m.draw = function() { m.draw = function() {
@@ -9343,6 +9288,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isSkin: true,
isNonRefundable: true, isNonRefundable: true,
isJunk: true, isJunk: true,
allowed() { allowed() {
@@ -9418,12 +9364,69 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "transparency",
description: "become invisible to yourself<br><em>mobs can still see you</em>",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
m.draw = () => {}
},
remove() {}
},
{
name: "posture",
description: "stand a bit taller",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.yOffWhen.stand = 70
},
remove() {
m.yOffWhen.stand = 49
}
},
{
name: "rhythm",
description: "you oscillate up and down",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isJunk: true,
isNonRefundable: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
setInterval(() => {
m.yOffWhen.stand = 53 + 28 * Math.sin(simulation.cycle * 0.2)
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand
}, 100);
},
remove() {}
},
{ {
name: "pareidolia", name: "pareidolia",
description: "don't", description: "don't",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isSkin: true,
isNonRefundable: true, isNonRefundable: true,
isJunk: true, isJunk: true,
allowed() { allowed() {
@@ -9492,6 +9495,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isSkin: true,
isNonRefundable: true, isNonRefundable: true,
isJunk: true, isJunk: true,
allowed() { return true }, allowed() { return true },
@@ -9509,6 +9513,40 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "microtransactions",
description: `when you choose a <strong class='color-m'>tech</strong> you can<br>use ${powerUps.orb.research(1)} to buy a free in game <strong>skin</strong>`,
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
tech.isMicroTransactions = true
},
remove() {
tech.isMicroTransactions = false
}
},
{
name: "ship",
description: "fly around with no legs<br>reduce combat <strong>difficulty</strong> by <strong>1 level</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
},
requires: "",
effect() {
m.shipMode()
level.difficultyDecrease(simulation.difficultyMode)
},
remove() {}
},
{ {
name: "assimilation", name: "assimilation",
description: "all your <strong class='color-bot'>bots</strong> are converted to the <strong>same</strong> random model", description: "all your <strong class='color-bot'>bots</strong> are converted to the <strong>same</strong> random model",
@@ -10213,7 +10251,7 @@ const tech = {
isNailCrit: null, isNailCrit: null,
isFlechetteExplode: null, isFlechetteExplode: null,
isWormholeWorms: null, isWormholeWorms: null,
isWormBullets: null, isWormHoleBullets: null,
isWideLaser: null, isWideLaser: null,
wideLaser: null, wideLaser: null,
isPulseLaser: null, isPulseLaser: null,
@@ -10389,5 +10427,7 @@ const tech = {
isCritKill: null, isCritKill: null,
isQuantumEraser: null, isQuantumEraser: null,
isQuantumEraserDuplication: null, isQuantumEraserDuplication: null,
quantumEraserCount: null quantumEraserCount: null,
isPhononBlock: null,
isMicroTransactions: null
} }

View File

@@ -1,31 +1,27 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: quantum eraser - for each mob left alive after you exit a level
kill a spawning mob with 100% duplication
symbiosis: bosses spawn a tech and also an ammo, research, and heal
when mobs dies lose 0.45 -> 0.5 max health
boson composite - when you move through mobs they drain a little bit of energy
incendiary ammunition makes bullets explode on impact with map tech: resonance - when a block gets vibrated by phonon, it has a chance to spin towards mobs
polyurethane foam now works for harpoons cross disciplinary gives 4% duplication
reactor level: timeBoss is much faster, mineBoss does 50% mine more damage boson composite lets you move through elevators again
all bosses spawn fewer numbers
spawning all 4 bosses spawns much fewer numbers JUNK tech: microtransactions - buy in-game skins for 1 research anytime you choose a tech
bug fixes bug fixes
loaded a patch to matter.js physics engine 0.18 to fix issues with time dilation
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
Tech: Resonant Frequency make buying skins from microtransactions have a lasting effect with a local storage list
Whenever a block gets vibrated by phonon, it has a chance to split and flywheel towards mobs add a dropdown menu to choose in settings
maybe just one at a time
JUNK tech: doctorate JUNK tech micro transactions
You don't need an explanation of techs! Just look at the title and your scientific knowledge should come into place all tech selection menus include the option to buy skins for 1 research
Remove all tech descriptions
improve mob invincible graphic improve mob invincible graphic
opacity oscillates from 100% to 0%? opacity oscillates from 100% to 0%?
make different from stun
hopBossMom hopBossMom
spawns lots of small hopBullets spawns lots of small hopBullets