grey intro

intro screen is more grey
experiment button is larger and darker

tech: nanowires - needles tunnel through blocks and map, +20% damage

Occam's razor gives 40->50% damage for each removed tech
determinism no longer removes the cancel button
superdeterminism now removes the cancel button and research, but doesn't remove gun and field power ups
railgun damage is doubled
regression does more damage per hit: 5->6% vs. mobs and 0.5->1% vs. bosses

bug fixes
This commit is contained in:
landgreen
2021-12-04 15:18:32 -08:00
parent 66025c14e2
commit 92457703d5
10 changed files with 227 additions and 119 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -88,9 +88,9 @@
<div style="position: absolute; top:0;right:0;"> <div style="position: absolute; top:0;right:0;">
<div id="pause-grid-right" class="pause-grid"></div> <div id="pause-grid-right" class="pause-grid"></div>
</div> </div>
<svg class="SVG-button" id="experiment-button" width="155" height="40" style="border: 2px #333 solid;"> <svg class="SVG-button" id="experiment-button" width="170" height="45" style="border: 2px #333 solid;">
<g stroke='none' fill='#333' stroke-width="2" font-size="28px" font-family="Arial, sans-serif"> <g stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Arial, sans-serif">
<text x="10" y="30">experiment</text> <text x="10" y="33">experiment</text>
</g> </g>
</svg> </svg>
<div id='info'> <div id='info'>
@@ -353,7 +353,7 @@
<path transform="translate(10.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" /> <path transform="translate(10.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" />
<path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" /> <path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" />
</g> </g>
<g transform="translate(100,210) scale(34)" fill='none' stroke='#222' stroke-linejoin="round" stroke-linecap="round"> <g transform="translate(100,210) scale(34)" fill='none' stroke='#333' stroke-linejoin="round" stroke-linecap="round">
<path class="draw-lines" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' /> <path class="draw-lines" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' />
<rect class="draw-lines-dash" x="4" y="1.25" width="1" height="0.5" stroke-width='0.0875' rx='0.03' /> <rect class="draw-lines-dash" x="4" y="1.25" width="1" height="0.5" stroke-width='0.0875' rx='0.03' />
<path class="draw-lines-g" transform="translate(6.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" stroke-width='0.07' /> <path class="draw-lines-g" transform="translate(6.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" stroke-width='0.07' />
@@ -368,7 +368,7 @@
<path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' /> <path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' />
</g> --> </g> -->
<!-- mouse --> <!-- mouse -->
<g class="draw-lines3" transform="translate(290,430) scale(0.28)" stroke-linecap="round" stroke-linejoin="round" stroke-width="10px" stroke="#222" fill="none"> <g class="draw-lines3" transform="translate(290,430) scale(0.28)" stroke-linecap="round" stroke-linejoin="round" stroke-width="10px" stroke="#333" fill="none">
<path class="fade-in" stroke="none" fill="#fff" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path class="fade-in" stroke="none" fill="#fff" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" />
<path class="fade-in" d="M832.41,106.64 V322 H651.57 V255 c0-82,67.5-148,150-148 Z" fill="rgb(0, 200, 255)" stroke="none" /> <path class="fade-in" d="M832.41,106.64 V322 H651.57 V255 c0-82,67.5-148,150-148 Z" fill="rgb(0, 200, 255)" stroke="none" />
<!-- <path class="fade-in" d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#789" stroke="none" /> <!-- <path class="fade-in" d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#789" stroke="none" />
@@ -390,7 +390,7 @@
<path d="M70 70 h60 v60 h-60 v-60" class="draw-lines-box-2" /> <path d="M70 70 h60 v60 h-60 v-60" class="draw-lines-box-2" />
<path d="M140 70 h60 v60 h-60 v-60" class="draw-lines-box-3" /> <path d="M140 70 h60 v60 h-60 v-60" class="draw-lines-box-3" />
</g> </g>
<g fill='none' stroke='#222' stroke-width="3.5" stroke-linejoin="round" stroke-linecap="round"> <g fill='none' stroke='#333' stroke-width="3.5" stroke-linejoin="round" stroke-linecap="round">
<path d="M0 60 h60 v-60 h-60 v60" class="draw-lines-box-1" /> <path d="M0 60 h60 v-60 h-60 v60" class="draw-lines-box-1" />
<path d="M70 60 h60 v-60 h-60 v60" class="draw-lines-box-2" /> <path d="M70 60 h60 v-60 h-60 v60" class="draw-lines-box-2" />
<path d="M140 60 h60 v-60 h-60 v60" class="draw-lines-box-3" /> <path d="M140 60 h60 v-60 h-60 v60" class="draw-lines-box-3" />

View File

@@ -2764,7 +2764,7 @@ const b = {
if ( if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) && (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isDeterminism) (powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab) // &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) { ) {
//draw pickup for a single cycle //draw pickup for a single cycle
@@ -2795,7 +2795,7 @@ const b = {
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
if ( if (
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) && (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isDeterminism) (powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab) // &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) { ) {
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) { if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
@@ -2981,7 +2981,7 @@ const b = {
if ( if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) && (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isDeterminism) (powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab) // &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) { ) {
//draw pickup for a single cycle //draw pickup for a single cycle
@@ -3013,7 +3013,7 @@ const b = {
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
if ( if (
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) && (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isDeterminism) (powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab) // &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) { ) {
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) { if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 && !simulation.isChoosing) {
@@ -3304,64 +3304,123 @@ const b = {
needle(angle = m.angle) { needle(angle = m.angle) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75 * tech.nailSize, 0.75 * tech.nailSize, b.fireAttributes(angle)); bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75 * tech.nailSize, 0.75 * tech.nailSize, b.fireAttributes(angle));
bullet[me].collisionFilter.mask = tech.isShieldPierce ? cat.body : cat.body | cat.mobShield
Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal
bullet[me].endCycle = simulation.cycle + 100;
bullet[me].immuneList = [] bullet[me].immuneList = []
bullet[me].do = function() { bullet[me].dmg = 6
const whom = Matter.Query.collides(this, mob) if (tech.needleTunnel) {
if (whom.length && this.speed > 20) { //if touching a mob bullet[me].dmg *= 1.2
for (let i = 0, len = whom.length; i < len; i++) { bullet[me].endCycle = simulation.cycle + 300;
who = whom[i].bodyA bullet[me].collisionFilter.mask = tech.isShieldPierce ? 0 : cat.mobShield
if (who && who.mob) { // bullet[me].turnRate = 0.005 * (Math.random() - 0.5)
let immune = false bullet[me].isInMap = false
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already bullet[me].do = function() {
if (this.immuneList[i] === who.id) { const whom = Matter.Query.collides(this, mob)
immune = true if (whom.length && this.speed > 20) { //if touching a mob
break for (let i = 0, len = whom.length; i < len; i++) {
who = whom[i].bodyA
if (who && who.mob) {
let immune = false
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already
if (this.immuneList[i] === who.id) {
immune = true
break
}
} }
} if (!immune) {
if (!immune) { if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end
b.explosion(this.position, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end }
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.nailSize * b.dmgScale
if (tech.isNailRadiation) {
mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
dmg *= 0.25
}
if (tech.isCrit && who.isStunned) dmg *= 4
who.damage(dmg, tech.isShieldPierce);
if (who.alive) who.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: simulation.playerDmgColor,
time: simulation.drawTime
});
} }
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = b.dmgScale * 6 * tech.nailSize
if (tech.isNailRadiation) {
mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
dmg *= 0.25
}
if (tech.isCrit && who.isStunned) dmg *= 4
who.damage(dmg, tech.isShieldPierce);
if (who.alive) who.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: simulation.playerDmgColor,
time: simulation.drawTime
});
} }
} }
} else if (Matter.Query.collides(this, map).length) { //penetrate walls
if (!this.isInMap) { //turn after entering the map, but only turn once
this.isInMap = true
Matter.Body.setVelocity(this, Vector.rotate(this.velocity, 0.25 * (Math.random() - 0.5)));
Matter.Body.setAngle(this, Math.atan2(this.velocity.y, this.velocity.x))
}
Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.98))) //move back 1/2 your velocity = moving at 1/2 speed
} else if (Matter.Query.collides(this, body).length) { //penetrate blocks
Matter.Body.setAngularVelocity(this, 0)
Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.94))) //move back 1/2 your velocity = moving at 1/2 speed
} else if (this.speed < 30) {
this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming
} }
} else if (Matter.Query.collides(this, map).length) { //stick in walls };
this.collisionFilter.mask = 0; } else {
Matter.Body.setAngularVelocity(this, 0) bullet[me].endCycle = simulation.cycle + 100;
Matter.Body.setVelocity(this, { bullet[me].collisionFilter.mask = tech.isShieldPierce ? cat.body : cat.body | cat.mobShield
x: 0, bullet[me].do = function() {
y: 0 const whom = Matter.Query.collides(this, mob)
}); if (whom.length && this.speed > 20) { //if touching a mob
this.do = function() { for (let i = 0, len = whom.length; i < len; i++) {
if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; who = whom[i].bodyA
if (who && who.mob) {
let immune = false
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already
if (this.immuneList[i] === who.id) {
immune = true
break
}
}
if (!immune) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end
}
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.nailSize * b.dmgScale
if (tech.isNailRadiation) {
mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
dmg *= 0.25
}
if (tech.isCrit && who.isStunned) dmg *= 4
who.damage(dmg, tech.isShieldPierce);
if (who.alive) who.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: simulation.playerDmgColor,
time: simulation.drawTime
});
}
}
}
} else if (Matter.Query.collides(this, map).length) { //stick in walls
this.collisionFilter.mask = 0;
Matter.Body.setAngularVelocity(this, 0)
Matter.Body.setVelocity(this, {
x: 0,
y: 0
});
this.do = function() {
if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
}
if (tech.isNeedleIce) {
b.iceIX(5 + 5 * Math.random(), 2 * Math.PI * Math.random(), this.position) // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
if (0.5 < Math.random()) b.iceIX(5 + 5 * Math.random(), 2 * Math.PI * Math.random(), this.position)
}
} else if (this.speed < 30) {
this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming
} }
if (tech.isNeedleIce) { };
b.iceIX(5 + 5 * Math.random(), 2 * Math.PI * Math.random(), this.position) // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { }
if (0.5 < Math.random()) b.iceIX(5 + 5 * Math.random(), 2 * Math.PI * Math.random(), this.position)
}
} else if (this.speed < 30) {
this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming
}
};
const SPEED = 90 const SPEED = 90
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + SPEED * Math.cos(angle), x: m.Vx / 2 + SPEED * Math.cos(angle),
@@ -5638,7 +5697,7 @@ const b = {
const size = 3 + tech.isLargeHarpoon * 0.1 * Math.sqrt(this.ammo) const size = 3 + tech.isLargeHarpoon * 0.1 * Math.sqrt(this.ammo)
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen
vertexGoal: [{ x: -40 * size, y: 2 * size, index: 0, isInternal: false }, { x: -40 * size, y: -2 * size, index: 1, isInternal: false }, { x: 50 * size, y: -3 * size, index: 3, isInternal: false }, { x: 30 * size, y: 2 * size, index: 4, isInternal: false }], vertexGoal: [{ x: -40 * size, y: 2 * size, index: 0, isInternal: false }, { x: -40 * size, y: -2 * size, index: 1, isInternal: false }, { x: 50 * size, y: -3 * size, index: 3, isInternal: false }, { x: 30 * size, y: 2 * size, index: 4, isInternal: false }],
density: 0.015, //0.001 is normal density: 0.03, //0.001 is normal
restitution: 0, restitution: 0,
frictionAir: 0, frictionAir: 0,
dmg: 0, //damage done in addition to the damage from momentum dmg: 0, //damage done in addition to the damage from momentum

View File

@@ -186,7 +186,7 @@ function collisionChecks(event) {
color: simulation.playerDmgColor, color: simulation.playerDmgColor,
time: simulation.drawTime time: simulation.drawTime
}); });
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.005 : 1.05 if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.01 : 1.06
return; return;
} }
//mob + body collisions //mob + body collisions

