crystallizer

random tech spawn chance now scales with levels clear (zero chance after level 10)
  (it used to scale with total tech acquired, but you probably will not even notice this change)

tech: crystallizer - mods produce ice-IX crystals when they die

tech pulse and tech slow light now work together for laser beam,
 (I think it is pretty dangerous to try them together though)
This commit is contained in:
landgreen
2021-05-08 07:35:25 -07:00
parent 59b124392c
commit ce169ba860
8 changed files with 104 additions and 65 deletions

View File

@@ -445,17 +445,17 @@ const b = {
}
}
},
pulse(charge, angle = m.angle) {
pulse(charge, angle = m.angle, where = m.pos) {
let best;
let explosionRadius = 6 * charge
let range = 5000
const path = [{
x: m.pos.x + 20 * Math.cos(angle),
y: m.pos.y + 20 * Math.sin(angle)
x: where.x + 20 * Math.cos(angle),
y: where.y + 20 * Math.sin(angle)
},
{
x: m.pos.x + range * Math.cos(angle),
y: m.pos.y + range * Math.sin(angle)
x: where.x + range * Math.cos(angle),
y: where.y + range * Math.sin(angle)
}
];
const vertexCollision = function(v1, v1End, domain) {
@@ -4477,7 +4477,6 @@ const b = {
this.do = () => {};
if (tech.isPulseLaser) {
this.fire = () => {
const drain = 0.01 * tech.isLaserDiode / b.fireCD
if (m.energy > drain) {
m.energy -= m.fieldRegen
@@ -4487,26 +4486,58 @@ const b = {
}
}
}
this.do = () => {
if (this.charge > 0) {
//draw charge level
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 4.2 * Math.sqrt(this.charge), 0, 2 * Math.PI);
ctx.fill();
if (!input.fire) {
m.fireCDcycle = m.cycle + 10; // cool down
if (tech.beamSplitter) {
const divergence = m.crouch ? 0.2 : 0.5
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
} else {
b.pulse(1.75 * this.charge, m.angle)
if (tech.historyLaser) {
this.do = () => {
const len = 1 + 2 * tech.historyLaser
const spacing = Math.ceil(40 - 9 * tech.historyLaser)
if (this.charge > 0) {
//draw charge level
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.beginPath();
const mag = 4.5 * Math.sqrt(this.charge)
for (let i = 0; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859
ctx.moveTo(history.position.x, history.position.y - off);
ctx.ellipse(history.position.x, history.position.y - off, mag, mag * 0.5, history.angle, 0, 2 * Math.PI)
}
ctx.fill();
//fire
if (!input.fire) {
m.fireCDcycle = m.cycle + 10; // cool down
for (let i = 1; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859
b.pulse(1.4 * this.charge, history.angle, { x: history.position.x, y: history.position.y - off })
}
this.charge = 0;
}
this.charge = 0;
}
}
};
};
} else {
this.do = () => {
if (this.charge > 0) {
//draw charge level
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 4.2 * Math.sqrt(this.charge), 0, 2 * Math.PI);
ctx.fill();
//fire
if (!input.fire) {
m.fireCDcycle = m.cycle + 10; // cool down
if (tech.beamSplitter) {
const divergence = m.crouch ? 0.2 : 0.5
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
} else {
b.pulse(1.75 * this.charge, m.angle)
}
this.charge = 0;
}
}
};
}
} else if (tech.beamSplitter) {
this.fire = this.fireSplit
} else if (tech.historyLaser) {
@@ -4532,13 +4563,9 @@ const b = {
b.laser();
}
},
// laser(where = {
// x: m.pos.x + 20 * Math.cos(m.angle),
// y: m.pos.y + 20 * Math.sin(m.angle)
// }, whereEnd = {
// x: where.x + 3000 * Math.cos(m.angle),
// y: where.y + 3000 * Math.sin(m.angle)
// }, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) {
firePulse() {
},
fireSplit() {
if (m.energy < tech.laserFieldDrain) {
m.fireCDcycle = m.cycle + 100; // cool down if out of energy

View File

@@ -12,17 +12,19 @@ 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(90)
// level.difficultyIncrease(30)
// simulation.zoomScale = 1000;
// simulation.setZoom();
// m.setField("metamaterial cloaking")
// b.giveGuns("wave beam")
// b.giveGuns("laser")
// tech.isExplodeRadio = true
// tech.giveTech("phase velocity")
// tech.giveTech("pulse")
// for (let i = 0; i < 1; i++) tech.giveTech("crystallizer")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state")
// for (let i = 0; i < 3; i++) tech.giveTech("propagation")
// for (let i = 0; i < 3; i++) tech.giveTech("amplitude")
// for (let i = 0; i < 9; i++) tech.giveTech("slow light")
level.intro(); //starting level
// level.testing(); //not in rotation

View File

@@ -1053,6 +1053,11 @@ const mobs = {
this.alive = false; //triggers mob removal in mob[i].replace(i)
if (this.isDropPowerUp) {
if (tech.iceIXOnDeath && this.isSlowed && Math.random() > 0.5) {
for (let i = 0, len = 3 * Math.sqrt(this.mass) * tech.iceIXOnDeath; i < len; i++) b.iceIX(3, Math.random() * 2 * Math.PI, this.position)
}
if (tech.deathSpawnsFromBoss || (tech.deathSpawns && this.isDropPowerUp)) {
const spawns = tech.deathSpawns + tech.deathSpawnsFromBoss
const len = Math.min(12, spawns * Math.ceil(Math.random() * simulation.difficulty * spawns))

View File

@@ -115,7 +115,9 @@ const powerUps = {
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
}
if (tech.renormalization && Math.random() < 0.37 && amount < 0) powerUps.spawn(m.pos.x, m.pos.y, "research");
if (tech.renormalization && Math.random() < 0.37 && amount < 0) {
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
}
if (tech.isRerollHaste) {
if (powerUps.research.count === 0) {
tech.researchHaste = 0.66;
@@ -532,7 +534,8 @@ const powerUps = {
powerUps.spawn(x, y, "gun");
return;
}
if (Math.random() < 0.0027 * (22 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 25
// if (Math.random() < 0.0027 * (22 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 25
if (Math.random() < 0.005 * (10 - level.levelsCleared)) { //a new tech has a low chance that decreases in later levels
powerUps.spawn(x, y, "tech");
return;
}

View File

@@ -606,7 +606,7 @@ const spawn = {
me.seeAtDistance2 = 200000 //1400000;
me.cellMassMax = 70
me.stroke = "transparent"
me.collisionFilter.mask = cat.player | cat.bullet | cat.body //| cat.map //"rgba(255,60,0,0.3)"
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)"
// Matter.Body.setDensity(me, 0.0014) // normal density is 0.001
Matter.Body.setAngularVelocity(me, 0.12 * (Math.random() - 0.5))
// spawn.shield(me, x, y, 1);
@@ -687,7 +687,7 @@ const spawn = {
me.seeAtDistance2 = 1000000;
me.accelMag = 0.0005 * simulation.accelScale;
Matter.Body.setDensity(me, 0.00035); //normal is 0.001
me.collisionFilter.mask = cat.bullet | cat.player | cat.body
me.collisionFilter.mask = cat.bullet | cat.player //| cat.body
me.memory = Infinity;
me.seePlayerFreq = 30
me.lockedOn = null;
@@ -3168,7 +3168,7 @@ const spawn = {
me.memory = Infinity;
me.frictionAir = 0.01;
me.accelMag = 0.00004 * simulation.accelScale;
me.collisionFilter.mask = cat.player | cat.bullet | cat.body
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
spawn.shield(me, x, y, 1);
const rangeInnerVsOuter = Math.random()

View File

@@ -877,7 +877,7 @@
count: 0,
frequency: 2,
allowed() {
return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling
return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
},
requires: "an explosive damage source, no other mob death tech",
effect: () => {
@@ -887,6 +887,23 @@
tech.isExplodeMob = false;
}
},
{
name: "crystallizer",
description: "after <strong class='color-s'>frozen</strong> mobs <strong>die</strong><br>they have a chance shatter into <strong class='color-s'>ice IX</strong> crystals",
maxCount: 9,
count: 0,
frequency: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
},
requires: "a localized freeze effect, no other mob death tech",
effect() {
tech.iceIXOnDeath++
},
remove() {
tech.iceIXOnDeath = 0
}
},
{
name: "impact shear",
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br><em>nails target nearby mobs</em>",
@@ -894,7 +911,7 @@
count: 0,
frequency: 2,
allowed() {
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
},
requires: "no other mob death tech",
effect: () => {
@@ -911,7 +928,7 @@
count: 0,
frequency: 2,
allowed() {
return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
},
requires: "no other mob death tech",
effect() {
@@ -988,7 +1005,7 @@
frequency: 1,
isBotTech: true,
allowed() {
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob && !tech.isMobBlockFling
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob && !tech.isMobBlockFling && !tech.iceIXOnDeath
},
requires: "no other mob death tech",
effect() {
@@ -1504,7 +1521,7 @@
frequency: 4,
frequencyDefault: 4,
allowed() {
return tech.throwChargeRate > 1 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner
return tech.throwChargeRate > 1 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.iceIXOnDeath
},
requires: "mass driver, no other mob death tech",
effect() {
@@ -4460,7 +4477,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isPulseLaser && !tech.isWideLaser
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isWideLaser
},
requires: "laser, not specular reflection, diffraction grating, diffuse beam",
effect() {
@@ -4488,7 +4505,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && !tech.historyLaser
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser
},
requires: "laser, not specular reflection, not diffuse",
effect() {
@@ -6622,5 +6639,6 @@
waveBeamSpeed: null,
wavePacketAmplitude: null,
waveLengthRange: null,
isCollisionRealitySwitch: null
isCollisionRealitySwitch: null,
iceIXOnDeath: null
}