some tech come with a skin - but only 1 at a time
  tech aperture -  skin, damage cycles between -25% and +125%
  tungsten carbide - skin, +100->150 max health
  mass-energy equivalence - skin, gets a bit more benefit from defense
  CPT symmetry - skin, costs a bit less energy
  flip-flop, and relay switch and a few JUNK tech are also skins

some new images
bug fixes
This commit is contained in:
landgreen
2023-02-04 06:54:08 -08:00
parent 74f569b836
commit c9f355b225
26 changed files with 960 additions and 473 deletions

BIN
img/aperture.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -83,6 +83,7 @@
<input list="ban-suggest" id="banned" name="banned" placeholder="list levels by name" autocomplete="off" spellcheck="false" style="width: 182px;" />
<datalist id="ban-suggest">
<option value="testChamber">
<option value="lock">
<option value="sewers">
<option value="satellite">
<option value="aerie">
@@ -103,6 +104,7 @@
<option value="vats">
<option value="basement">
<option value="stronghold">
<option value="stereo madness">
<option value="house">
<option value="dripp">
<option value="crossfire">

View File

@@ -109,7 +109,7 @@ function collisionChecks(event) {
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (m.isCloak) dmg *= 0.75
mob[k].foundPlayer();
if (tech.isRewindAvoidDeath && m.energy > 0.66 && dmg > 0.01) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(1, m.maxEnergy) && dmg > 0.01) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
m.damage(dmg);
return
}

View File

