shotgun rivets

some shotgun ammo tech upgrades will continue to fire some original recipe shotgun bullets
  rivets, fleas, worms, iceIX
tech: band gap - boosts give more damage but it lasts for 1 less second

WIMPs are 10% faster
controlled explosion renamed shaped charge

bug fixes
  construction mode works better with my buttons
  to unlock run this and press T to enter testing mode
  simulation.enableConstructMode() //used to build maps in testing mode

removed -experiment- tech because it's function was reproduced by "tech - tinker"
This commit is contained in:
landgreen
2022-08-28 19:47:32 -07:00
parent 6d1e62d6b8
commit cc1bbeb53b
11 changed files with 525 additions and 378 deletions

View File

@@ -1926,7 +1926,7 @@ const b = {
if (tech.isMissileBig) { if (tech.isMissileBig) {
size *= 1.55 size *= 1.55
if (tech.isMissileBiggest) { if (tech.isMissileBiggest) {
size *= 2 size *= 1.55
} }
} }
@@ -2015,7 +2015,7 @@ const b = {
ctx.fill(); ctx.fill();
}, },
}); });
const thrust = 0.0066 * bullet[me].mass * (tech.isMissileBig ? (tech.isMissileBiggest ? 0.15 : 0.7) : 1); const thrust = 0.0066 * bullet[me].mass * (tech.isMissileBig ? (tech.isMissileBiggest ? 0.3 : 0.7) : 1);
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: m.Vx / 2 + speed * Math.cos(angle), x: m.Vx / 2 + speed * Math.cos(angle),
y: m.Vy / 2 + speed * Math.sin(angle) y: m.Vy / 2 + speed * Math.sin(angle)
@@ -5463,16 +5463,40 @@ const b = {
player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps
} }
const spray = (num) => {
const side = 22
for (let i = 0; i < num; i++) {
const me = bullet.length;
const dir = m.angle + (Math.random() - 0.5) * spread
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = 52 + Math.random() * 8
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
bullet[me].endCycle = simulation.cycle + 40 * tech.isBulletsLastLonger
bullet[me].minDmgSpeed = 15
if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0015)
// bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.034;
bullet[me].do = function() {
const scale = 1 - 0.034 / tech.isBulletsLastLonger
Matter.Body.scale(this, scale, scale);
};
}
}
b.muzzleFlash(35); b.muzzleFlash(35);
if (tech.isRivets) { if (tech.isRivets) {
const me = bullet.length; const me = bullet.length;
// const dir = m.angle + 0.02 * (Math.random() - 0.5) // const dir = m.angle + 0.02 * (Math.random() - 0.5)
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60 * tech.bulletSize, 27 * tech.bulletSize, b.fireAttributes(m.angle)); bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 56 * tech.bulletSize, 25 * tech.bulletSize, b.fireAttributes(m.angle));
Matter.Body.setDensity(bullet[me], 0.007 * (tech.isShotgunReversed ? 1.6 : 1)); Matter.Body.setDensity(bullet[me], 0.005 * (tech.isShotgunReversed ? 1.5 : 1));
Composite.add(engine.world, bullet[me]); //add bullet to world Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = (input.down ? 50 : 37) const SPEED = (input.down ? 50 : 43)
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle), x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle) y: SPEED * Math.sin(m.angle)
@@ -5480,7 +5504,7 @@ const b = {
if (tech.isIncendiary) { if (tech.isIncendiary) {
bullet[me].endCycle = simulation.cycle + 60 bullet[me].endCycle = simulation.cycle + 60
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, 300 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end b.explosion(this.position, 360 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
} }
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -5490,10 +5514,10 @@ const b = {
} }
bullet[me].minDmgSpeed = 7 bullet[me].minDmgSpeed = 7
// bullet[me].restitution = 0.4 // bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.006; bullet[me].frictionAir = 0.004;
bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75) bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75)
bullet[me].do = function() { bullet[me].do = function() {
this.force.y += this.mass * 0.0022 this.force.y += this.mass * 0.002
if (this.speed > 6) { //rotates bullet to face current velocity? if (this.speed > 6) { //rotates bullet to face current velocity?
const facing = { x: Math.cos(this.angle), y: Math.sin(this.angle) } const facing = { x: Math.cos(this.angle), y: Math.sin(this.angle) }
if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) {
@@ -5512,9 +5536,11 @@ const b = {
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize) b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn this.endCycle = 0 //triggers despawn
} }
if (tech.isIncendiary) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
if (tech.isCritKill) b.crit(who, this) if (tech.isCritKill) b.crit(who, this)
} }
} }
spray(12); //fires normal shotgun bullets
} else if (tech.isIncendiary) { } else if (tech.isIncendiary) {
spread *= 0.15 spread *= 0.15
const END = Math.floor(input.down ? 10 : 7); const END = Math.floor(input.down ? 10 : 7);
@@ -5534,7 +5560,7 @@ const b = {
y: speed * Math.sin(dirOff) y: speed * Math.sin(dirOff)
}); });
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.5 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.4 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
} }
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -5546,7 +5572,7 @@ const b = {
} }
} else if (tech.isNailShot) { } else if (tech.isNailShot) {
spread *= 0.65 spread *= 0.65
const dmg = 2 * (tech.isShotgunReversed ? 1.6 : 1) const dmg = 2 * (tech.isShotgunReversed ? 1.5 : 1)
if (input.down) { if (input.down) {
for (let i = 0; i < 17; i++) { for (let i = 0; i < 17; i++) {
speed = 38 + 15 * Math.random() speed = 38 + 15 * Math.random()
@@ -5576,47 +5602,49 @@ const b = {
} }
} else if (tech.isSporeFlea) { } else if (tech.isSporeFlea) {
const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) } const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) }
const number = 4 * (tech.isShotgunReversed ? 1.6 : 1) const number = 2 * (tech.isShotgunReversed ? 1.5 : 1)
for (let i = 0; i < number; i++) { for (let i = 0; i < number; i++) {
const angle = m.angle + 0.2 * (Math.random() - 0.5) const angle = m.angle + 0.2 * (Math.random() - 0.5)
const speed = (input.down ? 33 : 20) * (1 + 0.1 * Math.random()) const speed = (input.down ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random()))
b.flea(where, { x: speed * Math.cos(angle), y: speed * Math.sin(angle) }) b.flea(where, { x: speed * Math.cos(angle), y: speed * Math.sin(angle) })
bullet[bullet.length - 1].setDamage() bullet[bullet.length - 1].setDamage()
} }
spray(10); //fires normal shotgun bullets
} else if (tech.isSporeWorm) { } else if (tech.isSporeWorm) {
const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) } const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) }
const spread = (input.down ? 0.02 : 0.07) const spread = (input.down ? 0.02 : 0.07)
const number = 4 * (tech.isShotgunReversed ? 1.6 : 1) const number = 3 * (tech.isShotgunReversed ? 1.5 : 1)
let angle = m.angle - (number - 1) * spread * 0.5 let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) { for (let i = 0; i < number; i++) {
b.worm(where) b.worm(where)
const SPEED = (8 + 10 * input.down) * (1 + 0.15 * Math.random()) const SPEED = (30 + 10 * input.down) * (1 + 0.2 * Math.random())
Matter.Body.setVelocity(bullet[bullet.length - 1], { Matter.Body.setVelocity(bullet[bullet.length - 1], {
x: player.velocity.x * 0.5 + SPEED * Math.cos(angle), x: player.velocity.x * 0.5 + SPEED * Math.cos(angle),
y: player.velocity.y * 0.5 + SPEED * Math.sin(angle) y: player.velocity.y * 0.5 + SPEED * Math.sin(angle)
}); });
angle += spread angle += spread
} }
spray(7); //fires normal shotgun bullets
} else if (tech.isIceShot) { } else if (tech.isIceShot) {
const spread = (input.down ? 0.7 : 1.2) const spread = (input.down ? 0.7 : 1.2)
for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) { for (let i = 0, len = 10 * (tech.isShotgunReversed ? 1.5 : 1); i < len; i++) {
// iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { b.iceIX(23 + 10 * Math.random(), m.angle + spread * (Math.random() - 0.5))
b.iceIX(25 + 20 * Math.random(), m.angle + spread * (Math.random() - 0.5))
} }
spray(10); //fires normal shotgun bullets
} else if (tech.isFoamShot) { } else if (tech.isFoamShot) {
const spread = (input.down ? 0.15 : 0.4) const spread = (input.down ? 0.15 : 0.4)
const where = { const where = {
x: m.pos.x + 25 * Math.cos(m.angle), x: m.pos.x + 25 * Math.cos(m.angle),
y: m.pos.y + 25 * Math.sin(m.angle) y: m.pos.y + 25 * Math.sin(m.angle)
} }
const number = 16 * (tech.isShotgunReversed ? 1.6 : 1) const number = 16 * (tech.isShotgunReversed ? 1.5 : 1)
for (let i = 0; i < number; i++) { for (let i = 0; i < number; i++) {
const SPEED = 11 + 4 * Math.random(); const SPEED = 13 + 4 * Math.random();
const angle = m.angle + spread * (Math.random() - 0.5) const angle = m.angle + spread * (Math.random() - 0.5)
b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 8 + 7 * Math.random()) b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 8 + 7 * Math.random())
} }
} else if (tech.isNeedles) { } else if (tech.isNeedles) {
const number = 9 * (tech.isShotgunReversed ? 1.6 : 1) const number = 9 * (tech.isShotgunReversed ? 1.5 : 1)
const spread = (input.down ? 0.03 : 0.05) const spread = (input.down ? 0.03 : 0.05)
let angle = m.angle - (number - 1) * spread * 0.5 let angle = m.angle - (number - 1) * spread * 0.5
for (let i = 0; i < number; i++) { for (let i = 0; i < number; i++) {
@@ -5624,27 +5652,7 @@ const b = {
angle += spread angle += spread
} }
} else { } else {
const side = 22 spray(16); //fires normal shotgun bullets
for (let i = 0; i < 17; i++) {
const me = bullet.length;
const dir = m.angle + (Math.random() - 0.5) * spread
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = 52 + Math.random() * 8
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
bullet[me].endCycle = simulation.cycle + 40 * tech.isBulletsLastLonger
bullet[me].minDmgSpeed = 15
if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0016)
// bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.034;
bullet[me].do = function() {
const scale = 1 - 0.034 / tech.isBulletsLastLonger
Matter.Body.scale(this, scale, scale);
};
}
} }
} }
}, { }, {

View File

@@ -208,7 +208,6 @@ function collisionChecks(event) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)); const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) { if (v > 9) {
if (tech.blockDmg) { //electricity if (tech.blockDmg) { //electricity
// console.log("hi")
Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y }); Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y });
if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) { if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) {
mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12

View File

@@ -431,7 +431,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
//update tech text //disable not allowed tech //update tech text //disable not allowed tech
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
const techID = document.getElementById("tech-" + i) const techID = document.getElementById("tech-" + i)
if (!tech.tech[i].isExperimentHide && !tech.tech[i].isNonRefundable && (!tech.tech[i].isJunk || tech.tech[i].isExperimentalMode || localSettings.isJunkExperiment)) { if (!tech.tech[i].isExperimentHide && !tech.tech[i].isNonRefundable && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) {
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) { if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""; const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
// <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div> // <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div>
@@ -460,8 +460,6 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
</div>` </div>`
} else if (tech.tech[i].isJunk) { } else if (tech.tech[i].isJunk) {
techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>` techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
} else if (tech.tech[i].isExperimentalMode) {
techID.innerHTML = `<div class="grid-title">${tech.tech[i].name}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
} else { } else {
techID.innerHTML = `<div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>` techID.innerHTML = `<div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
} }
@@ -531,11 +529,9 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
text += `<div id = "gun-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div> ${b.guns[i].description}</div>` text += `<div id = "gun-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div> ${b.guns[i].description}</div>`
} }
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //&& (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode)) { if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //&& (!tech.tech[i].isNonRefundable)) {
if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment" if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
if (tech.tech[i].isExperimentalMode) { if (tech.tech[i].isJunk) {
text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title">${tech.tech[i].name}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
} else if (tech.tech[i].isJunk) {
text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].link}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>` text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].link}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
} else { } else {
text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>` text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].link}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
@@ -668,13 +664,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
build.hasExperimentalMode = false build.hasExperimentalMode = false
if (!simulation.isCheating) { if (!simulation.isCheating) {
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) { if (tech.tech[i].count > 0 && !tech.tech[i].isLore) simulation.isCheating = true;
if (tech.tech[i].isExperimentalMode) {
build.hasExperimentalMode = true
} else if (!tech.tech[i].isLore) {
simulation.isCheating = true;
}
}
} }
if (b.inventory.length !== 0 || m.fieldMode !== 0) simulation.isCheating = true; if (b.inventory.length !== 0 || m.fieldMode !== 0) simulation.isCheating = true;
} }

View File

@@ -16,7 +16,7 @@ const level = {
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100 // m.maxHealth = m.health = 100
// tech.isRerollDamage = true // tech.isRerollDamage = true
@@ -24,9 +24,11 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.setField("metamaterial cloaking") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass // m.setField("metamaterial cloaking") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
// b.giveGuns("laser") //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 // b.giveGuns("shotgun") //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
// b.guns[0].ammo = 1000000 // b.guns[0].ammo = 1000000
// tech.giveTech("1st ionization energy") // tech.giveTech("rivet gun")
// tech.isFoamShot = true
// tech.isIncendiary = true
// for (let i = 0; i < 1; ++i) tech.giveTech("field coupling") // for (let i = 0; i < 1; ++i) tech.giveTech("field coupling")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser") // for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// m.damage(0.1); // m.damage(0.1);
@@ -36,10 +38,10 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500, 200)
// spawn.beetleBoss(1900, -400) // spawn.ghoster(2538, -1950)
// spawn.shooter(1900, -500) // for (let i = 0; i < 15; ++i) spawn.shooter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// level.testing(); // level.testing();
// spawn.blowSuckBoss(1900, -500)
// 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 < 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"); // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
@@ -114,7 +116,6 @@ const level = {
spawn.WIMP() spawn.WIMP()
for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
} }
for (let i = 0; i < tech.wimpExperiment; i++) spawn.WIMP()
// if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) { // if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) {
if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) { if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) {
tech.isFlipFlopOn = true tech.isFlipFlopOn = true
@@ -2809,6 +2810,17 @@ const level = {
spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5300, -275, 50, 175);
spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175); spawn.mapRect(4850, -275, 50, 175);
spawn.mapRect(-950, -3250, 850, 1750);
//roof
spawn.mapRect(-175, -2975, 300, 1425);
spawn.mapRect(75, -2650, 325, 1150);
spawn.mapRect(375, -2225, 250, 650);
spawn.mapRect(4075, -2125, 700, 800);
spawn.mapRect(4450, -2950, 675, 1550);
spawn.mapRect(4875, -3625, 725, 2225);
spawn.mapRect(5525, -4350, 1725, 2925);
spawn.mapRect(7200, -5125, 300, 3900);
//??? //???
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
@@ -10926,9 +10938,6 @@ const level = {
simulation.fallHeight = -1000; simulation.fallHeight = -1000;
simulation.setZoom(1800); simulation.setZoom(1800);
templePlayer.startAnim = -1; templePlayer.startAnim = -1;
for (let i = 0; i < tech.wimpCount + tech.wimpExperiment; i++) {
addWIMP();
}
templePlayer.drawExit = false; templePlayer.drawExit = false;
} }
}, },

View File

@@ -899,7 +899,7 @@ const mobs = {
//accelerate towards the searchTarget //accelerate towards the searchTarget
if (!this.seePlayer.recall) { if (!this.seePlayer.recall) {
const newTarget = function(that) { const newTarget = function(that) {
if (Math.random() < 0.0005) { if (Math.random() < 0.0007) {
that.searchTarget = player.position; //chance to target player that.searchTarget = player.position; //chance to target player
} else { } else {
//target random body //target random body
@@ -1246,18 +1246,6 @@ const mobs = {
} }
} }
} }
if (tech.removeMaxHealthOnKill) {
const amount = 0.002
if (tech.isEnergyHealth) {
if (m.maxEnergy > amount) {
tech.healMaxEnergyBonus -= amount
m.setMaxEnergy();
}
} else if (m.maxHealth > amount) {
tech.extraMaxHealth -= amount //decrease max health
m.setMaxHealth();
}
}
if (tech.cloakDuplication && !this.isBoss) { if (tech.cloakDuplication && !this.isBoss) {
tech.cloakDuplication -= 0.02 tech.cloakDuplication -= 0.02
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance

View File

@@ -1571,24 +1571,24 @@ const m = {
case 0: //field emitter case 0: //field emitter
return `gain the effects of <strong>all</strong> <strong class='color-f'>fields</strong>` return `gain the effects of <strong>all</strong> <strong class='color-f'>fields</strong>`
case 1: //standing wave case 1: //standing wave
return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${Math.ceil(couple)} <strong class='color-s'>ice IX</strong></span>` return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${couple.toFixed(1)} <strong class='color-s'>ice IX</strong></span>`
case 2: //perfect diamagnetism case 2: //perfect diamagnetism
return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${Math.ceil(couple)} <strong class='color-s'>ice IX</strong></span>` return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${couple.toFixed(1)} <strong class='color-s'>ice IX</strong></span>`
// return `<span style = 'font-size:89%;'><strong>invulnerable</strong> <strong>+${2*couple}</strong> seconds post collision</span>` // return `<span style = 'font-size:89%;'><strong>invulnerable</strong> <strong>+${2*couple}</strong> seconds post collision</span>`
case 3: //negative mass case 3: //negative mass
return `<strong>+${((1-0.73 ** couple)*100).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>` return `<strong>+${((1-0.73 ** couple)*100).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>`
case 4: //assembler case 4: //assembler
return `generate <strong>${6*couple}</strong> <strong class='color-f'>energy</strong> per second` return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma case 5: //plasma
return `<strong>+${15*couple}</strong> <strong class='color-d'>damage</strong>` return `<strong>+${(15*couple).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation case 6: //time dilation
return `<strong>+${25*couple}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and return `<strong>+${(25*couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking case 7: //cloaking
return `<strong>+${33*couple}%</strong> ambush <strong class='color-d'>damage</strong>` return `<strong>+${(33*couple).toFixed(0)}%</strong> ambush <strong class='color-d'>damage</strong>`
case 8: //pilot wave case 8: //pilot wave
return `<strong>+${40*couple}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>` return `<strong>+${(40*couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
case 9: //wormhole case 9: //wormhole
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${20*couple}</strong> <strong class='color-f'>energy</strong></span>` return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(20*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
} }
}, },
couplingChange() { couplingChange() {

View File

@@ -333,7 +333,7 @@ const powerUps = {
}, },
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) { if (isCanceled) {
if (tech.isCancelTech && Math.random() < 0.9) { if (tech.isCancelTech && Math.random() < 0.88) {
// powerUps.research.use('tech') // powerUps.research.use('tech')
powerUps[type].effect(); powerUps[type].effect();
return return
@@ -414,8 +414,8 @@ const powerUps = {
return 11; return 11;
}, },
endCycle: 0, endCycle: 0,
duration: 600, duration: null, //set by "tech: band gap"
damage: 1.5, damage: null, //set by "tech: band gap"
effect() { effect() {
powerUps.boost.endCycle = m.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - m.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left powerUps.boost.endCycle = m.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - m.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
}, },
@@ -912,7 +912,7 @@ const powerUps = {
} }
function removeOption(index) { function removeOption(index) {
for (let i = options.length; i > -1; i--) { for (let i = options.length - 1; i > -1; i--) {
if (index === options[i]) { if (index === options[i]) {
options.splice(i, 1) //remove all copies of that option form the options array (some tech are in the options array multiple times because of frequency) options.splice(i, 1) //remove all copies of that option form the options array (some tech are in the options array multiple times because of frequency)
optionLengthNoDuplicates-- optionLengthNoDuplicates--
@@ -1272,9 +1272,11 @@ const powerUps = {
} }
if (tech.isCouplingPowerUps && Math.random() < 0.17) { if (tech.isCouplingPowerUps && Math.random() < 0.17) {
powerUps.spawn(x, y, "coupling"); powerUps.spawn(x, y, "coupling");
return;
} }
if (tech.isBoostPowerUps && Math.random() < 0.17) { if (tech.isBoostPowerUps && Math.random() < 0.18) {
powerUps.spawn(x, y, "boost"); powerUps.spawn(x, y, "boost");
return;
} }
// if (Math.random() < 0.01) { // if (Math.random() < 0.01) {
// powerUps.spawn(x, y, "research"); // powerUps.spawn(x, y, "research");

View File

@@ -1458,21 +1458,22 @@ const simulation = {
const y = round(simulation.constructMouseDownPosition.y) const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(simulation.mouseInGame.x) - x) const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(simulation.mouseInGame.y) - y) const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
console.log(e.button)
if (e.button === 2) { if (e.button === 1) {
if (level.isProcedural) { if (level.isProcedural) {
simulation.outputMapString(`spawn.randomMob(x+${x}, y+${y}, 0);`); simulation.outputMapString(`spawn.randomMob(x+${x}, y+${y}, 0);\n`);
} else { } else {
simulation.outputMapString(`spawn.randomMob(${x}, ${y}, 0);`); simulation.outputMapString(`spawn.randomMob(${x}, ${y}, 0);\n`);
} }
} else if (e.button === 4) { } else if (e.button === 4) {
simulation.outputMapString(`${Math.floor(simulation.constructMouseDownPosition.x)}, ${Math.floor(simulation.constructMouseDownPosition.y)}`); simulation.outputMapString(`${Math.floor(simulation.constructMouseDownPosition.x)}, ${Math.floor(simulation.constructMouseDownPosition.y)}`);
} else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive } else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive
if (e.button === 1) { //add map
if (e.button === 0) { //add map
if (level.isProcedural) { if (level.isProcedural) {
simulation.outputMapString(`spawn.mapRect(x+${x}, y+${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.mapRect(x+${x}, y+${y}, ${dx}, ${dy});\n`);
} else { } else {
simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});\n`);
} }
//see map in world //see map in world
@@ -1484,11 +1485,11 @@ const simulation = {
Composite.add(engine.world, map[len]); //add to world Composite.add(engine.world, map[len]); //add to world
simulation.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
} else if (e.button === 3) { //add body } else if (e.button === 2) { //add body
if (level.isProcedural) { if (level.isProcedural) {
simulation.outputMapString(`spawn.bodyRect(x+${x}, y+${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.bodyRect(x+${x}, y+${y}, ${dx}, ${dy});\n`);
} else { } else {
simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});\n`);
} }
//see map in world //see map in world
@@ -1513,6 +1514,7 @@ const simulation = {
} }
}); });
//undo last element added after you press z
document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67 document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) { if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) {
if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level

View File

@@ -5,8 +5,8 @@ const spawn = {
randomBossList: [ randomBossList: [
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
"dragonFlyBoss", "beetleBoss" "timeSkipBoss", "dragonFlyBoss", "beetleBoss"
], ],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -142,7 +142,7 @@ const spawn = {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y); spawn[pick](x, y);
} }
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) { if (tech.isDuplicateBoss && Math.random() < tech.duplicationChance()) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y); spawn[pick](x, y);
} }
@@ -158,7 +158,7 @@ const spawn = {
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size); spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
} }
} }
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) { if (tech.isDuplicateBoss && Math.random() < tech.duplicationChance()) {
for (let i = 0; i < num; ++i) { for (let i = 0; i < num; ++i) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size); spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
@@ -296,7 +296,7 @@ const spawn = {
me.showHealthBar = false; me.showHealthBar = false;
me.collisionFilter.category = 0; me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 1 + 2 * Math.random() me.chaseSpeed = 1.2 + 2 * Math.random()
me.awake = function() { me.awake = function() {
//chase player //chase player
@@ -4104,8 +4104,8 @@ const spawn = {
if (this.phaseCycle > -1) { if (this.phaseCycle > -1) {
Matter.Body.rotate(this, 0.02) Matter.Body.rotate(this, 0.02)
for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex
spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 6, 4); spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 5, 4);
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -17) const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -15)
Matter.Body.setVelocity(mob[mob.length - 1], { Matter.Body.setVelocity(mob[mob.length - 1], {
x: velocity.x, x: velocity.x,
y: velocity.y y: velocity.y
@@ -5013,13 +5013,13 @@ const spawn = {
}, 2000); //add in a delay in case the level gets flipped left right }, 2000); //add in a delay in case the level gets flipped left right
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.01 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.01 + 0.0004 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true me.isVerticesChange = true
me.memory = 240; me.memory = 240;
me.fireFreq = 0.025; me.fireFreq = 0.009 + 0.0004 * Math.min(40, simulation.difficulty); //bigger number means more shots per second
me.noseLength = 0; me.noseLength = 0;
me.fireAngle = 0; me.fireAngle = 0;
me.accelMag = 0.005 * simulation.accelScale; me.accelMag = 0.005 * simulation.accelScale;
@@ -5066,16 +5066,14 @@ const spawn = {
//fire //fire
for (let i = 0, len = 2 + 0.07 * simulation.difficulty; i < len; i++) { for (let i = 0, len = 2 + 0.07 * simulation.difficulty; i < len; i++) {
spawn.bullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 25)); spawn.bullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 25));
const v = 15; const spread = Vector.rotate({
Matter.Body.setVelocity(mob[mob.length - 1], { x: Math.sqrt(len) + 4,
x: this.velocity.x + this.fireDir.x * v + 7 * Math.random(), y: 0
y: this.velocity.y + this.fireDir.y * v + 7 * Math.random() }, 2 * Math.PI * Math.random())
}); const dir = Vector.add(Vector.mult(this.fireDir, 15), spread)
Matter.Body.setVelocity(mob[mob.length - 1], dir);
} }
this.noseLength = 0; this.noseLength = 0;
// recoil
this.force.x -= 0.005 * this.fireDir.x * this.mass;
this.force.y -= 0.005 * this.fireDir.y * this.mass;
} }
if (this.noseLength < 1.5) this.noseLength += this.fireFreq; if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
setNoseShape(); setNoseShape();
@@ -5421,6 +5419,163 @@ const spawn = {
} }
}; };
}, },
// blowSuckBoss(x, y, radius = 80) {
// mobs.spawn(x, y, 10, radius, "transparent");
// let me = mob[mob.length - 1];
// me.isBoss = true;
// Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.fireFreq = Math.floor(60 * simulation.CDScale)
// me.seePlayerFreq = 15
// me.seeAtDistance2 = 300000;
// me.accelMag = 0.0003 * simulation.accelScale;
// if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
// // Matter.Body.setDensity(me, 0.001); //normal is 0.001 //makes effective life much lower
// me.stroke = "transparent"; //used for drawGhost
// me.alpha = 1; //used in drawGhost
// me.canTouchPlayer = false; //used in drawGhost
// me.isBadTarget = true;
// // me.leaveBody = false;
// me.collisionFilter.mask = cat.bullet //| cat.body
// me.showHealthBar = false;
// me.memory = 480;
// me.onDeath = function() {
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// };
// me.onDamage = function() {};
// me.suck = function() {
// for (let i = 0; i < mob.length; i++) {
// if (mob[i].isBlowSuckBullet) {
// const unit = Vector.normalise(Vector.sub(this.position, mob[i].position))
// const mag = Vector.mult(unit, 0.0008 * mob[i].mass)
// mob[i].force.x += mag.x
// mob[i].force.y += mag.y
// }
// }
// }
// me.do = function() {
// //cap max speed
// if (this.speed > 8) {
// Matter.Body.setVelocity(this, {
// x: this.velocity.x * 0.8,
// y: this.velocity.y * 0.8
// });
// }
// this.seePlayerCheckByDistance();
// this.checkStatus();
// this.attraction();
// this.search();
// //draw
// if (this.distanceToPlayer2() < this.seeAtDistance2) {
// if (this.alpha < 1) this.alpha += 0.005 * simulation.CDScale; //near player go solid
// } else {
// if (this.alpha > 0) this.alpha -= 0.05; ///away from player, hide
// }
// if (this.alpha > 0) {
// if (this.alpha > 0.8 && this.seePlayer.recall) {
// this.healthBar();
// if (!this.canTouchPlayer) {
// this.canTouchPlayer = true;
// this.isBadTarget = false;
// this.collisionFilter.mask = cat.player | cat.bullet
// }
// }
// //draw body
// ctx.beginPath();
// const vertices = this.vertices;
// ctx.moveTo(vertices[0].x, vertices[0].y);
// for (let j = 1, len = vertices.length; j < len; ++j) {
// ctx.lineTo(vertices[j].x, vertices[j].y);
// }
// ctx.lineTo(vertices[0].x, vertices[0].y);
// ctx.lineWidth = 1;
// ctx.fillStyle = `rgba(255,255,255,${this.alpha * this.alpha})`;
// ctx.fill();
// this.suck();
// if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) {
// this.suckCount = 0;
// Matter.Body.setAngularVelocity(this, 0.11)
// //fire a bullet from each vertex
// for (let i = 0, len = this.vertices.length; i < len; i++) {
// spawn.bounceBullet(this.vertices[i].x, this.vertices[i].y, 8)
// //give the bullet a rotational velocity as if they were attached to a vertex
// const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -16)
// const who = mob[mob.length - 1]
// who.isBlowSuckBullet = true
// Matter.Body.setVelocity(who, {
// x: this.velocity.x + velocity.x,
// y: this.velocity.y + velocity.y
// });
// }
// }
// } else if (this.canTouchPlayer) {
// this.canTouchPlayer = false;
// this.isBadTarget = true;
// this.collisionFilter.mask = cat.bullet; //can't touch player or walls
// }
// };
// },
// blowSuckBoss(x, y, radius = 80, isSpawnBossPowerUp = true) {
// mobs.spawn(x, y, 10, radius, "transparent"); //rgb(60,60,85)
// let me = mob[mob.length - 1];
// me.isBoss = true;
// Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.accelMag = 0.0001 * simulation.accelScale;
// me.fireFreq = Math.floor(180 * simulation.CDScale)
// me.frictionStatic = 0;
// me.friction = 0;
// me.frictionAir = 0.005;
// me.memory = 420;
// me.repulsionRange = 1000000; //squared
// // spawn.shield(me, x, y, 1);
// // spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
// me.onDeath = function() {
// if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// };
// me.onDamage = function() {};
// me.suck = function() {
// for (let i = 0; i < mob.length; i++) {
// if (mob[i].isBlowSuckBullet) {
// const unit = Vector.normalise(Vector.sub(this.position, mob[i].position))
// const mag = Vector.mult(unit, 0.0008 * mob[i].mass)
// mob[i].force.x += mag.x
// mob[i].force.y += mag.y
// }
// }
// }
// me.do = function() {
// this.seePlayerCheck();
// this.checkStatus();
// this.attraction();
// // this.repulsion();
// this.suck();
// if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) {
// this.suckCount = 0;
// Matter.Body.setAngularVelocity(this, 0.11)
// //fire a bullet from each vertex
// for (let i = 0, len = this.vertices.length; i < len; i++) {
// spawn.bounceBullet(this.vertices[i].x, this.vertices[i].y, 8)
// //give the bullet a rotational velocity as if they were attached to a vertex
// const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -16)
// const who = mob[mob.length - 1]
// who.isBlowSuckBullet = true
// Matter.Body.setVelocity(who, {
// x: this.velocity.x + velocity.x,
// y: this.velocity.y + velocity.y
// });
// }
// }
// };
// },
grenadierBoss(x, y, radius = 95) { grenadierBoss(x, y, radius = 95) {
mobs.spawn(x, y, 6, radius, "rgb(0,235,255)"); mobs.spawn(x, y, 6, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -6192,7 +6347,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)"); mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body
me.damageReduction = 0.021 me.damageReduction = 0.024
Matter.Body.setDensity(me, 0.0001); //normal is 0.001 Matter.Body.setDensity(me, 0.0001); //normal is 0.001
// me.accelMag = 0.0007 * simulation.accelScale; // me.accelMag = 0.0007 * simulation.accelScale;

View File

@@ -2227,7 +2227,7 @@ const tech = {
name: "1st ionization energy", name: "1st ionization energy",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Ionization_energy' class="link">1st ionization energy</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Ionization_energy' class="link">1st ionization energy</a>`,
description: `after you collect ${powerUps.orb.heal()}<br><strong>+10</strong> maximum <strong class='color-f'>energy</strong>`, description: `after you collect ${powerUps.orb.heal()}<br><strong>+10</strong> maximum <strong class='color-f'>energy</strong>`,
description: `convert ${powerUps.orb.heal()} into <div class="heal-circle" style = "background-color: #ff0; border: 0.5px #000 solid;"></div><br><div class="heal-circle" style = "background-color: #ff0; border: 0.5px #000 solid;"></div> give <strong>+10</strong> maximum <strong class='color-f'>energy</strong>`, description: `convert current and future ${powerUps.orb.heal()} into <div class="heal-circle" style = "background-color: #ff0; border: 0.5px #000 solid;"></div><br><div class="heal-circle" style = "background-color: #ff0; border: 0.5px #000 solid;"></div> give <strong>+10</strong> maximum <strong class='color-f'>energy</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -3240,7 +3240,8 @@ const tech = {
}, },
{ {
name: "abiogenesis", name: "abiogenesis",
description: `at the start of a level spawn a 2nd <strong>boss</strong><br>use ${powerUps.orb.research(4)}or add <strong>49%</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool`, description: `use ${powerUps.orb.research(4)} (or <strong>49%</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool if you can't) to add a 2nd <strong>boss</strong> to each level`,
description: `<span style = 'font-size:94%;'>as a level begins spawn a 2nd <strong>boss</strong> using ${powerUps.orb.research(4)}<br>(<strong>+49%</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool if you can't pay)</span>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -3297,7 +3298,7 @@ const tech = {
{ {
name: "exciton", name: "exciton",
descriptionFunction() { descriptionFunction() {
return `<span style = 'font-size:94%;'>after mobs <strong>die</strong> they have a <strong>17%</strong> chance to<br>spawn ${powerUps.orb.boost(1)} that give <strong>+${powerUps.boost.damage*100}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds</span>` return `<span style = 'font-size:94%;'>after mobs <strong>die</strong> they have a <strong>18%</strong> chance to<br>spawn ${powerUps.orb.boost(1)} that give <strong>+${(powerUps.boost.damage*100).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds</span>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3314,6 +3315,29 @@ const tech = {
tech.isBoostPowerUps = false tech.isBoostPowerUps = false
} }
}, },
{
name: "band gap",
descriptionFunction() {
return `${powerUps.orb.boost(1)} give <strong>+77%</strong> <strong class='color-d'>damage</strong><br>but their duration is reduced by <strong>1</strong> second`
},
maxCount: 9,
count: 1,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isBoostPowerUps || tech.isBoostReplaceAmmo
},
requires: "exciton, quasiparticles",
effect() {
powerUps.boost.duration -= 60
powerUps.boost.damage += 0.77
},
remove() {
powerUps.boost.duration = 600
powerUps.boost.damage = 1.25
}
},
{ {
name: "eternalism", name: "eternalism",
description: "<strong>+34%</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em>(time can be dilated)</em>", description: "<strong>+34%</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em>(time can be dilated)</em>",
@@ -3463,7 +3487,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 100,
allowed() { allowed() {
return true return true
}, },
@@ -3474,11 +3498,14 @@ const tech = {
simulation.makeTextLog(`m.coupling <span class='color-symbol'>+=</span> ${(this.value).toFixed(1)}`); simulation.makeTextLog(`m.coupling <span class='color-symbol'>+=</span> ${(this.value).toFixed(1)}`);
m.coupling += this.value m.coupling += this.value
m.couplingChange() m.couplingChange()
this.maxCount = 0
}, },
remove() { remove() {
if (this.count) { if (this.count) {
m.coupling -= this.value m.coupling -= this.value
m.couplingChange() m.couplingChange()
} else {
this.maxCount = 1
} }
tech.isCouplingNoHit = false tech.isCouplingNoHit = false
} }
@@ -3506,7 +3533,7 @@ const tech = {
{ {
name: "options exchange", name: "options exchange",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Option_(finance)' class="link">options exchange</a>`,
description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>90%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`, description: `clicking <strong style = 'font-size:150%;'>×</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> has a <strong>88%</strong><br>chance to randomize <strong>choices</strong> and not <strong>cancel</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3542,7 +3569,7 @@ const tech = {
}, },
{ {
name: "futures exchange", name: "futures exchange",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br><strong>+4.5%</strong> power up <strong class='color-dup'>duplication</strong> chance", description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+4.5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -4034,7 +4061,7 @@ const tech = {
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
// return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines")) // return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines"))
return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles)
}, },
// //
requires: "nail gun, not rotary cannon, rivets, or needles", requires: "nail gun, not rotary cannon, rivets, or needles",
@@ -4298,7 +4325,7 @@ const tech = {
{ {
name: "Noether violation", name: "Noether violation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Noether%27s_theorem' class="link">Noether violation</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Noether%27s_theorem' class="link">Noether violation</a>`,
description: "<strong>+60%</strong> <strong>shotgun</strong> <strong class='color-d'>damage</strong><br><strong>shotgun</strong> <strong>recoil</strong> is <strong>reversed</strong>", description: "<strong>+50%</strong> <strong>shotgun</strong> <strong class='color-d'>damage</strong><br><strong>shotgun</strong> <strong>recoil</strong> is <strong>reversed</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4318,7 +4345,7 @@ const tech = {
{ {
name: "nail-shot", name: "nail-shot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Nail_(fastener)' class="link">nail-shot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Nail_(fastener)' class="link">nail-shot</a>`,
description: "<strong>shotgun</strong> fires <strong>17</strong> <strong>nails</strong>", description: "<strong>shotgun</strong> drives a long clip of <strong>nails</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4338,7 +4365,7 @@ const tech = {
{ {
name: "foam-shot", name: "foam-shot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Foam' class="link">foam-shot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Foam' class="link">foam-shot</a>`,
description: "<strong>shotgun</strong> sprays <strong>15</strong> sticky <strong>foam</strong> bubbles", description: "<strong>shotgun</strong> sprays sticky <strong>foam</strong> bubbles",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4358,7 +4385,7 @@ const tech = {
{ {
name: "ice-shot", name: "ice-shot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Ice-nine_(disambiguation)' class="link">ice-shot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Ice-nine_(disambiguation)' class="link">ice-shot</a>`,
description: "<strong>shotgun</strong> grows <strong>15</strong> freezing <strong class='color-s'>ice IX</strong> crystals", description: "<strong>shotgun</strong> grows freezing <strong class='color-s'>ice IX</strong> crystals",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4756,7 +4783,7 @@ const tech = {
}, },
{ {
name: "cruise missile", name: "cruise missile",
description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missiles</strong> speed", description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missile</strong> speed",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4765,7 +4792,7 @@ const tech = {
allowed() { allowed() {
return (tech.haveGunCheck("missiles") && tech.missileFireCD === 45) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount return (tech.haveGunCheck("missiles") && tech.missileFireCD === 45) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount
}, },
requires: "missiles", requires: "missiles, not launch system",
effect() { effect() {
tech.isMissileBig = true tech.isMissileBig = true
}, },
@@ -4775,7 +4802,7 @@ const tech = {
}, },
{ {
name: "ICBM", name: "ICBM",
description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>66%</strong> <strong>missiles</strong> speed", description: "<strong>+75%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missile</strong> speed",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4803,7 +4830,7 @@ const tech = {
allowed() { allowed() {
return tech.haveGunCheck("missiles") && !tech.isMissileBig return tech.haveGunCheck("missiles") && !tech.isMissileBig
}, },
requires: "missiles", requires: "missiles, not cruise missile",
ammoBonus: 1.2, ammoBonus: 1.2,
effect() { effect() {
tech.missileFireCD = 10 tech.missileFireCD = 10
@@ -4976,7 +5003,7 @@ const tech = {
} }
}, },
{ {
name: "controlled explosion", name: "shaped charge",
description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`, description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`,
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
@@ -5959,9 +5986,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple && !tech.isBoostReplaceAmmo
}, },
requires: "harpoon, not UHMWPE, induction furnace, grappling hook", requires: "harpoon, not UHMWPE, induction furnace, grappling hook, quasiparticles",
ammoBonus: 9, ammoBonus: 9,
effect() { effect() {
tech.isRailGun = true; tech.isRailGun = true;
@@ -6179,6 +6206,35 @@ const tech = {
tech.harpoonDensity = 0.004 tech.harpoonDensity = 0.004
} }
}, },
{
name: "quasiparticles",
descriptionFunction() {
return `convert current and future ${powerUps.orb.ammo(1)} into ${powerUps.orb.boost(1)} which<br>give <strong>+${(powerUps.boost.damage*100).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds`
},
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("laser") || (tech.haveGunCheck("harpoon") && !tech.isRailGun)
},
requires: "harpoon, laser, not railgun",
effect() {
tech.isBoostReplaceAmmo = true
for (let i = powerUp.length - 1; i > -1; i--) {
if (powerUp[i].name === "ammo") {
powerUps.spawn(powerUp[i].position.x + 50 * (Math.random() - 0.5), powerUp[i].position.y + 50 * (Math.random() - 0.5), "boost");
Matter.Composite.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
}
}
},
remove() {
tech.isBoostReplaceAmmo = false
}
},
{ {
name: "optical amplifier", name: "optical amplifier",
description: "gain <strong>3</strong> random <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br><strong class='color-laser'>laser</strong> only turns <strong>off</strong> if you have no <strong class='color-f'>energy</strong>", description: "gain <strong>3</strong> random <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br><strong class='color-laser'>laser</strong> only turns <strong>off</strong> if you have no <strong class='color-f'>energy</strong>",
@@ -6195,7 +6251,7 @@ const tech = {
effect() { effect() {
let techGiven = 0 let techGiven = 0
for (let j = 0; j < 3; j++) { for (let j = 0; j < 3; j++) {
const names = ["lens", "compound lens", "arc length", "infrared diode", "free-electron laser", "dye laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"] const names = ["quasiparticles", "lens", "compound lens", "arc length", "infrared diode", "free-electron laser", "dye laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"]
//convert names into indexes //convert names into indexes
const options = [] const options = []
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
@@ -6241,27 +6297,6 @@ const tech = {
tech.isStuckOn = false tech.isStuckOn = false
} }
}, },
{
name: "quasiparticles",
descriptionFunction() {
return `replace all ${powerUps.orb.ammo(1)} spawns with ${powerUps.orb.boost(1)} which give<br><strong>+${powerUps.boost.damage*100}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds`
},
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("laser")
},
requires: "laser, not pulse",
effect() {
tech.isBoostReplaceAmmo = true
},
remove() {
tech.isBoostReplaceAmmo = false
}
},
{ {
name: "relativistic momentum", name: "relativistic momentum",
description: "<strong class='color-laser'>lasers</strong> push <strong>mobs</strong> and <strong class='color-block'>blocks</strong>", description: "<strong class='color-laser'>lasers</strong> push <strong>mobs</strong> and <strong class='color-block'>blocks</strong>",
@@ -7812,207 +7847,153 @@ const tech = {
//************************************************** experimental //************************************************** experimental
//************************************************** modes //************************************************** modes
//************************************************** //**************************************************
{ // {
name: "-ship-", // name: "-ship-",
description: "<strong style='color: #f55;'>experiment:</strong> fly around with no legs<br>aim with the keyboard", // description: "<strong style='color: #f55;'>experiment:</strong> fly around with no legs<br>aim with the keyboard",
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 0, // frequency: 0,
isNonRefundable: true, // isNonRefundable: true,
isBadRandomOption: true, // isBadRandomOption: true,
isExperimentalMode: true, // isExperimentalMode: true,
allowed() { // allowed() {
return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass" // return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass"
}, // },
requires: "", // requires: "",
effect() { // effect() {
m.shipMode() // m.shipMode()
}, // },
remove() {} // remove() {}
}, // },
{ // {
name: "-quantum leap-", // name: "-quantum leap-",
description: "<strong style='color: #f55;'>experiment:</strong> every 20 seconds<br>become an <strong class='alt'>alternate</strong> version of yourself", // description: "<strong style='color: #f55;'>experiment:</strong> every 20 seconds<br>become an <strong class='alt'>alternate</strong> version of yourself",
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 0, // frequency: 0,
isBadRandomOption: true, // isBadRandomOption: true,
isExperimentalMode: true, // isExperimentalMode: true,
allowed() { // allowed() {
return build.isExperimentSelection // return build.isExperimentSelection
}, // },
requires: "", // requires: "",
interval: undefined, // interval: undefined,
effect() { // effect() {
this.interval = setInterval(() => { // this.interval = setInterval(() => {
if (!build.isExperimentSelection) { // if (!build.isExperimentSelection) {
m.switchWorlds() // m.switchWorlds()
simulation.trails() // simulation.trails()
} // }
}, 20000); //every 20 seconds // }, 20000); //every 20 seconds
// },
// remove() {
// if (this.count > 0) clearTimeout(this.interval);
// }
// },
// {
// name: "-shields-",
// description: "<strong style='color: #f55;'>experiment:</strong> every 5 seconds<br>all mobs gain a shield",
// maxCount: 1,
// count: 0,
// frequency: 0,
// isBadRandomOption: true,
// isExperimentalMode: true,
// allowed() {
// return build.isExperimentSelection
// },
// requires: "",
// effect() {
// this.interval = setInterval(() => {
// if (!build.isExperimentSelection) {
// for (let i = 0; i < mob.length; i++) {
// if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
// }
// }
// }, 5000); //every 5 seconds
// },
// interval: undefined,
// remove() {
// if (this.count > 0) clearTimeout(this.interval);
// }
// },
// {
// name: "-Fourier analysis-",
// description: "<strong style='color: #f55;'>experiment:</strong> your aiming is random",
// maxCount: 1,
// count: 0,
// frequency: 0,
// isBadRandomOption: true,
// isExperimentalMode: true,
// allowed() {
// return build.isExperimentSelection && !m.isShipMode
// },
// requires: "not ship",
// effect() {
// m.look = () => {
// m.angle = 2 * Math.sin(m.cycle * 0.0133) + Math.sin(m.cycle * 0.013) + 0.5 * Math.sin(m.cycle * 0.031) + 0.33 * Math.sin(m.cycle * 0.03)
// const scale = 0.8;
// m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
// m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
// m.transX += (m.transSmoothX - m.transX) * 0.07;
// m.transY += (m.transSmoothY - m.transY) * 0.07;
// }
// },
// remove() {
// if (this.count > 0) m.look = m.lookDefault()
// }
// },
// {
// name: "-panopticon-",
// description: "<strong style='color: #f55;'>experiment:</strong> mobs can always see you",
// maxCount: 1,
// count: 0,
// frequency: 0,
// isBadRandomOption: true,
// isExperimentalMode: true,
// allowed() {
// return build.isExperimentSelection
// },
// requires: "",
// effect() {
// this.interval = setInterval(() => {
// if (!build.isExperimentSelection) {
// for (let i = 0; i < mob.length; i++) {
// if (!mob[i].shield && mob[i].isDropPowerUp) {
// mob[i].locatePlayer()
// mob[i].seePlayer.yes = true;
// }
// }
// }
// }, 1000); //every 1 seconds
// },
// interval: undefined,
// remove() {
// if (this.count > 0) clearTimeout(this.interval);
// }
// },
// {
// name: "-decomposers-",
// description: "<strong style='color: #f55;'>experiment:</strong> after they die<br>mobs leave behind spawns",
// maxCount: 1,
// count: 0,
// frequency: 0,
// isBadRandomOption: true,
// isExperimentalMode: true,
// allowed() {
// return build.isExperimentSelection
// },
// requires: "",
// effect() {
// tech.deathSpawns = 0.2
// },
// remove() {
// tech.deathSpawns = 0
// }
// },
},
remove() {
if (this.count > 0) clearTimeout(this.interval);
}
},
{
name: "-shields-",
description: "<strong style='color: #f55;'>experiment:</strong> every 5 seconds<br>all mobs gain a shield",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
this.interval = setInterval(() => {
if (!build.isExperimentSelection) {
for (let i = 0; i < mob.length; i++) {
if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
}
}
}, 5000); //every 5 seconds
},
interval: undefined,
remove() {
if (this.count > 0) clearTimeout(this.interval);
}
},
{
name: "-Fourier analysis-",
description: "<strong style='color: #f55;'>experiment:</strong> your aiming is random",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection && !m.isShipMode
},
requires: "not ship",
effect() {
m.look = () => {
m.angle = 2 * Math.sin(m.cycle * 0.0133) + Math.sin(m.cycle * 0.013) + 0.5 * Math.sin(m.cycle * 0.031) + 0.33 * Math.sin(m.cycle * 0.03)
const scale = 0.8;
m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
m.transX += (m.transSmoothX - m.transX) * 0.07;
m.transY += (m.transSmoothY - m.transY) * 0.07;
}
},
remove() {
if (this.count > 0) m.look = m.lookDefault()
}
},
{
name: "-panopticon-",
description: "<strong style='color: #f55;'>experiment:</strong> mobs can always see you",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
this.interval = setInterval(() => {
if (!build.isExperimentSelection) {
for (let i = 0; i < mob.length; i++) {
if (!mob[i].shield && mob[i].isDropPowerUp) {
mob[i].locatePlayer()
mob[i].seePlayer.yes = true;
}
}
}
}, 1000); //every 1 seconds
},
interval: undefined,
remove() {
if (this.count > 0) clearTimeout(this.interval);
}
},
{
name: "-decomposers-",
description: "<strong style='color: #f55;'>experiment:</strong> after they die<br>mobs leave behind spawns",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
tech.deathSpawns = 0.2
},
remove() {
tech.deathSpawns = 0
}
},
{
name: "-WIMP-",
description: "<strong style='color: #f55;'>experiment:</strong> <strong class='color-defense'>harmful</strong> particles slowly <strong>chase</strong> you",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
tech.wimpExperiment = 5
},
remove() {
tech.wimpExperiment = 0
}
},
{
name: "-symbiosis-",
description: "<strong style='color: #f55;'>experiment:</strong> if you <strong>kill</strong> a <strong>mob</strong><br>lose <strong>0.2</strong> max <strong class='color-h'>health</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
tech.removeMaxHealthOnKill = 0.002
},
remove() {
tech.removeMaxHealthOnKill = 0
}
},
{
name: "-parthenocarpy-",
description: "<strong style='color: #f55;'>experiment:</strong> spawn about 50% more mobs",
maxCount: 1,
count: 1,
frequency: 0,
isBadRandomOption: true,
isExperimentalMode: true,
allowed() {
return build.isExperimentSelection
},
requires: "",
effect() {
tech.isMoreMobs = true
},
remove() {
tech.isMoreMobs = false
}
},
//************************************************** //**************************************************
//************************************************** JUNK //************************************************** JUNK
//************************************************** tech //************************************************** tech
@@ -10629,12 +10610,10 @@ const tech = {
isHarpoonPowerUp: null, isHarpoonPowerUp: null,
harpoonDensity: null, harpoonDensity: null,
isAddRemoveMaxHealth: null, isAddRemoveMaxHealth: null,
removeMaxHealthOnKill: null,
isSpawnExitTech: null, isSpawnExitTech: null,
cloakDuplication: null, cloakDuplication: null,
extruderRange: null, extruderRange: null,
isForeverDrones: null, isForeverDrones: null,
isMoreMobs: null,
nailRecoil: null, nailRecoil: null,
baseJumpForce: null, baseJumpForce: null,
baseFx: null, baseFx: null,

View File

@@ -1,21 +1,41 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: virtual particles - mobs have a chance to spawn coupling power ups some shotgun ammo tech upgrades will continue to fire some original recipe shotgun bullets
old tech virtual particles renamed vacuum fluctuation rivets, fleas, worms, iceIX
tech: band gap - boosts give more damage but it lasts for 1 less second
tech: exciton - mobs have a chance to spawn a boost WIMPs are 10% faster
boosts are a power up that increases your damage for 10 seconds controlled explosion renamed shaped charge
old tech exciton renamed non-renewables
laser tech: quasiparticles - replace all ammo with boosts
added +20px to grid elements to prevent text spillover
bug fixes bug fixes
construction mode works better with my buttons
to unlock run this and press T to enter testing mode
simulation.enableConstructMode() //used to build maps in testing mode
removed -experiment- tech because it's function was reproduced by "tech - tinker"
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
complete blowSuckBoss... or don't
tech: laser reflections increase damage
JUNK tech different effects based on night or day
use system time
buffing your deflecting for 1 second after pressing the field button
2 second cooldown on the effect to prevent spamming it
buff: giving energy or doing damage makes sense
maybe this could be a rework for bremstralung
replace field descriptions with a function call so they can have dynamic text
add in dynamic coupling text as a 4th line
Boss that shoots out a ring of bullets, then after a few seconds it gravitates the bullets back
JUNK: Placebo: double the power up spawn rate but make half of them do nothing
coupling coupling
pause menu +defense on coupling description goes above 100%
put coupling description as 4th line on field description put coupling description as 4th line on field description
raw text no function call raw text no function call
no need for coupling description in power ups, pause no need for coupling description in power ups, pause
@@ -27,15 +47,8 @@ coupling tech
tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use
some fields aren't used much (that's ok?) some fields aren't used much (that's ok?)
tech: increase the effect of boosts, but shorten the duration?
tech give laser mines more lasers (3->4? 5?) tech give laser mines more lasers (3->4? 5?)
buffing your deflecting for 1 second after pressing the field button sounds cool
2 second cooldown on the effect to prevent spamming it
buff: giving energy or doing damage makes sense
maybe this could be a rework for bremstralung
rewindBoss: after hitting 1/5 damage thresholds the boss rewinds back in time to where it was a few seconds ago rewindBoss: after hitting 1/5 damage thresholds the boss rewinds back in time to where it was a few seconds ago
track it's data like player history track it's data like player history
@@ -913,6 +926,8 @@ possible names for tech
lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown. lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown.
p-zombie p-zombie
p-hacking JUNK tech p-hacking JUNK tech
https://en.wikipedia.org/wiki/High-entropy_alloys
https://en.wikipedia.org/wiki/Refractory_metals
plot script: plot script: