substructure

new level substructure
  featured element - motion triggered lasers

futures exchange 5->6% duplication per cancel
plasma torch coupling 0.015->0.025x damage per coupling
Gibbs free energy  1.005->1.006x damage per missing energy
compound lens arc adds 25->30 degrees
instability 2->2.5x damage when damage taken is 1x
constraint: after 30->40 seconds spawn WIMPs
constraint: 0.1->0.3x damage after getting power ups
renamed holographic principle -> charmed baryons

updates to community map: downpour
updated lasers in labs and testChamber to the new more realistic laser

bugs
  returning to the old console.log system from last patch
    I rather read bugs in the browser console not the n-gon console
  bots properly follow player when level flips vertically
  community map: arena's sword is properly removed at end of level
  rewrote shaped charge to be better at protecting you from all explosions
  pause correctly lists both mobs types for the level
  for quasiparticles "boost" replaces ammo in more edge cases
  bug with removing surfactant setting b.activeGun false and crashing game with checking active gun
    not sure if this is fixed or not?
This commit is contained in:
landgreen
2024-11-12 20:16:17 -08:00
parent 8bb8222b73
commit 1fde74d65a
10 changed files with 1254 additions and 476 deletions

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -23,7 +23,7 @@ const b = {
},
fire() { },
fireNormal() {
if (b.inventory.length && b.activeGun !== null) {
if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire)) {
if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo()
@@ -36,7 +36,7 @@ const b = {
}
},
fireNotMove() { //added && player.speed < 0.5 && m.onGround
if (b.inventory.length && b.activeGun !== null) {
if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire) && player.speed < 2.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo()
@@ -49,7 +49,7 @@ const b = {
}
},
fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire)
if (b.inventory.length && b.activeGun !== null) {
if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo()
@@ -60,7 +60,7 @@ const b = {
}
},
fireFloat() { //added && player.speed < 0.5 && m.onGround
if (b.inventory.length && b.activeGun !== null) {
if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && (!input.field || m.fieldFire)) {
if (m.fireCDcycle < m.cycle) {
if (b.guns[b.activeGun].ammo > 0) {
@@ -116,7 +116,7 @@ const b = {
}
},
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to
if (tech.crouchAmmoCount && m.crouch && b.activeGun !== null) {
if (tech.crouchAmmoCount && m.crouch && (b.activeGun !== null && b.activeGun !== undefined)) {
tech.crouchAmmoCount--
if ((tech.crouchAmmoCount) % 2) {
b.guns[b.activeGun].ammo++;
@@ -377,7 +377,7 @@ const b = {
explosion(where, radius, color = "rgba(255,25,0,0.6)", reducedKnock = 1) { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius
let dist, sub, knock;
let knock;
let dmg = radius * 0.019
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) {
@@ -385,10 +385,13 @@ const b = {
radius *= 0.7
dmg *= 1.7
}
let sub = Vector.sub(where, player.position);
let dist = Vector.magnitude(sub);
if (tech.isSmartRadius && radius > dist - 50) radius = Math.max(dist - 50, 1)
if (tech.isExplodeRadio) { //radiation explosion
radius *= 1.25; //alert range
if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
// if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
color = "rgba(25,139,170,0.25)"
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
@@ -425,7 +428,7 @@ const b = {
}
}
} else { //normal explosions
if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
// if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
@@ -444,9 +447,6 @@ const b = {
//player damage and knock back
if (m.immuneCycle < m.cycle) {
sub = Vector.sub(where, player.position);
dist = Vector.magnitude(sub);
if (dist < radius) {
if (simulation.dmgScale) {
const harm = tech.isExplosionHarm ? 0.067 : 0.05
@@ -7716,10 +7716,7 @@ const b = {
} else {
m.fireCDcycle = m.cycle
m.energy -= drain
const where = {
x: m.pos.x + 20 * Math.cos(m.angle),
y: m.pos.y + 20 * Math.sin(m.angle)
}
const where = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) }
b.laser(where, {
x: where.x + 3000 * Math.cos(m.angle),
y: where.y + 3000 * Math.sin(m.angle)

View File

@@ -13,7 +13,9 @@ Math.hash = s => {
// document.getElementById("seed").placeholder = Math.initialSeed = Math.floor(Date.now() % 100000) //random every time: just the time in milliseconds UTC
window.addEventListener('error', error => {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${error.message} <u>${error.filename}:${error.lineno}</u>`)
// simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${error.message} <u>${error.filename}:${error.lineno}</u>`)
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
});
document.getElementById("seed").placeholder = Math.initialSeed = String(Math.floor(Date.now() % 100000))
@@ -512,7 +514,7 @@ ${botText}
<span style="float: right;">mouse (${simulation.mouseInGame.x.toFixed(0)}, ${simulation.mouseInGame.y.toFixed(0)})</span>
<br>cycles ${m.cycle}
<span style="float: right;">velocity (${player.velocity.x.toFixed(2)}, ${player.velocity.y.toFixed(2)})</span>
<br>mobs ${mob.length} (${spawn.pickList[0]}, ${spawn.pickList[0]})
<br>mobs ${mob.length} (${spawn.pickList[0]}, ${spawn.pickList[1]})
<span style="float: right;">blocks ${body.length}</span>
<br>bullets ${bullet.length}
<span style="float: right;">power ups ${powerUp.length}</span>

File diff suppressed because it is too large Load Diff

View File

@@ -455,6 +455,7 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
spawn.setSpawnList(); //new mob types
level.isFlipped = false
simulation.clearNow = true; //triggers a map reset
m.switchWorlds()
@@ -3389,7 +3390,7 @@ const m = {
case 4: //assembler
return `<strong>+${(0.6 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma
return `<strong>${(1 + 0.015 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
return `<strong>${(1 + 0.025 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation
return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking

View File

@@ -285,7 +285,7 @@ const powerUps = {
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
if (tech.isCancelDuplication) {
const value = 0.05
const value = 0.06
tech.duplication += value
simulation.inGameConsole(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${value}`)
simulation.circleFlare(value);
@@ -883,7 +883,7 @@ const powerUps = {
const couplingExtraAmmo = (m.fieldMode === 10 || m.fieldMode === 0) ? 1 + 0.04 * m.coupling : 1
if (b.inventory.length > 0) {
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
if (tech.isAmmoForGun && (b.activeGun !== null && b.activeGun !== undefined)) { //give extra ammo to one gun only with tech logistics
const name = b.guns[b.activeGun]
if (name.ammo !== Infinity) {
if (tech.ammoCap) {
@@ -1618,7 +1618,7 @@ const powerUps = {
powerUps.spawn(x, y - 40, "heal", false)
}
if (tech.isResearchReality) powerUps.spawnDelay("research", 6)
if (tech.isBanish) powerUps.spawnDelay("research", 2)
if (tech.isBanish) powerUps.spawnDelay("research", 3)
if (tech.isCouplingNoHit) powerUps.spawnDelay("coupling", 9)
// if (tech.isRerollDamage) powerUps.spawnDelay("research", 1)
}
@@ -1735,9 +1735,10 @@ const powerUps = {
}
//count big power ups and small power ups
let options = ["heal", "research", "ammo"]
let options = ["heal", "research", tech.isBoostReplaceAmmo ? "boost" : "ammo"]
if (m.coupling) options.push("coupling")
if (tech.isBoostPowerUps) options.push("boost")
let bigIndexes = []
let smallIndexes = []
for (let i = 0; i < powerUp.length; i++) {

View File

@@ -2,152 +2,152 @@
//*********************************************************************
const simulation = {
loop() { }, //main game loop, gets set to normal or testing loop
normalLoop() {
try {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
powerUps.do();
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
if (!m.isBodiesAsleep) mobs.loop();
mobs.healthBar();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.drawMapPath();
b.fire();
b.bulletRemove();
b.bulletDraw();
if (!m.isBodiesAsleep) b.bulletDo();
simulation.drawCircle();
simulation.runEphemera();
ctx.restore();
} catch (error) {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
} finally {
simulation.drawCursor();
}
},
testingLoop() {
try {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.wireFrame();
if (input.fire && m.fireCDcycle < m.cycle) {
m.fireCDcycle = m.cycle + 15; //fire cooldown
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
console.log(mob[i])
}
}
}
simulation.draw.cons();
simulation.draw.testing();
simulation.drawCircle();
simulation.runEphemera();
simulation.constructCycle()
} catch (error) {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
} finally {
ctx.restore();
simulation.testingOutput();
simulation.drawCursor();
}
},
// normalLoop() {
// simulation.gravity();
// Engine.update(engine, simulation.delta);
// simulation.wipe();
// simulation.textLog();
// if (m.onGround) {
// m.groundControl()
// } else {
// m.airControl()
// try {
// simulation.gravity();
// Engine.update(engine, simulation.delta);
// simulation.wipe();
// simulation.textLog();
// if (m.onGround) {
// m.groundControl()
// } else {
// m.airControl()
// }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// powerUps.do();
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) mobs.loop();
// mobs.healthBar();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.drawMapPath();
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// simulation.drawCircle();
// simulation.runEphemera();
// ctx.restore();
// } catch (error) {
// simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
// } finally {
// simulation.drawCursor();
// }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// powerUps.do();
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) mobs.loop();
// mobs.healthBar();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.drawMapPath();
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// simulation.drawCircle();
// simulation.runEphemera();
// ctx.restore();
// simulation.drawCursor();
// },
// testingLoop() {
// simulation.gravity();
// Engine.update(engine, simulation.delta);
// simulation.wipe();
// simulation.textLog();
// if (m.onGround) {
// m.groundControl()
// } else {
// m.airControl()
// }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.wireFrame();
// if (input.fire && m.fireCDcycle < m.cycle) {
// m.fireCDcycle = m.cycle + 15; //fire cooldown
// for (let i = 0, len = mob.length; i < len; i++) {
// if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
// console.log(mob[i])
// try {
// simulation.gravity();
// Engine.update(engine, simulation.delta);
// simulation.wipe();
// simulation.textLog();
// if (m.onGround) {
// m.groundControl()
// } else {
// m.airControl()
// }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.wireFrame();
// if (input.fire && m.fireCDcycle < m.cycle) {
// m.fireCDcycle = m.cycle + 15; //fire cooldown
// for (let i = 0, len = mob.length; i < len; i++) {
// if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
// console.log(mob[i])
// }
// }
// }
// simulation.draw.cons();
// simulation.draw.testing();
// simulation.drawCircle();
// simulation.runEphemera();
// simulation.constructCycle()
// } catch (error) {
// simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
// } finally {
// ctx.restore();
// simulation.testingOutput();
// simulation.drawCursor();
// }
// simulation.draw.cons();
// simulation.draw.testing();
// simulation.drawCircle();
// simulation.runEphemera();
// simulation.constructCycle()
// ctx.restore();
// simulation.testingOutput();
// simulation.drawCursor();
// },
normalLoop() {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
powerUps.do();
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
if (!m.isBodiesAsleep) mobs.loop();
mobs.healthBar();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.drawMapPath();
b.fire();
b.bulletRemove();
b.bulletDraw();
if (!m.isBodiesAsleep) b.bulletDo();
simulation.drawCircle();
simulation.runEphemera();
ctx.restore();
simulation.drawCursor();
},
testingLoop() {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.wireFrame();
if (input.fire && m.fireCDcycle < m.cycle) {
m.fireCDcycle = m.cycle + 15; //fire cooldown
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
console.log(mob[i])
}
}
}
simulation.draw.cons();
simulation.draw.testing();
simulation.drawCircle();
simulation.runEphemera();
simulation.constructCycle()
ctx.restore();
simulation.testingOutput();
simulation.drawCursor();
},
isTimeSkipping: false,
timeSkip(cycles = 60) {
simulation.isTimeSkipping = true;
@@ -712,7 +712,7 @@ const simulation = {
mouseMove = mouseMoveDefault
}
},
translatePlayerAndCamera(where) {
translatePlayerAndCamera(where, isTranslateBots = true) {
//infinite falling. teleport to sky after falling
const before = { x: player.position.x, y: player.position.y, }
Matter.Body.setPosition(player, { x: where.x, y: where.y });
@@ -728,14 +728,15 @@ const simulation = {
//is there a reason to update m.pos here?
// m.pos.x = player.position.x;
// m.pos.y = playerBody.position.y - m.yOff;
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
if (Vector.magnitudeSquared(Vector.sub(bullet[i].position, player.position)) > 1000000) { //far away bots teleport to player
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) }));
Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
} else { //close bots maintain relative distance to player on teleport
Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
if (isTranslateBots) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
if (Vector.magnitudeSquared(Vector.sub(bullet[i].position, player.position)) > 1000000) { //far away bots teleport to player
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) }));
Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
} else { //close bots maintain relative distance to player on teleport
Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
}
}
}
}
@@ -996,7 +997,7 @@ const simulation = {
simulation.makeGunHUD();
simulation.lastLogTime = 0;
mobs.mobDeaths = 0
level.isFlipped = false
level.onLevel = 0;
level.levelsCleared = 0;
level.updateDifficulty()

View File

@@ -42,6 +42,7 @@ const spawn = {
spawn.pickList.splice(0, 1);
const push = spawn.mobTypeSpawnOrder[spawn.mobTypeSpawnIndex++ % spawn.mobTypeSpawnOrder.length]
spawn.pickList.push(push);
// if (spawn.mobTypeSpawnIndex > spawn.mobTypeSpawnOrder.length) spawn.mobTypeSpawnIndex = 0
//each level has 2 mobs: one new mob and one from the last level
// spawn.pickList.splice(0, 1);
@@ -116,8 +117,8 @@ const spawn = {
secondaryBossChance(x, y) {
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo");
powerUps.spawn(x - 30, y, "ammo");
powerUps.spawn(x + 30, y, "ammo");
} else {
return false
}

View File

@@ -249,18 +249,7 @@ const tech = {
}
},
haveGunCheck(name, needActive = true) {
// if (
// !build.isExperimentSelection &&
// b.inventory.length > 2 &&
// name !== b.guns[b.activeGun].name &&
// Math.random() > 2 - b.inventory.length * 0.5
// ) {
// return false
// }
// for (i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].name === name) return true
// }
// return false
if (b.activeGun === null || b.activeGun === undefined) return false
if (build.isExperimentSelection || !needActive) {
for (i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].name === name) return true
@@ -269,6 +258,15 @@ const tech = {
} else { //must be holding gun, this is the standard while playing
return b.inventory.length > 0 && b.guns[b.activeGun].name === name
}
// if (build.isExperimentSelection || !needActive) {
// for (i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].name === name) return true
// }
// return false
// } else { //must be holding gun, this is the standard while playing
// return b.inventory.length > 0 && b.guns[b.activeGun].name === name
// }
},
hasExplosiveDamageCheck() {
return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
@@ -276,9 +274,9 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() {
let dmg = tech.damage * m.fieldDamage
if (level.isNoDamage && (m.cycle - 180 < level.noDamageCycle)) dmg *= 0.1
if (level.isNoDamage && (m.cycle - 180 < level.noDamageCycle)) dmg *= 0.3
if (tech.isMaxHealthDamage && m.health === m.maxHealth) dmg *= 1.5
if (tech.noDefenseSettingDamage && m.defense() === 1) dmg *= 2
if (tech.noDefenseSettingDamage && m.defense() === 1) dmg *= 2.5
if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 3
if (tech.isPowerUpDamage) dmg *= 1 + 0.07 * powerUp.length
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4
@@ -288,7 +286,7 @@ const tech = {
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length
if (powerUps.boost.endCycle > simulation.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.025 * m.coupling
if (tech.isVerlet) dmg *= 3
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.71828
@@ -299,7 +297,7 @@ const tech = {
if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count)
if (tech.isBotDamage) dmg *= 1 + 0.04 * b.totalBots()
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isLowEnergyDamage) dmg *= 1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)
if (tech.isLowEnergyDamage) dmg *= 1 + 0.6 * Math.max(0, m.maxEnergy - m.energy)
if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
@@ -2874,7 +2872,7 @@ const tech = {
{
name: "Gibbs free energy",
descriptionFunction() {
return `<strong>1.005x</strong> <strong class='color-d'>damage</strong> for each missing <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em>`
return `<strong>1.006x</strong> <strong class='color-d'>damage</strong> for each missing <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em>`
},
maxCount: 1,
count: 0,
@@ -3086,7 +3084,7 @@ const tech = {
{
name: "instability",
descriptionFunction() {
return `<strong>2x</strong> <strong class='color-d'>damage</strong> while your <strong class='color-defense'>damage taken</strong> is <strong>1.00x</strong><br><em style ="float: right;">(current damage taken = ${(m.defense()).toFixed(2)}x)</em>`
return `<strong>2.5x</strong> <strong class='color-d'>damage</strong> while your <strong class='color-defense'>damage taken</strong> is <strong>1.00x</strong><br><em style ="float: right;">(current damage taken = ${(m.defense()).toFixed(2)}x)</em>`
},
maxCount: 1,
count: 0,
@@ -3597,7 +3595,7 @@ const tech = {
},
{
name: "decoherence",
description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(2)}<br>${powerUps.orb.tech()} options you don't <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> won't <strong>reoccur</strong>`,
description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(3)}<br>${powerUps.orb.tech()} options you don't <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> won't <strong>reoccur</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3606,7 +3604,6 @@ const tech = {
return !tech.isSuperDeterminism
},
requires: "not, superdeterminism",
bonusResearch: 7,
effect() {
tech.isBanish = true
},
@@ -3626,8 +3623,8 @@ const tech = {
description: `after observing a ${powerUps.orb.tech()} <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong><br>that <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong> is available for all <strong>all</strong> future ${powerUps.orb.tech()}`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
frequency: 3,
frequencyDefault: 3,
allowed() {
return tech.isBanish
},
@@ -4301,7 +4298,7 @@ const tech = {
},
{
name: "futures exchange",
description: `clicking <strong class='color-cancel'>cancel</strong> for ${powerUps.orb.field()}, ${powerUps.orb.tech()}, or ${powerUps.orb.gun()}<br>gives <strong>+5%</strong> power up <strong class='color-dup'>duplication</strong> chance`,
description: `clicking <strong class='color-cancel'>cancel</strong> for ${powerUps.orb.field()}, ${powerUps.orb.tech()}, or ${powerUps.orb.gun()}<br>gives <strong>+6%</strong> power up <strong class='color-dup'>duplication</strong> chance`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -7448,7 +7445,7 @@ const tech = {
},
{
name: "compound lens",
description: "<strong>1.4x</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+25°</strong> lens arc",
description: "<strong>1.4x</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+30°</strong> lens arc",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -7459,7 +7456,7 @@ const tech = {
},
requires: "lens",
effect() {
b.guns[11].arcRange += 25 * Math.PI / 180 / 2
b.guns[11].arcRange += 30 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.4
},
remove() {
@@ -8763,7 +8760,7 @@ const tech = {
},
{
name: "vacuum fluctuation",
description: `use ${powerUps.orb.research(3)}<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
description: `use ${powerUps.orb.research(2)}<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -8777,14 +8774,16 @@ const tech = {
tech.fieldDuplicate = 0.11
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
for (let i = 0; i < 3; i++) {
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
remove() {
tech.fieldDuplicate = 0
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (this.count > 0) powerUps.research.changeRerolls(3)
if (this.count) {
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
powerUps.research.changeRerolls(2)
}
}
},
{
@@ -8900,7 +8899,7 @@ const tech = {
}
},
{
name: "charmed baryons",
name: "holographic principle",
description: `<strong>0.8x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong class='color-worm'>wormholes</strong> cost <strong>zero</strong> <strong class='color-f'>energy</strong>`,
isFieldTech: true,
maxCount: 1,
@@ -9694,7 +9693,7 @@ const tech = {
effect() {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp) {
powerUps.directSpawn(mob[i].position.x, mob[i].position.y, "ammo");
powerUps.spawn(mob[i].position.x, mob[i].position.y, "ammo");
mob[i].death();
}
}
@@ -11701,7 +11700,7 @@ const tech = {
bc.activated = false
bc.onmessage = function (ev) {
if (ev.data === 'tech') powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'tech') powerUps.spawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') {
m.death()
bc.close(); //end session

105
todo.txt
View File

@@ -1,16 +1,30 @@
******************************************************** NEXT PATCH **************************************************
tech: Halbach array - throwing a block will also throw other nearby blocks
new level substructure
featured element - motion triggered lasers
tech non-renewables now spawns ammo, but ammo can't be picked up
grenade tech that cause multiple explosions have less knock back for mobs
constraint: 0->0.5x healing
wormhole 7->8% duplication
many worlds takes a few frames between each tech given
futures exchange 5->6% duplication per cancel
plasma torch coupling 0.015->0.025x damage per coupling
Gibbs free energy 1.005->1.006x damage per missing energy
compound lens arc adds 25->30 degrees
instability 2->2.5x damage when damage taken is 1x
constraint: after 30->40 seconds spawn WIMPs
constraint: 0.1->0.3x damage after getting power ups
renamed holographic principle -> charmed baryons
bug fixes
harpoon ammo gain on autonomous defense fixed
constraints are properly randomized again
updates to community map: downpour
updated lasers in labs and testChamber to the new more realistic laser
bugs
returning to the old console.log system from last patch
I rather read bugs in the browser console not the n-gon console
bots properly follow player when level flips vertically
community map: arena's sword is properly removed at end of level
rewrote shaped charge to be better at protecting you from all explosions
pause correctly lists both mobs types for the level
for quasiparticles "boost" replaces ammo in more edge cases
bug with removing surfactant setting b.activeGun false and crashing game with checking active gun
not sure if this is fixed or not?
******************************************************** BUGS ********************************************************
@@ -50,14 +64,39 @@ player can become crouched while not touching the ground if they exit the ground
*********************************************************** TODO *****************************************************
rework focuser mobs to fire blue laser instead of charging player
like in classic 7-1-2017
this makes more sense that a bean is focusing
!!conformal - similar rules for small and big scales linked to holographic principle
!!holonomy - parallel transport of a vector leads to movement (applies to curved space)
when far away from your wormhole regenerate 1% of your max energy per second
when far away from your wormhole reduce damage taken
heal last hit damage after enter wormhole
!!quasar - plasma torch from both ends
only after wormhole eats a block fire?
or just increase plasma length after eating block?
new level element - motion trigger for laser
new level heist
above - a building with rooms and doors like office/warehouse
below - long indoor tunnels like sewers
dark colors
narrow branching paths
elements
motion triggered lasers
doors opened by buttons
button that opens 1 door, but closes another when down
make the button down state easier, have extra power ups
make a text orb for JUNK text to make JUNK more clear
extended vertical flip to edge cases:
!!stored circular graphics simulation.drawList.push
new level based laser element
!!update new version into other levels
procedural animation
https://www.youtube.com/watch?v=qlfh_rv6khY
@@ -839,9 +878,6 @@ mob/boss that fires a laser at player, but give player time to avoid
they target where player was 1 second ago
they turn to face player?
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
require electric reactive armor?
Plasma Burner: upgrade for plasma torch, basically just a jet engine. does high damage, but short range, mostly for player movement.
maybe reduce gravity to really low then apply a vector away from mouse direction
@@ -851,17 +887,6 @@ auto-gon - auto battler with n-gon mob AI and tech
similar research and tech system to n-gon
some mobs can fire player weapons
tech: relativistic jets:
small particles that shot out from front and back poles and end up in a wide variety of spirals
slow trickle when charging and several more when firing
Tech: Make player smol
adapt the cloaking graphics to make a flashlight cone visual effect
put code in level.do?
be nice if block throwing had a projected path
Pilot wave tech
Energy use is increased, but you can now shape blocks using pressure
Grouping blocks will merge them into a massive ball
@@ -1234,11 +1259,8 @@ look up sci-fi science ideas here https://projectrho.com/public_html/rocket/
possible names for tech
sidereal - with respect to the stars (an extra rotation for time keeping)
holonomy - parallel transport of a vector leads to movement (applies to curved space)
holographic - 2-D surface can predict the 3-D space behind it? I think
entropic gravity - gravity is emergent in a holographic way
(maybe a field tech for negative mass)
conformal - similar rules for small and big scales linked to holographic principle
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
swarm intelligence - for a drone tech
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
@@ -1307,8 +1329,11 @@ possible names for tech
cork - used as a heat shield for rockets
P = NP - something with speeding up calculation times
transistivity - something where a>b and b>c -> a>c
lenticular - looks different from different angles (lasers?)
lenticular - looks different from different angles (lasers?, cloaking?)
every few seconds pick a random skin tech?
De Sitter space - simple model of universe related to general relativity (mass-energy?)
active optics - something with lasers? maybe something with diffuse beam getting smaller
Quintessence - related to dark energy
******************************************************* DESIGN ******************************************************
@@ -1333,3 +1358,23 @@ list of powerful synergies
electronegativity and high energy?
electronegativity + anyon + duplication + Maxwells demon + interest + pair production
chain reaction + invulnerable + Abelian group + parasitism = clear all mobs on level
************************************************* COMMUNITY LINKS *************************************************
load old commits
www.cornbread2100.com/n-gon-loader
n-gon fork
kgurchiek.github.io/n-gon-portal-gun
3xiondev.github.io/n-gon-upgraded
coaldeficit.github.io/c-gon
c-rxxp-y.github.io/n-gon-enhanced
bookmarlet
github.com/Whyisthisnotavalable/n-scythe
github.com/kgurchiek/n-gon-mobile
github.com/kgurchiek/n-gon-controller
text
ngon.fandom.com/wiki/N-gon
github.com/3xionDev/n-docs