diff --git a/.DS_Store b/.DS_Store index fd8a40c..47c1a1f 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 1ce44d4..de6be64 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1348,11 +1348,10 @@ const b = { Composite.add(engine.world, bullet[me]); //add bullet to world }, - grapple(where, angle = m.angle, isReturn = false, harpoonSize = 1) { + grapple(where, angle = m.angle, harpoonSize = 1) { const me = bullet.length; const returnRadius = 100 * Math.sqrt(harpoonSize) - bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -40 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -40 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 50 * harpoonSize, y: -3 * harpoonSize, index: 3, isInternal: false }, { x: 30 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }], { - cycle: 0, + bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -70 * harpoonSize, y: 3 * harpoonSize, index: 0, isInternal: false }, { x: -70 * harpoonSize, y: -3 * harpoonSize, index: 1, isInternal: false }, { x: 45 * harpoonSize, y: -2 * harpoonSize, index: 2, isInternal: false }, { x: 50 * harpoonSize, y: 0, index: 3, isInternal: false }, { x: 45 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }], { angle: angle, friction: 1, frictionAir: 0.4, @@ -1362,12 +1361,13 @@ const b = { endCycle: simulation.cycle + 45, collisionFilter: { category: cat.bullet, - mask: tech.isShieldPierce ? cat.map | cat.body | cat.mob | cat.mobBullet : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield, + mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield, }, minDmgSpeed: 4, ropeExtension: 0, lookFrequency: Math.floor(7 + Math.random() * 3), density: tech.harpoonDensity, //0.001 is normal for blocks, 0.006 is normal for harpoon, 0.006*6 when buffed + drain: 0.004, beforeDmg(who) { if (tech.isShieldPierce && who.isShielded) { //disable shields who.isShielded = false @@ -1375,19 +1375,10 @@ const b = { } if (tech.fragments) { b.targetedNail(this.vertices[2], tech.fragments * 3) - if (!isReturn) this.endCycle = 0; - } - if (!who.isBadTarget) { - if (isReturn) { - this.do = this.returnToPlayer - } else { - this.frictionAir = 0.01 - this.do = () => { - this.force.y += this.mass * 0.003; //gravity - this.draw(); - } - } } + // if (!who.isBadTarget) { + // this.do = this.returnToPlayer + // } }, caughtPowerUp: null, dropCaughtPowerUp() { @@ -1416,7 +1407,7 @@ const b = { this.dropCaughtPowerUp() } }, - drawString() { + draw() { const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) @@ -1430,8 +1421,9 @@ const b = { ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y) // ctx.lineTo(this.vertices[0].x, this.vertices[0].y); ctx.stroke(); + //draw hook + // ctx.beginPath(); }, - draw() {}, returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player this.endCycle = 0; @@ -1482,149 +1474,129 @@ const b = { } }, do() { - this.cycle++ - if (isReturn) { - if (input.fire) { - this.grabPowerUp() - if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction - this.endCycle = simulation.cycle + 60 - m.fireCDcycle = m.cycle + 20 // cool down - this.do = this.returnToPlayer - Matter.Body.setDensity(this, 0.0005); //reduce density on return - if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) - this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body - } - } else { - //snap rope if not enough energy - if (m.energy < 0.05) { - const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) - this.force.x -= returnForce.x - this.force.y -= returnForce.y - this.frictionAir = 0.002 - this.do = () => { - if (this.speed < 20) this.force.y += 0.0005 * this.mass; - } - this.dropCaughtPowerUp() - } else { - //return to player - this.do = this.returnToPlayer - this.endCycle = simulation.cycle + 60 - Matter.Body.setDensity(this, 0.0005); //reduce density on return - if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) - this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body - } + if (input.fire) { //&& !Matter.Query.collides(this, body).length + this.grabPowerUp() + if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction + this.endCycle = simulation.cycle + 60 + m.fireCDcycle = m.cycle + 20 // cool down + this.do = this.returnToPlayer + Matter.Body.setDensity(this, 0.0005); //reduce density on return + if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) + this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body } + } else { + //snap rope if not enough energy + if (m.energy < 0.05) { + const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) + this.force.x -= returnForce.x + this.force.y -= returnForce.y + this.frictionAir = 0.002 + this.do = () => { + if (this.speed < 20) this.force.y += 0.0005 * this.mass; + } + this.dropCaughtPowerUp() + } else { + //return to player + this.do = this.returnToPlayer + this.endCycle = simulation.cycle + 60 + Matter.Body.setDensity(this, 0.0005); //reduce density on return + if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) + this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body + } + } + //grappling hook + if (input.fire && Matter.Query.collides(this, map).length) { + Matter.Body.setPosition(this, Vector.add(this.position, { x: 20 * Math.cos(this.angle), y: 20 * Math.sin(this.angle) })) + if (Matter.Query.collides(this, map).length) { + Matter.Sleeping.set(this, true) + this.endCycle = simulation.cycle + 5 + this.dropCaughtPowerUp() + this.do = () => { + //between player nose and the grapple + const sub = Vector.sub(this.vertices[0], { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + }) + let dist = Vector.magnitude(sub) - this.ropeExtension + if (input.fire) { + //control position while hooked + // if (input.down) { //down + // player.force.y += 5 * player.mass * simulation.g; + // dist *= 0.25 + // this.ropeExtension += 10 + // } else if (input.up) { //up + // this.ropeExtension -= 10 + // if (this.ropeExtension < 0) this.ropeExtension = 0 + // player.force.y -= 5 * player.mass * simulation.g; + // dist *= 0.4 + // } else {} - //grappling hook - if (input.fire && Matter.Query.collides(this, map).length) { - const pull = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 0.1) - player.force.x += pull.x - player.force.y += pull.y - player.mass * 0.02 - const move = { x: 50 * Math.cos(this.angle), y: 50 * Math.sin(this.angle), } - Matter.Body.setPosition(this, Vector.add(this.position, move)) - - if (Matter.Query.collides(this, map).length) { - Matter.Body.setStatic(this, true) - this.endCycle = simulation.cycle + 5 - this.dropCaughtPowerUp() - this.do = () => { - // const grappleBack = { - // x: this.position.x - 50 * Math.cos(this.angle), - // y: this.position.y - 50 * Math.sin(this.angle) + // if (input.right) { //down + // dist *= 0.4 + // player.force.x += 5 * player.mass * simulation.g; + // } else if (input.left) { //up + // dist *= 0.4 + // player.force.x -= 5 * player.mass * simulation.g; // } - - //between player nose and the grapple - const sub = Vector.sub(this.vertices[0], { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - }) - let dist = Vector.magnitude(sub) - this.ropeExtension - if (input.fire) { - m.fireCDcycle = m.cycle + 30; // cool down if out of energy - this.endCycle = simulation.cycle + 10 - + m.fireCDcycle = m.cycle + 30; // cool down if out of energy + this.endCycle = simulation.cycle + 10 + if (input.down) { //down + dist = 0 + player.force.y += 5 * player.mass * simulation.g; + } + if (m.energy > this.drain || tech.isRailEnergyGain) { Matter.Body.setVelocity(player, { x: player.velocity.x * 0.8, y: player.velocity.y * 0.8 }); - if (input.down) { //down - dist *= 0.25 - player.force.y += 5 * player.mass * simulation.g; - } - //control position while hooked - // if (input.down) { //down - // player.force.y += 5 * player.mass * simulation.g; - // dist *= 0.25 - // this.ropeExtension += 10 - // } else if (input.up) { //up - // this.ropeExtension -= 10 - // if (this.ropeExtension < 0) this.ropeExtension = 0 - // player.force.y -= 5 * player.mass * simulation.g; - // dist *= 0.4 - // } else {} - - // if (input.right) { //down - // dist *= 0.4 - // player.force.x += 5 * player.mass * simulation.g; - // } else if (input.left) { //up - // dist *= 0.4 - // player.force.x -= 5 * player.mass * simulation.g; - // } - if (!tech.isRailEnergyGain && m.energy > 0.004 && dist > 400) m.energy -= 0.004 - const pull = Vector.mult(Vector.normalise(sub), 0.00035 * Math.min(Math.max(30, dist), 500)) + const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200)) player.force.x += pull.x player.force.y += pull.y - } else { //if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius + 200) - // if (input.up) { //up - // player.force.y -= 20 * player.mass * simulation.g; - // } - //automatically get ammo back - this.endCycle = 0; - if (m.cycle + 15 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 15 * b.fireCDscale //lower cd to 15 if it is above 15 - // refund ammo - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "harpoon") { - b.guns[i].ammo++; - simulation.updateGunHUD(); - break; + + if (!tech.isRailEnergyGain && dist > 500) { + m.energy -= this.drain + if (m.energy < 0) { + this.endCycle = 0; + if (m.cycle + 50 < m.fireCDcycle) m.fireCDcycle = m.cycle + 50 + // refund ammo + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "harpoon") { + b.guns[i].ammo++; + simulation.updateGunHUD(); + break; + } + } } } } - // if (dist > returnRadius) - this.draw(); + // if (tech.isIntangibleGrapple) { + // player.collisionFilter.mask = cat.map + // let inPlayer = Matter.Query.region(mob, player.bounds) + // if (inPlayer.length > 0) { + // for (let i = 0; i < inPlayer.length; i++) { + // if (m.energy > 0 && inPlayer[i].shield) m.energy -= 0.014; + // } + // } + // //check for disabling intangible in next cycle + // requestAnimationFrame(() => { + // if (!tech.isIntangibleGrapple || !input.fire || this.) { + // player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions + // } + // }); + // } + } else { + Matter.Sleeping.set(this, false) + this.collisionFilter.category = 0 + this.collisionFilter.mask = 0 + this.do = this.returnToPlayer + this.endCycle = simulation.cycle + 60 } + this.draw(); } } - this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); - this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); - this.draw() } + this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); + this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); + this.draw() }, }); - if (!isReturn) { - Matter.Body.setVelocity(bullet[me], { - x: m.Vx / 2 + 60 * Math.cos(bullet[me].angle), - y: m.Vy / 2 + 60 * Math.sin(bullet[me].angle) - }); - bullet[me].frictionAir = 0.002 - bullet[me].do = function() { - if (this.speed < 20) this.force.y += 0.0005 * this.mass; - this.draw(); - } - } - if (tech.isHarpoonPowerUp && bullet[me].density > 0.01) { - if (isReturn) { - bullet[me].draw = function() { - this.drawToggleHarpoon() - this.drawString() - } - } else { - bullet[me].draw = function() { - this.drawToggleHarpoon() - } - } - } else if (isReturn) { - bullet[me].draw = function() { - this.drawString() - } - } Composite.add(engine.world, bullet[me]); //add bullet to world }, harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35) { @@ -6122,7 +6094,7 @@ const b = { simulation.updateGunHUD(); m.fireCDcycle = m.cycle + 90 // cool down } else { - b.grapple(where, m.angle, !input.down, harpoonSize) + b.grapple(where, m.angle, harpoonSize) } m.fireCDcycle = m.cycle + 45 // cool down }, diff --git a/js/index.js b/js/index.js index 09f1b47..dacc841 100644 --- a/js/index.js +++ b/js/index.js @@ -257,31 +257,37 @@ const build = { if (tech.plasmaBotCount) botText += `
plasma-bots: ${tech.plasmaBotCount}` if (tech.missileBotCount) botText += `
missile-bots: ${tech.missileBotCount}` - const harm = (1 - m.harmReduction()) * 100 let text = `
` if (!simulation.isChoosing) text += `
PAUSED               press P to resume

copy build url
` - text += `damage increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}% -
harm reduction: ${harm.toFixed(harm > 90 ? 2 : 0)}% -
fire delay decrease: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% -
duplication chance: ${(tech.duplicationChance()*100).toFixed(0)}% -${botText} + //{ /* damage increase: ${((tech.damageFromTech()-1)*100).toFixed(0)}% */ } + //
damage difficulty reduction: ${((1-m.dmgScale)*100).toFixed(2)}% + //
effective damage: ${(((tech.damageFromTech()-1)*m.dmgScale)*100).toFixed(0)}% + //
+ //
damage = ${((tech.damageFromTech())*100).toFixed(0)}% × ${((m.dmgScale)*100).toFixed(2)}% = ${(((tech.damageFromTech())*m.dmgScale)*100).toFixed(0)}% + ///
heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}% + text += + ` +
effective damage: ${(tech.damageFromTech() * m.dmgScale).toPrecision(4)} +
damage: ${((tech.damageFromTech())).toPrecision(4)}, difficulty: ${((m.dmgScale)).toPrecision(4)}
-
tech: ${tech.totalCount}   research: ${powerUps.research.count} +
effective harm: ${(simulation.dmgScale*m.harmReduction()).toPrecision(4)} +
reduction: ${(m.harmReduction()).toPrecision(4)}, difficulty: ${(simulation.dmgScale).toPrecision(4)} +
+${botText}
health: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})   energy: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)})
gun: ${b.activeGun !== null ? b.guns[b.activeGun].name: "null"}   ammo: ${b.activeGun !== null ? b.guns[b.activeGun].ammo: "0"} +
fire delay decrease: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% +
duplication chance: ${(tech.duplicationChance()*100).toFixed(0)}% +
tech: ${tech.totalCount}   research: ${powerUps.research.count}
position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)})   velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})
mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})   mass: ${player.mass.toFixed(1)}

seed: ${Math.initialSeed}
level: ${level.levels[level.onLevel]} (${level.difficultyText()})   ${m.cycle} cycles
${mob.length} mobs,   ${body.length} blocks,   ${bullet.length} bullets,   ${powerUp.length} power ups - -
damage difficulty scale: ${(m.dmgScale*100).toFixed(2) }% -
harm difficulty scale: ${(simulation.dmgScale*100).toFixed(0)}% -
heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}% ${simulation.isCheating ? "

lore disabled": ""}
`; for (let i = 0, len = b.inventory.length; i < len; i++) { diff --git a/js/level.js b/js/level.js index 9a1ea23..06b8a6f 100644 --- a/js/level.js +++ b/js/level.js @@ -18,7 +18,7 @@ const level = { // m.setField("time dilation") // b.giveGuns("harpoon") // for (let i = 0; i < 9; i++) tech.giveTech("smelting") - // tech.giveTech("UHMWPE") + // tech.giveTech("boson quasiparticles") // tech.giveTech("grappling hook") // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 3; i++) tech.giveTech("undefined") @@ -32,7 +32,7 @@ const level = { // simulation.enableConstructMode() //used to build maps in testing mode // level.reactor(); // level.testing(); //not in rotation, used for testing - // level.run() + // level.pavilion() if (simulation.isTraining) { level.walk(); } else { level.intro(); } // powerUps.research.changeRerolls(3000) @@ -2547,7 +2547,7 @@ const level = { // spawn.launcherBoss(3200, -500) // spawn.laserTargetingBoss(1700, -500) // spawn.powerUpBoss(1900, -500) - // spawn.powerUpBossBaby(3200, -500) + spawn.powerUpBossBaby(3200, -500) // spawn.snakeBoss(1700, -500) // spawn.streamBoss(3200, -500) // spawn.pulsarBoss(1700, -500) diff --git a/js/mob.js b/js/mob.js index 9545ada..97fbf9c 100644 --- a/js/mob.js +++ b/js/mob.js @@ -803,27 +803,27 @@ const mobs = { } } }, - invulnerability() { - if (this.isInvulnerable) { - if (this.invulnerabilityCountDown > 0) { - this.invulnerabilityCountDown-- - //graphics //draw a super shield? - ctx.beginPath(); - let vertices = this.vertices; - ctx.moveTo(vertices[0].x, vertices[0].y); - for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); - ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - // ctx.fillStyle = `rgba(${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},0.5)` - // ctx.fill(); - ctx.strokeStyle = "rgba(255,255,255,0.4)"; - ctx.stroke(); - } else { - this.isInvulnerable = false - this.damageReduction = this.startingDamageReduction - } - } - }, + // invulnerability() { + // if (this.isInvulnerable) { + // if (this.invulnerabilityCountDown > 0) { + // this.invulnerabilityCountDown-- + // //graphics //draw a super shield? + // ctx.beginPath(); + // let vertices = this.vertices; + // ctx.moveTo(vertices[0].x, vertices[0].y); + // for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); + // ctx.lineTo(vertices[0].x, vertices[0].y); + // ctx.lineWidth = 20; + // // ctx.fillStyle = `rgba(${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},0.5)` + // // ctx.fill(); + // ctx.strokeStyle = "rgba(255,255,255,0.4)"; + // ctx.stroke(); + // } else { + // this.isInvulnerable = false + // this.damageReduction = this.startingDamageReduction + // } + // } + // }, grow() { if (this.seePlayer.recall) { if (this.radius < 80) { diff --git a/js/powerup.js b/js/powerup.js index 54d4fdc..f48b69a 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -872,7 +872,7 @@ const powerUps = { powerUps.research.currentRerollCount = 0 if (tech.isTechDamage && who.name === "tech") m.damage(0.11) if (tech.isMassEnergy) m.energy += 2; - if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.66) { + if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.60) { if (tech.isLaserMine && input.down) { b.laserMine(who.position) } else { diff --git a/js/simulation.js b/js/simulation.js index a5a2f49..7e48d45 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -121,7 +121,7 @@ const simulation = { fpsCapDefault: 72, //use to change fpsCap back to normal after a hit from a mob isCommunityMaps: false, cyclePaused: 0, - fallHeight: 5000, //below this y position the player dies + fallHeight: 6000, //below this y position the player dies 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, diff --git a/js/spawn.js b/js/spawn.js index 1c0e616..84a05e9 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1238,8 +1238,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } else { this.isInvulnerable = false @@ -2010,8 +2010,8 @@ const spawn = { ctx.lineTo(vertices[0].x, vertices[0].y); } } - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } else if (this.invulnerabilityCountDown > 0) { this.invulnerabilityCountDown-- @@ -3420,10 +3420,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - // ctx.fillStyle = `rgba(${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},0.5)` - // ctx.fill(); - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } else { this.isInvulnerable = false @@ -3702,8 +3700,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } this.checkStatus(); @@ -3840,8 +3838,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } else if (this.mass < 100) { Matter.Body.scale(this, 1.01, 1.01); //grow back to normal size @@ -3970,8 +3968,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } me.swordSlash = function() { @@ -3992,8 +3990,8 @@ const spawn = { ctx.moveTo(vertices[0].x, vertices[0].y); for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); ctx.lineTo(vertices[0].x, vertices[0].y); - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,255,255,0.7)"; + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; ctx.stroke(); } me.laserSword = function(where, angle) { diff --git a/js/tech.js b/js/tech.js index 0f5b619..292a53a 100644 --- a/js/tech.js +++ b/js/tech.js @@ -4831,7 +4831,7 @@ const tech = { }, { name: "booby trap", - description: "50% chance to drop a mine from power ups
+50% JUNK to the potential tech pool", + description: "60% chance to drop a mine from power ups
+46% JUNK to the potential tech pool", isGunTech: true, maxCount: 1, count: 0, @@ -4844,7 +4844,7 @@ const tech = { effect() { tech.isMineDrop = true; if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0) - this.refundAmount += tech.addJunkTechToPool(0.5) + this.refundAmount += tech.addJunkTechToPool(0.46) }, refundAmount: 0, remove() { @@ -5557,7 +5557,7 @@ const tech = { // }, { name: "grappling hook", - description: `harpoons attach to the map and pull you in
rope extends much farther while you hold fire`, + description: `harpoons attach to the map and pull you in
your rope extends while holding fire`, isGunTech: true, maxCount: 1, count: 0, @@ -5582,6 +5582,46 @@ const tech = { } } }, + // { + // name: "exchange interaction", + // description: `immune to harm while grappling`, + // // link: `boson`, + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.isGrapple && !tech.isRailEnergyGain + // }, + // requires: "grappling hook, not alternator", + // effect() { + // tech.isIntangibleGrapple = true; + // }, + // remove() { + // tech.isIntangibleGrapple = false + // } + // }, + // { + // name: "boson quasiparticles", + // description: `intangible to blocks and mobs while grappling
passing through shields drains your energy`, + // link: `boson`, + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.isGrapple && !tech.isRailEnergyGain + // }, + // requires: "grappling hook, not alternator", + // effect() { + // tech.isIntangibleGrapple = true; + // }, + // remove() { + // tech.isIntangibleGrapple = false + // } + // }, { name: "alternator", description: "harpoon and grappling hook drain no energy
railgun generates energy", //as they retract
crouch firing harpoon generates energy", @@ -7476,6 +7516,27 @@ const tech = { }, remove() {} }, + { + name: "harvest", + description: "convert all the mobs on this level into ammo", + maxCount: 1, + count: 0, + frequency: 0, + frequencyDefault: 0, + isJunk: true, + isNonRefundable: true, + allowed() { + return true + }, + requires: "", + effect() { + for (let i = 0, len = mob.length; i < len; i++) { + powerUps.directSpawn(mob[i].position.x, mob[i].position.y, "ammo"); + mob[i].death(); + } + }, + remove() {} + }, { name: "brainstorm", description: "the tech choice menu randomizes
every 0.5 seconds for 10 seconds", @@ -7611,6 +7672,21 @@ const tech = { if (this.count) m.look = m.lookDefault } }, + { + name: "Mech v4.48", + description: `open a portal to a primordial version of reality`, + maxCount: 1, + count: 0, + frequency: 0, + isNonRefundable: true, + isJunk: true, + allowed() { return true }, + requires: "", + effect() { + window.open('https://scratch.mit.edu/projects/14005697/fullscreen/', '_blank') + }, + remove() {} + }, { name: "planetesimals", description: `play planetesimals (an asteroids-like game)
clear levels in planetesimals to spawn tech
if you die in planetesimals you die in n-gon`, @@ -9411,5 +9487,6 @@ const tech = { isTimeCrystals: null, isGroundState: null, isRailGun: null, - isGrapple: null + isGrapple: null, + // isIntangibleGrapple: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 40464d2..c19ead6 100644 --- a/todo.txt +++ b/todo.txt @@ -1,28 +1,44 @@ ******************************************************** NEXT PATCH ************************************************** -tech grappling hook - can attack to walls and pull you towards the walls - harpoon extends farther as you hold down fire, but no longer has auto-steering - -mobs do 4% less harm per difficulty level -railgun/harpoon auto-targeting is smarter at long distances with multiple small targets - but it still has trouble with moving targets -booby trap only has a 100 -> 50% chance to drop a mine when picking up power ups -added fallback for browsers that don't allow local storage +grappling hook - small quality of life improvements + about 30% larger, and a new shape (does more damage as a result) + continues past mobs after hitting them instead of retracting + pulls faster even at close range + sticks into walls more reliably + returns to you when you let go of fire, even when stuck + loses ammo less often + drains energy as it pulls + +JUNK tech: Mech v4.48 - open a portal to a primordial version of reality (an old scratch game I wrote) +JUNK tech: harvest - convert all the mobs on this level into ammo +pause menu stats are a bit different ******************************************************** TODO ******************************************************** grappling hook - new shape, different from harpoon - how to draw convex? - composite - draw the hook part directly + fire delay reduction doesn't have much effect + tech: give harm immunity while being pulled? + make not stack with alternator? so no energy regen + tech: give no collisions, like boson composite while attached to harpoon + make not stack with alternator? so no energy regen + this was annoying to code, but probably doable + draw the hook part directly + two backwards angled spikes near the front give player more control over motion while hanging and retracting reduce friction effects so player swing around? up down left right push player around? - lengthen and shrink the rope length? - scale velocity dampening with distance to grapple - get induction furnace working? - I'm not a fan of this tech, I'd be happy if it was basic harpoon only + scale velocity dampening with distance to grapple? + +tech that does less damage the more tech you have? + tech.totalCount + +add coyote jump + log game m.cycle when last on ground + for jump check if game cycle is < last on ground cycle -2 + +setting to remove UI, except health bar + except active gun? to see ammo + checkbox in pause and in settings tech - Plasma railgun like foam, or phonon? @@ -34,10 +50,6 @@ pause time like invariant for other things... bug - url sharing still broken sometimes -setting to remove UI, except health bar - except active gun? to see ammo - checkbox in pause and in settings - +damage for each different bot type you have disables bot upgrades?