scroll tech when choosing tech

you can scroll through the tech and gun menus while selecting power ups
added another classic n-gon option in settings

tech: options exchange - canceling tech,gun,field has a 90% chance for a reroll

stabber mobs now stab 15% shorter distance, but they can stab more often
weak interaction gives 5->10 max energy per unused power up

bug fixes
This commit is contained in:
landgreen
2022-04-25 06:35:36 -07:00
parent fcbbf29375
commit 099fc07efe
11 changed files with 175 additions and 104 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -71,11 +71,13 @@
<br>
<label for="classic-select" title="play older versions of n-gon">classic n-gon:</label>
<select name="classic-select" id="classic-select" onChange="window.location.href=this.value">
<option value="https://scratch.mit.edu/projects/14005697/fullscreen/">scratch: 2014</option>
<option value="https://scratch.mit.edu/projects/22573757/fullscreen/">scratch: 2015</option>
<option value="https://codepen.io/lilgreenland/full/ozXNWZ">codepen: 2016</option>
<option value="https://codepen.io/lilgreenland/full/wzARJY">codepen: 2016</option>
<option value="classic/7-1-2017/">n-gon: 2017</option>
<option value="https://scratch.mit.edu/projects/14005697/fullscreen/">mech: 2014</option>
<option value="https://scratch.mit.edu/projects/22573757/fullscreen/">spacetime: 2015</option>
<option value="https://scratch.mit.edu/projects/41429974/fullscreen/">ballistics: 2015</option>
<option value="https://scratch.mit.edu/projects/43690666/fullscreen/">portal: 2016</option>
<option value="https://codepen.io/lilgreenland/full/ozXNWZ">side scroller: 2016</option>
<option value="https://codepen.io/lilgreenland/full/wzARJY">side scroller: 2016</option>
<option value="classic/7-1-2017/">LandGame: 2017</option>
<option value="classic/4-15-2018/">n-gon: 2018</option>
<option value="classic/7-11-2019/">n-gon: summer-2019</option>
<option value="classic/9-8-2019/">n-gon: fall-2019</option>
@@ -191,7 +193,7 @@
</g>
</svg>
</a>
<a href="https://github.com/landgreen/n-gon">Github</a> hosts the source code for n-gon.<br> It's written in JavaScript, CSS, and HTML using the matter.js 2-D physics library.
<a href="https://github.com/landgreen/n-gon">Github</a> hosts n-gon's 2.5MB source code.<br>It's written in JavaScript, CSS, and HTML and uses the matter.js 2-D physics library.
</div>
</details>
</div>

View File

