wide laser

tech: antiscience - 100% damage, but lose 11 health when you pick up a tech
tech: laser widebeam + output coupler can now stack up to 9x (was 1x)
  but it not longer works with tech: slow light propagation
This commit is contained in:
landgreen
2021-01-10 05:19:13 -08:00
parent cd0e47df30
commit ef8ae42591
9 changed files with 239 additions and 222 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1358,6 +1358,81 @@ const b = {
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
} }
}, },
laserMine(position, velocity = { x: 0, y: -8 }) {
const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, {
bulletType: "mine",
angle: mech.angle,
friction: 0,
frictionAir: 0.05,
restitution: 0.5,
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 60 + Math.floor(7 * Math.random()),
drain: tech.isLaserDiode * tech.laserFieldDrain,
isArmed: false,
torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1),
range: 1500,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
beforeDmg() {},
onEnd() {
if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "mine") {
b.guns[i].ammo++
simulation.updateGunHUD();
break;
}
}
}
},
do() {
if (!(simulation.cycle % this.lookFrequency) && mech.energy > this.drain) { //find mob targets
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 2000000 &&
mob[i].dropPowerUp &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
this.do = this.laserSpin
this.endCycle = simulation.cycle + 300
// if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin
this.isArmed = true
}
}
}
},
reflections: Math.max(0, tech.laserReflections - 2),
laserSpin() {
//drain energy
if (mech.energy > this.drain) {
mech.energy -= this.drain
if (this.angularSpeed < 0.02) this.torque += this.inertia * this.torqueMagnitude //spin
//fire lasers
ctx.strokeStyle = "#f00";
ctx.lineWidth = 1.5
// ctx.globalAlpha = 1;
ctx.beginPath();
for (let i = 0; i < 3; i++) {
const where = this.vertices[i]
const endPoint = Vector.add(where, Vector.mult(Vector.normalise(Vector.sub(where, this.position)), 2500))
b.laser(where, endPoint, tech.laserDamage * 10, this.reflections, true)
}
ctx.stroke();
// ctx.globalAlpha = 1;
}
}
})
Matter.Body.setVelocity(bullet[me], velocity);
World.add(engine.world, bullet[me]); //add bullet to world
},
mine(where, velocity, angle = 0, isAmmoBack = false) { mine(where, velocity, angle = 0, isAmmoBack = false) {
const bIndex = bullet.length; const bIndex = bullet.length;
bullet[bIndex] = Bodies.rectangle(where.x, where.y, 45, 16, { bullet[bIndex] = Bodies.rectangle(where.x, where.y, 45, 16, {
@@ -1530,7 +1605,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: tech.isMutualism ? 8 : 4, //2x bonus damage from tech.isMutualism dmg: tech.isMutualism ? 10 : 4, //2x bonus damage from tech.isMutualism
lookFrequency: 100 + Math.floor(117 * Math.random()), lookFrequency: 100 + Math.floor(117 * Math.random()),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -1793,7 +1868,7 @@ const b = {
) { ) {
//pick up nearby power ups //pick up nearby power ups
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 60000 && !simulation.isChoosing) { if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 60000 && !simulation.isChoosing) {
powerUps.onPickUp(this.position); powerUps.onPickUp(powerUp[i]);
powerUp[i].effect(); powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); powerUp.splice(i, 1);
@@ -3312,91 +3387,9 @@ const b = {
have: false, have: false,
fire() { fire() {
if (tech.isLaserMine) { //laser mine if (tech.isLaserMine) { //laser mine
const me = bullet.length; const speed = mech.crouch ? 50 : 20
const position = mech.pos const velocity = { x: speed * Math.cos(mech.angle), y: speed * Math.sin(mech.angle) }
bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, { b.laserMine(mech.pos, velocity)
bulletType: "mine",
angle: mech.angle,
friction: 0,
frictionAir: 0.05,
restitution: 0.5,
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 60 + Math.floor(7 * Math.random()),
drain: tech.isLaserDiode * tech.laserFieldDrain,
isArmed: false,
torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1),
range: 1500,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
beforeDmg() {},
onEnd() {
if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "mine") {
b.guns[i].ammo++
simulation.updateGunHUD();
break;
}
}
}
},
do() {
if (!(simulation.cycle % this.lookFrequency) && mech.energy > this.drain) { //find mob targets
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 2000000 &&
mob[i].dropPowerUp &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
this.do = this.laserSpin
this.endCycle = simulation.cycle + 300
// if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin
this.isArmed = true
}
}
}
},
reflections: Math.max(0, tech.laserReflections - 2),
laserSpin() {
//drain energy
if (mech.energy > this.drain) {
mech.energy -= this.drain
if (this.angularSpeed < 0.02) this.torque += this.inertia * this.torqueMagnitude //spin
//fire lasers
ctx.strokeStyle = "#f00";
ctx.lineWidth = 1.5
// ctx.globalAlpha = 1;
ctx.beginPath();
for (let i = 0; i < 3; i++) {
const where = this.vertices[i]
const endPoint = Vector.add(where, Vector.mult(Vector.normalise(Vector.sub(where, this.position)), 2500))
b.laser(where, endPoint, tech.laserDamage * 10, this.reflections, true)
}
ctx.stroke();
// ctx.globalAlpha = 1;
}
}
})
// if (tech.isMineSentry) {
// bullet[me].endCycle = simulation.cycle + 480
// bullet[me].do = bullet[me].laserSpin
// bullet[me].isArmed = true
// Matter.Body.setAngularVelocity(bullet[me], 3000 * bullet[me].torqueMagnitude);
// }
let speed = mech.crouch ? 50 : 20
Matter.Body.setVelocity(bullet[me], {
x: speed * Math.cos(mech.angle),
y: speed * Math.sin(mech.angle)
});
World.add(engine.world, bullet[me]); //add bullet to world
} else { //normal mines } else { //normal mines
const pos = { const pos = {
x: mech.pos.x + 30 * Math.cos(mech.angle), x: mech.pos.x + 30 * Math.cos(mech.angle),
@@ -4008,9 +4001,13 @@ const b = {
mech.fireCDcycle = mech.cycle mech.fireCDcycle = mech.cycle
mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
const dmg = 0.55 * tech.laserDamage // 3.5 * 0.55 = 200% more damage const dmg = 0.55 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
const eye = {
x: mech.pos.x + 16 * Math.cos(mech.angle),
y: mech.pos.y + 16 * Math.sin(mech.angle)
}
const wideLaser = function(where = { const wideLaser = function(where = {
x: mech.pos.x + 20 * Math.cos(mech.angle), x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle) y: mech.pos.y + 30 * Math.sin(mech.angle)
}, angle = mech.angle) { }, angle = mech.angle) {
ctx.strokeStyle = "#f00"; ctx.strokeStyle = "#f00";
ctx.lineWidth = 8 ctx.lineWidth = 8
@@ -4018,26 +4015,35 @@ const b = {
ctx.beginPath(); ctx.beginPath();
const off = 7.5 const off = 7.5
b.laser(where, { b.laser(where, {
x: where.x + 3000 * Math.cos(angle), x: eye.x + 3000 * Math.cos(angle),
y: where.y + 3000 * Math.sin(angle) y: eye.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.3) }, dmg, 0, true, 0.3)
for (let i = 1; i < tech.wideLaser; i++) { for (let i = 1; i < tech.wideLaser; i++) {
let whereOff = Vector.add(where, { let whereOff = Vector.add(where, {
x: i * off * Math.cos(angle + Math.PI / 2), x: i * off * Math.cos(angle + Math.PI / 2),
y: i * off * Math.sin(angle + Math.PI / 2) y: i * off * Math.sin(angle + Math.PI / 2)
}) })
b.laser(whereOff, { if (Matter.Query.ray(map, eye, whereOff).length === 0) {
x: whereOff.x + 3000 * Math.cos(angle), ctx.moveTo(eye.x, eye.y)
y: whereOff.y + 3000 * Math.sin(angle) ctx.lineTo(whereOff.x, whereOff.y)
}, dmg, 0, true, 0.3) b.laser(whereOff, {
x: whereOff.x + 3000 * Math.cos(angle),
y: whereOff.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.3)
}
whereOff = Vector.add(where, { whereOff = Vector.add(where, {
x: i * off * Math.cos(angle - Math.PI / 2), x: i * off * Math.cos(angle - Math.PI / 2),
y: i * off * Math.sin(angle - Math.PI / 2) y: i * off * Math.sin(angle - Math.PI / 2)
}) })
b.laser(whereOff, { if (Matter.Query.ray(map, eye, whereOff).length === 0) {
x: whereOff.x + 3000 * Math.cos(angle), ctx.moveTo(eye.x, eye.y)
y: whereOff.y + 3000 * Math.sin(angle) ctx.lineTo(whereOff.x, whereOff.y)
}, dmg, 0, true, 0.3) b.laser(whereOff, {
x: whereOff.x + 3000 * Math.cos(angle),
y: whereOff.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.3)
}
} }
ctx.stroke(); ctx.stroke();
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
@@ -4052,21 +4058,7 @@ const b = {
mech.fireCDcycle = mech.cycle mech.fireCDcycle = mech.cycle
mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
ctx.strokeStyle = "#f00"; const spacing = Math.ceil(5.2 - 0.2 * tech.historyLaser)
let spacing, len
if (tech.wideLaser === 3) {
ctx.lineWidth = 2
spacing = 2
len = 10 + tech.historyLaser * 5
} else if (tech.wideLaser === 4) {
ctx.lineWidth = 3
spacing = 1
len = 15 + tech.historyLaser * 5
} else {
ctx.lineWidth = 1
spacing = 5
len = 5 + tech.historyLaser * 5
}
ctx.beginPath(); ctx.beginPath();
b.laser({ b.laser({
x: mech.pos.x + 20 * Math.cos(mech.angle), x: mech.pos.x + 20 * Math.cos(mech.angle),
@@ -4075,7 +4067,7 @@ const b = {
x: mech.pos.x + 3000 * Math.cos(mech.angle), x: mech.pos.x + 3000 * Math.cos(mech.angle),
y: mech.pos.y + 3000 * Math.sin(mech.angle) y: mech.pos.y + 3000 * Math.sin(mech.angle)
}, dmg, 0, true, 0.2); }, dmg, 0, true, 0.2);
for (let i = 1; i < len; i++) { for (let i = 1, len = 5 + tech.historyLaser * 5; i < len; i++) {
const history = mech.history[(mech.cycle - i * spacing) % 600] const history = mech.history[(mech.cycle - i * spacing) % 600]
b.laser({ b.laser({
x: history.position.x + 20 * Math.cos(history.angle), x: history.position.x + 20 * Math.cos(history.angle),
@@ -4085,6 +4077,8 @@ const b = {
y: history.position.y + 3000 * Math.sin(history.angle) - mech.yPosDifference y: history.position.y + 3000 * Math.sin(history.angle) - mech.yPosDifference
}, dmg, 0, true, 0.2); }, dmg, 0, true, 0.2);
} }
ctx.strokeStyle = "#f00";
ctx.lineWidth = 1
ctx.stroke(); ctx.stroke();
} }
}, },

View File

@@ -19,14 +19,14 @@ const level = {
// mech.setField("plasma torch") // mech.setField("plasma torch")
// b.giveGuns("laser") // b.giveGuns("laser")
// tech.isMineSentry = true // tech.isMineSentry = true
// tech.giveTech("foam fractionation") // tech.giveTech("diffuse beam")
// tech.giveTech("missile-bot") // tech.giveTech("missile-bot")
// tech.giveTech("nail-bot") // tech.giveTech("nail-bot")
// for (let i = 0; i < 15; i++) tech.giveTech("plasma jet") // for (let i = 0; i < 15; i++) tech.giveTech("plasma jet")
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation // level.testing(); //not in rotation
// level.escape() //after the final boss, ending // level.null() //after the final boss, ending
// level.final() //final boss level // level.final() //final boss level
// level.gauntlet(); //before final boss level // level.gauntlet(); //before final boss level
// level.testChamber() //less mobs, more puzzle // level.testChamber() //less mobs, more puzzle
@@ -61,11 +61,8 @@ const level = {
b.respawnBots(); b.respawnBots();
mech.resetHistory(); mech.resetHistory();
if (tech.isArmorFromPowerUps) { if (tech.isArmorFromPowerUps) {
const gain = Math.min(0.03 * powerUps.totalPowerUps, 0.42) tech.armorFromPowerUps += Math.min(0.03 * powerUps.totalPowerUps, 0.42)
tech.armorFromPowerUps += gain
mech.setMaxHealth(); mech.setMaxHealth();
// if (powerUps.totalPowerUps) simulation.makeTextLog("<span style='font-size:115%;'> max health increased by " + (gain * 100).toFixed(0) + "%</span>", 300)
simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>+=</span> ${(gain).toFixed(2)}`)
} }
if (tech.isHealLowHealth) { if (tech.isHealLowHealth) {
const len = Math.floor((mech.maxHealth - mech.health) / 0.5) const len = Math.floor((mech.maxHealth - mech.health) / 0.5)
@@ -98,7 +95,7 @@ const level = {
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
escape() { null() {
const hazardSlime = level.hazard(-1775, 150, 3575, 650, 0.01, "hsla(160, 100%, 35%,0.75)") const hazardSlime = level.hazard(-1775, 150, 3575, 650, 0.01, "hsla(160, 100%, 35%,0.75)")
// const hazardLaser1 = level.hazard(-475, -800, 1, 800, 0.4, "#50f", true) //laser // const hazardLaser1 = level.hazard(-475, -800, 1, 800, 0.4, "#50f", true) //laser
// const hazardLaser2 = level.hazard(475, -800, 1, 800, 0.4, "#50f", true) //laser // const hazardLaser2 = level.hazard(475, -800, 1, 800, 0.4, "#50f", true) //laser
@@ -165,7 +162,7 @@ const level = {
// spawn.mapRect(450, -820, 50, 25); //edge shelf ceiling // spawn.mapRect(450, -820, 50, 25); //edge shelf ceiling
// spawn.bodyRect(1540, -1110, 300, 25, 0.9); // spawn.bodyRect(1540, -1110, 300, 25, 0.9);
setTimeout(() => { simulation.makeTextLog(`test`) }, 3000); // setTimeout(() => { simulation.makeTextLog(`test`) }, 3000);

View File

@@ -1,5 +1,28 @@
const lore = { const lore = {
alfie: {
color: "#e06",
text: function(say, isSpeech = false) {
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${Date.now()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
if (isSpeech) this.speech(say)
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-GB";
speechSynthesis.speak(utterance);
}
},
zoe: {
color: "#f50",
text: function(say, isSpeech = false) {
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${Date.now()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
if (isSpeech) this.speech(say)
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-AU";
speechSynthesis.speak(utterance);
}
},
dialogue: [ dialogue: [
``, ``,
``, ``,
@@ -8,27 +31,18 @@ const lore = {
} }
} }
/* ending outline
if no cheats
after final boss is cleared, player enters a level with no mobs // speech: function(say) {
level maybe has some environmental damage, so player has an option to die at any time // var utterance = new SpeechSynthesisUtterance(say);
player can see text output between two colors of text strings (scientists) // //msg.voice = voices[10]; // Note: some voices don't support altering params
audio.ambient(current time and date)<br> "text" // //msg.voiceURI = 'native';
player reads a conversation between the two colors of text // //utterance.volume = 1; // 0 to 1
first time win on east or normal they talk about: // //utterance.rate = 1; // 0.1 to 10
how many runs the player has done // //utterance.pitch = 1; //0 to 2
they guess why // //utterance.text = 'Hello World';
player is asked to stand on an in game button to enable the vocoder // //http://stackoverflow.com/questions/14257598/what-are-language-codes-for-voice-recognition-languages-in-chromes-implementati
they reveal the player is running simulations, and it isn't real // //de-DE en-GB fr-FR en-US en-AU
they ask the player to communicate // utterance.lang = "en-GB";
jump twice if you understand // speechSynthesis.speak(utterance);
they ask the player to enter console commands // }
give ammo or tech or something
They tell the play a console command to permanently enable custom and testing mode (in local storage)
players can use this command in the future to enable custom and testing without beating the game even if local storage is wiped
they then tell the player the command to increase the difficulty and the command to restart the game.
If you win on hard or why:
they give the player and option to exit the simulation and entre the real world
simulation.exit()
This wipes all local storage, and closes the browser tab
*/

View File

@@ -481,10 +481,9 @@ const mech = {
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
const set = mech.baseHealth + tech.bonusHealth + tech.armorFromPowerUps mech.maxHealth = mech.baseHealth + tech.bonusHealth + tech.armorFromPowerUps
simulation.makeTextLog(`<span class='color-var'>mech</span>.maxHealth <span class='color-symbol'>=</span> ${set}`) simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${mech.maxHealth.toFixed(2)}`)
mech.maxHealth = set if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
if(mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth(); mech.displayHealth();
}, },
@@ -900,19 +899,19 @@ const mech = {
}, },
setMaxEnergy() { setMaxEnergy() {
mech.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus mech.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus
simulation.makeTextLog(`<span class='color-var'>mech</span>.maxEnergy <span class='color-symbol'>=</span> ${mech.maxEnergy}`) simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(mech.maxEnergy.toFixed(2))}`)
}, },
fieldMeterColor: "#0cf", fieldMeterColor: "#0cf",
drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
if (mech.energy < mech.maxEnergy) { if (mech.energy < mech.maxEnergy) {
mech.energy += mech.fieldRegen; mech.energy += mech.fieldRegen;
if (mech.energy < 0) mech.energy = 0
ctx.fillStyle = bgColor; ctx.fillStyle = bgColor;
const xOff = mech.pos.x - mech.radius * mech.maxEnergy const xOff = mech.pos.x - mech.radius * mech.maxEnergy
const yOff = mech.pos.y - 50 const yOff = mech.pos.y - 50
ctx.fillRect(xOff, yOff, range * mech.maxEnergy, 10); ctx.fillRect(xOff, yOff, range * mech.maxEnergy, 10);
ctx.fillStyle = mech.fieldMeterColor; ctx.fillStyle = mech.fieldMeterColor;
ctx.fillRect(xOff, yOff, range * mech.energy, 10); ctx.fillRect(xOff, yOff, range * mech.energy, 10);
if (mech.energy < 0) mech.energy = 0
} else if (mech.energy > mech.maxEnergy + 0.05) { } else if (mech.energy > mech.maxEnergy + 0.05) {
ctx.fillStyle = bgColor; ctx.fillStyle = bgColor;
const xOff = mech.pos.x - mech.radius * mech.energy const xOff = mech.pos.x - mech.radius * mech.energy
@@ -1142,7 +1141,7 @@ const mech = {
y: powerUp[i].velocity.y * 0.11 y: powerUp[i].velocity.y * 0.11
}); });
if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough
powerUps.onPickUp(mech.pos); powerUps.onPickUp(powerUp[i]);
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
x: player.velocity.x + powerUp[i].velocity.x / player.mass * 5, x: player.velocity.x + powerUp[i].velocity.x / player.mass * 5,
y: player.velocity.y + powerUp[i].velocity.y / player.mass * 5 y: player.velocity.y + powerUp[i].velocity.y / player.mass * 5
@@ -1502,11 +1501,12 @@ const mech = {
mech.hold = function() { mech.hold = function() {
if (mech.energy > mech.maxEnergy - 0.02 && mech.fieldCDcycle < mech.cycle && !input.field && bullet.length < 200) { if (mech.energy > mech.maxEnergy - 0.02 && mech.fieldCDcycle < mech.cycle && !input.field && bullet.length < 200) {
if (tech.isSporeField) { if (tech.isSporeField) {
const len = Math.floor(5 + 4 * Math.random()) // const len = Math.floor(5 + 4 * Math.random())
mech.energy -= len * 0.105; const len = Math.ceil(mech.energy * 10)
mech.energy = 0;
for (let i = 0; i < len; i++) b.spore(mech.pos) for (let i = 0; i < len; i++) b.spore(mech.pos)
} else if (tech.isMissileField) { } else if (tech.isMissileField) {
mech.energy -= 0.55; mech.energy -= 0.5;
b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1) b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1)
} else if (tech.isIceField) { } else if (tech.isIceField) {
mech.energy -= 0.057; mech.energy -= 0.057;
@@ -1926,6 +1926,7 @@ const mech = {
if (mech.energy < mech.maxEnergy) { // replaces mech.drawFieldMeter() with custom code if (mech.energy < mech.maxEnergy) { // replaces mech.drawFieldMeter() with custom code
mech.energy += mech.fieldRegen; mech.energy += mech.fieldRegen;
if (mech.energy < 0) mech.energy = 0
const xOff = mech.pos.x - mech.radius * mech.maxEnergy const xOff = mech.pos.x - mech.radius * mech.maxEnergy
const yOff = mech.pos.y - 50 const yOff = mech.pos.y - 50
ctx.fillStyle = "rgba(0, 0, 0, 0.3)"; ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
@@ -2145,7 +2146,7 @@ const mech = {
y: powerUp[i].velocity.y * 0.11 y: powerUp[i].velocity.y * 0.11
}); });
if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough
powerUps.onPickUp(powerUp[i].position); powerUps.onPickUp(powerUp[i]);
powerUp[i].effect(); powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); powerUp.splice(i, 1);
@@ -2388,7 +2389,7 @@ const mech = {
}); });
if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
powerUps.onPickUp(powerUp[i].position); powerUps.onPickUp(powerUp[i]);
powerUp[i].effect(); powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); powerUp.splice(i, 1);

View File

@@ -461,15 +461,16 @@ const powerUps = {
} }
} }
}, },
onPickUp(where) { onPickUp(who) {
if (tech.isTechDamage && who.name === "tech") mech.damage(0.11)
if (tech.isMassEnergy) mech.energy += 2.5; if (tech.isMassEnergy) mech.energy += 2.5;
if (tech.isMineDrop) b.mine({ if (tech.isMineDrop) {
x: where.x, if (tech.isLaserMine) { //laser mine
y: where.y b.laserMine(who.position)
}, { } else {
x: 0, b.mine(who.position, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
y: 0 }
}, 0, tech.isMineAmmoBack) }
}, },
giveRandomAmmo() { giveRandomAmmo() {
const ammoTarget = Math.floor(Math.random() * (b.guns.length)); const ammoTarget = Math.floor(Math.random() * (b.guns.length));

View File

@@ -514,7 +514,6 @@ const simulation = {
input.endKeySensing(); input.endKeySensing();
b.removeAllGuns(); b.removeAllGuns();
simulation.isNoPowerUps = false; simulation.isNoPowerUps = false;
tech.setupAllTech(); //sets tech to default values tech.setupAllTech(); //sets tech to default values
tech.laserBotCount = 0; tech.laserBotCount = 0;
tech.orbitBotCount = 0; tech.orbitBotCount = 0;
@@ -529,23 +528,23 @@ const simulation = {
powerUps.totalPowerUps = 0; powerUps.totalPowerUps = 0;
powerUps.research.research = 0; powerUps.research.research = 0;
mech.setFillColors(); mech.setFillColors();
mech.maxHealth = 1 // mech.maxHealth = 1
mech.maxEnergy = 1 // mech.maxEnergy = 1
mech.energy = 1 // mech.energy = 1
mech.hole.isOn = false mech.hole.isOn = false
simulation.paused = false; simulation.paused = false;
engine.timing.timeScale = 1; engine.timing.timeScale = 1;
simulation.fpsCap = simulation.fpsCapDefault; simulation.fpsCap = simulation.fpsCapDefault;
simulation.isAutoZoom = true; simulation.isAutoZoom = true;
simulation.makeGunHUD(); simulation.makeGunHUD();
mech.drop(); simulation.lastLogTime = 0;
mech.holdingTarget = null
mech.health = 0.25;
mech.displayHealth();
mech.alive = true;
level.onLevel = 0; level.onLevel = 0;
level.levelsCleared = 0; level.levelsCleared = 0;
//resetting difficulty //resetting difficulty
simulation.dmgScale = 0; //increases in level.difficultyIncrease simulation.dmgScale = 0; //increases in level.difficultyIncrease
b.dmgScale = 1; //decreases in level.difficultyIncrease b.dmgScale = 1; //decreases in level.difficultyIncrease
@@ -560,6 +559,14 @@ const simulation = {
document.getElementById("text-log").style.opacity = 0; document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0; document.getElementById("fade-out").style.opacity = 0;
document.title = "n-gon"; document.title = "n-gon";
mech.alive = true;
mech.setMaxHealth()
mech.health = 0;
mech.addHealth(0.25)
mech.drop();
mech.holdingTarget = null
//set to default field //set to default field
mech.fieldMode = 0; mech.fieldMode = 0;
// simulation.makeTextLog(`${simulation.SVGrightMouse}<strong style='font-size:30px;'> ${mech.fieldUpgrades[mech.fieldMode].name}</strong><br><span class='faded'></span><br>${mech.fieldUpgrades[mech.fieldMode].description}`, 600); // simulation.makeTextLog(`${simulation.SVGrightMouse}<strong style='font-size:30px;'> ${mech.fieldUpgrades[mech.fieldMode].name}</strong><br><span class='faded'></span><br>${mech.fieldUpgrades[mech.fieldMode].description}`, 600);
@@ -573,45 +580,36 @@ const simulation = {
// <br>input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>right mouse</span>"] // <br>input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>right mouse</span>"]
// <br><span class='color-var'>mech</span>.field.description <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>" // <br><span class='color-var'>mech</span>.field.description <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>"
// `, 800); // `, 800);
let delay = 500 let delay = 500
const step = 150 const step = 150
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.up<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`); simulation.makeTextLog(`input.key.up<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`);
}, delay); }, delay += step);
delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.left<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`); simulation.makeTextLog(`input.key.left<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`);
}, delay); }, delay += step);
delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.down<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`); simulation.makeTextLog(`input.key.down<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`);
}, delay); }, delay += step);
delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.right<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`); simulation.makeTextLog(`input.key.right<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`);
}, delay); }, delay += step);
delay += 1000
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`<br><span class='color-var'>mech</span>.fieldMode <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>"`); simulation.makeTextLog(`<br><span class='color-var'>mech</span>.fieldMode <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>"`);
}, delay); }, delay += step);
delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`); simulation.makeTextLog(`input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`);
}, delay); }, delay += step);
// delay += step
// setTimeout(function() {
// simulation.makeTextLog(`<span class='color-var'>mech</span>.field.description<br>"<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>"`);
// }, delay);
mech.setField(mech.fieldMode) mech.setField(mech.fieldMode)
// mech.energy = 0;
//exit testing //exit testing
if (simulation.testing) { if (simulation.testing) {
simulation.testing = false; simulation.testing = false;
simulation.loop = simulation.normalLoop simulation.loop = simulation.normalLoop
if (simulation.isConstructionMode) { if (simulation.isConstructionMode) document.getElementById("construct").style.display = 'none'
document.getElementById("construct").style.display = 'none'
}
} }
simulation.isCheating = false simulation.isCheating = false
simulation.firstRun = false; simulation.firstRun = false;

View File

@@ -77,6 +77,7 @@ const tech = {
}, },
damageFromTech() { damageFromTech() {
let dmg = mech.fieldDamage let dmg = mech.fieldDamage
if (tech.isTechDamage) dmg *= 2
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - mech.energy) * 0.5 if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - mech.energy) * 0.5
if (tech.isMaxEnergyTech) dmg *= 1.4 if (tech.isMaxEnergyTech) dmg *= 1.4
@@ -185,7 +186,7 @@ const tech = {
count: 0, count: 0,
isNonRefundable: true, isNonRefundable: true,
allowed() { allowed() {
return tech.isDamageForGuns || tech.isFireRateForGuns return (tech.isDamageForGuns || tech.isFireRateForGuns) && (b.inventory.length + 5) < b.guns.length
}, },
requires: "arsenal or cyclic rate boost", requires: "arsenal or cyclic rate boost",
effect() { effect() {
@@ -1181,9 +1182,9 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return !tech.isEnergyLoss && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field" && !tech.isHealLowHealth return !tech.isEnergyLoss && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field" && !tech.isHealLowHealth && !tech.isTechDamage
}, },
requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass", requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass , ...",
effect: () => { effect: () => {
mech.health = 0 mech.health = 0
// mech.displayHealth(); // mech.displayHealth();
@@ -1282,9 +1283,9 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return tech.isEnergyLoss && mech.maxEnergy < 1.1 && !tech.isMissileField && !tech.isSporeField && !tech.isRewindAvoidDeath return tech.isEnergyLoss && mech.maxEnergy < 1.1 && !tech.isSporeField && !tech.isRewindAvoidDeath
}, },
requires: "exothermic process, not max energy increase, CPT, missile or spore nano-scale", requires: "exothermic process, not max energy increase, CPT, or spore nano-scale",
effect() { effect() {
tech.isMaxEnergyTech = true; tech.isMaxEnergyTech = true;
mech.setMaxEnergy() mech.setMaxEnergy()
@@ -1400,7 +1401,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mech.health < 0.6 || build.isCustomSelection return mech.health < 0.5 || build.isCustomSelection
}, },
requires: "health below 60", requires: "health below 60",
effect() { effect() {
@@ -1409,6 +1410,21 @@ const tech = {
remove() { remove() {
tech.isLowHealthDmg = false; tech.isLowHealthDmg = false;
} }
}, {
name: "antiscience",
description: "increase <strong class='color-d'>damage</strong> by <strong>100%</strong><br>lose <strong>11</strong> <strong class='color-h'>health</strong> when you pick up a <strong class='color-m'>tech</strong>",
maxCount: 1,
count: 0,
allowed() {
return (mech.harmReduction() < 1 || tech.healthDrain || tech.isLowHealthDmg || tech.isHealthRecovery || tech.isHealLowHealth || tech.largerHeals > 1 || tech.isPerpetualHeal) && !tech.isEnergyHealth
},
requires: "negative feedback or extra healing tech or harm reduction, not mass-energy",
effect() {
tech.isTechDamage = true;
},
remove() {
tech.isTechDamage = false;
}
}, },
{ {
name: "entropy exchange", name: "entropy exchange",
@@ -2822,7 +2838,7 @@ const tech = {
}, },
{ {
name: "mutualism", name: "mutualism",
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>100%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>", description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3093,9 +3109,9 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser && !tech.historyLaser
}, },
requires: "laser, not specular reflection<br>not diffraction grating", requires: "laser, not specular reflection, diffraction grating, slow light",
effect() { effect() {
if (tech.wideLaser === 0) tech.wideLaser = 3 if (tech.wideLaser === 0) tech.wideLaser = 3
tech.isWideLaser = true; tech.isWideLaser = true;
@@ -3115,14 +3131,14 @@ const tech = {
name: "output coupler", name: "output coupler",
description: "<strong>widen</strong> diffuse <strong class='color-laser'>laser</strong> beam by <strong>40%</strong><br>increase full beam <strong class='color-d'>damage</strong> by <strong>40%</strong>", description: "<strong>widen</strong> diffuse <strong class='color-laser'>laser</strong> beam by <strong>40%</strong><br>increase full beam <strong class='color-d'>damage</strong> by <strong>40%</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
return tech.haveGunCheck("laser") && tech.isWideLaser return tech.haveGunCheck("laser") && tech.isWideLaser
}, },
requires: "laser, not specular reflection<br>not diffraction grating", requires: "laser, not specular reflection<br>not diffraction grating",
effect() { effect() {
tech.wideLaser = 4 tech.wideLaser += 2
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
} }
@@ -3145,9 +3161,9 @@ const tech = {
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser && !tech.isWideLaser
}, },
requires: "laser, not specular reflection<br>not diffraction grating", requires: "laser, not specular reflection, diffraction grating, diffuse beam",
effect() { effect() {
// this.description = `add 5 more <strong>laser</strong> beams into into your past` // this.description = `add 5 more <strong>laser</strong> beams into into your past`
tech.historyLaser++ tech.historyLaser++
@@ -3434,7 +3450,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab) return mech.maxEnergy > 0.5 && mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab)
}, },
requires: "nano-scale manufacturing", requires: "nano-scale manufacturing",
effect() { effect() {
@@ -4057,5 +4073,6 @@ const tech = {
isIceIX: null, isIceIX: null,
isDupDamage: null, isDupDamage: null,
isFireRateForGuns: null, isFireRateForGuns: null,
cyclicImmunity: null cyclicImmunity: null,
isTechDamage: null
} }

View File

@@ -1,12 +1,8 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
tech: active cooling - 15% faster fire rate for each gun in your inventory tech: antiscience - 100% damage, but lose 11 health when you pick up a tech
tech: specialist - spawn a random power up for each gun in your inventory tech: laser widebeam + output coupler can now stack up to 9x (was 1x)
(not available in custom, requires tech: generalist) but it not longer works with tech: slow light propagation
tech: complex spin-statistics - become immune to harm for 1s every 7s
requires Pauli exclusion
even less difficulty ramp after killing final boss
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -27,8 +23,7 @@ CPT check for crouch after rewind
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
tech "Circadian Rhythm": Become immune to harm for 1 second every 10 seconds while playing. tech: can't fire while moving, get attack speed and damage
bot that follows the players history bot that follows the players history
could have the same shape as the mech circle head could have the same shape as the mech circle head
@@ -437,7 +432,7 @@ ending outline
jump twice if you understand jump twice if you understand
they ask the player to enter console commands they ask the player to enter console commands
give ammo or tech or something give ammo or tech or something
They tell the play a console command to permanently enable custom and testing mode (in local storage) They tell the player a console command to permanently enable custom and testing mode (in local storage)
players can use this command in the future to enable custom and testing without beating the game even if local storage is wiped players can use this command in the future to enable custom and testing without beating the game even if local storage is wiped
they then tell the player the command to increase the difficulty and the command to restart the game. they then tell the player the command to increase the difficulty and the command to restart the game.
If you win on hard or why: If you win on hard or why: