demineralization
tech: demineralization - after mobs die gain 0.85x damage taken, effect stacks, but fades 10% every second
tech: remineralization - after mobs die gain 1.08x damage, effect stacks, but fades 10% every second
tech: equivalence principle - negative mass field doesn't cost energy
new JUNK tech: aerodynamics
interferometer
slower elevator and lasers
wider side ledges
large laser blocking blocks
flocculation
fewer mobs
it's easier to get out of the slime
pavilion
move vanish elements
easier traversal
secret tunnel
removed debris, but added power ups and blocks
corridor
limited to bosses that don't interact with the movers poorly
gravitron, substructure, corridor, interferometer
added more heal and ammo power ups to match other levels
because some newer levels are zoomed out more
laser max range is 3000->5000
nails last 1/3 of a second longer
bosses spawn an extra ammo power up
and 2 extra ammo on the hardest 2 difficulties
slasher mob's laserSwords will now damage a cloaked player
constraint announcement text looks more like computer code style to match game theme
foam recoil is back: 1->0.7x horizontal force and 2->4.3x vertical up force
this makes it less annoying to horizontally and easier to kinda fly/float
negative mass field damage reduction 0.4->0.5x
holographic principle no longer slows player movement
added 2 research cost
fermion gives 6->5 seconds of invulnerability after mobs die
stability 0.2->0.1x damage taken at max health
non-Newtonian armor 0.3->0.4x damage taken after collisions
Zeno's paradox 0.15->0.2x damage taken
annihilation energy cost 10->8 to destroy mobs after collisions
radiative equilibrium damage is 3->4x for 8->4 seconds
aerostat can be taken 1->3 times
dynamic equilibrium damage increased by 6->8x damage per last damage taken
aerostat no longer has 0.9x damage for being on the ground
launch system 1.2->1.3x ammo for missiles
research says that repeatedly entering alternate realities builds up some positive effects
Hilbert space 4x->3x damage
Ψ(t) collapse 6->4 research on boss death
transdimensional worms: 50% chance for a second worm per block in wormhole
wormhole 7->8 energy regen per second
hidden-variable theory 1.15->1.2 damage after choosing a field tech
ghoster mobs are less likely to get knocked far away from the player for long periods of time
bug fixes
dynamic equilibrium was set to 100 times higher frequency then normal
when constraints hide health bar's it's now hidden in the pause menu
mobs aiming at cloaked player
snakeBoss more intelligently chases player for a few seconds
pulsarBoss aims at player's history 3 seconds in past
pulsar will not stop firing
but it will still not fire at cloaked player
This commit is contained in:
48
js/spawn.js
48
js/spawn.js
@@ -1,6 +1,6 @@
|
||||
//main object for spawning things in a level
|
||||
const spawn = {
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture", "snakeBoss"],
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss, mineBoss, hopMotherBoss //these need a particular level to work so they are not included in the random pool
|
||||
randomBossList: [
|
||||
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||
@@ -114,9 +114,9 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
secondaryBossChance(x, y) {
|
||||
secondaryBossChance(x, y, options = []) {
|
||||
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
|
||||
spawn.randomLevelBoss(x, y);
|
||||
spawn.randomLevelBoss(x, y, options);
|
||||
powerUps.spawn(x - 30, y, "ammo");
|
||||
powerUps.spawn(x + 30, y, "ammo");
|
||||
} else {
|
||||
@@ -3921,8 +3921,8 @@ const spawn = {
|
||||
}
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.memory = 240
|
||||
me.seePlayerFreq = 55
|
||||
me.memory = 900;
|
||||
me.seePlayerFreq = 41
|
||||
me.delay = 5 + 2 * simulation.CDScale;//8 + 3 * simulation.CDScale;
|
||||
me.nextBlinkCycle = me.delay;
|
||||
me.JumpDistance = 0//set in redMode()
|
||||
@@ -4082,21 +4082,18 @@ const spawn = {
|
||||
move()
|
||||
} else if (this.seePlayer.recall) { //chase player's history
|
||||
this.lostPlayer();
|
||||
if (!m.isCloak) {
|
||||
for (let i = 0; i < 50; i++) { //if lost player lock onto a player location in history
|
||||
if (m.isCloak) {
|
||||
move(this.seePlayer.position) //go after where you last saw the player
|
||||
} else {
|
||||
for (let i = 0; i < 55; i++) { //if lost player lock onto a player location in history
|
||||
let history = m.history[(m.cycle - 10 * i) % 600]
|
||||
if (Matter.Query.ray(map, this.position, history.position).length === 0) {
|
||||
this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //cycles before mob falls a sleep
|
||||
this.seePlayer.position.x = history.position.x;
|
||||
this.seePlayer.position.y = history.position.y;
|
||||
this.seePlayer.yes = true;
|
||||
move()
|
||||
move(history.position) //go after where you last saw the player
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.checkStatus();
|
||||
if (this.isInvulnerable) {
|
||||
@@ -4170,7 +4167,7 @@ const spawn = {
|
||||
me.fire = function () {
|
||||
// this.armor();
|
||||
this.checkStatus();
|
||||
if (!m.isCloak && !this.isStunned) {
|
||||
if (!this.isStunned) {
|
||||
if (this.isFiring) {
|
||||
if (this.fireCycle > this.fireDelay) { //fire
|
||||
this.isFiring = false
|
||||
@@ -4221,7 +4218,9 @@ const spawn = {
|
||||
}
|
||||
} else { //aim at player
|
||||
this.fireCycle++
|
||||
this.fireDir = Vector.normalise(Vector.sub(m.pos, this.position)); //set direction to turn to fire
|
||||
//if cloaked, aim at player's history from 3 seconds ago
|
||||
const whereIsPlayer = m.isCloak ? m.history[(m.cycle - 180) % 600].position : m.pos
|
||||
this.fireDir = Vector.normalise(Vector.sub(whereIsPlayer, this.position)); //set direction to turn to fire
|
||||
//rotate towards fireAngle
|
||||
const angle = this.angle + Math.PI / 2;
|
||||
const c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
@@ -4233,7 +4232,7 @@ const spawn = {
|
||||
} else if (this.fireCycle > 45) { //fire
|
||||
unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100)
|
||||
this.fireTarget = Vector.add(this.vertices[1], unit)
|
||||
if (Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur
|
||||
if (Vector.magnitude(Vector.sub(whereIsPlayer, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
this.fireLockCount = 0
|
||||
this.isFiring = true
|
||||
@@ -4277,7 +4276,7 @@ const spawn = {
|
||||
}, Vector.normalise(Vector.sub(this.fireTarget, this.position)));
|
||||
//distance between the target and the player's location
|
||||
if (
|
||||
m.isCloak ||
|
||||
// m.isCloak ||
|
||||
dot > 0.03 || // not looking at target
|
||||
Matter.Query.ray(map, this.fireTarget, this.position).length || Matter.Query.ray(body, this.fireTarget, this.position).length || //something blocking line of sight
|
||||
Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) > 1000 // distance from player to target is very far, (this is because dot product can't tell if facing 180 degrees away)
|
||||
@@ -5056,7 +5055,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle, length) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + length * Math.cos(angle), y: where.y + length * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map] : [map, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5663,7 +5662,7 @@ const spawn = {
|
||||
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
@@ -5762,7 +5761,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5854,7 +5853,7 @@ const spawn = {
|
||||
me.laserSword = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
|
||||
m.damage(this.swordDamage);
|
||||
@@ -5964,7 +5963,7 @@ const spawn = {
|
||||
me.laserSpear = function (where, angle) {
|
||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||
const look = { x: where.x + this.swordRadius * Math.cos(angle), y: where.y + this.swordRadius * Math.sin(angle) };
|
||||
best = vertexCollision(where, look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
|
||||
best = vertexCollision(where, look, [map, body, [playerBody, playerHead]]);
|
||||
|
||||
if (best.who && (best.who === playerBody || best.who === playerHead)) {
|
||||
this.swordRadiusGrowRate = 1 / this.swordRadiusGrowRateInitial //!!!! this retracts the sword if it hits the player
|
||||
@@ -6180,7 +6179,7 @@ const spawn = {
|
||||
mobs.spawn(x, y, 7, radius, "transparent");
|
||||
let me = mob[mob.length - 1];
|
||||
me.seeAtDistance2 = 500000;
|
||||
me.accelMag = 0.00007 + 0.0001 * simulation.accelScale;
|
||||
me.accelMag = 0.0002 + 0.0001 * simulation.accelScale;
|
||||
if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
|
||||
Matter.Body.setDensity(me, 0.0002); //normal is 0.001
|
||||
me.damageReduction = 0.1
|
||||
@@ -6222,7 +6221,7 @@ const spawn = {
|
||||
if (this.health < 0.8) me.seeAtDistance2 = 2000000;
|
||||
}
|
||||
me.do = function () {
|
||||
if (this.speed > 7) Matter.Body.setVelocity(this, { x: this.velocity.x * 0.8, y: this.velocity.y * 0.8 }); //cap max speed to avoid getting launched by deflection, explosion
|
||||
if (this.speed > 6) Matter.Body.setVelocity(this, { x: this.velocity.x * 0.8, y: this.velocity.y * 0.8 }); //cap max speed to avoid getting launched by deflection, explosion
|
||||
this.seePlayerCheckByDistance();
|
||||
this.checkStatus();
|
||||
this.attraction();
|
||||
@@ -7215,6 +7214,7 @@ const spawn = {
|
||||
me.do = function () {
|
||||
this.seePlayerByHistory(60);
|
||||
this.attraction();
|
||||
if (this.distanceToPlayer2() > 9000000) this.attraction(); //extra attraction if far away
|
||||
this.checkStatus();
|
||||
this.eventHorizon = 950 + 250 * Math.sin(simulation.cycle * 0.005)
|
||||
if (!simulation.isTimeSkipping) {
|
||||
|
||||
Reference in New Issue
Block a user