diff --git a/.DS_Store b/.DS_Store index ed02d81..e0d71b1 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 8ad65bc..c9dafbb 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1141,6 +1141,7 @@ const b = { this.frictionAir = 0.01 this.do = () => { this.force.y += this.mass * 0.003; //gravity + this.draw(); } } @@ -1165,7 +1166,7 @@ const b = { this.caughtPowerUp.effect(); Matter.Composite.remove(engine.world, this.caughtPowerUp); powerUp.splice(index, 1); - if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.008 * 6 //0.006 is normal + if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.008 * 8 //0.006 is normal } else { this.dropCaughtPowerUp() } @@ -1173,23 +1174,42 @@ const b = { this.dropCaughtPowerUp() } }, + drawToggleHarpoon() { + ctx.beginPath(); + ctx.moveTo(this.vertices[0].x, this.vertices[0].y); + for (let j = 1, len = this.vertices.length; j < len; j += 1) ctx.lineTo(this.vertices[j].x, this.vertices[j].y); + ctx.lineTo(this.vertices[0].x, this.vertices[0].y); + ctx.lineJoin = "miter" + ctx.miterLimit = 100; + ctx.lineWidth = 60; + ctx.strokeStyle = "rgba(0,255,255,0.25)"; + ctx.stroke(); + ctx.lineWidth = 20; + ctx.strokeStyle = "rgb(0,255,255)"; + ctx.stroke(); + ctx.lineJoin = "round" + ctx.miterLimit = 10 + ctx.sillStyle = "#000" + ctx.fill(); + }, drawString() { - if (isReturn) { - const where = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } - const sub = Vector.sub(where, this.vertices[0]) - const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub)))) - const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular) - ctx.strokeStyle = "#000" // "#0ce" - ctx.lineWidth = 0.5 - ctx.beginPath(); - ctx.moveTo(where.x, where.y); - 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(); + const where = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) } + const sub = Vector.sub(where, this.vertices[0]) + const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub)))) + const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular) + ctx.strokeStyle = "#000" // "#0ce" + ctx.lineWidth = 0.5 + ctx.beginPath(); + ctx.moveTo(where.x, where.y); + 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() { + }, returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player @@ -1214,9 +1234,9 @@ const b = { const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass) this.force.x -= returnForce.x this.force.y -= returnForce.y - this.drawString() this.grabPowerUp() } + this.draw(); }, grabPowerUp() { //grab power ups near the tip of the harpoon if (this.caughtPowerUp) { @@ -1257,7 +1277,6 @@ const b = { 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 { this.grabPowerUp() @@ -1316,41 +1335,7 @@ const b = { // } // } } - this.drawString() - if (tech.isHarpoonPowerUp && this.density > 0.01) { - this.drawString = () => { - ctx.beginPath(); - ctx.moveTo(this.vertices[0].x, this.vertices[0].y); - for (let j = 1, len = this.vertices.length; j < len; j += 1) { - ctx.lineTo(this.vertices[j].x, this.vertices[j].y); - } - ctx.lineTo(this.vertices[0].x, this.vertices[0].y); - ctx.lineWidth = 4; - ctx.strokeStyle = "#000"; - ctx.lineJoin = "miter" - ctx.miterLimit = 100; - ctx.stroke(); - ctx.lineJoin = "round" - ctx.miterLimit = 10 - - if (isReturn) { - const where = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } - const sub = Vector.sub(where, this.vertices[0]) - const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(80, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub)))) - const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular) - ctx.strokeStyle = "#000" // "#0ce" - ctx.lineWidth = 0.5 - ctx.beginPath(); - ctx.moveTo(where.x, where.y); - 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(); - } - } - } + this.draw() }, }); if (!isReturn && !target) { @@ -1361,8 +1346,26 @@ const b = { bullet[me].frictionAir = 0.002 bullet[me].do = function() { this.force.y += this.mass * 0.001; //gravity + 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 /* todo despawn @@ -1405,7 +1408,6 @@ const b = { // this.drawString() // } // } - Composite.add(engine.world, bullet[me]); //add bullet to world }, missile(where, angle, speed, size = 1) { if (tech.missileSize) size *= 1.5 @@ -1526,13 +1528,13 @@ const b = { m.energy = 0; } b.isExtruderOn = true - const SPEED = 10 + 10 * tech.isPlasmaRange + const SPEED = 8 + 8 * tech.isPlasmaRange const me = bullet.length; const where = Vector.add(m.pos, player.velocity) bullet[me] = Bodies.polygon(where.x + 20 * Math.cos(m.angle), where.y + 20 * Math.sin(m.angle), 4, 0.01, { cycle: -0.5, isWave: true, - endCycle: simulation.cycle + 33, // + 30 * tech.isPlasmaRange, + endCycle: simulation.cycle + 40, // + 30 * tech.isPlasmaRange, inertia: Infinity, frictionAir: 0, isInHole: true, //this keeps the bullet from entering wormholes @@ -1554,39 +1556,25 @@ const b = { if (this.endCycle < simulation.cycle + 1) this.isWave = false if (Matter.Query.point(map, this.position).length) { //check if inside map this.isBranch = true; + this.do = () => { if (this.endCycle < simulation.cycle + 1) this.isWave = false } } else { //check if inside a body for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) - const radius = mob[i].radius + 20 + const radius = mob[i].radius + tech.extruderRange if (dist < radius * radius) { - Matter.Body.setVelocity(mob[i], { - x: mob[i].velocity.x * 0.15, - y: mob[i].velocity.y * 0.15 - }); + Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.25, y: mob[i].velocity.y * 0.25 }); Matter.Body.setPosition(this, Vector.add(this.position, mob[i].velocity)) //move with the medium let dmg = this.dmg / Math.min(10, mob[i].mass) mob[i].damage(dmg); if (mob[i].alive) mob[i].foundPlayer(); } } - // const q = Matter.Query.point(mob, this.position) - // for (let i = 0; i < q.length; i++) { - // Matter.Body.setVelocity(q[i], { - // x: q[i].velocity.x * 0.15, - // y: q[i].velocity.y * 0.15 - // }); - // Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium - // let dmg = this.dmg / Math.min(10, q[i].mass) - // q[i].damage(dmg); - // if (q[i].alive) q[i].foundPlayer(); - // } } this.cycle++ const wiggleMag = (input.down ? 6 : 12) * Math.cos(simulation.cycle * 0.09) const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(simulation.cycle * 0.3)) - const velocity = Vector.mult(player.velocity, 0.3) //move with player + const velocity = Vector.mult(player.velocity, 0.4) //move with player Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle))) - // Matter.Body.setPosition(this, Vector.add(this.position, wiggle)) } } }); @@ -1596,9 +1584,11 @@ const b = { y: SPEED * Math.sin(m.angle) }); const transverse = Vector.normalise(Vector.perp(bullet[me].velocity)) - if (180 - Math.abs(Math.abs(b.lastAngle - m.angle) - 180) > 0.13) bullet[me].isBranch = true; //don't draw stroke for this bullet + if (180 - Math.abs(Math.abs(b.lastAngle - m.angle) - 180) > 0.13 || !b.wasExtruderOn) { + bullet[me].isBranch = true; //don't draw stroke for this bullet + bullet[me].do = function() { if (this.endCycle < simulation.cycle + 1) this.isWave = false } + } b.lastAngle = m.angle //track last angle for the above angle difference calculation - if (!b.wasExtruderOn) bullet[me].isBranch = true; } else { b.canExtruderFire = false; } @@ -3049,7 +3039,7 @@ const b = { bullet[me].endCycle = simulation.cycle + 60 + 18 * Math.random(); bullet[me].dmg = tech.isNailRadiation ? 0 : dmg bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech - if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 2.6 : 0.65), tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end } @@ -3083,7 +3073,7 @@ const b = { this.immuneList.push(who.id) //remember that this needle has hit this mob once already let dmg = b.dmgScale * 6 if (tech.isNailRadiation) { - mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + mobs.statusDoT(who, tech.isFastRadiation ? 6 : 2, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles dmg *= 0.25 } if (tech.isCrit && who.isStunned) dmg *= 4 @@ -4040,7 +4030,7 @@ const b = { if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end } - if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 1.4 : 0.35), tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles }; bullet[me].minDmgSpeed = 10 @@ -4088,7 +4078,7 @@ const b = { if (tech.isIceCrystals) { bullet[bullet.length - 1].beforeDmg = function(who) { mobs.statusSlow(who, 60) - if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 2.6 : 0.65), tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end } diff --git a/js/index.js b/js/index.js index ee86224..3a3ea1c 100644 --- a/js/index.js +++ b/js/index.js @@ -506,11 +506,12 @@ const build = { return `${text}` }, reset() { + build.isExperimentSelection = true; + build.isExperimentRun = true; simulation.startGame(true); //starts game, but pauses it build.isExperimentSelection = true; build.isExperimentRun = true; simulation.paused = true; - m.setField(0) b.inventory = []; //removes guns and ammo for (let i = 0, len = b.guns.length; i < len; ++i) { b.guns[i].count = 0; diff --git a/js/level.js b/js/level.js index 2b33b25..e8a58fc 100644 --- a/js/level.js +++ b/js/level.js @@ -15,13 +15,13 @@ const level = { // localSettings.levelsClearedLastGame = 10 // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true - // m.setField("plasma torch") // b.giveGuns("harpoon") + // m.setField("plasma torch") // tech.giveTech("extruder") - // tech.giveTech("filament") + // for (let i = 0; i < 1; i++) tech.giveTech("refractory metal") // tech.giveTech("mouth") // tech.giveTech("all-stars") - // for (let i = 0; i < 3; i++) tech.giveTech("super sized") + // for (let i = 0; i < 3; i++) tech.giveTech("overcharge") // for (let i = 0; i < 9; i++) tech.giveTech("MIRV") // tech.isCancelDuplication = true @@ -2265,7 +2265,7 @@ const level = { spawn.mapRect(-950, -1800, 8200, 800); //roof spawn.mapRect(-250, -400, 1000, 600); // shelf spawn.mapRect(-250, -1200, 1000, 550); // shelf roof - powerUps.spawnStartingPowerUps(600, -800); + // powerUps.spawnStartingPowerUps(600, -800); // for (let i = 0; i < 50; ++i) powerUps.spawn(550, -800, "research", false); // powerUps.spawn(350, -800, "gun", false); @@ -2302,7 +2302,7 @@ const level = { // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) // spawn.slashBoss(1900, -500) - spawn.shooter(1900, -500) + spawn.slasher(1900, -500) // spawn.shield(mob[mob.length - 1], 1900, -500, 1); // mob[mob.length - 1].isShielded = true // spawn.growBossCulture(1200, -500) diff --git a/js/player.js b/js/player.js index ec8d23a..878bbc1 100644 --- a/js/player.js +++ b/js/player.js @@ -393,12 +393,18 @@ const m = { // for (let i = 0; i < tech.tech.length; i++) { // if (tech.tech[i].name === "quantum immortality") tech.removeTech(i) // } + + m.setMaxHealth() + m.health = 1; + // m.addHealth(1) + simulation.wipe = function() { //set wipe to have trails ctx.fillStyle = "rgba(255,255,255,0)"; ctx.fillRect(0, 0, canvas.width, canvas.height); } spawn.setSpawnList(); //new mob types simulation.clearNow = true; //triggers a map reset + m.switchWorlds() const swapPeriod = 1000 for (let i = 0, len = 5; i < len; i++) { @@ -1443,6 +1449,7 @@ const m = { document.getElementById("field").innerHTML = m.fieldUpgrades[index].name m.setHoldDefaults(); m.fieldUpgrades[index].effect(); + simulation.makeTextLog(`m.setField("${m.fieldUpgrades[m.fieldMode].name}")`); }, fieldUpgrades: [{ name: "field emitter", @@ -1972,34 +1979,82 @@ const m = { } } }, + // { + // name: "plasma torch", + // description: "use energy to emit short range plasma
damages and pushes mobs away", + // effect() { + // m.fieldMeterColor = "#f0f" + // m.eyeFillColor = m.fieldMeterColor + // m.hold = function() { + // b.isExtruderOn = false + // if (m.isHolding) { + // m.drawHold(m.holdingTarget); + // m.holding(); + // m.throwBlock(); + // } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed + // m.grabPowerUp(); + // m.lookForPickUp(); + // if (tech.isExtruder) { + // b.extruder(); + // } else { + // b.plasma(); + // } + // } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released + // m.pickUp(); + // } else { + // m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) + // } + // m.drawFieldMeter("rgba(0, 0, 0, 0.2)") + + // if (tech.isExtruder) { + // if (input.field) { + // b.wasExtruderOn = true + // } else { + // b.wasExtruderOn = false + // b.canExtruderFire = true + // } + // ctx.beginPath(); //draw all the wave bullets + // for (let i = 0, len = bullet.length; i < len; i++) { + // if (bullet[i].isWave) { + // if (bullet[i].isBranch) { + // ctx.moveTo(bullet[i].position.x, bullet[i].position.y) + // } else { + // ctx.lineTo(bullet[i].position.x, bullet[i].position.y) + // } + // } + // } + // if (b.wasExtruderOn && b.isExtruderOn) ctx.lineTo(m.pos.x + 15 * Math.cos(m.angle), m.pos.y + 15 * Math.sin(m.angle)) + // ctx.lineWidth = 4; + // ctx.strokeStyle = "#f07" + // ctx.stroke(); + // ctx.lineWidth = tech.extruderRange; + // ctx.strokeStyle = "rgba(255,0,110,0.05)" + // ctx.stroke(); + // } + // } + // } + // }, { name: "plasma torch", description: "use energy to emit short range plasma
damages and pushes mobs away", - effect() { - m.fieldMeterColor = "#f0f" - m.eyeFillColor = m.fieldMeterColor - m.hold = function() { - b.isExtruderOn = false - if (m.isHolding) { - m.drawHold(m.holdingTarget); - m.holding(); - m.throwBlock(); - } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed - m.grabPowerUp(); - m.lookForPickUp(); - if (tech.isExtruder) { + set() { + if (tech.isExtruder) { + m.hold = function() { + b.isExtruderOn = false + if (m.isHolding) { + m.drawHold(m.holdingTarget); + m.holding(); + m.throwBlock(); + } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed + m.grabPowerUp(); + m.lookForPickUp(); b.extruder(); + } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released + m.pickUp(); } else { - b.plasma(); + m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) } - } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released - m.pickUp(); - } else { - m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) - } - m.drawFieldMeter("rgba(0, 0, 0, 0.2)") - - if (tech.isExtruder) { + m.drawFieldMeter("rgba(0, 0, 0, 0.2)") if (input.field) { b.wasExtruderOn = true } else { @@ -2007,32 +2062,47 @@ const m = { b.canExtruderFire = true } ctx.beginPath(); //draw all the wave bullets - for (let i = 0, len = bullet.length; i < len; i++) { + for (let i = 1, len = bullet.length; i < len; i++) { //skip the first bullet (which is is oldest bullet) if (bullet[i].isWave) { - if (bullet[i].isBranch) { + if (bullet[i].isBranch || bullet[i - 1].isBranch) { ctx.moveTo(bullet[i].position.x, bullet[i].position.y) - - // ctx.lineWidth = 5; - // ctx.strokeStyle = "#f07" - // ctx.stroke(); - // ctx.lineWidth = 30; - // ctx.strokeStyle = "rgba(255,0,110,0.05)" - // ctx.stroke(); - // ctx.beginPath(); //draw all the wave bullets } else { ctx.lineTo(bullet[i].position.x, bullet[i].position.y) } } } if (b.wasExtruderOn && b.isExtruderOn) ctx.lineTo(m.pos.x + 15 * Math.cos(m.angle), m.pos.y + 15 * Math.sin(m.angle)) - ctx.lineWidth = 5; + ctx.lineWidth = 4; ctx.strokeStyle = "#f07" ctx.stroke(); - ctx.lineWidth = 35; - ctx.strokeStyle = "rgba(255,0,110,0.05)" + ctx.lineWidth = tech.extruderRange; + ctx.strokeStyle = "rgba(255,0,110,0.06)" ctx.stroke(); } + } else { + m.hold = function() { + b.isExtruderOn = false + if (m.isHolding) { + m.drawHold(m.holdingTarget); + m.holding(); + m.throwBlock(); + } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed + m.grabPowerUp(); + m.lookForPickUp(); + b.plasma(); + } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released + m.pickUp(); + } else { + m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) + } + m.drawFieldMeter("rgba(0, 0, 0, 0.2)") + } } + }, + effect() { + m.fieldMeterColor = "#f0f" + m.eyeFillColor = m.fieldMeterColor + this.set(); } }, { diff --git a/js/powerup.js b/js/powerup.js index 1b2ff89..fb7b57c 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -217,7 +217,6 @@ const powerUps = { simulation.makeTextLog(text); } else if (type === "field") { m.setField(index) - simulation.makeTextLog(`m.setField("${m.fieldUpgrades[m.fieldMode].name}")`); } else if (type === "tech") { setTimeout(() => { powerUps.lastTechIndex = index diff --git a/js/simulation.js b/js/simulation.js index 5f3e678..6823ca1 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -678,8 +678,6 @@ const simulation = { level.setDifficulty() simulation.difficultyMode = Number(document.getElementById("difficulty-select").value) - build.isExperimentSelection = false; - build.isExperimentRun = false; simulation.clearNow = true; document.getElementById("text-log").style.opacity = 0; document.getElementById("fade-out").style.opacity = 0; @@ -690,7 +688,6 @@ const simulation = { // simulation.makeTextLog(`input.key.right: ["${input.key.right}", "ArrowRight"]`); simulation.makeTextLog(`const engine = Engine.create(); //simulation begin`); simulation.makeTextLog(`engine.timing.timeScale = 1`); - simulation.makeTextLog(`m.setField("${m.fieldUpgrades[m.fieldMode].name}")`); // simulation.makeTextLog(`input.key.field: ["${input.key.field}", "MouseRight"]`); document.getElementById("health").style.display = "inline" @@ -706,7 +703,6 @@ const simulation = { tech.healMaxEnergyBonus = 0 m.setMaxEnergy(); m.energy = 0 - m.fieldMode = 0; // simulation.makeTextLog(`${simulation.SVGrightMouse} ${m.fieldUpgrades[m.fieldMode].name}

${m.fieldUpgrades[m.fieldMode].description}`, 600); // simulation.makeTextLog(` // input.key.up = ["${input.key.up}", "ArrowUp"] @@ -719,7 +715,7 @@ const simulation = { //
m.field.description = "${m.fieldUpgrades[m.fieldMode].description}" // `, 800); - m.setField(m.fieldMode) + m.setField(0) // m.energy = 0; //exit testing if (simulation.testing) { @@ -729,6 +725,8 @@ const simulation = { } simulation.isCheating = false simulation.firstRun = false; + build.isExperimentSelection = false; + build.isExperimentRun = false; //setup FPS cap simulation.fpsInterval = 1000 / simulation.fpsCap; diff --git a/js/spawn.js b/js/spawn.js index 6046699..29802f2 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -3013,11 +3013,12 @@ const spawn = { me.delay = 120 * simulation.CDScale; me.cd = 0; me.swordRadius = 0; + me.swordVertex = 1 me.swordRadiusMax = 350 + 5 * simulation.difficulty; me.swordRadiusGrowRate = me.swordRadiusMax * (0.018 + 0.0006 * simulation.difficulty) me.isSlashing = false; me.swordDamage = 0.05 * simulation.dmgScale - const laserAngle = 3 * Math.PI / 5 + me.laserAngle = 3 * Math.PI / 5 const seeDistance2 = 200000 spawn.shield(me, x, y); me.onDamage = function() {}; @@ -3027,7 +3028,6 @@ const spawn = { this.attraction(); if (!m.isBodiesAsleep) this.sword() //does various things depending on what stage of the sword swing }; - me.swordWaiting = function() { if ( this.seePlayer.recall && @@ -3036,6 +3036,17 @@ const spawn = { Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0 ) { + //find vertex farthest away from player + let dist = 0 + for (let i = 0, len = this.vertices.length; i < len; i++) { + const D = Vector.magnitudeSquared(Vector.sub({ x: this.vertices[i].x, y: this.vertices[i].y }, m.pos)) + if (D > dist) { + dist = D + this.swordVertex = i + } + } + // this.laserAngle = 7 / 10 * Math.PI + this.swordVertex / 5 * 2 * Math.PI - Math.PI / 2 + this.laserAngle = this.swordVertex / 5 * 2 * Math.PI + 0.6283 this.sword = this.swordGrow // Matter.Body.setVelocity(this, { x: 0, y: 0 }); this.accelMag = 0 @@ -3043,7 +3054,7 @@ const spawn = { } me.sword = me.swordWaiting //base function that changes during different aspects of the sword swing me.swordGrow = function() { - this.laserSword(this.vertices[1], this.angle + laserAngle); + this.laserSword(this.vertices[this.swordVertex], this.angle + this.laserAngle); this.swordRadius += this.swordRadiusGrowRate if (this.swordRadius > this.swordRadiusMax) { this.sword = this.swordSlash @@ -3051,7 +3062,7 @@ const spawn = { } } me.swordSlash = function() { - this.laserSword(this.vertices[1], this.angle + laserAngle); + this.laserSword(this.vertices[this.swordVertex], this.angle + this.laserAngle); this.torque += this.torqueMagnitude; this.spinCount++ if (this.spinCount > 60) { @@ -3064,23 +3075,23 @@ const spawn = { me.laserSword = function(where, angle) { const vertexCollision = function(v1, v1End, domain) { for (let i = 0; i < domain.length; ++i) { - let vertices = domain[i].vertices; - const len = vertices.length - 1; + let v = domain[i].vertices; + const len = v.length - 1; for (let j = 0; j < len; j++) { - results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + results = simulation.checkLineIntersection(v1, v1End, v[j], v[j + 1]); if (results.onLine1 && results.onLine2) { const dx = v1.x - results.x; const dy = v1.y - results.y; const dist2 = dx * dx + dy * dy; - if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: vertices[j], v2: vertices[j + 1] }; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: v[j], v2: v[j + 1] }; } } - results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + results = simulation.checkLineIntersection(v1, v1End, v[0], v[len]); if (results.onLine1 && results.onLine2) { const dx = v1.x - results.x; const dy = v1.y - results.y; const dist2 = dx * dx + dy * dy; - if (dist2 < best.dist2) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: vertices[0], v2: vertices[len] }; + if (dist2 < best.dist2) best = { x: results.x, y: results.y, dist2: dist2, who: domain[i], v1: v[0], v2: v[len] }; } } }; diff --git a/js/tech.js b/js/tech.js index 3044d38..d1eeadf 100644 --- a/js/tech.js +++ b/js/tech.js @@ -3876,7 +3876,7 @@ { name: "irradiated nails", link: `irradiated nails`, - description: "nails, needles, and rivets are radioactive
about 90% more damage over 2 seconds", + description: "nails, needles, and rivets are radioactive
about 90% more damage over 3 seconds", isGunTech: true, maxCount: 1, count: 0, @@ -3894,8 +3894,8 @@ } }, { - name: "4s half-life", - link: `4s half-life`, + name: "6s half-life", + link: `6s half-life`, description: "nails are made of plutonium-238
increase damage by 100% over 6 seconds", isGunTech: true, maxCount: 1, @@ -3905,7 +3905,7 @@ allowed() { return tech.isNailRadiation && !tech.isFastRadiation }, - requires: "irradiated nails, not 1/2s half-life", + requires: "irradiated nails, not 1s half-life", effect() { tech.isSlowRadiation = true; }, @@ -3914,9 +3914,9 @@ } }, { - name: "1/2s half-life", - link: `1/2s half-life`, - description: "nails are made of lithium-8
damage occurs after 1/2 a second", + name: "1s half-life", + link: `1s half-life`, + description: "nails are made of lithium-8
damage occurs after 1 second", isGunTech: true, maxCount: 1, count: 0, @@ -3925,7 +3925,7 @@ allowed() { return tech.isNailRadiation && !tech.isSlowRadiation }, - requires: "irradiated nails, not 4s half-life", + requires: "irradiated nails, not 6s half-life", effect() { tech.isFastRadiation = true; }, @@ -4188,7 +4188,7 @@ }, { name: "super sized", - description: `increase super ball radius by 15%
increases damage by about 30%`, + description: `increase super ball radius by 14%
increases damage by about 27%`, isGunTech: true, maxCount: 9, count: 0, @@ -5084,7 +5084,7 @@ }, { name: "toggling harpoon", - description: "increase the damage of your next harpoon
by 600% after using it to collect a power up", + description: "increase the damage of your next harpoon
by 800% after using it to collect a power up", isGunTech: true, maxCount: 1, count: 0, @@ -5206,7 +5206,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return (tech.haveGunCheck("laser") || tech.laserBotCount > 1 || tech.isLaserMine) && tech.laserDamage === 0.16 + return (tech.haveGunCheck("laser") || tech.laserBotCount > 1 || tech.isLaserMine) && tech.laserDamage === 0.17 }, requires: "laser, not free-electron", effect() { @@ -5234,13 +5234,13 @@ requires: "laser, not pulse, diodes", effect() { tech.laserFieldDrain = 0.007 //base is 0.002 - tech.laserDamage = 0.48; //base is 0.16 + tech.laserDamage = 0.51; //base is 0.16 tech.laserColor = "#83f" tech.laserColorAlpha = "rgba(136, 51, 255,0.5)" }, remove() { tech.laserFieldDrain = 0.002; - tech.laserDamage = 0.16; //used in check on pulse and diode: tech.laserDamage === 0.16 + tech.laserDamage = 0.17; //used in check on pulse and diode: tech.laserDamage === 0.16 tech.laserColor = "#f00" tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" } @@ -5999,7 +5999,7 @@ description: `use ${powerUps.orb.research(1)} to increase plasma torch range 50%`, // description: "use 1 research to
increase plasma torch's range by 50%", isFieldTech: true, - maxCount: 3, + maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, @@ -6018,7 +6018,7 @@ }, { name: "extruder", - description: "plasma torch extrudes a thin hot wire
increases damage, energy drain, and lag", + description: "plasma torch extrudes a thin hot wire
increases damage and energy drain", isFieldTech: true, maxCount: 1, count: 0, @@ -6030,9 +6030,30 @@ requires: "plasma torch, not plasma-bot", effect() { tech.isExtruder = true; + m.fieldUpgrades[m.fieldMode].set() }, remove() { tech.isExtruder = false; + if (this.count) m.fieldUpgrades[m.fieldMode].set() + } + }, + { + name: "refractory metal", + description: "extrude metals at a higher temperature
increases effective radius", + isFieldTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.isExtruder + }, + requires: "extruder", + effect() { + tech.extruderRange += 50 + }, + remove() { + tech.extruderRange = 15 } }, { @@ -6252,7 +6273,7 @@ }, { name: "dynamical systems", - description: `use ${powerUps.orb.research(1)}to increase your damage by 35%`, + description: `use ${powerUps.orb.research(2)}to increase your damage by 35%`, // description: "use 1 research
increase your damage by 35%", isFieldTech: true, maxCount: 1, @@ -6260,34 +6281,34 @@ frequency: 3, frequencyDefault: 3, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 0) + return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 1) }, - requires: "metamaterial cloaking or pilot wave", + requires: "metamaterial cloaking pilot wave or plasma torch", effect() { tech.isCloakingDamage = true - for (let i = 0; i < 1; i++) { + for (let i = 0; i < 2; i++) { if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } }, remove() { tech.isCloakingDamage = false - if (this.count > 0) powerUps.research.changeRerolls(1) + if (this.count > 0) powerUps.research.changeRerolls(2) } }, { name: "discrete optimization", - description: "increase damage by 50%
50% increased delay after firing", + description: "increase damage by 40%
40% increased delay after firing", isFieldTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler" + 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 or pilot wave", + requires: "metamaterial cloaking, plasma torch or pilot wave", effect() { - tech.aimDamage = 1.5 + tech.aimDamage = 1.40 b.setFireCD(); }, remove() { @@ -8459,5 +8480,6 @@ isAddRemoveMaxHealth: null, removeMaxHealthOnKill: null, isSpawnExitTech: null, - cloakDuplication: null + cloakDuplication: null, + extruderRange: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index b3960f9..3abcc41 100644 --- a/todo.txt +++ b/todo.txt @@ -1,32 +1,18 @@ ******************************************************** NEXT PATCH ************************************************** +extruder: + new tech: refractory metal - increase extruder damage radius + fixed extruder graphics bug, and collisions bug + dynamical systems and discrete optimization are allowed with plasma torch + (although I nerfed them both just a bit) -plasma extruder - extruder lag issues should be fixed! - extruder graphics have a cool glow - 45% more damage - 20% more energy drain - slows mobs a bit more - extends faster - it can hit mobs that get near it now instead of just inside it - plasma jet now works with extruder +irradiated nails: 90% damage spread over 2s -> 3s + same total damage, but it takes 1 second longer +toggling harpoon: 6x -> 8x damage + also the graphic effect is more obvious +slasher mobs will grow their sword at the farthest vertex from the player ******************************************************** TODO ******************************************************** -toggle harpoon is weak and should be more obvious - -Tech: "Growth": Increase damage by 3% for every mob currently alive. - -add link URL to all tech guns and field on page load - but only if URL is undefined so hard to search names can be added in by hand - -slasherBoss - sine wave of lasers that travel around vertexes - 10+ sided - low laser damage, but it doesn't trigger damage immunity - -slasher compute fastest direction to rotate towards player - cross product - death animation ideas: redraw game in strange ways, to show that it's a simulation (for example the testing mode is a strange redraw of map) stroke only, but connect all vertices together, no moveTo @@ -34,25 +20,9 @@ death animation ideas: be nice if block throwing had a projected path -slasher mob: extends a thin radial line, then spins around and damages player if in circle around mob - do short length laser damage - doesn't have to be a full spin - JUNK tech: planetesimals game inside n-gon https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 -how to make it more interesting to get multiple guns? - make final boss less about having huge dps - lower final boss health when it spawns boss - spawn more bosses - make guns have more weaknesses/advantages to specific situations - no gun should be good at everything - remove gun tech that stacks to 9? - nerf a few of the most overpowered gun tech - make more gun tech apply to multiple guns - after picking up a gun tech open a menu with just gun tech for that gun? - but then the player never gets to try the vanilla version of the gun - Tech: Make player smol disable zoom progress when paused @@ -91,10 +61,6 @@ Pilot wave tech Grouping blocks will merge them into a massive ball Size, density is determined by total mass - -make experiment and understand vibe more obvious - mostly in early game or first time players - look into 360 matter wave lag aoe effect pushes mobs away, then rapidly pulls them in @@ -484,6 +450,8 @@ possible names for tech SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions. nuclear pasta - hard matter in neutron star nonlocal + fine-tuned universe + eternalism https://en.wikipedia.org/wiki/Eternalism_(philosophy_of_time) a tutorial / lore intro needs to be optional so it doesn't slow experienced players