many worlds renamed to ansatz
new tech many-worlds: at the start of each new level switch realities

removed tech: electroactive polymers - convert bots to the same type on weapon swap
all bot upgrades convert current bots to the upgraded type
  only one bot upgrade allowed
This commit is contained in:
landgreen
2021-02-20 16:37:32 -08:00
parent c085b30af4
commit 10b5616460
9 changed files with 365 additions and 268 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1089,18 +1089,18 @@ const b = {
m.energy = 0;
}
b.isExtruderOn = true
const SPEED = 10
const SPEED = 8
const me = bullet.length;
const where = Vector.add(m.pos, player.velocity)
bullet[me] = Bodies.polygon(where.x + 20 * Math.cos(m.angle), where.y + 20 * Math.sin(m.angle), 4, 0.01, {
cycle: -0.5,
isWave: true,
endCycle: simulation.cycle + 10 + 40 * tech.isPlasmaRange,
endCycle: simulation.cycle + 35 + 45 * tech.isPlasmaRange,
inertia: Infinity,
frictionAir: 0,
isInHole: true, //this keeps the bullet from entering wormholes
minDmgSpeed: 0,
dmg: b.dmgScale * 1.35, //damage also changes when you divide by mob.mass on in .do()
dmg: b.dmgScale * 1.2, //damage also changes when you divide by mob.mass on in .do()
classType: "bullet",
isBranch: false,
restitution: 0,
@@ -1121,8 +1121,8 @@ const b = {
const q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
Matter.Body.setVelocity(q[i], {
x: q[i].velocity.x * 0.6,
y: q[i].velocity.y * 0.6
x: q[i].velocity.x * 0.2,
y: q[i].velocity.y * 0.2
});
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = this.dmg / Math.min(10, q[i].mass)
@@ -2226,6 +2226,55 @@ const b = {
// ******************************** Bots *********************************************
// **************************************************************************************************
// **************************************************************************************************
totalBots() {
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
},
hasBotUpgrade() {
return tech.isNailBotUpgrade + tech.isFoamBotUpgrade + tech.isBoomBotUpgrade + tech.isLaserBotUpgrade + tech.isOrbitBotUpgrade + tech.isDynamoBotUpgrade
},
convertBotsTo(type) { //type can be a string like "dynamoBotCount"
//count all bots
const totalBots = b.totalBots()
//remove all bots techs and convert them to the new type so that tech refunds work correctly
let totalTechToConvert = 0 //count how many tech need to be converted
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count && tech.tech[i].isBotTech) {
totalTechToConvert += tech.tech[i].count
tech.removeTech(i)
}
}
console.log(totalTechToConvert)
let name = ""
if (type === "nailBotCount") name = "nail-bot"
if (type === "orbitBotCount") name = "orbital-bot"
if (type === "boomBotCount") name = "boom-bot"
if (type === "laserBotCount") name = "laser-bot"
if (type === "foamBotCount") name = "foam-bot"
if (type === "dynamoBotCount") name = "dynamo-bot"
if (type === "plasmaBotCount") name = "plasma-bot"
if (type === "missileBotCount") name = "missile-bot"
//spawn tech for the correct bot type
for (let i = 0; i < totalTechToConvert; i++) tech.giveTech(name)
//remove all bots
b.zeroBotCount()
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].endCycle === Infinity) bullet[i].endCycle = 0 //don't remove temp bots
}
//set all bots to type
tech[type] = totalBots
//respawn all bots
b.respawnBots();
},
zeroBotCount() { //remove all bots
tech.dynamoBotCount = 0
tech.laserBotCount = 0
tech.nailBotCount = 0
tech.foamBotCount = 0
tech.boomBotCount = 0
tech.orbitBotCount = 0
},
respawnBots() {
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({ x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({ x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, false)
@@ -2311,61 +2360,65 @@ const b = {
// ctx.arc(this.position.x, this.position.y, 150, 0, 2 * Math.PI);
// ctx.fill();
// }
if (!((m.cycle + this.phase) % 30)) { //twice a second
if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250) { //give energy
Matter.Body.setAngularVelocity(this, this.spin)
if (this.isUpgraded) {
m.energy += 0.12
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: 8,
color: m.fieldMeterColor,
time: simulation.drawTime
});
} else {
m.energy += 0.03
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: 5,
color: m.fieldMeterColor,
time: simulation.drawTime
});
}
}
}
//check for damage
if (!m.isCloak && !m.isBodiesAsleep) { //if time dilation isn't active
const size = 33
q = Matter.Query.region(mob, {
min: {
x: this.position.x - size,
y: this.position.y - size
},
max: {
x: this.position.x + size,
y: this.position.y + size
if (!m.isBodiesAsleep) {
if (!((m.cycle + this.phase) % 30)) { //twice a second
if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250) { //give energy
Matter.Body.setAngularVelocity(this, this.spin)
if (this.isUpgraded) {
m.energy += 0.12
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: 8,
color: m.fieldMeterColor,
time: simulation.drawTime
});
} else {
m.energy += 0.03
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: 5,
color: m.fieldMeterColor,
time: simulation.drawTime
});
}
}
})
for (let i = 0; i < q.length; i++) {
Matter.Body.setAngularVelocity(this, this.spin)
// mobs.statusStun(q[i], 180)
// const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1)
const dmg = 0.5 * b.dmgScale
q[i].damage(dmg);
q[i].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: Math.log(2 * dmg + 1.1) * 40,
color: 'rgba(0,0,0,0.4)',
time: simulation.drawTime
});
}
if (!m.isCloak) { //if time dilation isn't active
const size = 33
q = Matter.Query.region(mob, {
min: {
x: this.position.x - size,
y: this.position.y - size
},
max: {
x: this.position.x + size,
y: this.position.y + size
}
})
for (let i = 0; i < q.length; i++) {
Matter.Body.setAngularVelocity(this, this.spin)
// mobs.statusStun(q[i], 180)
// const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1)
const dmg = 0.5 * b.dmgScale
q[i].damage(dmg);
q[i].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: Math.log(2 * dmg + 1.1) * 40,
color: 'rgba(0,0,0,0.4)',
time: simulation.drawTime
});
}
}
let history = m.history[(m.cycle - this.followDelay) % 600]
Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
}
let history = m.history[(m.cycle - this.followDelay) % 600]
Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
}
})
World.add(engine.world, bullet[me]); //add bullet to world
@@ -2605,7 +2658,7 @@ const b = {
}
//hit target with laser
if (this.lockedOn && this.lockedOn.alive && m.energy > this.drainThreshold) {
m.energy -= tech.laserFieldDrain * tech.isLaserDiode
m.energy -= tech.laserFieldDrain * tech.isLaserDiode * 0.7
b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.38 * tech.laserDamage + this.isUpgraded * 0.25), tech.laserReflections, false, 0.4) //tech.laserDamage = 0.16
// laser(where = {
// x: m.pos.x + 20 * Math.cos(m.angle),

