diff --git a/.DS_Store b/.DS_Store
index e9600d7..36d56b8 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 8e83493..796fe50 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -3612,10 +3612,10 @@ const b = {
name: "wave beam",
description: "emit a wave packet of oscillating particles
that propagate through solids",
ammo: 0,
- ammoPack: 75,
+ ammoPack: 80,
have: false,
wavePacketCycle: 0,
- delay: 45,
+ delay: 40,
do() {
if (this.wavePacketCycle && !input.fire) {
this.wavePacketCycle = 0;
@@ -3634,7 +3634,7 @@ const b = {
inertia: Infinity,
frictionAir: 0,
slow: 0,
- amplitude: (m.crouch ? 10 : 20) * Math.sin(this.wavePacketCycle * tech.wavePacketFrequency) * ((this.wavePacketCycle % 2) ? -1 : 1),
+ amplitude: (m.crouch ? 5 : 10) * Math.sin(this.wavePacketCycle * tech.wavePacketFrequency) * ((this.wavePacketCycle % 2) ? -1 : 1),
minDmgSpeed: 0,
dmg: b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage, //also control damage when you divide by mob.mass
classType: "bullet",
diff --git a/js/engine.js b/js/engine.js
index 0668ee0..bea675a 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -123,6 +123,12 @@ function collisionChecks(event) {
} else {
m.damage(dmg); //normal damage
}
+
+ if (tech.isCollisionRealitySwitch) {
+ m.switchWorlds()
+ simulation.trails()
+ simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
+ }
if (tech.isPiezo) m.energy += 20.48;
if (tech.isBayesian) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(k);
@@ -158,51 +164,17 @@ function collisionChecks(event) {
time: simulation.drawTime
});
}
- return;
+ // return;
// }
- }
- //mob + bullet collisions
- if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
- obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
- let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
- if (tech.isCrit && mob[k].isStunned) dmg *= 4
- mob[k].foundPlayer();
- mob[k].damage(dmg);
- simulation.drawList.push({ //add dmg to draw queue
- x: pairs[i].activeContacts[0].vertex.x,
- y: pairs[i].activeContacts[0].vertex.y,
- radius: Math.log(2 * dmg + 1.1) * 40,
- color: simulation.playerDmgColor,
- time: simulation.drawTime
- });
- return;
- }
- //mob + body collisions
- if (obj.classType === "body" && obj.speed > 6) {
- const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
- if (v > 9) {
- let dmg = 0.075 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
- if (mob[k].isShielded) dmg *= 0.6
- mob[k].damage(dmg, true);
- if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp) {
- let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
- if (Math.random() < 0.4) {
- type = "heal"
- } else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
- type = "research"
- }
- powerUps.spawn(mob[k].position.x, mob[k].position.y, type);
- // for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {}
- }
-
- const stunTime = dmg / Math.sqrt(obj.mass)
- if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
- if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
- if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
- obj.hasFragmented = true;
- b.targetedNail(obj.position, tech.fragments * 4)
- }
- simulation.drawList.push({
+ } else {
+ //mob + bullet collisions
+ if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
+ obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
+ let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
+ if (tech.isCrit && mob[k].isStunned) dmg *= 4
+ mob[k].foundPlayer();
+ mob[k].damage(dmg);
+ simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
radius: Math.log(2 * dmg + 1.1) * 40,
@@ -211,6 +183,41 @@ function collisionChecks(event) {
});
return;
}
+ //mob + body collisions
+ if (obj.classType === "body" && obj.speed > 6) {
+ const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
+ if (v > 9) {
+ let dmg = 0.075 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
+ if (mob[k].isShielded) dmg *= 0.6
+ mob[k].damage(dmg, true);
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp) {
+ let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
+ if (Math.random() < 0.4) {
+ type = "heal"
+ } else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
+ type = "research"
+ }
+ powerUps.spawn(mob[k].position.x, mob[k].position.y, type);
+ // for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {}
+ }
+
+ const stunTime = dmg / Math.sqrt(obj.mass)
+ if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
+ if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
+ if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
+ obj.hasFragmented = true;
+ b.targetedNail(obj.position, tech.fragments * 4)
+ }
+ simulation.drawList.push({
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: Math.log(2 * dmg + 1.1) * 40,
+ color: simulation.playerDmgColor,
+ time: simulation.drawTime
+ });
+ return;
+ }
+ }
}
}
}
diff --git a/js/level.js b/js/level.js
index 0654d44..00df9a5 100644
--- a/js/level.js
+++ b/js/level.js
@@ -19,22 +19,10 @@ const level = {
// b.giveGuns("wave beam")
// tech.isExplodeRadio = true
// tech.giveTech("phase velocity")
- // for (let i = 0; i < 9; i++) tech.giveTech("packet length")
+ // for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state")
- // for (let i = 0; i < 9; i++) tech.giveTech("propagation")
- // for (let i = 0; i < 9; i++) tech.giveTech("amplitude")
- // tech.isExplodeRadio = true;
-
- // tech.isMineSentry = true
- // for (let i = 0; i < 60; i++) tech.giveTech("rivet diameter")
- // tech.giveTech("missile-bot")
- // for (let i = 0; i < 5; i++)
- // tech.giveTech("nail-bot")
- // for (let i = 0; i < 54; i++) tech.giveTech("foam-bot")
- // for (let i = 0; i < 15; i++) tech.giveTech("plasma jet")
- // tech.isBlockPowerUps = true;
- // m.shipMode()
- // tech.isBotSwap = true;
+ // for (let i = 0; i < 3; i++) tech.giveTech("propagation")
+ // for (let i = 0; i < 1; i++) tech.giveTech("amplitude")
level.intro(); //starting level
// level.testing(); //not in rotation
diff --git a/js/player.js b/js/player.js
index 1ec7154..f117160 100644
--- a/js/player.js
+++ b/js/player.js
@@ -335,7 +335,8 @@ const m = {
if (
!tech.tech[i].isNonRefundable &&
tech.tech[i].name !== "many-worlds" &&
- tech.tech[i].name !== "Ψ(t) collapse"
+ tech.tech[i].name !== "Ψ(t) collapse" &&
+ tech.tech[i].name !== "non-unitary operator"
) {
totalTech += tech.tech[i].count
tech.tech[i].remove();
diff --git a/js/powerup.js b/js/powerup.js
index b42fd14..e313e9b 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -18,9 +18,9 @@ const powerUps = {
} else if (type === "tech") {
setTimeout(() => {
powerUps.lastTechIndex = index
- }, 100);
- tech.giveTech(index)
+ }, 10);
simulation.makeTextLog(`tech.giveTech("${tech.tech[index].name}")`);
+ tech.giveTech(index)
}
powerUps.endDraft(type);
},
@@ -532,7 +532,7 @@ const powerUps = {
powerUps.spawn(x, y, "gun");
return;
}
- if (Math.random() < 0.0027 * (25 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 25
+ if (Math.random() < 0.0027 * (22 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 25
powerUps.spawn(x, y, "tech");
return;
}
diff --git a/js/spawn.js b/js/spawn.js
index 011a0f2..fcdf5a6 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -701,8 +701,8 @@ const spawn = {
}
me.onHit = function() { //run this function on hitting player
powerUps.ejectTech()
- powerUps.spawn(m.pos.x, m.pos.y, "heal");
- powerUps.spawn(m.pos.x, m.pos.y, "heal");
+ powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "ammo");
+ powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "research");
};
me.onDeath = function() {
this.leaveBody = false;
diff --git a/js/tech.js b/js/tech.js
index e2440e7..ddd5ab1 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -2488,7 +2488,7 @@
allowed() {
return !tech.isSwitchReality && !tech.isResearchReality && tech.isDeathAvoid
},
- requires: "anthropic principle, not many-worlds, perturbation theory",
+ requires: "anthropic principle, not many-worlds, Ψ(t) collapse",
effect() {
tech.isImmortal = true;
// for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
@@ -2507,7 +2507,7 @@
allowed() {
return !tech.isImmortal && !tech.isResearchReality && level.onLevel < 6
},
- requires: "before level 6, not quantum immortality, perturbation theory",
+ requires: "before level 6, not quantum immortality, Ψ(t) collapse",
effect() {
tech.isSwitchReality = true;
},
@@ -2515,9 +2515,31 @@
tech.isSwitchReality = false;
}
},
+ {
+ name: "non-unitary operator",
+ description: "after a collision enter an alternate reality
reduce combat difficulty by 2 levels",
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ allowed() {
+ return !tech.isImmortal && !tech.isResearchReality
+ },
+ requires: "not quantum immortality, Ψ(t) collapse",
+ effect() {
+ tech.isCollisionRealitySwitch = true;
+ level.difficultyDecrease(simulation.difficultyMode * 2)
+ },
+ remove() {
+ tech.isCollisionRealitySwitch = false;
+ if (this.count > 0) {
+ level.difficultyIncrease(simulation.difficultyMode * 2)
+ }
+ }
+ },
{
name: "Ψ(t) collapse",
- description: "enter an alternate reality after you research
spawn 11 research",
+ description: "enter an alternate reality after you research
spawn 12 research",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2528,7 +2550,7 @@
requires: "not quantum immortality, many-worlds",
effect() {
tech.isResearchReality = true;
- for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
+ for (let i = 0; i < 12; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
},
remove() {
tech.isResearchReality = false;
@@ -2908,7 +2930,7 @@
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
- requires: "at least 1 tech and 1 research, a chance to duplicate power ups",
+ requires: "at least 1 tech and 2 research, a chance to duplicate power ups",
effect: () => {
powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`m.research -= 2
@@ -3007,25 +3029,37 @@
}
},
+
+ // allowed() {
+ // return (b.totalBots() > 1 && powerUps.research.count > 0) || build.isExperimentSelection
+ // },
+ // requires: "at least 2 bots, 1 research",
+ // effect: () => {
+ // if (powerUps.research.count > 0) {
+ // powerUps.research.changeRerolls(-1)
+ // b.randomBot()
+ // }
+
{
name: "backward induction",
- description: "choose all the tech options you didn't choose
from your previous tech selection",
+ description: "use 2 research to choose all the unchosen
tech from your previous tech selection",
maxCount: 1,
count: 0,
frequency: 1,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
- return powerUps.tech.choiceLog.length > 10 && !tech.isDeterminism
+ return powerUps.tech.choiceLog.length > 10 && !tech.isDeterminism && powerUps.research.count > 1
},
- requires: "rejected an option in the last tech selection",
+ requires: "rejected an option in the last tech selection, at least 2 research",
effect: () => {
+ powerUps.research.changeRerolls(-2)
let num = 3
if (tech.isExtraChoice) num = 5
if (tech.isDeterminism) num = 1
- for (let i = powerUps.tech.choiceLog.length - 1 - num; i > powerUps.tech.choiceLog.length - 1 - num * 2; i--) {
- const index = powerUps.tech.choiceLog[i]
- if (powerUps.tech.choiceLog[i] !== powerUps.lastTechIndex && tech.tech[index].count < tech.tech[index].maxCount && tech.tech[index].allowed()) {
+ for (let i = 0; i < num; i++) {
+ const index = powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - i - 1]
+ if (index !== powerUps.lastTechIndex && tech.tech[index].count < tech.tech[index].maxCount && tech.tech[index].allowed()) {
tech.giveTech(index)
simulation.makeTextLog(`tech.giveTech("${tech.tech[index].name}") // backward induction`);
}
@@ -3068,8 +3102,11 @@
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
},
remove() {
- tech.isDeterminism = false;
- for (let i = 0; i < 6; i++) powerUps.removeRandomTech()
+ if (tech.isDeterminism) {
+ tech.isDeterminism = false;
+
+ for (let i = 0; i < 6; i++) powerUps.removeRandomTech()
+ }
}
},
{
@@ -3104,7 +3141,7 @@
allowed() {
return level.onLevel < 8 && level.onLevel > 0
},
- requires: "between levels 1 and 7",
+ requires: "on levels 1 through 7",
effect() {
level.difficultyDecrease(simulation.difficultyMode)
// simulation.difficulty-=
@@ -3632,7 +3669,7 @@
},
{
name: "packet length",
- description: "wave packet length and duration
is increased by 50%", // description: "holding fire allows the wave beam to emits a second packet
at zero ammo cost",
+ description: "wave packet length and duration
is increased by 40%", // description: "holding fire allows the wave beam to emits a second packet
at zero ammo cost",
isGunTech: true,
maxCount: 3,
count: 0,
@@ -3642,15 +3679,15 @@
},
requires: "wave beam",
effect() {
- const scale = 1.5 - 0.025 * this.count
- tech.waveLengthRange *= Math.sqrt(scale)
+ const scale = 1.4 - 0.025 * this.count
tech.wavePacketLength *= scale
tech.wavePacketFrequency /= scale
+ tech.waveLengthRange *= Math.sqrt(scale)
},
remove() {
- tech.wavePacketFrequency = 0.088 //shorten wave packet
- tech.wavePacketLength = tech.wavePacketFrequency * 408 //36.96 //how many wave packets are released // double this to emit 2 packets
- tech.waveLengthRange = 140;
+ tech.wavePacketFrequency = 0.088 //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
+ tech.wavePacketLength = 36 //32.7 //31.3 //28.8 //36 //how many wave packets are released // double this to emit 2 packets
+ tech.waveLengthRange = 130;
}
},
{
@@ -3666,16 +3703,16 @@
requires: "wave beam",
effect() {
tech.waveFrequency *= 0.5
- tech.wavePacketDamage *= 1.33
+ tech.wavePacketDamage *= 1.5
},
remove() {
- tech.waveFrequency = 0.35
+ tech.waveFrequency = 0.2
tech.wavePacketDamage = 1
}
},
{
name: "propagation",
- description: "wave packet propagation speed is 25% slower
wave damage is increased by 50%",
+ description: "wave packet propagation speed is 30% slower
wave damage is increased by 50%",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -3685,12 +3722,12 @@
},
requires: "wave beam",
effect() {
- tech.waveBeamSpeed *= 0.75;
- tech.waveBeamDamage += 1.2 * 0.5
+ tech.waveBeamSpeed *= 0.7;
+ tech.waveBeamDamage += 1.3 * 0.5
},
remove() {
tech.waveBeamSpeed = 10;
- tech.waveBeamDamage = 1.2 //this sets base wave beam damage
+ tech.waveBeamDamage = 1.3 //this sets base wave beam damage
}
},
{
@@ -5256,6 +5293,36 @@
// },
// remove() {}
// },
+ {
+ name: "spinor",
+ description: "the direction you aim is determined by your position",
+ maxCount: 1,
+ count: 0,
+ frequency: 0,
+ isExperimentHide: true,
+ isNonRefundable: true,
+ isJunk: true,
+ allowed() {
+ return !m.isShipMode
+ },
+ requires: "",
+ effect() {
+ m.look = function() {
+ //always on mouse look
+ m.angle = (((m.pos.x + m.pos.y) / 100 + Math.PI) % Math.PI * 2) - Math.PI
+ //smoothed mouse look translations
+ const scale = 0.8;
+ m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
+ m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
+
+ m.transX += (m.transSmoothX - m.transX) * 0.07;
+ m.transY += (m.transSmoothY - m.transY) * 0.07;
+ }
+ },
+ remove() {
+ m.look = m.lookDefault
+ }
+ },
{
name: "decomposers",
description: "after they die mobs leave behind spawns",
@@ -5266,7 +5333,7 @@
isNonRefundable: true,
isJunk: true,
allowed() {
- return build.isExperimentSelection
+ return true
},
requires: "",
effect() {
@@ -5286,7 +5353,7 @@
isNonRefundable: true,
isJunk: true,
allowed() {
- return build.isExperimentSelection
+ return true
},
requires: "",
effect() {
@@ -6555,4 +6622,5 @@
waveBeamSpeed: null,
wavePacketAmplitude: null,
waveLengthRange: null,
+ isCollisionRealitySwitch: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 2cc4fa7..1c81d86 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,9 +1,18 @@
******************************************************** NEXT PATCH ********************************************************
more wave beam balance
+backward induction costs 2 research now, also it is fixed (it would sometimes give an extra tech or the wrong tech)
+powerupBoss now gives research and ammo when it hits you, not 2 heals (it still ejects one of your tech also)
+
+tech: non-unitary operator - taking damage randomizes your run, reduce difficulty by 2 levels
******************************************************** BUGS ********************************************************
+
+(once) CPT gun only rewound 0.25 seconds
+ after a randomize run (non-unityary)
+ had enough energy
+
increase the width on the grid by a few pixels so that very small screens or people with odd fonts don't goto a new line
you have to press z once to get copy to work for simulation.enableConstructMode() sometimes
@@ -41,6 +50,12 @@ wave tech: chirp - amplitude and damage increases towards the end of the wavePac
wave tech: wave bullets are removed after doing damage, but they do something
more damage, explode, freeze,
+taking damage randomizes your run
+
+power ups disappear after 3-5 seconds
+ only apply to drops from killing mobs
+ +duplication 20%
+
tech: mobs that die while frozen produce ice-IX bullets
tech: picking up heal power ups when at full health does harm equal to the heal values