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

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,
}