tech: tokamak - instead of throwing a block convert it into energy and a pulse explosion
  requires plasma

standing wave field no longer gives 25% harm reduction
standing wave field can now block through walls

bug fixes
This commit is contained in:
landgreen
2021-06-09 05:59:38 -07:00
parent d9f17ec2db
commit 0ed604a74a
8 changed files with 285 additions and 275 deletions

View File

@@ -1578,7 +1578,7 @@ const b = {
restitution: 0.5,
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 60 + Math.floor(7 * Math.random()),
lookFrequency: 67 + Math.floor(7 * Math.random()),
drain: 0.7 * tech.isLaserDiode * tech.laserFieldDrain,
isArmed: false,
torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1),
@@ -1611,7 +1611,7 @@ const b = {
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
this.do = this.laserSpin
this.endCycle = simulation.cycle + 300
this.endCycle = simulation.cycle + 360
// if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin
this.isArmed = true
}

View File

@@ -15,11 +15,11 @@ const level = {
// simulation.zoomScale = 1000;
// simulation.setZoom();
// simulation.enableConstructMode() //used to build maps in testing mode
// m.setField("standing wave harmonics")
// m.setField("plasma torch")
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
// b.giveGuns("laser")
// tech.isExplodeRadio = true
// for (let i = 0; i < 5; i++) tech.giveTech("spherical harmonics")
// tech.giveTech("expansion")
// tech.giveTech("Z-pinch")
// tech.giveTech("MACHO")
// tech.giveTech("potential well")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
@@ -55,7 +55,7 @@ const level = {
// level.vats() //community level
// level["n-gon"]() //community level
// level.tunnel() //community level
// tech.giveTech("undefined")
// for (let i = 0; i < 7; i++) tech.giveTech("undefined")
// lore.techCount = 6
// localSettings.loreCount = 1;
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
@@ -1152,7 +1152,7 @@ const level = {
spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
}
}
// blockDoor(710, -710);
blockDoor(710, -710);
// for (let i = 0; i < 30; i++) powerUps.directSpawn(710, -710, "tech");
spawn.mapRect(2500, -1200, 200, 750); //right wall

View File

@@ -1135,58 +1135,73 @@ const m = {
//throw the body
m.fieldCDcycle = m.cycle + 15;
m.isHolding = false;
//bullet-like collisions
m.holdingTarget.collisionFilter.category = tech.isBlockBullets ? cat.bullet : cat.body;
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
//check every second to see if player is away from thrown body, and make solid
const solid = function(that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
that.collisionFilter.category = cat.body; //make solid
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {
setTimeout(solid, 40, that);
if (tech.isBlockExplosion && m.throwCharge > 5) { //remove the block body and pulse in the direction you are facing
//m.throwCharge > 5 seems to be when the field full colors in a block you are holding
m.throwCharge = 0;
m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds
m.definePlayerMass() //return to normal player mass
m.energy += 3 * Math.sqrt(m.holdingTarget.mass)
//remove block before pulse, so it doesn't get in the way
for (let i = 0; i < body.length; i++) {
if (body[i] === m.holdingTarget) {
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
}
}
};
setTimeout(solid, 200, m.holdingTarget);
const charge = Math.min(m.throwCharge / 5, 1)
//***** scale throw speed with the first number, 80 *****
let speed = 80 * charge * Math.min(1, 0.8 / Math.pow(m.holdingTarget.mass, 0.25));
if (Matter.Query.collides(m.holdingTarget, map).length !== 0) {
speed *= 0.7 //drop speed by 30% if touching map
if (Matter.Query.ray(map, m.holdingTarget.position, m.pos).length !== 0) speed = 0 //drop to zero if the center of the block can't see the center of the player through the map
//|| Matter.Query.ray(body, m.holdingTarget.position, m.pos).length > 1
}
m.throwCharge = 0;
m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds
Matter.Body.setVelocity(m.holdingTarget, {
x: player.velocity.x * 0.5 + Math.cos(m.angle) * speed,
y: player.velocity.y * 0.5 + Math.sin(m.angle) * speed
});
//player recoil //stronger in x-dir to prevent jump hacking
Matter.Body.setVelocity(player, {
x: player.velocity.x - Math.cos(m.angle) * speed / (m.crouch ? 30 : 10) * Math.sqrt(m.holdingTarget.mass),
y: player.velocity.y - Math.sin(m.angle) * speed / 30 * Math.sqrt(m.holdingTarget.mass)
});
m.definePlayerMass() //return to normal player mass
if (tech.isAddBlockMass) {
const expand = function(that, massLimit) {
if (that.mass < massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
setTimeout(expand, 20, that, massLimit);
b.pulse(50 * Math.pow(m.holdingTarget.mass, 0.25), m.angle)
} else { //normal throw
//bullet-like collisions
m.holdingTarget.collisionFilter.category = tech.isBlockBullets ? cat.bullet : cat.body;
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
//check every second to see if player is away from thrown body, and make solid
const solid = function(that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
that.collisionFilter.category = cat.body; //make solid
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {
setTimeout(solid, 40, that);
}
};
expand(m.holdingTarget, Math.min(20, m.holdingTarget.mass * 3))
setTimeout(solid, 200, m.holdingTarget);
const charge = Math.min(m.throwCharge / 5, 1)
//***** scale throw speed with the first number, 80 *****
let speed = 80 * charge * Math.min(1, 0.8 / Math.pow(m.holdingTarget.mass, 0.25));
if (Matter.Query.collides(m.holdingTarget, map).length !== 0) {
speed *= 0.7 //drop speed by 30% if touching map
if (Matter.Query.ray(map, m.holdingTarget.position, m.pos).length !== 0) speed = 0 //drop to zero if the center of the block can't see the center of the player through the map
//|| Matter.Query.ray(body, m.holdingTarget.position, m.pos).length > 1
}
m.throwCharge = 0;
m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds
Matter.Body.setVelocity(m.holdingTarget, {
x: player.velocity.x * 0.5 + Math.cos(m.angle) * speed,
y: player.velocity.y * 0.5 + Math.sin(m.angle) * speed
});
//player recoil //stronger in x-dir to prevent jump hacking
Matter.Body.setVelocity(player, {
x: player.velocity.x - Math.cos(m.angle) * speed / (m.crouch ? 30 : 10) * Math.sqrt(m.holdingTarget.mass),
y: player.velocity.y - Math.sin(m.angle) * speed / 30 * Math.sqrt(m.holdingTarget.mass)
});
m.definePlayerMass() //return to normal player mass
if (tech.isAddBlockMass) {
const expand = function(that, massLimit) {
if (that.mass < massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
setTimeout(expand, 20, that, massLimit);
}
};
expand(m.holdingTarget, Math.min(20, m.holdingTarget.mass * 3))
}
}
}
} else {
m.isHolding = false
@@ -1353,11 +1368,8 @@ const m = {
},
pushMobs360(range) { // find mobs in range in any direction
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range &&
!mob[i].isShielded &&
Matter.Query.ray(map, mob[i].position, m.pos).length === 0
) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range && !mob[i].isShielded) {
// && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
m.pushMass(mob[i]);
}
@@ -1495,25 +1507,16 @@ const m = {
},
{
name: "standing wave harmonics",
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> drains <strong class='color-f'>energy</strong> with no <strong>cool down</strong><br>reduce <strong class='color-harm'>harm</strong> and deflecting <strong>recoil</strong> by <strong>25%</strong>",
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> drains <strong class='color-f'>energy</strong> with no <strong>cool down</strong><br><strong>deflecting</strong> has <strong>75%</strong> less <strong>recoil</strong>", //<strong class='color-harm'>harm</strong> and
effect: () => {
// m.fieldHarmReduction = 0.80;
m.fieldBlockCD = 0;
m.fieldHarmReduction = 0.75;
// m.fieldHarmReduction = 0.75;
m.blockingRecoil = 1 //4 is normal
m.fieldRange = 175
m.fieldShieldingScale = Math.pow(0.5, (tech.harmonics - 3))
m.harmonicRadius = 1 //for smoothing function when player holds mouse (for harmonicAtomic)
m.harmonic3Phase = () => { //normal standard 3 different 2-d circles
if (tech.isStandingWaveExpand) {
if (input.field) {
const oldHarmonicRadius = m.harmonicRadius
m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5
m.energy -= 0.3 * (m.harmonicRadius - oldHarmonicRadius)
} else {
m.harmonicRadius = 0.998 * m.harmonicRadius + 0.002 * 1
}
}
const fieldRange1 = (0.7 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius
const fieldRange2 = (0.63 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
const fieldRange3 = (0.65 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius
@@ -1533,15 +1536,6 @@ const m = {
m.harmonicAtomic = () => { //several ellipses spinning about different axises
const rotation = simulation.cycle * 0.002
const phase = simulation.cycle * 0.03
if (tech.isStandingWaveExpand) {
if (input.field) {
const oldHarmonicRadius = m.harmonicRadius
m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5
m.energy -= 0.3 * (m.harmonicRadius - oldHarmonicRadius)
} else {
m.harmonicRadius = 0.998 * m.harmonicRadius + 0.002 * 1
}
}
const radius = m.fieldRange * m.harmonicRadius //+ 20 * Math.sin(m.cycle * 0.05)
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(110,170,200,0.9)"
@@ -1585,6 +1579,15 @@ const m = {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
if (m.energy > 0.1 && m.fieldCDcycle < m.cycle) {
if (tech.isStandingWaveExpand) {
if (input.field) {
const oldHarmonicRadius = m.harmonicRadius
m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5
m.energy -= 0.45 * (m.harmonicRadius - oldHarmonicRadius)
} else {
m.harmonicRadius = 0.997 * m.harmonicRadius + 0.003 * 1
}
}
m.harmonicShield()
}

View File

@@ -1,7 +1,7 @@
// game Object ********************************************************
//*********************************************************************
const simulation = {
loop() {}, //main game loop, gets se tto normal or testing loop
loop() {}, //main game loop, gets set to normal or testing loop
normalLoop() {
simulation.gravity();
Engine.update(engine, simulation.delta);
@@ -525,18 +525,9 @@ const simulation = {
level.levels.push("tunnel");
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels
lore.techCount = 0; //remove undefined tech for community maps
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0;
tech.tech[i].count = 0;
}
}
} else {
level.levels = shuffle(level.levels); //shuffles order of maps
}
level.levels.unshift("intro"); //add level to the start of the randomized levels list
level.levels.push("gauntlet"); //add level to the end of the randomized levels list
level.levels.push("final"); //add level to the end of the randomized levels list
@@ -657,6 +648,7 @@ const simulation = {
simulation.fpsInterval = 1000 / simulation.fpsCap;
simulation.then = Date.now();
requestAnimationFrame(cycle); //starts game loop
},
clearTimeouts() {
let id = window.setTimeout(function() {}, 0);

View File

@@ -242,120 +242,127 @@ const spawn = {
me.isBoss = true;
me.frictionAir = 0.01;
me.memory = Infinity;
me.hasRunDeathScript = false
me.locatePlayer();
const density = 0.25
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
// spawn.shield(me, x, y, 1);
me.onDeath = function() {
if (!this.hasRunDeathScript) {
this.hasRunDeathScript = true
//make a block body to replace this one
//this body is too big to leave behind in the normal way mobs.replace()
const len = body.length;
const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure
body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v);
Matter.Body.setVelocity(body[len], { x: 0, y: -3 });
Matter.Body.setAngularVelocity(body[len], this.angularVelocity);
body[len].collisionFilter.category = cat.body;
body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
body[len].classType = "body";
World.add(engine.world, body[len]); //add to world
const expand = function(that, massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
if (that.mass < massLimit) setTimeout(expand, 20, that, massLimit);
};
expand(body[len], 200)
//make a block body to replace this one
//this body is too big to leave behind in the normal way mobs.replace()
const len = body.length;
const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure
body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v);
Matter.Body.setVelocity(body[len], { x: 0, y: -3 });
Matter.Body.setAngularVelocity(body[len], this.angularVelocity);
body[len].collisionFilter.category = cat.body;
body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
body[len].classType = "body";
World.add(engine.world, body[len]); //add to world
const expand = function(that, massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
if (that.mass < massLimit) setTimeout(expand, 20, that, massLimit);
};
expand(body[len], 200)
function unlockExit() {
if (simulation.isHorizontalFlipped) {
level.exit.x = -5500 - 100;
} else {
level.exit.x = 5500;
}
level.exit.y = -330;
Matter.World.remove(engine.world, map[map.length - 1]);
map.splice(map.length - 1, 1);
simulation.draw.setPaths(); //redraw map draw path
}
function unlockExit() {
level.exit.x = 5500;
level.exit.y = -330;
Matter.World.remove(engine.world, map[map.length - 1]);
map.splice(map.length - 1, 1);
simulation.draw.setPaths(); //redraw map draw path
}
//add lore level as next level if player took lore tech earlier in the game
if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) {
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}<br>level.levels.push("<span class='lore-text'>null</span>")`);
level.levels.push("null")
//remove block map element so exit is clear
unlockExit()
} else { //reset game
let count = 0
//add lore level as next level if player took lore tech earlier in the game
if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) {
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}<br>level.levels.push("<span class='lore-text'>null</span>")`);
level.levels.push("null")
//remove block map element so exit is clear
unlockExit()
} else { //reset game
let count = 0
function loop() {
if (!simulation.paused) {
count++
if (count < 600) {
if (count === 1) simulation.makeTextLog(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
if (!(count % 60)) simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${(count/60- Math.random()).toFixed(3)}`);
} else if (count === 600) {
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> 1 <em>//analysis complete</em>`);
} else if (count === 720) {
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}`)
} else if (count === 900) {
simulation.makeTextLog(`World.clear(engine.world) <em>//simulation successful</em>`);
} else if (count === 1140) {
// tech.isImmortal = false;
// m.death()
// m.alive = false;
// simulation.paused = true;
// m.health = 0;
// m.displayHealth();
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
document.getElementById("fade-out").style.opacity = 1; //slowly fades out
// build.shareURL(false)
function loop() {
if (!simulation.paused) {
count++
if (count < 600) {
if (count === 1) simulation.makeTextLog(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
if (!(count % 60)) simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> ${(count/60- Math.random()).toFixed(3)}`);
} else if (count === 600) {
simulation.makeTextLog(`simulation.analysis <span class='color-symbol'>=</span> 1 <em>//analysis complete</em>`);
} else if (count === 720) {
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}`)
} else if (count === 900) {
simulation.makeTextLog(`World.clear(engine.world) <em>//simulation successful</em>`);
} else if (count === 1140) {
// tech.isImmortal = false;
// m.death()
// m.alive = false;
// simulation.paused = true;
// m.health = 0;
// m.displayHealth();
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
document.getElementById("fade-out").style.opacity = 1; //slowly fades out
// build.shareURL(false)
setTimeout(function() {
simulation.paused = true;
World.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
}, 6000);
return
}
}
if (simulation.testing) {
unlockExit()
setTimeout(function() {
simulation.paused = true;
World.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
}, 6000);
return
simulation.makeTextLog(`level.levels.length <span class='color-symbol'>=</span> <strong>Infinite</strong>`);
}, 1500);
} else {
requestAnimationFrame(loop);
}
}
if (simulation.testing) {
unlockExit()
setTimeout(function() {
simulation.makeTextLog(`level.levels.length <span class='color-symbol'>=</span> <strong>Infinite</strong>`);
}, 1500);
} else {
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
// for (let i = 0; i < 3; i++)
level.difficultyIncrease(simulation.difficultyMode) //ramp up damage
//remove power Ups, to avoid spamming console
function removeAll(array) {
for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]);
}
removeAll(powerUp);
powerUp = [];
// for (let i = 0; i < 3; i++)
level.difficultyIncrease(simulation.difficultyMode) //ramp up damage
//remove power Ups, to avoid spamming console
function removeAll(array) {
for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]);
}
removeAll(powerUp);
powerUp = [];
//pull in particles
for (let i = 0, len = body.length; i < len; ++i) {
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65)
const pushUp = Vector.add(velocity, { x: 0, y: -0.5 })
Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp));
}
//damage all mobs
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i] !== this) mob[i].damage(Infinity, true);
}
//pull in particles
for (let i = 0, len = body.length; i < len; ++i) {
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65)
const pushUp = Vector.add(velocity, { x: 0, y: -0.5 })
Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp));
}
//damage all mobs
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i] !== this) mob[i].damage(Infinity, true);
}
//draw stuff
for (let i = 0, len = 22; i < len; i++) {
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: (i + 1) * 150,
color: `rgba(255,255,255,0.17)`,
time: 5 * (len - i + 1)
});
//draw stuff
for (let i = 0, len = 22; i < len; i++) {
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: (i + 1) * 150,
color: `rgba(255,255,255,0.17)`,
time: 5 * (len - i + 1)
});
}
}
};
me.onDamage = function() {};
@@ -448,7 +455,7 @@ const spawn = {
}
const len = (this.totalCycles / 400 + simulation.difficulty / 2 - 30) / 15
for (let i = 0; i < len; i++) {
spawn.randomLevelBoss(3000 + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5))
spawn.randomLevelBoss(-3000 + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5))
}
}
}
@@ -1760,8 +1767,8 @@ const spawn = {
y: me.position.y
},
bodyB: me,
stiffness: 0.001,
damping: 1
stiffness: 0.0001,
damping: 0.3
});
World.add(engine.world, me.constraint);
}, 2000); //add in a delay in case the level gets flipped left right
@@ -1876,18 +1883,18 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "#f08");
let me = mob[mob.length - 1];
setTimeout(() => { //fix mob in place, but allow rotation
me.constraint = Constraint.create({
pointA: {
x: me.position.x,
y: me.position.y
},
bodyB: me,
stiffness: 0.0001,
damping: 1
});
World.add(engine.world, me.constraint);
}, 2000); //add in a delay in case the level gets flipped left right
// setTimeout(() => { //fix mob in place, but allow rotation
// me.constraint = Constraint.create({
// pointA: {
// x: me.position.x,
// y: me.position.y
// },
// bodyB: me,
// stiffness: 0.00001,
// damping: 0.1
// });
// World.add(engine.world, me.constraint);
// }, 2000); //add in a delay in case the level gets flipped left right
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2);