View File

@@ -878,7 +878,7 @@ window.addEventListener("keydown", function(event) {
build.pauseGrid() build.pauseGrid()
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
if (tech.isGunSwitchField || simulation.testing) { if (tech.isPauseSwitchField || simulation.testing) {
document.getElementById("pause-field").addEventListener("click", () => { document.getElementById("pause-field").addEventListener("click", () => {
const energy = m.energy const energy = m.energy
m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field

View File

@@ -20,8 +20,8 @@ const level = {
// b.giveGuns("shotgun") // b.giveGuns("shotgun")
// b.giveGuns("nail gun") // b.giveGuns("nail gun")
// b.giveGuns("harpoon") // b.giveGuns("harpoon")
// tech.giveTech("slug") // tech.giveTech("needle gun")
// tech.giveTech("regression") // tech.giveTech("nanowires")
// tech.giveTech("relativistic momentum") // tech.giveTech("relativistic momentum")
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
// tech.giveTech("antiscience") // tech.giveTech("antiscience")

View File

@@ -256,8 +256,8 @@ const powerUps = {
if (tech.isCancelDuplication) { if (tech.isCancelDuplication) {
tech.cancelCount++ tech.cancelCount++
tech.maxDuplicationEvent() tech.maxDuplicationEvent()
simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.045}`) simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.042}`)
simulation.circleFlare(0.045); simulation.circleFlare(0.042);
} }
if (tech.isCancelRerolls) { if (tech.isCancelRerolls) {
for (let i = 0, len = 5 + 5 * Math.random(); i < len; i++) { for (let i = 0, len = 5 + 5 * Math.random(); i < len; i++) {
@@ -550,7 +550,7 @@ const powerUps = {
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = "" let text = ""
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</div>` if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>`
if (!tech.isDeterminism) { if (!tech.isDeterminism) {
@@ -665,7 +665,7 @@ const powerUps = {
} }
let text = "" let text = ""
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>` if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick() let choice1 = pick()
let choice2 = -1 let choice2 = -1
@@ -770,7 +770,7 @@ const powerUps = {
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = "" let text = ""
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>✕</div>` if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
if (!tech.isDeterminism) { if (!tech.isDeterminism) {
@@ -873,7 +873,7 @@ const powerUps = {
randomPowerUpCounter: 0, randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades
if (level.levels[level.onLevel] !== "final") { if (level.levels[level.onLevel] !== "final") {
if (m.fieldMode === 0 && !tech.isSuperDeterminism) { if (m.fieldMode === 0) {
powerUps.spawn(x, y, "field") powerUps.spawn(x, y, "field")
} else { } else {
powerUps.randomPowerUpCounter++; powerUps.randomPowerUpCounter++;
@@ -1026,7 +1026,7 @@ const powerUps = {
}, },
spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
if ( if (
(!tech.isSuperDeterminism || (target === 'tech' || target === 'heal' || target === 'ammo')) && (!tech.isSuperDeterminism || (target !== 'research')) &&
!(tech.isEnergyNoAmmo && target === 'ammo') && !(tech.isEnergyNoAmmo && target === 'ammo') &&
(!simulation.isNoPowerUps || (target === 'research' || target === 'heal' || target === 'ammo')) (!simulation.isNoPowerUps || (target === 'research' || target === 'heal' || target === 'ammo'))
) { ) {

View File

@@ -229,7 +229,7 @@ const tech = {
if (tech.isEnergyDamage) dmg *= 1 + m.energy / 11; if (tech.isEnergyDamage) dmg *= 1 + m.energy / 11;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007 if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007
if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.1995 if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
if (tech.isBotDamage) dmg *= 1 + 0.07 * b.totalBots() if (tech.isBotDamage) dmg *= 1 + 0.07 * b.totalBots()
@@ -237,7 +237,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.04 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.45 : 0)) return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.042 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.45 : 0))
}, },
isScaleMobsWithDuplication: false, isScaleMobsWithDuplication: false,
maxDuplicationEvent() { maxDuplicationEvent() {
@@ -729,7 +729,7 @@ const tech = {
}, },
{ {
name: "regression", name: "regression",
description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>5%</strong> for mobs <em>(0.5% for bosses)</em>", description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>6%</strong> for mobs <em>(1% for bosses)</em>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3039,7 +3039,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (powerUps.research.count > 2 || build.isExperimentSelection) && !tech.isDeterminism return (powerUps.research.count > 2 || build.isExperimentSelection) && !tech.isSuperDeterminism
}, },
requires: "not determinism, at least 3 research", requires: "not determinism, at least 3 research",
effect() { effect() {
@@ -3197,7 +3197,7 @@ const tech = {
}, },
requires: "NOT EXPERIMENT MODE, more than 6 tech", requires: "NOT EXPERIMENT MODE, more than 6 tech",
removePercent: 0.5, removePercent: 0.5,
damagePerRemoved: 0.4, damagePerRemoved: 0.5,
effect() { effect() {
let pool = [] let pool = []
for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups
@@ -3207,6 +3207,7 @@ const tech = {
let removeCount = 0 let removeCount = 0
for (let i = 0, len = pool.length * this.removePercent; i < len; i++) removeCount += tech.removeTech(pool[i]) for (let i = 0, len = pool.length * this.removePercent; i < len; i++) removeCount += tech.removeTech(pool[i])
tech.OccamDamage = 1 + this.damagePerRemoved * removeCount tech.OccamDamage = 1 + this.damagePerRemoved * removeCount
// tech.OccamDamage = Math.pow(1.25, removeCount)
}, },
remove() { remove() {
tech.OccamDamage = 0; tech.OccamDamage = 0;
@@ -3333,15 +3334,15 @@ const tech = {
}, },
{ {
name: "futures exchange", name: "futures exchange",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4%</strong> power up <strong class='color-dup'>duplication</strong> chance", description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.2%</strong> power up <strong class='color-dup'>duplication</strong> chance",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.duplicationChance() < 1 && !tech.isDeterminism return tech.duplicationChance() < 1 && !tech.isSuperDeterminism
}, },
requires: "below 100% duplication chance, not determinism", requires: "below 100% 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
@@ -3359,9 +3360,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isDeterminism return !tech.isSuperDeterminism
}, },
requires: "not determinism", requires: "not superdeterminism",
effect() { effect() {
tech.isCancelRerolls = true tech.isCancelRerolls = true
}, },
@@ -3498,7 +3499,7 @@ const tech = {
}, },
{ {
name: "vector fields", name: "vector fields",
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>", description: "</strong>triple</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3512,13 +3513,13 @@ const tech = {
effect() { effect() {
powerUps.spawn(m.pos.x, m.pos.y, "field"); powerUps.spawn(m.pos.x, m.pos.y, "field");
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isFieldTech) tech.tech[i].frequency *= 2 if (tech.tech[i].isFieldTech) tech.tech[i].frequency *= 3
} }
}, },
remove() { remove() {
// if (this.count > 1) { // if (this.count > 1) {
// for (let i = 0, len = tech.tech.length; i < len; i++) { // for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isFieldTech) tech.tech[i].frequency /= 2 // if (tech.tech[i].isFieldTech) tech.tech[i].frequency /= 3
// } // }
// } // }
} }
@@ -3598,16 +3599,16 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isSuperDeterminism return true
}, },
requires: "not superdeterminism", requires: "not superdeterminism",
effect() { effect() {
tech.isGunSwitchField = true; tech.isPauseSwitchField = true;
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
}, },
remove() { remove() {
if (tech.isGunSwitchField) { if (tech.isPauseSwitchField) {
tech.isGunSwitchField = false; tech.isPauseSwitchField = false;
powerUps.research.changeRerolls(-6) powerUps.research.changeRerolls(-6)
} }
} }
@@ -3659,7 +3660,7 @@ const tech = {
}, },
{ {
name: "determinism", name: "determinism",
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have <strong>no cancel</strong><br>and <strong>1 choice</strong> for <strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong>", description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have only<br> <strong>1 choice</strong> for <strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3667,9 +3668,9 @@ const tech = {
isBadRandomOption: true, isBadRandomOption: true,
isNonRefundable: true, isNonRefundable: true,
allowed() { allowed() {
return !tech.isExtraChoice && !tech.isCancelDuplication && !tech.isCancelRerolls return !tech.isExtraChoice && !tech.isExtraGunField
}, },
requires: "not emergence, not futures or commodities exchanges", requires: "not emergence, cross disciplinary",
effect: () => { effect: () => {
tech.isDeterminism = true; tech.isDeterminism = true;
//if you change the number spawned also change it in Born rule //if you change the number spawned also change it in Born rule
@@ -3696,17 +3697,17 @@ const tech = {
}, },
{ {
name: "superdeterminism", name: "superdeterminism",
description: `spawn <strong>5</strong> <strong class='color-m'>tech</strong><br>${powerUps.orb.research(1)}, <strong class='color-g'>guns</strong>, and <strong class='color-f'>fields</strong> no longer <strong>spawn</strong>`, description: `spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have <strong>no cancel</strong><br>and ${powerUps.orb.research(1)}, no longer <strong>spawn</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 3, frequency: 4,
frequencyDefault: 3, frequencyDefault: 4,
isBadRandomOption: true, isBadRandomOption: true,
isNonRefundable: true, isNonRefundable: true,
allowed() { allowed() {
return tech.isDeterminism && !tech.isAnsatz && !tech.isGunSwitchField return tech.isDeterminism && !tech.isAnsatz
}, },
requires: "determinism, not unified field theory, not ansatz", requires: "determinism, not ansatz",
effect: () => { effect: () => {
tech.isSuperDeterminism = true; tech.isSuperDeterminism = true;
//if you change the number spawned also change it in Born rule //if you change the number spawned also change it in Born rule
@@ -3835,9 +3836,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isNeedles || tech.isNeedleShot return (tech.isNeedles || tech.isNeedleShot) && !tech.needleTunnel
}, },
requires: "nail gun, needle gun, needle-shot", requires: "nail gun, needle gun, needle-shot, not nanowires",
effect() { effect() {
tech.isNeedleIce = true tech.isNeedleIce = true
}, },
@@ -3864,6 +3865,25 @@ const tech = {
tech.isShieldPierce = false tech.isShieldPierce = false
} }
}, },
{
name: "nanowires",
description: `<strong>needles</strong> tunnel through <strong class='color-block'>blocks</strong> and <strong>map</strong><br>increase needle <strong class='color-d'>damage</strong> by <strong>20%</strong>`,
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isNeedles || tech.isNeedleShot) && !tech.isNeedleIce
},
requires: "needle gun, needle-shot, not needle ice",
effect() {
tech.needleTunnel = true
},
remove() {
tech.needleTunnel = false
}
},
{ {
name: "needle gun", name: "needle gun",
description: "<strong>nail gun</strong> fires <strong>3</strong> mob piercing <strong>needles</strong><br>requires <strong>3</strong> times more <strong>bullets</strong>", description: "<strong>nail gun</strong> fires <strong>3</strong> mob piercing <strong>needles</strong><br>requires <strong>3</strong> times more <strong>bullets</strong>",
@@ -8980,7 +9000,7 @@ const tech = {
isRivets: null, isRivets: null,
isNeedles: null, isNeedles: null,
isExplodeRadio: null, isExplodeRadio: null,
isGunSwitchField: null, isPauseSwitchField: null,
isShieldPierce: null, isShieldPierce: null,
isDuplicateBoss: null, isDuplicateBoss: null,
is111Duplicate: null, is111Duplicate: null,
@@ -9084,5 +9104,6 @@ const tech = {
isAxion: null, isAxion: null,
isWormholeMapIgnore: null, isWormholeMapIgnore: null,
isLessDamageReduction: null, isLessDamageReduction: null,
nailSize: null nailSize: null,
needleTunnel: null
} }

View File

@@ -6,7 +6,7 @@ body {
font-family: "Helvetica", "Arial", sans-serif; font-family: "Helvetica", "Arial", sans-serif;
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
background-color: #fff; /* background-color: #eee; */
user-select: none; user-select: none;
cursor: auto; cursor: auto;
} }
@@ -114,13 +114,13 @@ summary {
} }
.SVG-button:hover { .SVG-button:hover {
background-color: #e8e8ee; background-color: #eee;
} }
#experiment-button { #experiment-button {
position: absolute; position: absolute;
bottom: 3px; bottom: 4px;
right: 3px; right: 4px;
z-index: 12; z-index: 12;
transition: opacity 5s ease-in; transition: opacity 5s ease-in;
} }
@@ -430,7 +430,7 @@ summary {
z-index: 2; z-index: 2;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #fff; background-color: #ecf0f3;
opacity: 1; opacity: 1;
transition: opacity 3s; transition: opacity 3s;
pointer-events: none; pointer-events: none;

View File

@@ -1,15 +1,39 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
pneumatic hammer (20 -> +18% size and damage effects) intro screen is more grey
now applies to nails, slugs, needles, in addition to rivets experiment button is larger and darker
integrated armament 20->25% damage, also if you switch guns converts guntech to new gun
backward induction removed tech: nanowires - needles tunnel through blocks and map, +20% damage
symbiosis removes 1 -> 0.5 max health per mob kill
plasma jet - costs 1 -> 2 research, and goes a bit farther Occam's razor gives 40->50% damage for each removed tech
Occam's razor gives 36 -> 40% damage per removed tech determinism no longer removes the cancel button
superdeterminism now removes the cancel button and research, but doesn't remove gun and field power ups
railgun damage is doubled
regression does more damage per hit: 5->6% vs. mobs and 0.5->1% vs. bosses
bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
some boss mobs need invulnerability phases
maybe trigger immunity to damage for 5-10s after taking the first hit?
static electricity: walking on the ground does something
regen energy
build charge, and discharge to damage mobs
suggestion: particle accelerator: perfect diamagneticism accelerates projectiles passing through it, increasing their damage and velocity. Alternatively, matter wave's projectiles accelerate, with increased damage the faster they're travelling
don't in game console log scrap bots
increase mass and movement speed at the same time
increase jump differently because it scales extra with mass
m.defaultMass = 4.5
m.definePlayerMass()
tech selection menu choices randomize every second
JUNK tech?
needle benefit from pneumatic hammer? needle benefit from pneumatic hammer?
all nails? all nails?
@@ -24,11 +48,6 @@ new late game level that is easier if you can: platform well, jump high, immune
antimatter (assuming something else isn't already named this); requires negative mass, causes damage to self and enemies within range while active antimatter (assuming something else isn't already named this); requires negative mass, causes damage to self and enemies within range while active
increase mass and movement speed at the same time
increase jump differently because it scales extra with mass
m.defaultMass = 4.5
m.definePlayerMass()
give history boss legs? give history boss legs?
field tech - disable blocking, but does high damage to mobs inside field field tech - disable blocking, but does high damage to mobs inside field
@@ -481,6 +500,7 @@ possible names for tech
eternalism https://en.wikipedia.org/wiki/Eternalism_(philosophy_of_time) eternalism https://en.wikipedia.org/wiki/Eternalism_(philosophy_of_time)
axial motor axial motor
hall effect thrusters hall effect thrusters
spaghettification
a tutorial / lore intro a tutorial / lore intro
needs to be optional so it doesn't slow experienced players needs to be optional so it doesn't slow experienced players
@@ -637,3 +657,11 @@ add sounds
// tone(396) // tone(396)
// tone(445.50) // tone(445.50)
// tone(495) // tone(495)