View File

@@ -20,7 +20,7 @@ const level = {
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission")
// tech.giveTech("CPT reversal")
// tech.giveTech("micro-extruder")
// tech.giveTech("causality bombs")
// tech.giveTech("cardinality")
// tech.giveTech("Bayesian statistics")
@@ -110,6 +110,11 @@ const level = {
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
simulation.switchGun();
}
if (tech.isSwitchReality) {
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
m.switchWorlds()
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "tech", false);
}
},
custom() {},
customTopLayer() {},
@@ -2503,13 +2508,14 @@ const level = {
spawn.randomMob(1725, 125, 0.5);
if (simulation.difficulty > 3) {
if (Math.random() < 0.1) { // tether ball
const index = mob.length
spawn.tetherBoss(4250, 0)
cons[cons.length] = Constraint.create({
pointA: {
x: 4250,
y: -675
},
bodyB: mob[mob.length - 1],
bodyB: mob[index],
stiffness: 0.00007
});
World.add(engine.world, cons[cons.length - 1]);

View File

@@ -303,106 +303,117 @@ const m = {
}
},
alive: false,
switchWorlds() {
//count tech
const totalGuns = b.inventory.length - tech.isRewindGun //count guns, but not CPT gun
simulation.isTextLogOpen = false; //prevent console spam
//remove all tech and count current tech total
let totalTech = 0;
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isNonRefundable && tech.tech[i].name !== "quantum immortality" && tech.tech[i].name !== "many-worlds") {
totalTech += tech.tech[i].count
tech.tech[i].remove();
tech.tech[i].isLost = false
tech.tech[i].count = 0
}
}
lore.techCount = 0;
tech.removeJunkTechFromPool();
tech.removeLoreTechFromPool();
tech.addLoreTechToPool();
tech.armorFromPowerUps = 0;
tech.totalCount = 0;
//randomize health
m.health = 0.7 + Math.random()
if (m.health > 1) m.health = 1;
m.displayHealth();
//randomize field
m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
//track how ammo/ ammoPack count
let ammoCount = 0
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) ammoCount += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
}
//remove all bullets
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
//removes guns and ammo
b.inventory = [];
b.activeGun = null;
b.inventoryGun = 0;
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].have = false;
if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
}
//give random guns
for (let i = 0; i < totalGuns; i++) b.giveGuns()
//randomize ammo based on ammo/ammopack count
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.05 + 0.5 * (Math.random() - 0.5))))
}
//randomize tech
for (let i = 0; i < totalTech; i++) {
//find what tech I could get
let options = [];
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount &&
!tech.tech[i].isNonRefundable &&
tech.tech[i].name !== "quantum immortality" &&
tech.tech[i].name !== "many-worlds" &&
tech.tech[i].name !== "Born rule" &&
tech.tech[i].name !== "determinism" &&
tech.tech[i].allowed()
) options.push(i);
}
//add a new tech from options pool
if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)])
}
simulation.makeGunHUD(); //update gun HUD
simulation.updateTechHUD();
simulation.isTextLogOpen = true;
},
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
simulation.isTextLogOpen = false;
//count tech
let totalTech = 0;
//remove immortality tech
for (let i = 0; i < tech.tech.length; i++) {
if (!tech.tech[i].isNonRefundable) totalTech += tech.tech[i].count
}
if (tech.isDeterminism) totalTech -= 3 //remove the bonus tech
if (tech.isSuperDeterminism) totalTech -= 2 //remove the bonus tech
totalTech = totalTech * 1.15 + 1 // a few extra to make it stronger
const totalGuns = b.inventory.length //count guns
function randomizeTech() {
for (let i = 0; i < totalTech; i++) {
//find what tech I don't have
let options = [];
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount &&
!tech.tech[i].isNonRefundable &&
tech.tech[i].name !== "quantum immortality" &&
tech.tech[i].name !== "Born rule" &&
tech.tech[i].allowed()
) options.push(i);
}
//add a new tech
if (options.length > 0) {
const choose = Math.floor(Math.random() * options.length)
let newTech = options[choose]
tech.giveTech(newTech)
options.splice(choose, 1);
}
}
simulation.updateTechHUD();
}
function randomizeField() {
m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
}
function randomizeHealth() {
m.health = 0.7 + Math.random()
if (m.health > 1) m.health = 1;
m.displayHealth();
}
function randomizeGuns() {
//removes guns and ammo
b.inventory = [];
b.activeGun = null;
b.inventoryGun = 0;
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].have = false;
if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
}
//give random guns
for (let i = 0; i < totalGuns; i++) b.giveGuns()
//randomize ammo
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) {
b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(6 * b.guns[b.inventory[i]].ammo * Math.sqrt(Math.random())))
}
}
simulation.makeGunHUD(); //update gun HUD
if (tech.tech[i].name === "quantum immortality") tech.removeTech(i)
}
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function randomizeEverything() {
spawn.setSpawnList(); //new mob types
simulation.clearNow = true; //triggers a map reset
tech.setupAllTech(); //remove all tech
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove all bullets
randomizeHealth()
randomizeField()
randomizeGuns()
randomizeTech()
}
randomizeEverything()
spawn.setSpawnList(); //new mob types
simulation.clearNow = true; //triggers a map reset
m.switchWorlds()
const swapPeriod = 1000
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function() {
randomizeEverything()
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
spawn.setSpawnList(); //new mob types
simulation.clearNow = true; //triggers a map reset
m.switchWorlds()
simulation.isTextLogOpen = true;
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len-i-1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// pixelWindows()
}
}, (i + 1) * swapPeriod);
}
setTimeout(function() {
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
@@ -410,7 +421,6 @@ const m = {
simulation.isTextLogOpen = true;
simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
}, 6 * swapPeriod);
} else if (m.alive) { //normal death code here
m.alive = false;
simulation.paused = true;
@@ -482,7 +492,7 @@ const m = {
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
if (tech.isBotArmor) dmg *= 0.94 ** tech.totalBots()
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34
if (tech.energyRegen === 0) dmg *= 0.34
@@ -1163,7 +1173,7 @@ const m = {
//draw electricity
const step = 40
ctx.beginPath();
for (let i = 0, len = 2.5 * tech.blockDmg; i < len; i++) {
for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) {
let x = m.pos.x - 20 * unit.x;
let y = m.pos.y - 20 * unit.y;
ctx.moveTo(x, y);
@@ -1180,7 +1190,7 @@ const m = {
m.drawHold(who);
}
// if (tech.isFreezeMobs) mobs.statusSlow(who, 60) //this works but doesn't have a fun effect
if (tech.isStunField) mobs.statusStun(who, tech.isStunField)
// m.holdingTarget = null
//knock backs
if (m.fieldShieldingScale > 0) {
@@ -1202,7 +1212,6 @@ const m = {
});
}
} else {
if (tech.isStunField && m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, tech.isStunField)
// mobs.statusSlow(who, tech.isStunField)
const massRoot = Math.sqrt(Math.max(0.15, who.mass)); // masses above 12 can start to overcome the push back
Matter.Body.setVelocity(who, {

View File

@@ -94,7 +94,7 @@ const powerUps = {
}
}
if (tech.isRerollBots) {
const limit = 5
const limit = 4
for (; powerUps.research.count > limit - 1; powerUps.research.count -= limit) {
b.randomBot()
if (tech.renormalization) {
@@ -462,7 +462,7 @@ const powerUps = {
}
// console.log(powerUps.gun.choiceLog)
// console.log(choice1, choice2, choice3)
if (tech.isOneGun) text += `<div style = "color: #f24">replaces your current gun</div>`
if (tech.isOneGun && b.inventory.length > 0) text += `<div style = "color: #f24">replaces your current gun</div>`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {

View File

@@ -362,26 +362,6 @@ const simulation = {
b.activeGun = b.inventory[b.inventoryGun];
simulation.updateGunHUD();
simulation.boldActiveGunHUD();
if (tech.isBotSwap) {
//get total count
const countPermanent = tech.dynamoBotCount + tech.laserBotCount + tech.nailBotCount + tech.foamBotCount + tech.boomBotCount + tech.orbitBotCount
//remove all bots
tech.dynamoBotCount = 0
tech.laserBotCount = 0
tech.nailBotCount = 0
tech.foamBotCount = 0
tech.boomBotCount = 0
tech.orbitBotCount = 0
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].endCycle === Infinity) bullet[i].endCycle = 0 //don't remove temp bots
}
//set to a new type
options = [() => { tech.laserBotCount = countPermanent }, () => { tech.nailBotCount = countPermanent }, () => { tech.foamBotCount = countPermanent }, () => { tech.boomBotCount = countPermanent }, () => { tech.orbitBotCount = countPermanent }, () => { tech.dynamoBotCount = countPermanent }, ]
options[tech.botSwapCycleIndex]()
tech.botSwapCycleIndex++
if (tech.botSwapCycleIndex > options.length - 1) tech.botSwapCycleIndex = 0
b.respawnBots()
}
},
zoom: null,
zoomScale: 1000,

View File

@@ -82,6 +82,7 @@ const spawn = {
}
}
},
randomLevelBoss(x, y, options = ["orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
@@ -1355,7 +1356,7 @@ const spawn = {
me.isBoss = true;
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.accelMag = 0.00022 * Math.sqrt(simulation.accelScale);
me.accelMag = 0.00018 * Math.sqrt(simulation.accelScale);
me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale);
me.memory = 420;
me.restitution = 1;
@@ -1467,7 +1468,7 @@ const spawn = {
// hitting player
if (best.who === player) {
if (m.immuneCycle < m.cycle) {
const dmg = 0.001 * simulation.dmgScale;
const dmg = 0.002 * simulation.dmgScale;
m.damage(dmg);
//draw damage
ctx.fillStyle = color;
@@ -1477,9 +1478,7 @@ const spawn = {
}
}
//draw beam
if (best.dist2 === Infinity) {
best = look;
}
if (best.dist2 === Infinity) best = look;
ctx.beginPath();
ctx.moveTo(this.vertices[1].x, this.vertices[1].y);
ctx.lineTo(best.x, best.y);
@@ -1948,11 +1947,20 @@ const spawn = {
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.01;
me.memory = Infinity;
// me.memory = 300;
// Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001
me.collisionFilter.mask = cat.player | cat.bullet
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 150 + 250 * Math.random(), 1)
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
const speed = (0.007 + 0.003 * Math.random() + 0.004 * Math.sqrt(simulation.difficulty))
let radiusOrbitals = radius + 125 + 350 * Math.random()
for (let i = 0; i < len; i++) spawn.orbital(me, radiusOrbitals, i / len * 2 * Math.PI, speed)
radiusOrbitals = radius + 125 + 350 * Math.random()
for (let i = 0; i < len; i++) spawn.orbital(me, radiusOrbitals, i / len * 2 * Math.PI, -speed)
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
@@ -2570,8 +2578,8 @@ const spawn = {
me.memory = 20;
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
setTimeout(() => { spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random()) }, 100); //have to wait a sec so the tether constraint doesn't attach to an orbital
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
this.removeCons(); //remove constraint
@@ -2677,7 +2685,7 @@ const spawn = {
},
orbital(who, radius, phase, speed) {
// for (let i = 0, len = 7; i < len; i++) spawn.orbital(me, radius + 250, 2 * Math.PI / len * i)
mobs.spawn(0, 0, 8, 12, "rgb(255,0,150)");
mobs.spawn(who.position.x, who.position.y, 8, 12, "rgb(255,0,150)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
// Matter.Body.setDensity(me, 0.00004); //normal is 0.001
@@ -2701,11 +2709,10 @@ 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.damage(0.1 * simulation.dmgScale);
if (Matter.Query.collides(this, [player]).length > 0 && !m.isCloak) {
m.damage(0.035 * simulation.dmgScale);
this.death();
}
};
},
orbitalBoss(x, y, radius = 88) {

View File

@@ -46,7 +46,7 @@
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})` //give it a unique name so it can be found
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() {
@@ -127,7 +127,7 @@
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.isBotDamage) dmg *= 1 + 0.06 * tech.totalBots()
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
@@ -144,9 +144,6 @@
spawn.randomLevelBoss(m.pos.x, m.pos.y - range, bossOptions);
}
},
totalBots() {
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
},
tech: [{
name: "integrated armament",
description: `increase <strong class='color-d'>damage</strong> by <strong>25%</strong><br>your inventory can only hold 1 <strong class='color-g'>gun</strong>`,
@@ -158,7 +155,6 @@
requires: "no more than 1 gun",
effect() {
tech.isOneGun = true;
//
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].name === "CPT gun") tech.tech[i].description = `adds the <strong>CPT</strong> <strong class='color-g'>gun</strong> to your inventory<br>it <strong>rewinds</strong> your <strong class='color-h'>health</strong>, <strong>velocity</strong>, and <strong>position</strong><br><div style = 'color: #f24'>replaces your current gun</div>`
}
@@ -710,7 +706,7 @@
maxCount: 1,
count: 0,
allowed() {
return (tech.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
return (b.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
},
requires: "drones, spores, mines, or bots",
effect() {
@@ -742,7 +738,7 @@
maxCount: 3,
count: 0,
allowed() {
return tech.totalBots() > 0 && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob
return b.totalBots() > 0 && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob
},
requires: "a bot and no other mob death tech",
effect() {
@@ -757,6 +753,7 @@
description: "a <strong class='color-bot'>bot</strong> fires <strong>nails</strong> at mobs in line of sight",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return true
},
@@ -771,15 +768,16 @@
},
{
name: "nail-bot upgrade",
description: "<strong>500%</strong> increased <strong> fire rate</strong><br><em>applies to all current and future <strong class='color-bot'>nail-bots</strong></em>",
description: "<strong>convert</strong> all your permanent bots to <strong>nail-bots</strong><br><strong>500%</strong> increased nail-bot <strong>fire rate</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.nailBotCount > 1
return tech.nailBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more nail bots",
requires: "2 or more nail bots and only 1 bot upgrade",
effect() {
tech.isNailBotUpgrade = true
b.convertBotsTo("nailBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'nail') bullet[i].isUpgraded = true
}
@@ -796,6 +794,7 @@
description: "a <strong class='color-bot'>bot</strong> fires <strong>foam</strong> at nearby mobs",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return true
},
@@ -810,15 +809,16 @@
},
{
name: "foam-bot upgrade",
description: "<strong>250%</strong> increased <strong>foam</strong> <strong>size</strong> and <strong>fire rate</strong><br><em>applies to all current and future <strong class='color-bot'>foam-bots</strong></em>",
description: "<strong>convert</strong> all your permanent bots to <strong>foam-bots</strong><br><strong>250%</strong> increased foam-bot <strong>size</strong> and <strong>fire rate</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.foamBotCount > 1
return tech.foamBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more foam bots",
requires: "2 or more foam bots and only 1 bot upgrade",
effect() {
tech.isFoamBotUpgrade = true
b.convertBotsTo("foamBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'foam') bullet[i].isUpgraded = true
}
@@ -835,6 +835,7 @@
description: "a <strong class='color-bot'>bot</strong> <strong>defends</strong> the space around you<br>ignites an <strong class='color-e'>explosion</strong> after hitting a mob",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return true
},
@@ -849,15 +850,16 @@
},
{
name: "boom-bot upgrade",
description: "<strong>250%</strong> increased <strong class='color-e'>explosion</strong> <strong class='color-d'>damage</strong> and size<br><em>applies to all current and future <strong class='color-bot'>boom-bots</strong></em>",
description: "<strong>convert</strong> all your permanent bots to <strong>boom-bots</strong><br><strong>250%</strong> increased <strong class='color-e'>explosion</strong> <strong class='color-d'>damage</strong> and size",
maxCount: 1,
count: 0,
allowed() {
return tech.boomBotCount > 1
return tech.boomBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more boom bots",
requires: "2 or more boom bots and only 1 bot upgrade",
effect() {
tech.isBoomBotUpgrade = true
b.convertBotsTo("boomBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'boom') bullet[i].isUpgraded = true
}
@@ -874,6 +876,7 @@
description: "a <strong class='color-bot'>bot</strong> uses <strong class='color-f'>energy</strong> to emit a <strong class='color-laser'>laser</strong> beam<br>that targets nearby mobs",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return m.maxEnergy > 0.5
},
@@ -888,15 +891,16 @@
},
{
name: "laser-bot upgrade",
description: "<strong>400%</strong> increased <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong><br><em>applies to all current and future <strong class='color-bot'>laser-bots</strong></em>",
description: "<strong>convert</strong> all your permanent bots to <strong>laser-bots</strong><br><strong>400%</strong> increased <strong>laser-bot</strong> <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.laserBotCount > 1
return tech.laserBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more laser bots",
requires: "2 or more laser bots and only 1 bot upgrade",
effect() {
tech.isLaserBotUpgrade = true
b.convertBotsTo("laserBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'laser') bullet[i].isUpgraded = true
}
@@ -913,6 +917,7 @@
description: "a <strong class='color-bot'>bot</strong> is locked in <strong>orbit</strong> around you<br><strong>stuns</strong> and <strong class='color-d'>damages</strong> mobs on <strong>contact</strong>",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return true
},
@@ -927,15 +932,16 @@
},
{
name: "orbital-bot upgrade",
description: "increase <strong class='color-d'>damage</strong> by <strong>200%</strong> and <strong>radius</strong> by <strong>30%</strong><br><em>applies to all current and future <strong class='color-bot'>orbit-bots</strong></em>",
description: "<strong>convert</strong> all your permanent bots to <strong>orbital-bots</strong><br>increase <strong class='color-d'>damage</strong> by <strong>200%</strong> and <strong>radius</strong> by <strong>30%</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.orbitBotCount > 1
return tech.orbitBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more orbital bots",
requires: "2 or more orbital bots and only 1 bot upgrade",
effect() {
tech.isOrbitBotUpgrade = true
b.convertBotsTo("orbitBotCount")
const range = 190 + 60 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
@@ -962,6 +968,7 @@
description: "a <strong class='color-bot'>bot</strong> <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>regen <strong>6</strong> <strong class='color-f'>energy</strong> per second when it's near",
maxCount: 9,
count: 0,
isBotTech: true,
allowed() {
return true
},
@@ -976,15 +983,16 @@
},
{
name: "dynamo-bot upgrade",
description: "<strong class='color-bot'>dynamo-bots</strong> <strong>regen</strong> <strong>24</strong> <strong class='color-f'>energy</strong> per second<br><em>applies to all current and future dynamo-bots</em>",
description: "<strong>convert</strong> your permanent bots to <strong>dynamo-bots</strong><br>dynamo-bots <strong>regen</strong> <strong>24</strong> <strong class='color-f'>energy</strong> per second",
maxCount: 1,
count: 0,
allowed() {
return tech.dynamoBotCount > 1
return tech.dynamoBotCount > 1 && !b.hasBotUpgrade()
},
requires: "2 or more dynamo bots",
requires: "2 or more dynamo bots and only 1 bot upgrade",
effect() {
tech.isDynamoBotUpgrade = true
b.convertBotsTo("dynamoBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'dynamo') bullet[i].isUpgraded = true
}
@@ -1014,33 +1022,13 @@
tech.isRerollBots = false;
}
},
{
name: "electroactive polymers",
description: "build <strong>2</strong> random <strong class='color-bot'>bots</strong><br><strong>switching</strong> <strong>guns</strong> cycles <strong class='color-bot'>bots</strong> to the <strong>same</strong> type",
maxCount: 1,
isNonRefundable: true,
count: 0,
allowed() {
return tech.totalBots() > 2 && b.inventory.length > 1
},
requires: "at least 3 bots and 2 guns",
effect() {
tech.isBotSwap = true
b.randomBot()
b.randomBot()
},
remove() {
tech.isBotSwap = false
tech.botSwapCycleIndex = 0
}
},
{
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>",
maxCount: 1,
count: 0,
allowed() {
return tech.totalBots() > 3 && !tech.isEnergyHealth
return b.totalBots() > 3 && !tech.isEnergyHealth
},
requires: "at least 4 bots",
effect() {
@@ -1055,7 +1043,7 @@
maxCount: 1,
count: 0,
allowed() {
return tech.totalBots() > 3
return b.totalBots() > 3
},
requires: "at least 4 bots",
effect() {
@@ -1073,7 +1061,7 @@
isNonRefundable: true,
isExperimentHide: true,
allowed() {
return tech.totalBots() > 3
return b.totalBots() > 3
},
requires: "at least 4 bots",
effect() {
@@ -1836,6 +1824,22 @@
tech.isImmortal = false;
}
},
{
name: "many-worlds",
description: "on each new <strong>level</strong> enter an <strong>alternate reality</strong><br> find <strong>2</strong> <strong class='color-m'>tech</strong> power ups in that reality",
maxCount: 1,
count: 0,
allowed() {
return tech.isImmortal
},
requires: "quantum immortality",
effect() {
tech.isSwitchReality = true;
},
remove() {
tech.isSwitchReality = false;
}
},
{
name: "bubble fusion",
description: "after destroying a mob's <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
@@ -2096,9 +2100,9 @@
isExperimentHide: true,
count: 0,
allowed() {
return powerUps.research.count === 0 && level.onLevel < 6
return level.onLevel < 8 && level.onLevel > 0
},
requires: "no research, and in the first 5 levels",
requires: "between levels 1 and 7",
effect() {
level.difficultyDecrease(simulation.difficultyMode)
simulation.makeTextLog(`simulation.difficultyMode<span class='color-symbol'>--</span>`)
@@ -2183,7 +2187,7 @@
}
},
{
name: "many-worlds",
name: "ansatz",
description: "after choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>if you have no <strong class='color-r'>research</strong> spawn <strong>2</strong>",
maxCount: 1,
count: 0,
@@ -2306,7 +2310,7 @@
maxCount: 1,
count: 0,
allowed() {
return (tech.totalBots() > 5 || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth && !tech.isRewindAvoidDeath //build.isExperimentSelection ||
return (b.totalBots() > 5 || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth && !tech.isRewindAvoidDeath //build.isExperimentSelection ||
},
requires: "bots > 5, plasma torch, nano-scale, pilot wave, not mass-energy equivalence, CPT",
effect() {
@@ -2933,6 +2937,7 @@
isGunTech: true,
maxCount: 1,
count: 0,
isBotTech: true,
allowed() {
return tech.haveGunCheck("missiles")
},
@@ -3597,7 +3602,7 @@
},
requires: "standing wave harmonics",
effect() {
tech.blockDmg += 0.75 //if you change this value also update the for loop in the electricity graphics in m.pushMass
tech.blockDmg += 1.25 //if you change this value also update the for loop in the electricity graphics in m.pushMass
},
remove() {
tech.blockDmg = 0;
@@ -3605,7 +3610,7 @@
},
{
name: "frequency resonance",
description: "<strong>standing wave harmonics</strong> shield is retuned<br>increase <strong>size</strong> and <strong>blocking</strong> efficiency by <strong>40%</strong>",
description: "<strong>standing wave harmonics</strong> shield is retuned<br>increase <strong>size</strong> and <strong>blocking</strong> efficiency by <strong>50%</strong>",
isFieldTech: true,
maxCount: 9,
count: 0,
@@ -3614,8 +3619,8 @@
},
requires: "standing wave harmonics",
effect() {
m.fieldRange += 175 * 0.2
m.fieldShieldingScale *= 0.55
m.fieldRange += 175 * 0.25
m.fieldShieldingScale *= 0.5
},
remove() {
m.fieldRange = 175;
@@ -3624,38 +3629,21 @@
},
{
name: "flux pinning",
description: "blocking with <strong>perfect diamagnetism</strong><br><strong>stuns</strong> mobs for <strong>+1</strong> second",
description: "blocking with your <strong>field</strong><br><strong>stuns</strong> mobs for <strong>+2</strong> second",
isFieldTech: true,
maxCount: 9,
count: 0,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing"
},
requires: "perfect diamagnetism",
requires: "a field that can block",
effect() {
tech.isStunField += 60;
tech.isStunField += 120;
},
remove() {
tech.isStunField = 0;
}
},
{
name: "eddy current brake",
description: "your stored <strong class='color-f'>energy</strong> projects a field that<br>limits the <strong>top speed</strong> of mobs",
isFieldTech: true,
maxCount: 1,
count: 0,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
},
requires: "perfect diamagnetism",
effect() {
tech.isPerfectBrake = true;
},
remove() {
tech.isPerfectBrake = false;
}
},
{
name: "fracture analysis",
description: "bullet impacts do <strong>400%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> mobs",
@@ -3673,6 +3661,23 @@
tech.isCrit = false;
}
},
{
name: "eddy current brake",
description: "your stored <strong class='color-f'>energy</strong> projects a field that<br>limits the <strong>top speed</strong> of mobs",
isFieldTech: true,
maxCount: 1,
count: 0,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
},
requires: "perfect diamagnetism",
effect() {
tech.isPerfectBrake = true;
},
remove() {
tech.isPerfectBrake = false;
}
},
{
name: "pair production",
description: "picking up a <strong>power up</strong> gives you <strong>250</strong> <strong class='color-f'>energy</strong>",
@@ -3955,6 +3960,7 @@
isFieldTech: true,
maxCount: 1,
count: 0,
isBotTech: true,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
},
@@ -4323,6 +4329,46 @@
// },
// remove() {}
// },
{
name: "sliders",
description: "become an alternate version of yourself<br>every <strong>20</strong> seconds",
maxCount: 1,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isExperimentHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
setInterval(() => {
m.switchWorlds()
}, 20000); //every 30 sections
},
remove() {}
},
{
name: "pop-ups",
description: "sign up to learn endless easy ways to win n-gon<br>that landgreen doesn't want you to know about!!!1!!",
maxCount: 1,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isExperimentHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
setInterval(() => {
alert(`The best combo is <strong>${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}</strong> with <strong>${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}</strong>!`);
}, 30000); //every 30 sections
},
remove() {}
},
{
name: "music",
description: "add music to n-gon",
@@ -4882,11 +4928,11 @@
isExperimentHide: true,
isJunk: true,
allowed() {
return tech.totalBots() > 2
return b.totalBots() > 2
},
requires: "at least 3 bots",
effect() {
const total = tech.totalBots();
const total = b.totalBots();
tech.dynamoBotCount = 0;
tech.nailBotCount = 0;
tech.laserBotCount = 0;
@@ -5258,8 +5304,7 @@
isBlockPowerUps: null,
isBlockHarm: null,
foamFutureFire: null,
isBotSwap: null,
botSwapCycleIndex: null,
isDamageAfterKill: null,
isHarmReduceAfterKill: null
isHarmReduceAfterKill: null,
isSwitchReality: null
}

View File

@@ -1,13 +1,11 @@
******************************************************** NEXT PATCH ********************************************************
mob effect: freeze - now only slows mobs down
all freeze effects are about 50% longer
many worlds renamed to ansatz
new tech many-worlds: at the start of each new level switch realities
junk tech: music - adds background music to n-gon
junk tech: performance - adds fps tracker to n-gon
tech: dormancy - if a mob has died in the last 5 seconds increase damage by 50% else decrease damage by 50%
tech: torpor - if a mob has died in the last 5 seconds reduce harm by 66% else increase harm by 33%
removed tech: electroactive polymers - convert bots to the same type on weapon swap
all bot upgrades convert current bots to the upgraded type
only one bot upgrade allowed
******************************************************** BUGS ********************************************************
@@ -37,7 +35,6 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
decrease healing effects by 50%
decrease level scaling healing reduction
net effect: healing at difficulty 40 (level 10 hard) should be 25% higher then current levels
@@ -373,7 +370,7 @@ n-gon outreach ideas
******************************************************** LORE ********************************************************
cool names for tech
strange loop, ansatz, perturbation theory
strange loop, perturbation theory
voice singing with pitch?