View File

@@ -14,6 +14,14 @@
}
}
lore.techCount = 0;
if (simulation.isCommunityMaps || simulation.isCheating) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0;
tech.tech[i].count = 0;
}
}
}
// tech.removeJunkTechFromPool();
// tech.removeLoreTechFromPool();
// tech.addLoreTechToPool();
@@ -742,7 +750,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1)
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
},
requires: "an explosive damage source, not ammonium nitrate or nitroglycerin",
effect: () => {
@@ -759,7 +767,7 @@
count: 0,
frequency: 2,
allowed() {
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1)
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
},
requires: "an explosive damage source, not iridium-192",
effect: () => {
@@ -776,7 +784,7 @@
count: 0,
frequency: 2,
allowed() {
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1)
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
},
requires: "an explosive damage source, not iridium-192",
effect: () => {
@@ -794,7 +802,7 @@
frequency: 2,
isBadRandomOption: true,
allowed() {
return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField)
return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.isBlockExplosion)
},
requires: "an explosive damage source, not causality bombs",
effect: () => {
@@ -812,7 +820,7 @@
count: 0,
frequency: 2,
allowed() {
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1)
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
},
requires: "an explosive damage source, not iridium-192",
effect() {
@@ -830,7 +838,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser
return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion
},
requires: "an explosive damage source",
effect: () => {
@@ -881,7 +889,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 && !tech.iceIXOnDeath
return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
},
requires: "an explosive damage source, no other mob death tech",
effect: () => {
@@ -3063,27 +3071,6 @@
},
remove() {}
},
{
name: "booby trap",
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br>add <strong>9</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.duplicationChance() > 0
},
requires: "some power up duplication",
effect() {
tech.isMineDrop = true;
if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
tech.addJunkTechToPool(13)
},
remove() {
tech.isMineDrop = false;
if (this.count > 0) tech.removeJunkTechFromPool(13)
}
},
{
name: "unified field theory",
description: `in the <strong>pause</strong> menu, change your <strong class='color-f'>field</strong><br>by <strong>clicking</strong> on your <strong class='color-f'>field's</strong> box`,
@@ -4079,6 +4066,27 @@
tech.isMineSentry = false;
}
},
{
name: "booby trap",
description: "drop a <strong>mine</strong> after picking up a <strong>power up</strong><br>add <strong>13</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isMineSentry === true || tech.isLaserMine === true || tech.isMineAmmoBack === true
},
requires: "some mine tech",
effect() {
tech.isMineDrop = true;
if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
tech.addJunkTechToPool(13)
},
remove() {
tech.isMineDrop = false;
if (this.count > 0) tech.removeJunkTechFromPool(13)
}
},
{
name: "mycelial fragmentation",
description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release an extra <strong class='color-p' style='letter-spacing: 2px;'>spore</strong><br> once a <strong>second</strong> during their <strong>growth</strong> phase",
@@ -4613,35 +4621,14 @@
//************************************************** field
//************************************************** tech
//**************************************************
// {
// name: "frequency resonance",
// description: "<strong>standing wave harmonics</strong> shield is retuned<br>increase <strong>size</strong> and <strong>deflecting</strong> efficiency by <strong>50%</strong>",
// isFieldTech: true,
// maxCount: 9,
// count: 0,
// frequency: 2,
// allowed() {
// return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics"
// },
// requires: "standing wave harmonics",
// effect() {
// tech.frequencyResonance = this.count + 1 // +1 because count updates later
// m.fieldRange = 175 + 175 * 0.25 * tech.frequencyResonance
// m.fieldShieldingScale = Math.pow(0.5, tech.frequencyResonance)
// },
// remove() {
// m.fieldRange = 175;
// m.fieldShieldingScale = 1;
// tech.frequencyResonance = 0
// }
// },
{
name: "spherical harmonics",
description: "<strong>standing wave</strong> oscillates in a 3rd dimension<br>increasing <strong>deflecting</strong> efficiency by <strong>40%</strong>",
isFieldTech: true,
maxCount: 9,
count: 0,
frequency: 4,
frequency: 3,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics"
},
@@ -4659,7 +4646,7 @@
},
{
name: "expansion",
description: "using <strong>standing wave</strong> field drains <strong class='color-f'>energy</strong><br>to temporarily <strong>expand</strong> its <strong>radius</strong>",
description: "using <strong>standing wave</strong> field uses <strong class='color-f'>energy</strong><br>to temporarily <strong>expand</strong> its <strong>radius</strong>",
// description: "use <strong class='color-f'>energy</strong> to <strong>expand</strong> <strong>standing wave</strong><br>the field slowly <strong>contracts</strong> when not used",
isFieldTech: true,
maxCount: 1,
@@ -5053,6 +5040,24 @@
tech.isPlasmaRange = 1;
}
},
{
name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> convert it into <strong class='color-f'>energy</strong><br>and a <strong class='color-laser'>laser</strong> pulse <strong class='color-e'>explosion</strong> cluster",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
},
requires: "plasma torch",
effect() {
tech.isBlockExplosion = true;
},
remove() {
tech.isBlockExplosion = false;
}
},
{
name: "micro-extruder",
description: "<strong class='color-plasma'>plasma</strong> <strong>torch</strong> extrudes a thin <strong class='color-plasma'>hot</strong> wire<br>increases <strong class='color-d'>damage</strong>, <strong class='color-f'>energy</strong> drain, and <strong>lag</strong>",
@@ -6876,7 +6881,6 @@
droneCycleReduction: null,
droneEnergyReduction: null,
isNoHeals: null,
// frequencyResonance: null,
isAlwaysFire: null,
isDroneRespawn: null,
deathSpawns: null,
@@ -6897,5 +6901,6 @@
isSneakAttack: null,
isFallingDamage: null,
harmonics: null,
isStandingWaveExpand: null
isStandingWaveExpand: null,
isBlockExplosion: null
}