diff --git a/js/bullet.js b/js/bullet.js
index bb826bc..2f4f2f6 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -384,7 +384,7 @@ const b = {
//player damage
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
- const DRAIN = (tech.isExplosionHarm ? 0.67 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1)
+ const DRAIN = (tech.isExplosionHarm ? 0.63 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
if (m.energy < 0) {
m.energy = 0
@@ -433,7 +433,7 @@ const b = {
if (dist < radius) {
if (simulation.dmgScale) {
- const harm = tech.isExplosionHarm ? 0.075 : 0.05
+ const harm = tech.isExplosionHarm ? 0.07 : 0.05
if (tech.isImmuneExplosion && m.energy > 0.12) {
// const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
m.energy -= 0.12
diff --git a/js/level.js b/js/level.js
index 246c79d..2634cbf 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,7 +16,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
- // level.difficultyIncrease(9 * 4) //30 is near max on hard //60 is near max on why
+ // level.difficultyIncrease(1 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
@@ -24,11 +24,10 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000
-
- // m.setField("perfect diamagnetism") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
- // b.giveGuns("mine") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
+ // m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
+ // b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.giveTech("sentry");
- // tech.giveTech("laser-mines");
+ // tech.giveTech("MACHO");
// tech.giveTech("elephant's toothpaste")
// for (let i = 0; i < 1; ++i) tech.giveTech("slow light")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
@@ -39,10 +38,10 @@ const level = {
// spawn.flutter(1900, -500, 10)
// spawn.starter(1900, -500, 200)
- // spawn.dragonFlyBoss(1900, -400)
+ // spawn.historyBoss(1900, -400)
// spawn.beetleBoss(1900, -400)
- // for (let i = 0; i < 2; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
- // level.testing(); //not in rotation, used for testing
+ // for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
+ // level.testing();
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
@@ -58,6 +57,8 @@ const level = {
// level.null()
// lore.unlockTesting();
// tech.giveTech("tinker"); //show junk tech in experiment mode
+
+ // simulation.rumble()
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
diff --git a/js/simulation.js b/js/simulation.js
index 7f483bf..db62293 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -562,6 +562,38 @@ const simulation = {
}
}, len * swapPeriod);
},
+ // warp(translation = 5, skew = 0.05, scale = 0.05) {
+ // if (simulation.cycle % 2) { //have to alternate frames or else successive rumbles over write the effects of the previous rumble
+ // requestAnimationFrame(() => { ctx.setTransform(1, 0, 0, 1, 0, 0); }) //reset
+ // requestAnimationFrame(() => {
+ // if (!simulation.paused && m.alive) {
+ // ctx.transform(1 - scale * (Math.random() - 0.5), skew * (Math.random() - 0.5), skew * (Math.random() - 0.5), 1 - scale * (Math.random() - 0.5), translation * (Math.random() - 0.5), translation * (Math.random() - 0.5)); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving)) //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform
+ // }
+ // })
+
+ //reset
+ // ctx.transform(1, 0, 0, 1, 0, 0); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving)) //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform
+
+ // }
+ // const loop = () => {
+ // if (!simulation.paused && m.alive) {
+ // ctx.save();
+ // ctx.transform(1 - scale * (Math.random() - 0.5), skew * (Math.random() - 0.5), skew * (Math.random() - 0.5), 1 - scale * (Math.random() - 0.5), translation * (Math.random() - 0.5), translation * (Math.random() - 0.5)); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving))
+ // requestAnimationFrame(() => { ctx.restore(); })
+ // }
+ // }
+ // requestAnimationFrame(loop);
+
+ // function loop() {
+ // if (!simulation.paused && m.alive) {
+ // ctx.save();
+ // ctx.transform(1 - scale * (Math.random() - 0.5), skew * (Math.random() - 0.5), skew * (Math.random() - 0.5), 1 - scale * (Math.random() - 0.5), translation * (Math.random() - 0.5), translation * (Math.random() - 0.5)); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving))
+ // requestAnimationFrame(() => { ctx.restore(); })
+ // }
+ // requestAnimationFrame(loop);
+ // }
+ // requestAnimationFrame(loop);
+ // },
wipe() {}, //set in simulation.startGame
gravity() {
function addGravity(bodies, magnitude) {
@@ -699,6 +731,10 @@ const simulation = {
document.getElementById("pause-grid-left").style.opacity = "1"
ctx.globalCompositeOperation = "source-over"
ctx.shadowBlur = 0;
+ requestAnimationFrame(() => {
+ ctx.setTransform(1, 0, 0, 1, 0, 0); //reset warp effect
+ ctx.setLineDash([]) //reset stroke dash effect
+ })
// ctx.shadowColor = '#000';
if (!m.isShipMode) {
m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech
@@ -830,6 +866,7 @@ const simulation = {
},
clearNow: false,
clearMap() {
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
if (m.alive) {
if (tech.isLongitudinal) {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
diff --git a/js/spawn.js b/js/spawn.js
index ecfa377..7cdca1d 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -530,6 +530,7 @@ const spawn = {
this.totalCycles++;
if (this.health > 0.25) {
if (this.cycle > this.endCycle) {
+ this.showHealthBar = true
this.cycle = 0;
this.mode++
this.damageReduction = 0.25
@@ -550,6 +551,7 @@ const spawn = {
this.modeDo = this.modeSuck
Matter.Body.scale(this, 0.001, 0.001);
this.damageReduction = 0.000025
+ this.showHealthBar = false
}
if (tech.isGunCycle) {
b.inventoryGun++;
@@ -557,9 +559,11 @@ const spawn = {
simulation.switchGun();
}
}
- } else if (this.mode !== 3) { //all three modes at once
+ } else if (this.mode !== 3) { //all three modes at once , this runs once
+ this.showHealthBar = true
this.pushAway();
this.cycle = 0;
+ this.endCycle = Infinity
this.damageReduction = 0.15
if (this.mode === 2) {
Matter.Body.scale(this, 500, 500);
@@ -573,6 +577,7 @@ const spawn = {
this.rotateVelocity = 0.001 * (player.position.x > this.position.x ? 1 : -1) //rotate so that the player can get away
// if (!this.isShielded) spawn.shield(this, x, y, 1); //regen shield here ?
this.modeDo = this.modeAll
+ this.eventHorizonRadius = 700
if (tech.isGunCycle) {
b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
@@ -610,15 +615,15 @@ const spawn = {
}
}
}
- me.eventHorizon = 1300
- me.eventHorizonCycleRate = 4 * Math.PI / me.endCycle
+ me.eventHorizon = 0
+ me.eventHorizonRadius = 1300
me.modeSuck = function() {
- if (!(this.cycle % 60)) {
+ if (!(this.cycle % 30)) {
const index = Math.floor((this.cycle % 360) / 60)
spawn.seeker(this.vertices[index].x, this.vertices[index].y, 20 * (0.5 + Math.random()), 9); //give the bullet a rotational velocity as if they were attached to a vertex
const who = mob[mob.length - 1]
Matter.Body.setDensity(who, 0.00003); //normal is 0.001
- who.timeLeft = 760 //* (0.8 + 0.4 * Math.random());
+ who.timeLeft = 720 + 10 * simulation.difficulty //* (0.8 + 0.4 * Math.random());
who.accelMag = 0.0003 * simulation.accelScale; //* (0.8 + 0.4 * Math.random())
who.frictionAir = 0.01 //* (0.8 + 0.4 * Math.random());
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[index]))), -7)
@@ -629,33 +634,37 @@ const spawn = {
}
//eventHorizon waves in and out
- const eventHorizon = this.eventHorizon * (1 - 0.25 * Math.cos(simulation.cycle * this.eventHorizonCycleRate)) //0.014
+ if (this.cycle + 30 > this.endCycle) { //shrink fast in last bit of cycle
+ this.eventHorizon = 0.93 * this.eventHorizon
+ } else {
+ this.eventHorizon = 0.97 * this.eventHorizon + 0.03 * (this.eventHorizonRadius * (1 - 0.5 * Math.cos(this.cycle * 0.015)))
+ }
//draw darkness
ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon * 0.2, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,20,40,0.6)";
ctx.fill();
ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, eventHorizon * 0.4, 0, 2 * Math.PI);
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon * 0.4, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,20,40,0.4)";
ctx.fill();
ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, eventHorizon * 0.6, 0, 2 * Math.PI);
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon * 0.6, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,20,40,0.3)";
ctx.fill();
ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, eventHorizon * 0.8, 0, 2 * Math.PI);
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon * 0.8, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,20,40,0.2)";
ctx.fill();
ctx.beginPath();
- ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI);
+ ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.05)";
ctx.fill();
//when player is inside event horizon
- if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
+ if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
if (m.immuneCycle < m.cycle) {
- if (m.energy > 0) m.energy -= 0.01
- if (m.energy < 0.15 && m.immuneCycle < m.cycle) m.damage(0.0004 * simulation.dmgScale);
+ if (m.energy > 0) m.energy -= 0.015
+ if (m.energy < 0.05 && m.immuneCycle < m.cycle) m.damage(0.0005 * simulation.dmgScale);
}
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.0017 * Math.cos(angle) * player.mass * (m.onGround ? 1.7 : 1);
@@ -672,7 +681,7 @@ const spawn = {
ctx.fillStyle = "rgba(0,0,0,0.3)";
ctx.fill();
}
- this.curl(eventHorizon);
+ this.curl(this.eventHorizon);
}
me.rotateVelocity = 0.0025
me.rotateCount = 0;
@@ -2529,6 +2538,7 @@ const spawn = {
me.laserRange = 350;
me.seeAtDistance2 = 2000000;
me.isBoss = true;
+ me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReductionGoal
me.showHealthBar = false; //drawn in this.awake
me.delayLimit = 60 + Math.floor(30 * Math.random());
@@ -2539,10 +2549,13 @@ const spawn = {
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
requestAnimationFrame(() => {
- requestAnimationFrame(() => { ctx.setLineDash([]) })
+ requestAnimationFrame(() => {
+ ctx.setTransform(1, 0, 0, 1, 0, 0); //reset warp effect
+ ctx.setLineDash([]) //reset stroke dash effect
+ })
})
};
- me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReductionGoal
+ me.warpIntensity = 0
me.awake = function() {
// this.armor();
this.checkStatus();
@@ -2577,6 +2590,13 @@ const spawn = {
m.damage(0.0004 * simulation.dmgScale)
}
}
+ this.warpIntensity += 0.0004
+ requestAnimationFrame(() => {
+ if (!simulation.paused && m.alive) {
+ ctx.transform(1, this.warpIntensity * (Math.random() - 0.5), this.warpIntensity * (Math.random() - 0.5), 1, 0, 0); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving)) //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform
+ // ctx.transform(1 - scale * (Math.random() - 0.5), skew * (Math.random() - 0.5), skew * (Math.random() - 0.5), 1 - scale * (Math.random() - 0.5), translation * (Math.random() - 0.5), translation * (Math.random() - 0.5)); //ctx.transform(Horizontal scaling. A value of 1 results in no scaling, Vertical skewing, Horizontal skewing, Vertical scaling. A value of 1 results in no scaling, Horizontal translation (moving), Vertical translation (moving)) //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform
+ }
+ })
ctx.beginPath();
ctx.moveTo(eye.x, eye.y);
ctx.lineTo(m.pos.x, m.pos.y);
@@ -2588,6 +2608,8 @@ const spawn = {
ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(150,0,255,0.1)";
ctx.fill();
+ } else {
+ this.warpIntensity = 0;
}
//several ellipses spinning about the same axis
@@ -4402,11 +4424,13 @@ const spawn = {
}
//time dilation
if (!simulation.isTimeSkipping) {
- requestAnimationFrame(() => {
- simulation.timePlayerSkip(2)
- m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
- }); //wrapping in animation frame prevents errors, probably
- // if (!(simulation.cycle % 10))
+ // requestAnimationFrame(() => {
+ // simulation.timePlayerSkip(2)
+ // m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
+ // }); //wrapping in animation frame prevents errors, probably
+
+ simulation.timePlayerSkip(2)
+ m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
//draw invulnerable
ctx.beginPath();
@@ -5639,10 +5663,14 @@ const spawn = {
// simulation.timePlayerSkip(5)
// // simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
// }); //wrapping in animation frame prevents errors, probably
- requestAnimationFrame(() => {
- simulation.timePlayerSkip(1)
- m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
- }); //wrapping in animation frame prevents errors, probably
+
+ // requestAnimationFrame(() => {
+ // simulation.timePlayerSkip(1)
+ // m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
+ // }); //wrapping in animation frame prevents errors, probably
+
+ simulation.timePlayerSkip(1)
+ m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
diff --git a/js/tech.js b/js/tech.js
index afaf4c9..7d02ff7 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -4803,7 +4803,7 @@ const tech = {
},
{
name: "acetone peroxide",
- description: "+70% explosive radius
–50% explosive defense",
+ description: "+70% explosive radius
–40% explosive defense",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5671,7 +5671,7 @@ const tech = {
},
{
name: "necrophage",
- description: "if foam, fleas, or worms kill their target
grow 3 copies",
+ description: "if foam, fleas, or worms kill their target
they grow 3 copies",
isGunTech: true,
maxCount: 1,
count: 0,
diff --git a/todo.txt b/todo.txt
index e719017..8fc7cad 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,19 +1,42 @@
******************************************************** NEXT PATCH **************************************************
-elephant's toothpaste: mines make foam
+finalBoss black hole phase:
+ makes 100% more bullets
+ grows and shrinks smoothly near start and end of phase
+ does 20% more damage to player
-sentry fires about 40% faster
- but each shot slightly reduces the total duration
- (duration = 17s - 1/10 s per shot)
+historyBoss has a "fun" graphical effect
+acetone peroxide has 50 -> 40% less explosion defense
-foam can move through blocks a bit faster
-laser reflection damage is increased
- about 15% -> 8% damage loss per reflection
-beetleBoss pushes player away and spawns baby flutter mobs
-fire rate affects block throwing charge rate
+bug fix: timeSkip graphic glitch
+ there is a chance to cause other bugs with timeSkip effects
*********************************************************** TODO *****************************************************
+screen shake effect - add random numbers to ctx.translate
+
+quantum immortality: send you to a new tab after you die with a random load out
+ basically everything is the same as it is now, but you switch tabs
+
+tech: get sent to a new tab that closes in 3 minutes
+ in the new tab you play reactor
+ if you die in reactor you die in game, if you win you get 2-3 tech in the original game?
+ give player equipment like many-worlds
+ count guns, field, tech and give random stuff on new tab
+ i-frame instead of tab?
+
+field efficiency - Give each field an extra numerical effect, and add a 'field efficiency' stat that increases it
+ field numbers
+ standing wave, molecular assembler: energy efficiency
+ plasma, metamaterial: damage
+ time dilation: movement, jump, fire rate
+ negative mass: defense
+ diamagnetism: arc length
+ wormhole: (i dislike it but idk of other things) dupe chance
+ tech: +x% field efficiency, your field changes randomly every y seconds
+ tech: starts at 200%, but decays when the field is in use, efficiency recharges when the field is not in use
+
+
bug blocks and power ups falling through map
always foam gun (4-5 times)
might be about tech pressure vessel
@@ -38,6 +61,7 @@ mob mechanics
tech: You can place an extra perfect diamagnatism field on the map
standing wave no longer pushes mobs away, but it can do damage to mobs caught in area effect
+ Standing wave harmonics no longer deflects, but instead discharges excess energy as lightning toward nearby enemies
negative mass field does damage to mobs inside field
combine with standing wave effect? pilot wave?