@@ -220,33 +220,6 @@ for (let i = 0, len = tech.tech.length; i < len; i++) {
}
const build = {
// onLoadPowerUps() {
// const set = getUrlVars()
// if (Object.keys(set).length !== 0) {
// for (const property in set) {
// set[property] = set[property].replace(/%20/g, " ")
// if (property.substring(0, 3) === "gun") b.giveGuns(set[property])
// if (property.substring(0, 3) === "tech") tech.giveTech(set[property])
// if (property === "field") m.setField(set[property])
// if (property === "difficulty") {
// simulation.difficultyMode = Number(set[property])
// document.getElementById("difficulty-select").value = Number(set[property])
// }
// if (property === "level") {
// level.levelsCleared += Number(set[property]);
// level.difficultyIncrease(Number(set[property]) * simulation.difficultyMode) //increase difficulty based on modes
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// level.onLevel++
// }
// }
// for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
// bullet = []; //remove any bullets that might have spawned from tech
// if (b.inventory.length > 0) {
// b.activeGun = b.inventory[0] //set first gun to active gun
// simulation.makeGunHUD();
// }
// }
// },
pauseGrid() {
//left side
let botText = ""
@@ -264,14 +237,7 @@ const build = {
<br><br><svg class="SVG-button" onclick="build.shareURL(false)" width="92" height="20" style="padding:0px; margin: 1px;">
<g stroke='none' fill='#333' stroke-width="2" font-size="14px" font-family="Ariel, sans-serif"> <text x="5" y="15">copy build url</text></g>
</svg><br>`
//{ /* <strong class='color-d'>damage</strong> increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}% */ }
// <br>damage difficulty reduction: ${((1-m.dmgScale)*100).toFixed(2)}%
// <br>effective damage: ${(((tech.damageFromTech()-1)*m.dmgScale)*100).toFixed(0)}%
// <br>
// <br><strong class='color-d'>damage</strong> = ${((tech.damageFromTech())*100).toFixed(0)}% × ${((m.dmgScale)*100).toFixed(2)}% = ${(((tech.damageFromTech())*m.dmgScale)*100).toFixed(0)}%
/// <br>heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}%
text +=
`
text += `
<br>effective <strong class='color-d'>damage</strong>: ${(tech.damageFromTech() * m.dmgScale).toPrecision(4)}
<br>damage: ${((tech.damageFromTech())).toPrecision(4)}, difficulty: ${((m.dmgScale)).toPrecision(4)}
<br>
@@ -301,13 +267,13 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
//right side
text = "";
if (tech.isPauseSwitchField) {
if (tech.isPauseSwitchField && !simulation.isChoosing) {
text += `<div class="pause-grid-module" id ="pause-field" 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>`
} else {
text += `<div class="pause-grid-module" id ="pause-field"><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>`
}
const style = tech.isPauseEjectTech ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : ''
const style = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : ''
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) {
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
@@ -337,11 +303,24 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
el = document.getElementById("pause-grid-right")
el.style.display = "grid"
el.innerHTML = text
document.getElementById("tech").style.display = "none"
document.getElementById("guns").style.display = "none"
document.getElementById("field").style.display = "none"
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
},
unPauseGrid() {
document.getElementById("tech").style.display = "inline"
document.getElementById("guns").style.display = "inline"
document.getElementById("field").style.display = "inline"
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
// document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
document.getElementById("pause-grid-right").style.opacity = "1"
document.getElementById("pause-grid-left").style.opacity = "1"
window.scrollTo(0, 0);
},
isExperimentSelection: false,

View File

@@ -16,16 +16,16 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true
// m.setField("metamaterial cloaking")
// m.setField("standing wave")
// b.giveGuns("laser")
// tech.giveTech("scrap-bot manufacturing")
// tech.giveTech("dynamo-bot upgrade")
// tech.giveTech("time crystals")
// tech.giveTech("options exchange")
// tech.giveTech("ICBM")
// tech.giveTech("grappling hook")
// tech.giveTech("annelids")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(0, 0, "tech");
// for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
// tech.giveTech("paradigm shift")
// for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 15; i++) tech.giveTech()
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
// powerUps.research.changeRerolls(100000)
// for (let i = 0; i < 5; i++) tech.giveTech("corona discharge")
@@ -83,7 +83,7 @@ const level = {
}
}
if (tech.isExtraMaxEnergy) {
tech.healMaxEnergyBonus += 0.05 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51)
tech.healMaxEnergyBonus += 0.1 * powerUps.totalPowerUps //Math.min(0.02 * powerUps.totalPowerUps, 0.51)
m.setMaxEnergy();
}
if (tech.isGunCycle) {
@@ -243,7 +243,7 @@ const level = {
// level.levels.push(level.communityLevels)
level.levels = level.levels.concat(level.communityLevels)
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels
level.levels.splice(0, level.communityLevels.length); //remove some random levels to make up for adding the community levels
simulation.isHorizontalFlipped = false;
} else {
level.levels = shuffle(level.levels); //shuffles order of maps
@@ -2473,7 +2473,6 @@ const level = {
localSettings.loreCount++ //hear the next conversation next time you win
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
// const hazardSlime = level.hazard(-1800, 150, 3600, 650, 0.004, "hsla(160, 100%, 35%,0.75)")
level.isHazardRise = false //this is set to true to make the slime rise up
const hazardSlime = level.hazard(-1800, -800, 3600, 1600, 0.004, "hsla(160, 100%, 35%,0.75)")
@@ -2561,6 +2560,7 @@ const level = {
simulation.zoomTransition(level.defaultZoom)
// document.body.style.backgroundColor = "#aaa";
document.body.style.backgroundColor = "#ddd";
color.map = "#808f8f"
spawn.mapRect(-3000, 800, 5000, 1200); //bottom
spawn.mapRect(-2000, -2000, 5000, 1200); //ceiling
@@ -2624,7 +2624,7 @@ const level = {
spawn.mapRect(4850, -275, 50, 175);
//???
level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
m.addHealth(Infinity)
// spawn.starter(1900, -500, 200) //big boy
@@ -2636,7 +2636,7 @@ const level = {
// spawn.powerUpBossBaby(3200, -500)
// spawn.snakeBoss(1700, -500)
// spawn.streamBoss(3200, -500)
spawn.pulsarBoss(1700, -500)
// spawn.pulsarBoss(1700, -500)
// spawn.spawnerBossCulture(3200, -500)
// spawn.grenadierBoss(1700, -500)
// spawn.growBossCulture(3200, -500)
@@ -2646,7 +2646,7 @@ const level = {
// spawn.launcherBoss(3200, -500)
// spawn.blockBoss(1700, -500)
// spawn.blinkBoss(3200, -500)
// spawn.mantisBoss(1700, -500)
// spawn.spiderBoss(1700, -500)
// spawn.tetherBoss(1700, -500) //go to actual level?
// spawn.revolutionBoss(1900, -500)
// spawn.bomberBoss(1400, -500)
@@ -2654,8 +2654,8 @@ const level = {
// spawn.shieldingBoss(1700, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
// for (let i = 0; i < 5; i++) spawn.focuser(1900, -500)
spawn.pulsar(1900, -500)
for (let i = 0; i < 1; i++) spawn.stabber(1900, -500)
// spawn.pulsar(1900, -500)
// spawn.shield(mob[mob.length - 1], 1900, -500, 1);
// mob[mob.length - 1].isShielded = true
// spawn.nodeGroup(1200, 0, "grenadier")
@@ -2672,6 +2672,7 @@ const level = {
level.defaultZoom = 2000
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d0d5df" //"#d8dadf";
color.map = "#334046";
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
const button = level.button(1400, 0)
@@ -3198,6 +3199,8 @@ const level = {
level.defaultZoom = 2300
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d8dadf";
color.map = "#3d4240"
powerUps.spawnStartingPowerUps(-575, -2925)
// spawn.debris(750, -2200, 3700, 16); //16 debris per level //no debris?
@@ -3671,6 +3674,7 @@ const level = {
level.defaultZoom = 2200
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d5d5d5";
color.map = "#555"
spawn.mapRect(0, -1955, 175, 30);
const removeIndex1 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
spawn.mapRect(1225, -1955, 175, 30);
@@ -3968,6 +3972,7 @@ const level = {
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "hsl(138, 3%, 74%)";
color.map = "#3d4240"
powerUps.spawnStartingPowerUps(3475, 1775);
spawn.debris(4575, 2550, 1600, 9); //16 debris per level
spawn.debris(7000, 2550, 2000, 7); //16 debris per level
@@ -9489,10 +9494,9 @@ const level = {
Matter.Body.setDensity(me, 0.014); // extra dense, normal is 0.001 // makes effective life much larger
me.onDeath = function() {
// applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawn(this.position.x, this.position.y, "ammo");
powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.2) powerUps.spawn(this.position.x, this.position.y, "heal", true, null,
30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
powerUps.spawn(this.position.x + 20, this.position.y, "ammo");
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
if (simulation.difficulty > 5) {
// fling player to center
const SUB = V.sub(this.position, player.position)
@@ -9808,11 +9812,13 @@ const level = {
}
};
let oldNextLevel = level.nextLevel;
const oldFallHeight = simulation.fallHeight;
level.nextLevel = () => {
color.map = "#444";
m.death = m.oldDeath;
canvas.style.filter = "";
level.nextLevel = oldNextLevel;
simulation.fallHeight = oldFallHeight;
oldNextLevel();
}
let bounds = [];
@@ -9824,6 +9830,7 @@ const level = {
m.death = m.oldDeath;
canvas.style.filter = "";
level.nextLevel = oldNextLevel;
simulation.fallHeight = oldFallHeight;
}
m.oldDeath();
}
@@ -10233,6 +10240,7 @@ const level = {
level.exit.x = 4500;
level.exit.y = -2030;
relocateTo(50, -2050);
simulation.fallHeight = -1000;
simulation.setZoom(1800);
templePlayer.startAnim = -1;
for (let i = 0; i < tech.wimpCount + tech.wimpExperiment; i++) {
@@ -10266,6 +10274,7 @@ const level = {
if (templePlayer.room1ToRoom2Anim === 960) {
makeLore("You are trying too hard.");
relocateTo(0, -7050);
simulation.fallHeight = -6000;
templePlayer.stage = 2;
}
if (templePlayer.room1ToRoom2Anim === 1200) {
@@ -10313,6 +10322,7 @@ const level = {
makeLore("Do not interfere with me.");
templePlayer.stage = 3;
relocateTo(50, -13150);
simulation.fallHeight = -10000;
simulation.zoomTransition(1800);
templePlayer.startAnim = -1;
// Might be a bit harsh to the player if the WIMPs are involved in the third level

View File

@@ -1557,7 +1557,6 @@ const m = {
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
} else {
console.log(this.drainCD)
m.pushMass(mob[i]);
this.drainCD = m.cycle + 15
}

View File

@@ -259,14 +259,15 @@ const powerUps = {
showDraft() {
// document.getElementById("choose-grid").style.gridTemplateColumns = "repeat(2, minmax(370px, 1fr))"
// document.getElementById("choose-background").style.display = "inline"
document.getElementById("choose-background").style.visibility = "visible"
document.getElementById("choose-background").style.opacity = "0.6"
// document.getElementById("choose-background").style.visibility = "visible"
// document.getElementById("choose-background").style.opacity = "0.8"
// document.getElementById("choose-grid").style.display = "grid"
document.getElementById("choose-grid").style.transitionDuration = "0.25s";
document.getElementById("choose-grid").style.visibility = "visible"
document.getElementById("choose-grid").style.opacity = "1"
//disable clicking for 1/2 a second to prevent mistake clicks
document.getElementById("choose-grid").style.pointerEvents = "none";
document.body.style.cursor = "none";
setTimeout(() => {
document.getElementById("choose-grid").style.pointerEvents = "auto";
document.body.style.cursor = "auto";
@@ -279,10 +280,23 @@ const powerUps = {
// }
simulation.paused = true;
simulation.isChoosing = true; //stops p from un pausing on key down
build.pauseGrid(true)
build.pauseGrid()
document.getElementById("pause-grid-right").style.opacity = "0.3"
document.getElementById("pause-grid-left").style.opacity = "0.3"
//hide health bar, guns, power ups list
requestAnimationFrame(() => {
ctx.fillStyle = `rgba(221,221,221,0.6)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
},
endDraft(type, isCanceled = false) {
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
if (tech.isCancelTech && Math.random() < 0.9) {
// powerUps.research.use('tech')
powerUps[type].effect();
return
}
if (tech.isCancelDuplication) {
tech.cancelCount++
tech.maxDuplicationEvent()
@@ -300,6 +314,10 @@ const powerUps = {
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
}
}
// if (tech.isCancelTech && Math.random() < 0.3) {
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false);
// simulation.makeTextLog(`<strong>options exchange</strong>: returns 1 <strong class='color-m'>tech</strong>`)
// }
if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
for (let i = 0; i < banishLength; i++) {
@@ -579,7 +597,7 @@ const powerUps = {
let choice3 = -1
if (choice1 > -1) {
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'></div>`
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>`
powerUps.field.choiceLog.push(choice1)
@@ -689,7 +707,7 @@ const powerUps = {
}
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'></div>`
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick()
// console.log(choice1)
@@ -829,7 +847,7 @@ const powerUps = {
let choice3 = -1
if (choice1 > -1) {
let text = ""
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'></div>`
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
if (!tech.isDeterminism) {
@@ -1013,7 +1031,7 @@ const powerUps = {
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
powerUp[powerUp.length - 1].isDuplicated = true
// powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
@@ -1045,7 +1063,7 @@ const powerUps = {
}
},
pauseEjectTech(index) {
if (tech.isPauseEjectTech || simulation.testing) {
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing) {
if (Math.random() < 0.1 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
tech.removeTech(index)
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);

View File

@@ -631,6 +631,17 @@ const simulation = {
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
document.getElementById("dmg").style.display = "inline";
document.getElementById("health-bg").style.display = "inline";
document.getElementById("tech").style.display = "inline"
document.getElementById("guns").style.display = "inline"
document.getElementById("field").style.display = "inline"
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
// document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
document.getElementById("pause-grid-right").style.opacity = "1"
document.getElementById("pause-grid-left").style.opacity = "1"
ctx.globalCompositeOperation = "source-over"
ctx.shadowBlur = 0;
// ctx.shadowColor = '#000';
@@ -816,6 +827,9 @@ const simulation = {
let holdTarget = (m.holdingTarget) ? m.holdingTarget : undefined //if player is holding something this remembers it before it gets deleted
tech.deathSpawnsFromBoss = 0;
simulation.fallHeight = 3000;
document.body.style.backgroundColor = "#eee" //"#d8dadf";
color.map = "#444";
m.fireCDcycle = 0
m.drop();
m.hole.isOn = false;

View File

@@ -91,11 +91,11 @@ const spawn = {
spawn.lineGroup(x, y, pick);
}
} else {
if (Math.random() < 0.07) {
if (Math.random() < 0.1) {
spawn[pick](x, y, 90 + Math.random() * 40); //one extra large mob
spawn.spawnOrbitals(mob[mob.length - 1], mob[mob.length - 1].radius + 50 + 200 * Math.random(), 1)
} else if (Math.random() < 0.35) {
spawn.blockGroup(x, y) //hidden grouping blocks
// } else if (Math.random() < 0.35) {
// spawn.blockGroup(x, y) //hidden grouping blocks
} else {
pick = (Math.random() < 0.5) ? "randomList" : "random";
if (Math.random() < 0.55) {
@@ -3254,7 +3254,7 @@ const spawn = {
ctx.lineTo(best.x, best.y);
}
},
stabber(x, y, radius = 25 + Math.ceil(Math.random() * 12), spikeMax = 9) {
stabber(x, y, radius = 25 + Math.ceil(Math.random() * 12), spikeMax = 7) {
if (radius > 80) radius = 65;
mobs.spawn(x, y, 6, radius, "rgb(220,50,205)"); //can't have sides above 6 or collision events don't work (probably because of a convex problem)
let me = mob[mob.length - 1];
@@ -3265,11 +3265,14 @@ const spawn = {
me.spikeVertex = 0;
me.spikeLength = 0;
me.isSpikeGrowing = false;
me.spikeGrowth = 0;
me.isSpikeReset = true;
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.player //can't touch other mobs
Matter.Body.rotate(me, Math.PI * 0.1);
spawn.shield(me, x, y);
// me.onDamage = function () {};
// me.onHit = function() { //run this function on hitting player
// };
me.onDeath = function() {
if (this.spikeLength > 4) {
this.spikeLength = 4
@@ -3287,7 +3290,7 @@ const spawn = {
if (this.seePlayer.recall) {
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
if (distMag < this.radius * 7) {
if (distMag < radius * spikeMax) {
//find nearest vertex
let nearestDistance = Infinity
for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -3308,24 +3311,29 @@ const spawn = {
}
} else {
if (this.isSpikeGrowing) {
this.spikeLength += 1
this.spikeLength += Math.pow(this.spikeGrowth += 0.02, 8)
// if (this.spikeLength < 2) {
// this.spikeLength += 0.035
// } else {
// this.spikeLength += 1
// }
if (this.spikeLength > spikeMax) {
this.isSpikeGrowing = false;
this.spikeGrowth = 0
}
} else {
//reduce rotation
Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.8)
this.spikeLength -= 0.2
Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.8) //reduce rotation
this.spikeLength -= 0.3
if (this.spikeLength < 1) {
this.spikeLength = 1
this.isSpikeReset = true
this.radius = radius
}
}
const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), this.radius * this.spikeLength)
const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), radius * this.spikeLength)
this.vertices[this.spikeVertex].x = this.position.x + spike.x
this.vertices[this.spikeVertex].y = this.position.y + spike.y
// this.radius = radius * this.spikeLength;
}
};
},

View File

@@ -2246,7 +2246,7 @@ const tech = {
},
{
name: "weak interaction",
description: "each unused <strong>power up</strong> at the end of a <strong>level</strong><br>adds 5 <strong>maximum</strong> <strong class='color-f'>energy</strong>", // <em>(up to 51 health per level)</em>",
description: "each unused <strong>power up</strong> at the end of a <strong>level</strong><br>adds 10 <strong>maximum</strong> <strong class='color-f'>energy</strong>", // <em>(up to 51 health per level)</em>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3313,9 +3313,28 @@ const tech = {
tech.isShieldAmmo = false;
}
},
{
name: "options exchange",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>90%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isSuperDeterminism //&& (tech.isCancelRerolls || tech.isCancelDuplication)
},
requires: "not superdeterminism", //futures exchange, commodities exchange,
effect() {
tech.isCancelTech = true
},
remove() {
tech.isCancelTech = false
}
},
{
name: "commodities exchange",
description: `clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>5-10</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>5-10</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -5075,7 +5094,7 @@ const tech = {
},
{
name: "mutualism",
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong>health</strong> until they <strong>die</strong>",
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br>they borrow <strong>0.5</strong> <strong>health</strong> until they <strong>die</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5114,7 +5133,7 @@ const tech = {
// },
{
name: "nematodes",
description: "<strong>shotgun</strong> and <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> hatch <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong>", //<br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> do <strong>250%</strong> more <strong class='color-d'>damage</strong>
description: "<strong>shotgun</strong> and <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> hatch <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-m'>tech</strong> applies to <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5152,16 +5171,16 @@ const tech = {
},
{
name: "path integration",
description: "<strong>drones</strong>, <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>, and <strong class='color-p' style='letter-spacing: 2px;'>worms</strong><br>travel with you through <strong>levels</strong>",
description: "<strong>drones</strong>, <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>, and <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br>travel with you through <strong>levels</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.haveGunCheck("spores") && tech.isSporeFollow) || tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField))
return (tech.isSporeFollow && (tech.haveGunCheck("spores") || (tech.haveGunCheck("shotgun") && tech.isSporeWorm))) || tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField))
},
requires: "spores, diplochory, drones",
requires: "spores, worms, diplochory, drones",
effect() {
tech.isDronesTravel = true
},
@@ -5172,7 +5191,7 @@ const tech = {
{
name: "anti-shear topology",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Topology' class="link">anti-shear topology</a>`,
description: "some <strong>projectiles</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drone, spore, missile, foam, wave, neutron, ice</em>",
description: "some <strong>projectiles</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drone, spore, worm, missile, foam, wave, neutron, ice</em>",
isGunTech: true,
maxCount: 3,
count: 0,
@@ -7158,7 +7177,7 @@ const tech = {
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler"
},
requires: "metamaterial cloaking, molecular assembler, plasma torch or pilot wave",
requires: "cloaking, molecular assembler, plasma torch, pilot wave",
effect() {
tech.aimDamage = 1.35
b.setFireCD();
@@ -7217,9 +7236,9 @@ const tech = {
frequency: 3,
frequencyDefault: 3,
allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "wormhole") && (build.isExperimentSelection || powerUps.research.count > 3)
return (m.fieldUpgrades[m.fieldMode].name === "negative mass" || m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "wormhole") && (build.isExperimentSelection || powerUps.research.count > 3)
},
requires: "wormhole, time dilation",
requires: "wormhole, time dilation, negative mass",
effect() {
tech.fieldDuplicate = 0.12
powerUps.setDupChance(); //needed after adjusting duplication chance
@@ -9333,7 +9352,7 @@ const tech = {
},
{
name: "cosmogonic myth",
description: `open a portal to a primordial version of reality<br>after 5 minutes <strong>close</strong> the portal, and spawn 1 of every power up`,
description: `<span style = "opacity: 9%;">open a portal to a primordial version of reality<br>in 5 minutes close the portal, spawn 1 of each power up</span>`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -9342,7 +9361,7 @@ const tech = {
allowed() { return true },
requires: "",
effect() {
const urls = ["https://scratch.mit.edu/projects/14005697/fullscreen/", "https://scratch.mit.edu/projects/22573757/fullscreen/", "https://codepen.io/lilgreenland/full/ozXNWZ", "https://codepen.io/lilgreenland/full/wzARJY", "classic/7-1-2017/", "classic/4-15-2018/", "classic/7-11-2019/", "classic/9-8-2019/", "classic/7-15-2020/", "classic/6-1-2021/"]
const urls = ["https://scratch.mit.edu/projects/14005697/fullscreen/", "https://scratch.mit.edu/projects/22573757/fullscreen/", "https://scratch.mit.edu/projects/41429974/fullscreen/", "https://scratch.mit.edu/projects/43690666/fullscreen/", "https://codepen.io/lilgreenland/full/ozXNWZ", "https://codepen.io/lilgreenland/full/wzARJY", "classic/7-1-2017/", "classic/4-15-2018/", "classic/7-11-2019/", "classic/9-8-2019/", "classic/7-15-2020/", "classic/6-1-2021/"]
const choose = urls[Math.floor(Math.random() * urls.length)]
console.log(`opening new tab" ${choose}`)
let tab = window.open(choose, "_blank");
@@ -9665,6 +9684,7 @@ const tech = {
isCancelDuplication: null,
cancelCount: null,
isCancelRerolls: null,
isCancelTech: null,
isBotDamage: null,
isBanish: null,
isMaxEnergyTech: null,

View File

@@ -171,7 +171,7 @@ summary {
#choose-background {
position: absolute;
z-index: 3;
z-index: 2;
width: 100%;
height: 100%;
background-color: #ccc;

View File

@@ -1,21 +1,42 @@
******************************************************** NEXT PATCH **************************************************
new fan level temple by Scar1337 is now add to community maps!
you have to try it out!
you can scroll through the tech and gun menus while selecting power ups
added another classic n-gon option in settings
standing wave buffs
standing wave deflecting, is more efficient for multiple blocks in a very short time (< 1s)
spherical harmonics no longer deactivates on contact with shielded mobs
expansion increases block efficiency by 25->40%
tech: options exchange - canceling tech,gun,field has a 90% chance for a reroll
negative mass field
neutronium: move 33->25% slower
stabber mobs now stab 15% shorter distance, but they can stab more often
weak interaction gives 5->10 max energy per unused power up
bug fixes
******************************************************** TODO ********************************************************
nonrefundable tech don't display, this is confusing
maybe they can show up but greyed out or something
make your power up list scrollable while in power up selection pause menu
Tech could probably be indexed, something like running
tech.index = new Map();
for (let i = 0; i < tech.tech.length; i++) {
tech.index.set(tech.tech.name, tech.tech);
}
So when you do something like tech.giveTech("nematodes") it can just do
const queriedTech = tech.index.get("nematodes");
if (queriedTech) {
queriedTech.count++;
queriedTech.effect();
}
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
like overwatch roadhog
make mol fab field do something cool when it blocks
generate energy?
reset lifespan of: drone,spore,worm, iceIX
bring back:
the old phase decoherence field
make cloak only active on input.field down