diff --git a/.DS_Store b/.DS_Store index 0bf82d0..29517ca 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/index.js b/js/index.js index 14fb152..596a02e 100644 --- a/js/index.js +++ b/js/index.js @@ -101,6 +101,7 @@ window.addEventListener('load', () => { } } } + if (property === "difficulty") { simulation.difficultyMode = Number(set[property]) document.getElementById("difficulty-select-experiment").value = Number(set[property]) @@ -148,33 +149,33 @@ window.onresize = () => { // experimental build grid display and pause //********************************************************************** 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.World.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(); - } - } - }, + // 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.World.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() { let botText = "" if (tech.nailBotCount) botText += `
nail-bots: ${tech.nailBotCount}` @@ -296,20 +297,18 @@ const build = { m.setField(index) who.classList.add("build-field-selected"); } - } else if (type === "tech") { //remove tech if you have too many + } else if (type === "tech") { if (tech.tech[index].count < tech.tech[index].maxCount) { - if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); - tech.giveTech(index) + if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); } else if (!tech.tech[index].isNonRefundable) { tech.totalCount -= tech.tech[index].count tech.removeTech(index); who.classList.remove("build-tech-selected"); } else { who.classList.remove("build-tech-selected") - setTimeout(() => { //return energy + setTimeout(() => { who.classList.add("build-tech-selected") }, 50); - } } //update tech text //disable not allowed tech @@ -321,21 +320,21 @@ const build = { if (tech.tech[i].isFieldTech) { techID.innerHTML = `
- -
-
-
-         ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}` + +
+
+
+         ${tech.tech[i].name} ${isCount}${tech.tech[i].description}` //
//
// border: #fff solid 0px; } else if (tech.tech[i].isGunTech) { techID.innerHTML = `
- -
-
-
-         ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}` + +
+
+
+         ${tech.tech[i].name} ${isCount}${tech.tech[i].description}` } else if (tech.tech[i].isJunk) { // text += `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
` techID.innerHTML = `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}` @@ -355,6 +354,7 @@ const build = { // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].description}` + // console.log(techID) if (!techID.classList.contains("experiment-grid-disabled")) { techID.classList.add("experiment-grid-disabled"); techID.onclick = null diff --git a/js/level.js b/js/level.js index 3f3b083..b9d66df 100644 --- a/js/level.js +++ b/js/level.js @@ -9,6 +9,7 @@ const level = { levelsCleared: 0, playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], levels: [], + start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.enableConstructMode() //used to build maps in testing mode @@ -1289,6 +1290,30 @@ const level = { spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump spawn.mapRect(5425, -650, 375, 450); //blocking exit if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500); + + if (simulation.isHorizontalFlipped) { //flip the map horizontally + const flipX = (who) => { + for (let i = 0, len = who.length; i < len; i++) { + Matter.Body.setPosition(who[i], { x: -who[i].position.x, y: who[i].position.y }) + } + } + flipX(map) + flipX(body) + flipX(mob) + flipX(powerUp) + + level.setPosToSpawn(0, -250); + level.exit.x = -level.exit.x - 100 //minus the 100 because of the width of the graphic + level.custom = () => { + level.playerExitCheck(); + level.exit.draw(); + level.enter.draw(); + }; + level.customTopLayer = () => { + ctx.fillStyle = "rgba(0,255,255,0.1)" + ctx.fillRect(-5400 - 300, -550, 300, 350) + }; + } }, gauntlet() { level.custom = () => { @@ -1310,8 +1335,8 @@ const level = { simulation.zoomTransition(level.defaultZoom) document.body.style.backgroundColor = "#ddd"; - spawn.mapRect(-300, -1050, 300, 200); - Matter.Body.setAngle(map[map.length - 1], -Math.PI / 4) + // spawn.mapRect(-300, -1050, 300, 200); + // Matter.Body.setAngle(map[map.length - 1], -Math.PI / 4) spawn.mapRect(-950, 0, 8200, 800); //ground @@ -1344,6 +1369,32 @@ const level = { } powerUps.addRerollToLevel() //needs to run after mobs are spawned if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4125, -350); + + if (simulation.isHorizontalFlipped) { //flip the map horizontally + const flipX = (who) => { + for (let i = 0, len = who.length; i < len; i++) { + Matter.Body.setPosition(who[i], { x: -who[i].position.x, y: who[i].position.y }) + } + } + flipX(map) + flipX(body) + flipX(mob) + flipX(powerUp) + + level.setPosToSpawn(0, -475); + level.exit.x = -level.exit.x - 100 //minus the 100 because of the width of the graphic + level.custom = () => { + level.playerExitCheck(); + level.exit.draw(); + level.enter.draw(); + }; + level.customTopLayer = () => { + ctx.fillStyle = "rgba(0,255,255,0.1)" + ctx.fillRect(-6400 - 300, -550, 300, 350) + ctx.fillStyle = "rgba(0,0,0,0.1)" + ctx.fillRect(175 - 900, -975, 900, 575) + }; + } }, intro() { level.custom = () => { @@ -3627,7 +3678,7 @@ const level = { if (simulation.difficulty > 4) spawn.nodeGroup(2330, 1850, "spawns", 8, 20, 105); powerUps.chooseRandomPowerUp(3100, 1630); }, - detours() { + detours() { //by Francois from discord level.setPosToSpawn(0, 0); //lower start level.exit.y = 150; spawn.mapRect(level.enter.x, 45, 100, 20); @@ -3938,7 +3989,7 @@ const level = { } } }, - house() { + house() { //by Francois from discord const rotor = level.rotor(4315, -315, -0.0002, 120, 20, 200); const hazard = level.hazard(4350, -1000, 300, 110); const doorBedroom = level.door(1152, -1150, 25, 250, 250); @@ -4414,7 +4465,7 @@ const level = { } } }, - perplex() { + perplex() { //by Oranger from discord level.setPosToSpawn(-600, 400); spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); level.exit.x = 550; diff --git a/js/player.js b/js/player.js index 76a7d3f..e5d555b 100644 --- a/js/player.js +++ b/js/player.js @@ -1952,7 +1952,7 @@ const m = { }, { name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency" - description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 121%", + description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 146%", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -1960,7 +1960,7 @@ const m = { // m.eyeFillColor = '#333' m.fieldPhase = 0; m.isCloak = false - m.fieldDamage = 2.21 // 1 + 111/100 + m.fieldDamage = 2.46 // 1 + 146/100 m.fieldDrawRadius = 0 const drawRadius = 1000 @@ -1998,7 +1998,7 @@ const m = { } if (tech.isCloakStun) { //stun nearby mobs after exiting cloak let isMobsAround = false - const stunRange = m.fieldDrawRadius * 1.15 + const stunRange = m.fieldDrawRadius * 1.2 const drain = 0.3 * m.energy for (let i = 0, len = mob.length; i < len; ++i) { if ( @@ -2006,7 +2006,7 @@ const m = { Matter.Query.ray(map, mob[i].position, m.pos).length === 0 ) { isMobsAround = true - mobs.statusStun(mob[i], 30 + drain * 300) + mobs.statusStun(mob[i], 60 + drain * 360) } } if (isMobsAround && m.energy > drain) { diff --git a/js/simulation.js b/js/simulation.js index b794c6a..f72b54c 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -122,6 +122,7 @@ const simulation = { lastTimeStamp: 0, //tracks time stamps for measuring delta delta: 1000 / 60, //speed of game engine //looks like it has to be 16 to match player input buttonCD: 0, + isHorizontalFlipped: false, //makes some maps flipped horizontally levelsCleared: 0, difficultyMode: 2, //normal difficulty is 2 difficulty: 0, diff --git a/js/spawn.js b/js/spawn.js index 7977699..11a40ce 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -376,7 +376,7 @@ const spawn = { //push blocks and player away, since this is the end of suck, and suck causes blocks to fall on the boss and stun it Matter.Body.scale(this, 10, 10); Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger - if (!this.isShielded) spawn.shield(this, x, y, 1); // regen shield to also prevent stun + if (!this.isShielded) spawn.shield(this, this.position.x, this.position.y, 1); // regen shield to also prevent stun for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally if (body[i].position.x > this.position.x) { body[i].force.x = 0.5 diff --git a/js/tech.js b/js/tech.js index b877673..ca7da8c 100644 --- a/js/tech.js +++ b/js/tech.js @@ -151,6 +151,7 @@ if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.85 + if (tech.isSneakAttack && m.cycle > m.lastKillCycle + 300) dmg *= 1.66 if (tech.isTechDamage) dmg *= 1.9 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5 @@ -169,6 +170,7 @@ if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015) if (tech.isBotDamage) dmg *= 1 + 0.05 * b.totalBots() + return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { @@ -2540,7 +2542,7 @@ }, { name: "quantum immortality", - description: "after dying, continue in an alternate reality
reduce harm by 23%", //spawn 4 research + description: "after dying, continue in an alternate reality
reduce harm by 23%", //spawn 4 research maxCount: 1, count: 0, frequency: 4, @@ -2558,7 +2560,7 @@ }, { name: "many-worlds", - description: "each level is an alternate reality, where you
find a tech at the start of each level", + description: "each level is an alternate reality, where you
find a tech at the start of each level", maxCount: 1, count: 0, frequency: 1, @@ -2576,7 +2578,7 @@ }, { name: "non-unitary operator", - description: "reduce combat difficulty by 2 levels
after a collision enter an alternate reality", + description: "reduce combat difficulty by 2 levels
after a collision enter an alternate reality", maxCount: 1, count: 0, frequency: 1, @@ -2598,7 +2600,7 @@ }, { name: "Ψ(t) collapse", - description: "enter an alternate reality after you research
spawn 12 research", + description: "enter an alternate reality after you research
spawn 12 research", maxCount: 1, count: 0, frequency: 1, @@ -4881,9 +4883,9 @@ count: 0, frequency: 2, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field") && !tech.isEnergyHealth + return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field") && !tech.isEnergyHealth }, - requires: "negative mass field, not mass-energy", + requires: "field: perfect, negative mass, pilot wave, plasma, not mass-energy", effect() { tech.isHarmReduce = true }, @@ -5032,7 +5034,7 @@ count: 0, frequency: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "time dilation field" // || m.fieldUpgrades[m.fieldMode].name === "pilot wave" + return m.fieldUpgrades[m.fieldMode].name === "time dilation field" }, requires: "time dilation field", effect() { @@ -5056,7 +5058,7 @@ count: 0, frequency: 2, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "time dilation field") && tech.energyRegen !== 0; //|| m.fieldUpgrades[m.fieldMode].name === "pilot wave" + return (m.fieldUpgrades[m.fieldMode].name === "time dilation field") && tech.energyRegen !== 0 }, requires: "time dilation field, not ground state", effect: () => { @@ -5104,6 +5106,24 @@ tech.isCloakStun = false; } }, + { + name: "combinatorial optimization", + description: "increase damage by 66%
if a mob has not died in the last 5 seconds", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" + }, + requires: "metamaterial cloaking or pilot wave", + effect() { + tech.isSneakAttack = true; + }, + remove() { + tech.isSneakAttack = false; + } + }, { name: "discrete optimization", description: "increase damage by 50%
50% increased delay after firing", @@ -5114,7 +5134,7 @@ allowed() { return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" }, - requires: "metamaterial cloaking", + requires: "metamaterial cloaking or pilot wave", effect() { tech.aimDamage = 1.5 b.setFireCD(); @@ -5240,7 +5260,7 @@ }, { name: "-quantum leap-", - description: "experiment: every 20 seconds
become an alternate version of yourself", + description: "experiment: every 20 seconds
become an alternate version of yourself", maxCount: 1, count: 0, frequency: 0, @@ -5410,6 +5430,33 @@ // tech.wimpExperiment = 0 // } // }, + { + name: "not a bug", + description: "initiate a totally safe game crash for 5 seconds", + maxCount: 1, + count: 0, + frequency: 0, + isNonRefundable: true, + isExperimentHide: true, + isJunk: true, + allowed() { + return true + }, + requires: "", + effect() { + const savedfunction = simulation.drawCircle + simulation.drawCircle = () => { + const a = mob[Infinity].position //crashed the game in a visually interesting way, because of the ctx.translate command is never reverted in the main game loop + } + setTimeout(() => { + simulation.drawCircle = savedfunction + canvas.width = canvas.width //clears the canvas // works on chrome at least + }, 5000); + + // for (;;) {} //freezes the tab + }, + remove() {} + }, { name: "posture", description: "stand a bit taller", @@ -5676,7 +5723,7 @@ }, { name: "quantum leap", - description: "become an alternate version of yourself
every 20 seconds", + description: "become an alternate version of yourself
every 20 seconds", maxCount: 1, count: 0, frequency: 0, @@ -6781,5 +6828,6 @@ isBlockBullets: null, isAddBlockMass: null, isMACHO: null, - isHarmMACHO: null + isHarmMACHO: null, + isSneakAttack: null } \ No newline at end of file diff --git a/style.css b/style.css index e860d63..c1f0aa0 100644 --- a/style.css +++ b/style.css @@ -583,8 +583,26 @@ summary { /* } */ .color-cloaked { - opacity: 0.25; - letter-spacing: 1px; + letter-spacing: 2px; + animation: cloak 6s linear infinite alternate; + color: rgba(0, 0, 0, 0); +} + +@keyframes cloak { + 0% { + text-shadow: 0px 0px 0px #000; + opacity: 1; + } + + 50% { + text-shadow: 0px 0px 0px #000; + opacity: 1; + } + + 100% { + text-shadow: 0px 0px 15px #000; + opacity: 0; + } } .color-laser { @@ -652,6 +670,12 @@ summary { letter-spacing: -1px; } +.color-alt { + text-decoration: underline; + font-weight: 100; + letter-spacing: -1px; +} + .faded { opacity: 0.7; font-size: 90%; @@ -743,6 +767,23 @@ summary { float: right; } +.alt { + animation: alt 8s linear infinite alternate; + font-weight: 400; + letter-spacing: 1px; + /* color: rgba(0, 0, 0, 0.5) */ +} + +@keyframes alt { + 0% { + text-shadow: 3px 0px 0px; + } + + 100% { + text-shadow: -3px 0px 0px; + } + +} .flicker { animation: flicker 4s linear infinite; diff --git a/todo.txt b/todo.txt index 30f1d9e..b511c2a 100644 --- a/todo.txt +++ b/todo.txt @@ -1,12 +1,12 @@ ******************************************************** NEXT PATCH ******************************************************** -NEW COMMUNITY LEVEL n_gon by Oranger +"cloak" and "alternate reality" now have styled text -experimenting with some code the automatically positions blocks into the center of buttons - let me know if anything acts oddly as a result - -small adjustments to maps around buttons around platforms -some bug fixes +metamaterial field damage increased to 146% (was 121%) +tech: combinatorial optimization - increase damage by 66% if a mob hasn't died in the last 5 seconds + +fix bugs where some shared build URLs were crashing on some unusual tech, like lore tech and nonrefundable tech +junk tech: not a bug - crashes the game ******************************************************** BUGS ******************************************************** @@ -20,14 +20,6 @@ blue triangle boss can move backwards and aim away from you if set up properly HTML build system looks bad since tech does grey out -The html build share system crashing some times -tech: strange attractor before at least 1 other tech - https://landgreen.github.io/sidescroller/index.html?&gun0=rail%20gun&tech18=correlated%20damage&tech20=strange%20attractor -&tech0=auto-loading%20heuristics as only tech - https://landgreen.github.io/sidescroller/index.html?&tech0=auto-loading%20heuristics -crashed on this -https://landgreen.github.io/sidescroller/index.html?&gun0=rail%20gun&tech1=mass%20driver&tech2=restitution&tech3=flywheel&tech4=Pauli%20exclusion&tech5=mass-energy%20equivalence&tech6=1st%20ionization%20energy&tech7=electrolytes&tech8=negative%20feedback&tech9=entropy%20exchange&tech10=anthropic%20principle&tech11=renormalization&tech12=Bayesian%20statistics&tech13=bubble%20fusion&tech14=replication&tech15=replication&tech16=futures%20exchange&tech17=commodities%20exchange&tech18=correlated%20damage&tech19=parthenogenesis&tech21=cardinality&tech22=half-wave%20rectifier&tech23=pair%20production&tech24=Lorentz%20transformation&tech25=time%20crystals&tech26=undefined&tech27=undefined&tech28=undefined&tech29=undefined&tech30=undefined&tech31=undefined&tech32=undefined&field=pilot%20wave&difficulty=6 - you have to press z once to get copy to work for simulation.enableConstructMode() sometimes not sure how to reproduce, but it happens often on the first draw @@ -35,12 +27,6 @@ mouse event e.which is deprecated fix door.isOpen actually meaning isClosed? -(only once on my computer) once every 7 second check isn't running code - power ups don't teleport to exit - complex spin statistics isn't activating - wasn't able to understand bug after extensive testing - had tech: complex spin statistics - make it so that when you are immune to harm you can either jump on mobs or you pass through them is there a way to check if the player is stuck inside the map or block @@ -48,14 +34,15 @@ is there a way to check if the player is stuck inside the map or block (intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause -(once) bug - mine spawned one new mine every second - after sticking to the top right corner of a wall - notes: had only gun mine, tech mine reclamation, field plasma, - -(repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping - ******************************************************** TODO ******************************************************** +flip left right on some maps + some mobs use the original x parameter in their loop, but it doesn't get flipped + manually edit each mob's logic + finalBoss, shooters? + +tech: supersaturation is buffed but add falling damage + mob: molecule shapes - 2 separate mobs joined by a bond use constraints: just spawn 2x or 3x groupings low friction so they can spin around @@ -72,9 +59,6 @@ tech: increase health and harm taken remove air control negative tech aspect, junk , experiment? -add falling damage - negative tech aspect - tech: use the ability for power ups to have custom code (note: this code is half way done, it just needs to be completed) attracted to player @@ -404,6 +388,7 @@ possible names for tech quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields) counterfactual - something false axion - maybe a 3rd dark matter type tech + Pigeonhole principle - if there are several things that are matched up @@ -424,7 +409,7 @@ chapter 3: why is the bot attacking things? disable lore, but respawn on the level you die at? dialogue outline: scientist try to think of a way to communicate since the bot can't talk - they give up on getting the bot to respond, and just start ask questions and explaining things + they give up on getting the bot to respond, and just start ask questions and thinking of explanations with other when and how did it become self-aware why is the bot fighting things in these simulated locations? it wasn't designed to be violent