@@ -335,7 +335,7 @@ const build = {
<span style="float: right;">press ${input.key.pause} to resume</span>
<br>
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(4)}
<br><strong class='color-defense'>defense</strong>: ${tech.isEnergyHealth ? (1-Math.pow(m.harmReduction(), 0.1)).toPrecision(5) : (1-m.harmReduction()).toPrecision(5) } &nbsp; &nbsp; difficulty: ${(1/simulation.dmgScale).toPrecision(4)}
<br><strong class='color-defense'>defense</strong>: ${tech.isEnergyHealth ? (1-Math.pow(m.harmReduction(), 0.12)).toPrecision(5) : (1-m.harmReduction()).toPrecision(5) } &nbsp; &nbsp; difficulty: ${(1/simulation.dmgScale).toPrecision(4)}
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%`: ""}
${m.coupling ? `<br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)} &nbsp; <span style = 'font-size:90%;'>`+m.couplingDescription()+"</span>": ""}
@@ -358,13 +358,13 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
</span></div>`;
// deaths: ${mobs.mobDeaths} &nbsp;
if (tech.isPauseSwitchField && !simulation.isChoosing) {
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? Math.floor(Math.random()*10) : ""}.webp');"`
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
<div class="card-text" style = "animation: fieldColorCycle 1s linear infinite alternate;">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
} else {
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? Math.floor(Math.random()*10) : ""}.webp');"`
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
@@ -412,7 +412,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
// } else {
// text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
// }
const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"`
const style = (localSettings.isHideImages || tech.tech[i].isJunk || tech.tech[i].isLore) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"`
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isNonRefundable) {
text += `<div class="pause-grid-module" id ="${i}-pause-tech" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; margin: 1px; padding: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
@@ -629,7 +629,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
</div>`
const hideStyle = `style="height:auto; border: none; background-color: transparent;"`
for (let i = 0, len = m.fieldUpgrades.length; i < len; i++) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[i].name}${i === 0 ? Math.floor(Math.random()*10) : ""}.webp');"`
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[i].name}${i === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
//original
// text += powerUps.fieldText(i, `build.choosePowerUp(this,${i},'field')`)
// text += `<div id ="field-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'field')"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div> ${m.fieldUpgrades[i].description}</div>`
@@ -1642,7 +1642,7 @@ if (!localSettings.isHideImages) {
for (let i = 0, len = b.guns.length; i < len; i++) urls.push("img/gun/" + b.guns[i].name + ".webp")
for (let i = 1, len = m.fieldUpgrades.length; i < len; i++) urls.push("img/field/" + m.fieldUpgrades[i].name + ".webp")
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isJunk) urls.push("img/" + tech.tech[i].name + ".webp")
if (!tech.tech[i].isJunk && !tech.tech[i].isLore) urls.push("img/" + tech.tech[i].name + ".webp")
}
let images = new Array()
for (let i = 0; i < urls.length; i++) {

View File

@@ -23,7 +23,7 @@ const level = {
// spawn.setSpawnList();
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(10)
// powerUps.research.changeRerolls(6)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
@@ -33,18 +33,16 @@ const level = {
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 10000
// tech.giveTech("vacuum bomb")
// for (let i = 0; i < 3; ++i) tech.giveTech("collider")
// tech.giveTech("diffuse beam")
// for (let i = 0; i < 1; ++i) tech.giveTech("super ball")
// tech.isFoamBall = true
// for (let i = 0; i < 3; ++i) tech.giveTech("repeater")
// for (let i = 0; i < 1; i++) tech.giveTech("irradiated nails")
// for (let i = 0; i < 1; i++) tech.giveTech("colony")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// tech.giveTech("tungsten carbide")
// tech.giveTech("ship")
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence")
// for (let i = 0; i < 1; ++i) tech.giveTech("squirrel-cage rotor")
for (let i = 0; i < 1; i++) tech.giveTech("CPT symmetry")
// for (let i = 0; i < 1; i++) tech.giveTech("Meissner effect")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.lock();
// level.testChamber();
// spawn.nodeGroup(1200, 0, "slasher")
// spawn.blinkBoss(1900, -500)
// spawn.sneakBoss(1900, -500)
@@ -61,6 +59,10 @@ const level = {
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level ************************************************
// simulation.isAutoZoom = false;
// simulation.zoomScale *= 0.5;
// simulation.setZoom();
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "gun");
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
@@ -422,7 +424,7 @@ const level = {
player.velocity.y < 0.15
) {
// level.exitCount += input.down ? 8 : 2
level.exitCount++
level.exitCount += 2
} else if (level.exitCount > 0) {
level.exitCount -= 2
}
@@ -4520,6 +4522,8 @@ const level = {
spawn.mapVertex(4075, 2079, "-150 30 -120 0 150 0 150 600 -150 600");
//escape ledge when drowning
spawn.mapRect(2750, 525, 100, 25);
spawn.mapRect(2750, 125, 100, 25);
spawn.mapRect(4425, 800, 75, 25);
spawn.mapRect(4425, 325, 75, 25);
// spawn.mapRect(4425, -100, 75, 25);
@@ -14246,9 +14250,7 @@ const level = {
ctx.restore();
}
} else {
m.draw = () => {
m.drawDefault()
}
m.resetSkin()
m.airControl = () => {
if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + 5 > m.cycle) m.jump()
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {

View File

@@ -63,14 +63,14 @@ const m = {
grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
},
setFillColorsAlpha(alpha = 0.5) {
m.fillColor = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light}%,${alpha})`
m.fillColorDark = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%,${alpha})`
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
},
// setFillColorsAlpha(alpha = 0.5) {
// m.fillColor = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light}%,${alpha})`
// m.fillColorDark = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%,${alpha})`
// let grd = ctx.createLinearGradient(-30, 0, 30, 0);
// grd.addColorStop(0, m.fillColorDark);
// grd.addColorStop(1, m.fillColor);
// m.bodyGradient = grd
// },
height: 42,
yOffWhen: {
crouch: 22,
@@ -533,7 +533,7 @@ const m = {
},
baseHealth: 1,
setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 1.5 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -706,7 +706,7 @@ const m = {
}
}
if (tech.isEnergyHealth) {
dmg *= Math.pow(m.harmReduction(), 0.1) //defense has less effect
dmg *= Math.pow(m.harmReduction(), 0.12) //defense has less effect
m.energy -= 0.9 * dmg / Math.sqrt(simulation.healScale) //scale damage with heal reduction difficulty
if (m.energy < 0 || isNaN(m.energy)) { //taking deadly damage
if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) {
@@ -810,47 +810,10 @@ const m = {
// }
},
buttonCD: 0, //cool down for player buttons
drawLeg(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 7;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineWidth = 4;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 7, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 6, m.foot.y);
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = m.fillColor;
ctx.fill();
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
},
// *********************************************
// ****** drawing player and skins *************
// *********************************************
drawLeg(stroke) {},
calcLeg(cycle_offset, offset) {
m.hip.x = 12 + offset;
m.hip.y = 24 + offset;
@@ -871,61 +834,752 @@ const m = {
m.knee.y = (l / d) * (m.foot.y - m.hip.y) + (h / d) * (m.foot.x - m.hip.x) + m.hip.y;
},
draw() {},
drawFlipFlop() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
isAltSkin: false,
resetSkin() {
m.isAltSkin = false
m.color = {
hue: 0,
sat: 0,
light: 100,
}
m.setFillColors();
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 7;
ctx.stroke();
//draw body
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineWidth = 4;
ctx.stroke();
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
//draw eye
ctx.beginPath();
ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
ctx.fillStyle = m.eyeFillColor;
ctx.fill()
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 7, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 6, m.foot.y);
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = m.fillColor;
ctx.fill();
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
}
},
drawDefault() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
skin: {
none() {
m.isAltSkin = true
},
energy() {
m.isAltSkin = true
m.color = {
hue: 184,
sat: 100,
light: 85,
}
m.setFillColors();
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.strokeStyle = "rgba(0,255,255,0.22)";
ctx.lineWidth = 12;
ctx.stroke();
ctx.fillStyle = 'hsl(184,100%,85%)' //m.fillColor; //"#9ff" //m.bodyGradient
ctx.fill();
ctx.beginPath();
ctx.arc(17, 0, 5.5, 0, 2 * Math.PI);
ctx.fillStyle = "#333"
ctx.fill();
ctx.beginPath();
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 7;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineWidth = 4;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 7, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 6, m.foot.y);
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.strokeStyle = "rgba(0,255,255,0.25)";
ctx.lineWidth = 5;
ctx.stroke();
ctx.fillStyle = m.fillColor;
ctx.fill();
ctx.restore();
}
},
tungsten() {
m.isAltSkin = true
m.color = {
hue: 210,
sat: 5,
light: 75,
}
// m.setFillColors();
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 50}%)`
const grd = ctx.createLinearGradient(-30, -5, 30, 10);
grd.addColorStop(0, `#eee`);
grd.addColorStop(0.3, `#bbb`);
grd.addColorStop(0.4, `#aaa`);
grd.addColorStop(0.5, `#ccc`);
grd.addColorStop(0.65, `#bbb`);
grd.addColorStop(0.7, `#aaa`);
grd.addColorStop(0.75, `#bbb`);
grd.addColorStop(1, `#eee`);
// const grdRad = ctx.createRadialGradient(0, 0, 0, 0, 0, 30);
// grdRad.addColorStop(0, `rgba(0,0,0,0.3)`);
// grdRad.addColorStop(0.5, `rgba(210,210,210,0)`);
m.bodyGradient = grd
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(4.2, -3);
m.drawLeg("#666");
m.calcLeg(2.1, -1);
m.drawLeg("#5f5f5f");
m.calcLeg(0, 1);
m.drawLeg("#555");
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
// ctx.fillStyle = grdRad
// ctx.fill();
ctx.strokeStyle = "#000";
ctx.lineWidth = 1.5;
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.fillStyle = "#fff"
ctx.fill();
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 4.5;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y - 1);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineTo(m.foot.x, m.foot.y - 1);
ctx.lineWidth = 4;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y - 4, 12, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 6, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 6, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 5, m.foot.y);
ctx.arc(m.foot.x, m.foot.y, 5, 0, 2 * Math.PI);
ctx.fillStyle = m.fillColor;
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = "#000"
ctx.stroke();
ctx.restore();
}
},
anodize() {
m.isAltSkin = true
m.color = {
hue: 210,
sat: 14,
light: 65,
}
// m.setFillColors();
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 50}%)`
// let grd = ctx.createLinearGradient(-30, 0, 30, 0);
const grd = ctx.createRadialGradient(16, 0, 0, 0, 0, 40);
// grd.addColorStop(0, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`);
// grd.addColorStop(0.25, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 20}%)`);
// grd.addColorStop(0.5, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`);
// grd.addColorStop(1, `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 10}%)`);
grd.addColorStop(0, `#c78034`);
grd.addColorStop(0.04, `#bd5235`);
grd.addColorStop(0.08, `#ab554d`);
grd.addColorStop(0.12, `#8f5d8f`);
grd.addColorStop(0.16, `#4352ab`);
grd.addColorStop(0.2, `#2058b3`);
grd.addColorStop(0.24, `#1a6fc4`);
grd.addColorStop(0.28, `#1b85cf`);
grd.addColorStop(0.32, `#2d9bd7`);
grd.addColorStop(0.4, `#d2d7b4`);
grd.addColorStop(0.44, `#e1cd87`);
grd.addColorStop(0.48, `#f0b955`);
grd.addColorStop(0.52, `#ffa050`);
grd.addColorStop(0.56, `#ff8269`);
grd.addColorStop(0.6, `#f5697d`);
grd.addColorStop(0.64, `#e65aaf`);
grd.addColorStop(0.68, `#d732d7`);
grd.addColorStop(0.72, `#c846e6`);
grd.addColorStop(0.76, `#c850fa`);
grd.addColorStop(0.8, `#878cf0`);
grd.addColorStop(0.84, `#37beeb`);
grd.addColorStop(0.88, `#00d2be`);
grd.addColorStop(0.92, `#00e19b`);
grd.addColorStop(0.96, `#19f5aa`);
grd.addColorStop(1, `#aaf5af`);
m.bodyGradient = grd
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a5a");
m.calcLeg(0, 0);
m.drawLeg("#445");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#222";
ctx.lineWidth = 2;
// ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 7;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineWidth = 4;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
ctx.fillStyle = "#1b85cf";
ctx.fill();
//knee joint
ctx.beginPath();
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
ctx.fillStyle = "#ffa050";
ctx.fill();
//foot joint
ctx.beginPath();
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = "#878cf0";
ctx.fill();
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
}
},
dilate() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.beginPath();
ctx.arc(12, 0, 8 + 4 * Math.sin(m.cycle * 0.01), 0, 2 * Math.PI); //big eye
ctx.fillStyle = `hsl(${150+100*Math.sin(m.cycle * 0.01)},100%,50%)`
ctx.fill();
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
},
CPT() {
m.isAltSkin = true
m.color = {
hue: 0,
sat: 0,
light: 100,
}
// m.setFillColors();
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 45}%)`
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#3a3a3a");
m.calcLeg(0, 0);
m.drawLeg("#222");
ctx.rotate(0.013 * simulation.cycle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.arc(m.pos.x + 15 * Math.cos(m.angle), m.pos.y + 15 * Math.sin(m.angle), 5, 0, 2 * Math.PI);
ctx.fillStyle = "#222"
ctx.fill();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 7;
ctx.stroke();
//toe lines
ctx.beginPath();
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
ctx.moveTo(m.foot.x, m.foot.y);
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
ctx.lineWidth = 4;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 7, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(m.foot.x + 6, m.foot.y);
ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI);
ctx.fillStyle = m.fillColor;
ctx.fill();
// ctx.lineWidth = 2;
// ctx.stroke();
ctx.restore();
}
},
stubs() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#555");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function(stroke) {
// if (simulation.mouseInGame.x > m.pos.x) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(m.hip.x, m.hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(m.foot.x, m.foot.y + 5);
ctx.strokeStyle = stroke;
ctx.lineWidth = 6;
ctx.stroke();
ctx.restore();
}
},
Sleipnir() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
for (let i = 0; i < 16; i++) {
m.calcLeg(Math.PI * i / 8, -3 * i / 16)
m.drawLeg("#444")
}
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
},
diegesis() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle - (m.fireCDcycle !== Infinity ? m.flipLegs * 0.25 * Math.pow(Math.max(m.fireCDcycle - m.cycle, 0), 0.5) : 0));
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
},
cat() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
ctx.scale(1, -1);
ctx.rotate(Math.PI);
}
ctx.beginPath();
ctx.moveTo(-30, 0);
ctx.bezierCurveTo(-65, -75,
-5, 150 + (5 * Math.sin(simulation.cycle / 10)),
-70 + (10 * Math.sin(simulation.cycle / 10)), 0 + (10 * Math.sin(simulation.cycle / 10)));
ctx.strokeStyle = "#333";
ctx.lineWidth = 4;
ctx.stroke();
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
ctx.scale(1, -1);
ctx.rotate(0 - Math.PI);
}
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) ctx.scale(1, -1);
ctx.beginPath();
ctx.moveTo(5, -30);
ctx.lineTo(20, -40);
ctx.lineTo(20, -20);
ctx.lineWidth = 2;
ctx.fillStyle = "#f3f";
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.stroke();
ctx.moveTo(19, 0);
ctx.arc(15, 0, 4, Math.PI, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(24.3, 6, 5, Math.PI * 2, Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(30, 6);
ctx.lineTo(32, 0);
ctx.lineTo(26, 0);
ctx.lineTo(30, 6);
ctx.fillStyle = "#f3f";
ctx.fill();
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
},
pareidolia() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.7
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) ctx.scale(1, -1); //here is the flip
ctx.stroke();
ctx.beginPath();
ctx.arc(2, -6, 7, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(25, -6, 7, 0.25 * Math.PI, 1.6 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(2, -10, 9, 1.25 * Math.PI, 1.75 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(25, -10, 9, 1.25 * Math.PI, 1.4 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(18, 13, 10, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient;
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(18, 13, 6, 0, 2 * Math.PI);
ctx.fillStyle = "#555";
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(3, -6, 3, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(26, -6, 3, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15;
}
},
flipFlop() {
m.isAltSkin = true
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
//draw body
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
//draw eye
ctx.beginPath();
ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
ctx.fillStyle = m.eyeFillColor;
ctx.fill()
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
}
},
// *********************************************
// **************** fields *********************
@@ -1699,6 +2353,7 @@ const m = {
},
fieldUpgrades: [{
name: "field emitter",
imageNumber: Math.floor(Math.random() * 17),
description: `use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs
<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`, // <br><strong>100</strong> max <strong class='color-f'>energy</strong>
effect: () => {
@@ -1991,12 +2646,10 @@ const m = {
m.throwBlock();
} else if (input.field) { //not hold but field button is pressed
//float while field is on
// console.log(m.angle, Math.abs(m.angle + Math.PI / 2))
//
const angleReduction = 0.1 + (Math.PI / 2 - Math.min(Math.PI / 2, Math.abs(m.angle + Math.PI / 2)))
const angleReduction = 0.5 + 0.7 * (Math.PI / 2 - Math.min(Math.PI / 2, Math.abs(m.angle + Math.PI / 2)))
console.log(angleReduction)
if (player.velocity.y > 1) {
player.force.y -= angleReduction * (tech.isBigField ? 0.9 : 0.7) * player.mass * simulation.g;
player.force.y -= angleReduction * (tech.isBigField ? 0.95 : 0.5) * player.mass * simulation.g;
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: 0.98 * player.velocity.y
@@ -4226,7 +4879,7 @@ const m = {
}
//fix collisions
collisionChecks = (event) => {
collisionChecks = function(event) {
const pairs = event.pairs;
for (let i = 0, j = pairs.length; i != j; i++) {
//mob + (player,bullet,body) collisions
@@ -4250,7 +4903,7 @@ const m = {
) {
mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (tech.isRewindAvoidDeath && m.energy > 0.66) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(1, m.maxEnergy) && dmg > 0.01) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
m.damage(dmg);
return
}

View File

@@ -663,7 +663,7 @@ const powerUps = {
// width = "384px"
// }
let text = ""
if (localSettings.isHideImages || canvas.width < 1200) {
if (totalChoices === 1 || localSettings.isHideImages || canvas.width < 1200) {
document.getElementById("choose-grid").style.gridTemplateColumns = width
text += powerUps.cancelText(type)
text += powerUps.researchText(type)
@@ -671,10 +671,6 @@ const powerUps = {
document.getElementById("choose-grid").style.gridTemplateColumns = `repeat(2, ${width})`
text += powerUps.researchText(type)
text += powerUps.cancelText(type)
} else if (totalChoices === 1) {
document.getElementById("choose-grid").style.gridTemplateColumns = width
text += powerUps.cancelText(type)
text += powerUps.researchText(type)
} else {
document.getElementById("choose-grid").style.gridTemplateColumns = `repeat(3, ${width})`
text += "<div></div>"
@@ -718,7 +714,7 @@ const powerUps = {
},
techText(choose, click) {
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
const style = localSettings.isHideImages || tech.tech[choose].isLore ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"`
return `<div class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${style}>
<div class="card-text">
<div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
@@ -1044,15 +1040,15 @@ const powerUps = {
text += powerUps.fieldText(pick, `powerUps.choose('field',${pick})`)
}
}
if (tech.isMicroTransactions && powerUps.research.count > 0) {
const skins = [] //find skins
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isSkin) skins.push(i)
}
const choose = skins[Math.floor(Math.seededRandom(0, skins.length))] //pick an element from the array of options
// if (tech.isMicroTransactions && powerUps.research.count > 0) {
// const skins = [] //find skins
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech[i].isSkin) skins.push(i)
// }
// const choose = skins[Math.floor(Math.seededRandom(0, skins.length))] //pick an element from the array of options
text += `<div class="choose-grid-module" onclick="tech.giveTech(${choose});powerUps.research.changeRerolls(-1);powerUps.endDraft('tech');powerUps.tech.effect();"><div class="grid-title"><div class="circle-grid research"></div> <span style = 'font-size:90%; font-weight: 100; letter-spacing: -1.5px;'>microtransaction:</span> ${tech.tech[choose].name}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
// text += `<div class="choose-grid-module" onclick="tech.giveTech(${choose});powerUps.research.changeRerolls(-1);powerUps.endDraft('tech');powerUps.tech.effect();"><div class="grid-title"><div class="circle-grid research"></div> <span style = 'font-size:90%; font-weight: 100; letter-spacing: -1.5px;'>microtransaction:</span> ${tech.tech[choose].name}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
// }
if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
tech.isBrainstormActive = true
let count = 0
@@ -1410,13 +1406,13 @@ const powerUps = {
if (bigIndexes.length > 0) {
// console.log("at least 1 big will always spilt")
const index = bigIndexes[Math.floor(Math.random() * bigIndexes.length)]
for (let i = 0; i < 4; i++) powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
for (let i = 0; i < 3; i++) powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false)
Matter.Composite.remove(engine.world, powerUp[index]);
powerUp.splice(index, 1);
} else if (smallIndexes.length > 3 && Math.random() < 0.25) {
// console.log("no big, at least 4 small can combine")
for (let j = 0; j < 4; j++) {
} else if (smallIndexes.length > 2 && Math.random() < 0.33) {
// console.log("no big, at least 3 small can combine")
for (let j = 0; j < 3; j++) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal" || powerUp[i].name === "research" || powerUp[i].name === "ammo" || powerUp[i].name === "coupling" || powerUp[i].name === "boost") {
Matter.Composite.remove(engine.world, powerUp[i]);

View File

@@ -676,48 +676,6 @@ const simulation = {
},
fpsInterval: 0, //set in startGame
then: null,
introPlayer() { //not work, but trying to show player in the intro screen
setTimeout(() => {
document.getElementById("info").style.display = "none";
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
simulation.clearMap()
m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech
m.spawn(); //spawns the player
m.look = m.lookDefault
//level
level.testing(); //not in rotation, used for testing
//load level
simulation.setZoom();
level.addToWorld(); //add bodies to game engine
simulation.draw.setPaths();
function cycle() {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
// m.look();
// simulation.camera();
m.draw();
m.hold();
simulation.draw.drawMapPath();
ctx.restore();
if (simulation.onTitlePage) requestAnimationFrame(cycle);
}
requestAnimationFrame(cycle)
}, 1000);
},
startGame(isBuildRun = false, isTrainingRun = false) {
simulation.isTextLogOpen = true
simulation.clearMap()
@@ -762,7 +720,7 @@ const simulation = {
})
// ctx.shadowColor = '#000';
if (!m.isShipMode) {
m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech
m.resetSkin() //set the play draw to normal, undoing some junk tech
m.spawn(); //spawns the player
m.look = m.lookDefault
} else {

View File

@@ -220,6 +220,7 @@ 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 (tech.isDilate) dmg *= 1.25 + Math.sin(m.cycle * 0.01)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling
@@ -733,10 +734,10 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
return this.count > 0
},
requires: "",
effect() { // good with melee builds, content skipping builds
effect() {
tech.squirrelFx += 0.25;
tech.squirrelJump += 0.1;
m.setMovement()
@@ -1008,7 +1009,7 @@ const tech = {
{
name: "collider",
descriptionFunction() {
return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance <br>to change a <strong>power up</strong> into a different <strong>flavor</strong>`
return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance <br>to smash <strong>power ups</strong> into a different <strong>flavor</strong>`
},
maxCount: 3,
count: 0,
@@ -1896,6 +1897,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return !tech.isRelay
},
@@ -1912,7 +1914,7 @@ const tech = {
}
}
if (!m.isShipMode) {
m.draw = m.drawFlipFlop
m.skin.flipFlop()
}
},
remove() {
@@ -1927,6 +1929,7 @@ const tech = {
}
}
m.eyeFillColor = 'transparent'
m.resetSkin();
}
},
{
@@ -2047,11 +2050,13 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return !tech.isFlipFlop
},
requires: "not flip-flop",
effect() {
m.isAltSkin = true
tech.isRelay = true //do you have this tech?
if (!tech.isFlipFlopOn) {
tech.isFlipFlopOn = true //what is the state of flip-Flop?
@@ -2063,7 +2068,7 @@ const tech = {
}
}
if (!m.isShipMode) {
m.draw = m.drawFlipFlop
m.skin.flipFlop()
}
},
remove() {
@@ -2078,6 +2083,7 @@ const tech = {
}
}
m.eyeFillColor = 'transparent'
m.resetSkin();
}
},
{
@@ -2293,21 +2299,24 @@ const tech = {
// description: "<strong>charge</strong>, <strong>parity</strong>, and <strong>time</strong> invert to undo <strong class='color-defense'>defense</strong><br><strong class='color-rewind'>rewind</strong> <strong>(1.5—5)</strong> seconds for <strong>(66—220)</strong> <strong class='color-f'>energy</strong>",
// description: "after losing <strong class='color-h'>health</strong>, if you have <strong>full</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second",
descriptionFunction() {
return `after losing <strong class='color-h'>health</strong>, if you have <strong>${(100*Math.min(100,m.maxEnergy)).toFixed(0)}</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second`
return `after losing <strong class='color-h'>health</strong>, if you have <strong>${(100*Math.min(100,m.maxEnergy)).toFixed(0)}</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>40</strong> <strong class='color-f'>energy</strong> per second`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth
return !m.isAltSkin && m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth
},
requires: "not standing wave, max energy reduction, retrocausality, mass-energy",
requires: "not skinned, standing wave, max energy reduction, retrocausality, mass-energy",
effect() {
tech.isRewindAvoidDeath = true;
m.skin.CPT()
},
remove() {
tech.isRewindAvoidDeath = false;
m.resetSkin();
}
},
{
@@ -2371,13 +2380,14 @@ const tech = {
{
name: "mass-energy equivalence",
// description: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br>√ of <strong class='color-defense'>defense</strong> <strong>reduction</strong> reduces max <strong class='color-f'>energy</strong>",
description: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br>exponentially <strong>reduced</strong> <strong class='color-defense'>defense</strong> <em>(~ x^0.1)</em>",
description: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br>exponentially <strong>reduced</strong> <strong class='color-defense'>defense</strong> <em>(~ x^0.12)</em>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun
return !m.isAltSkin && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun
},
requires: "not piezoelectricity, CPT, annihilation",
effect() {
@@ -2386,8 +2396,9 @@ const tech = {
document.getElementById("health-bg").style.display = "none"
document.getElementById("dmg").style.backgroundColor = "#0cf";
tech.isEnergyHealth = true;
simulation.mobDmgColor = "rgba(14, 190, 235,0.7)" //"#0cf"
simulation.mobDmgColor = "rgba(0, 255, 255,0.6)" //"#0cf"
m.displayHealth();
m.skin.energy();
},
remove() {
if (tech.isEnergyHealth) {
@@ -2400,6 +2411,7 @@ const tech = {
m.displayHealth();
}
tech.isEnergyHealth = false;
m.resetSkin();
}
},
{
@@ -2850,23 +2862,26 @@ const tech = {
},
{
name: "tungsten carbide",
description: "<strong>+100</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
description: "<strong>+150</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return true
return !m.isAltSkin
},
requires: "",
requires: "not skin",
effect() {
tech.isFallingDamage = true;
m.setMaxHealth();
m.addHealth(1 / simulation.healScale)
m.skin.tungsten()
},
remove() {
tech.isFallingDamage = false;
m.setMaxHealth();
m.resetSkin();
}
},
{
@@ -3495,6 +3510,27 @@ const tech = {
}
}
},
{
name: "aperture",
description: "your damage cycles every <strong>6</strong> seconds<br>between <strong>-75%</strong> and <strong>+125%</strong> <strong class='color-d'>damage</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return !m.isAltSkin
},
requires: "not skinned",
effect() {
tech.isDilate = true
m.skin.dilate()
},
remove() {
tech.isDilate = false
m.resetSkin();
}
},
{
name: "exciton",
descriptionFunction() {
@@ -10063,30 +10099,25 @@ const tech = {
},
remove() {}
},
// {
// name: "inverted input",
// description: "left input becomes right and up input becomes down",
// maxCount: 9,
// count: 0,
// frequency: 0,
// isNonRefundable: true,
// isExperimentHide: true,
// isJunk: true,
// allowed() {
// return true
// },
// requires: "",
// effect() {
// const left = input.key.left
// input.key.left = input.key.right
// input.key.right = left
// const up = input.key.up
// input.key.up = input.key.down
// input.key.down = up
// },
// remove() {}
// },
{
name: "stubs",
description: "no knees or toes are drawn on the player",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.skin.stubs()
},
remove() {
m.resetSkin();
}
},
{
name: "Sleipnir",
description: "grow more legs",
@@ -10094,44 +10125,17 @@ const tech = {
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
//draw body
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
for (let i = 0; i < 16; i++) {
m.calcLeg(Math.PI * i / 8, -3 * i / 16)
m.drawLeg("#444")
}
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
// ctx.beginPath();
// ctx.arc(15, 0, 3, 0, 2 * Math.PI);
// ctx.fillStyle = '#0cf';
// ctx.fill()
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
m.skin.Sleipnir()
},
remove() {}
remove() {
m.resetSkin();
}
},
{
name: "diegesis",
@@ -10140,39 +10144,17 @@ const tech = {
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle - (m.fireCDcycle !== Infinity ? m.flipLegs * 0.25 * Math.pow(Math.max(m.fireCDcycle - m.cycle, 0), 0.5) : 0));
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
m.skin.diegesis()
},
remove() {}
remove() {
m.resetSkin();
}
},
{
name: "🐱",
@@ -10181,80 +10163,17 @@ const tech = {
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
ctx.scale(1, -1);
ctx.rotate(Math.PI);
}
ctx.beginPath();
ctx.moveTo(-30, 0);
ctx.bezierCurveTo(-65, -75,
-5, 150 + (5 * Math.sin(simulation.cycle / 10)),
-70 + (10 * Math.sin(simulation.cycle / 10)), 0 + (10 * Math.sin(simulation.cycle / 10)));
ctx.strokeStyle = "#333";
ctx.lineWidth = 4;
ctx.stroke();
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
ctx.scale(1, -1);
ctx.rotate(0 - Math.PI);
}
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) ctx.scale(1, -1);
ctx.beginPath();
ctx.moveTo(5, -30);
ctx.lineTo(20, -40);
ctx.lineTo(20, -20);
ctx.lineWidth = 2;
ctx.fillStyle = "#f3f";
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.stroke();
ctx.moveTo(19, 0);
ctx.arc(15, 0, 4, Math.PI, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(24.3, 6, 5, Math.PI * 2, Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(30, 6);
ctx.lineTo(32, 0);
ctx.lineTo(26, 0);
ctx.lineTo(30, 6);
ctx.fillStyle = "#f3f";
ctx.fill();
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
m.skin.cat();
},
remove() {}
remove() {
m.resetSkin();
}
},
{
name: "n-gone",
@@ -10263,7 +10182,6 @@ const tech = {
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return true
@@ -10272,7 +10190,29 @@ const tech = {
effect() {
m.draw = () => {}
},
remove() {}
remove() {
m.resetSkin();
}
},
{
name: "pareidolia",
description: "don't",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.skin.pareidolia()
},
remove() {
m.resetSkin();
}
},
{
name: "posture",
@@ -10280,7 +10220,6 @@ const tech = {
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isJunk: true,
allowed() {
return !m.isShipMode
@@ -10299,7 +10238,6 @@ const tech = {
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isJunk: true,
isNonRefundable: true,
allowed() {
@@ -10314,82 +10252,12 @@ const tech = {
},
remove() {}
},
{
name: "pareidolia",
description: "don't",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
m.draw = function() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.7
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) ctx.scale(1, -1); //here is the flip
ctx.stroke();
ctx.beginPath();
ctx.arc(2, -6, 7, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(25, -6, 7, 0.25 * Math.PI, 1.6 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(2, -10, 9, 1.25 * Math.PI, 1.75 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(25, -10, 9, 1.25 * Math.PI, 1.4 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(18, 13, 10, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient;
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(18, 13, 6, 0, 2 * Math.PI);
ctx.fillStyle = "#555";
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(3, -6, 3, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(26, -6, 3, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15;
}
},
remove() {}
},
{
name: "prism",
description: "you cycle through different <strong>colors</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isSkin: true,
isNonRefundable: true,
isJunk: true,
allowed() {
@@ -10409,24 +10277,24 @@ const tech = {
},
remove() {}
},
{
name: "microtransactions",
description: `when you choose a <strong class='color-m'>tech</strong> you can<br>use ${powerUps.orb.research(1)} to buy a free in game <strong>skin</strong>`,
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
tech.isMicroTransactions = true
},
remove() {
tech.isMicroTransactions = false
}
},
// {
// name: "microtransactions",
// description: `when you choose a <strong class='color-m'>tech</strong> you can<br>use ${powerUps.orb.research(1)} to buy a free in game <strong>skin</strong>`,
// maxCount: 1,
// count: 0,
// frequency: 0,
// isJunk: true,
// allowed() {
// return true
// },
// requires: "",
// effect() {
// tech.isMicroTransactions = true
// },
// remove() {
// tech.isMicroTransactions = false
// }
// },
{
name: "ship",
description: "fly around with no legs<br>reduce combat <strong>difficulty</strong> by <strong>1 level</strong>",
@@ -10436,10 +10304,11 @@ const tech = {
isNonRefundable: true,
isJunk: true,
allowed() {
return !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
return !m.isShipMode && !m.isAltSkin && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
},
requires: "",
effect() {
m.isAltSkin = true
m.shipMode()
level.difficultyDecrease(simulation.difficultyMode)
//unlock relativistic rotation
@@ -11399,7 +11268,7 @@ const tech = {
quantumEraserCount: null,
isPhononBlock: null,
isPhononWave: null,
isMicroTransactions: null,
// isMicroTransactions: null,
isLaserLens: null,
laserCrit: null,
isSporeColony: null,
@@ -11422,4 +11291,5 @@ const tech = {
isSuperMine: null,
sentryAmmo: null,
collidePowerUps: null,
isDilate: null,
}

View File

@@ -1,38 +1,50 @@
******************************************************** NEXT PATCH **************************************************
exit doors take longer to open
it's nice to take a few seconds to relax between levels
please don't submit a bug report about this
some tech come with a skin - but only 1 at a time
tech aperture - skin, damage cycles between -25% and +125%
tungsten carbide - skin, +100->150 max health
mass-energy equivalence - skin, gets a bit more benefit from defense
CPT symmetry - skin, costs a bit less energy
flip-flop, and relay switch and a few JUNK tech are also skins
plasma torch energy regen 6->10
perfect diamagnetism energy regen 6->5
a few more new images
tech: collider - after a mob dies smash power ups and change the flavor of one of them
powerUps.randomize(where)
if there is a tech,field,gun it will split into 4 small power ups
else if there are at least 4 small power ups they have a 1/4 chance to combine into a tech, field, gun
else a random small power up will change
some new images
bug fixes
*********************************************************** TODO *****************************************************
tech: if a needle hits 2 mobs reset your fire CD
and maybe to 2x damage for each consecutive mob hit?
tech for lens - you can only fire through the lens and some buff? damage or energy?
this was in todo.txt on GitHub. I think it should be 'laser never drains energy, but you can only fire through lens and +90° lens arc, +100% damage (also you can not gain compound lens with this upgrade)
Tech: Von Neuman probes - Drones will consume blocks to replicate themselves
it's a little too similar to the drone repair tech, but I kinda like it better. drones that eat blocks and spit out more drones is cool
new boss level like reactor with a very very big boss
mechanics around a very big boss?
maybe the boss moves into rooms so you have to do platforming to clear the room before the boss enters the room
boss can destroy blocks and smaller map elements
tech - after standing wave runs out of energy from blocking, gain a buff
buff: defense, damage?
aoe damage like railgun
push mobs away
diagetic UI Elements
ammo number?
doesn't text look choppy when camera moves?
health bar could be rendered similarly to energy bar
what about 2 bezier curves on left and right of player head that looks like 1/3 circleRadiusScale
what about 2 bezier both above player
rotate the curves as the head rotates
what about 2 bezier both above player
as the total energy and health increases the curses could asymptotically approach a maximum length as max energy/health goes to infinity
level: lock
should there be something in the top part of the map?
add alt versions of left and right sides
make flipped L/R version (after everything else is done)
Tech: Drones always follow you mouse, never going to attack enemies or pick up power ups unless they are close to your mouse
tech: add an selection option to all tech, gun, fields to do something
set all mobs to 30% health, and stun all mobs
50% chance to convert all power ups into research
@@ -43,8 +55,6 @@ tech: if you die inside MACHO, heal to full and delete the MACHO for the rest of
tech: after bosses die<br>they spawn a research
tech: neutrino oscillation - when a mob dies there is a __% chance to convert a random existing power up to a different type
tech: +8% damage each time you kill a boss
tech: maybe missiles explode when they hit walls, but explosions only drain energy
@@ -66,11 +76,6 @@ tech: Bose Einstein condensate - freezes enemies in pilot wave, and drains some
super-bot
tech - after standing wave runs out of energy from blocking, gain a buff
buff: defense, damage?
aoe damage like railgun
push mobs away
make super balls with Zectron deflectable with field
but is there a simple way to do this?
@@ -1172,6 +1177,7 @@ if pause is pressed while selecting power ups, display pause menu on top of sele
supercritical fission
***past style themes***
field emitter - isometric, clean white robot spherical gun turret on bird legs, blender 3d, style of artstation and behance, Disney Pixar, cute
damaged dirty white robot spherical gun turret on bird legs in the style of Solarpunk
standing wave - concentric transparent blue geometric circles science
perfect diamagnetism - physics magnetic field chalk diagram
time dilation - graphic of a hyperbolic equation Luminogram