wave beam damage works better vs. high mass mobs
  also more damage and ammo

mod plasma torch: extruder - plasma torch ejects a thin hot wire, does more damage, but drains more energy

mod: Bose Einstein condensate - freeze mobs inside your field
  pilot wave, negative mass field, time dilation field

difficulty - after you clear the finalBoss, difficulty increase per level is now lower
  but, when the finalBoss dies difficulty immediately increases greatly

  difficulty used to work like this:
  (+1 per level) 0,1,2,3,4,5,6,7,8,9,10, (final boss dies)
  (+2,3,4 per level) 12,14,16,19,22,25,29,33,37,41, (final boss dies)
  (+4 per level) 44,48,52,56 ...

  difficulty works like this now:
  (+1 per level) 0,1,2,3,4,5,6,7,8,9,10, (final boss dies +5)
  (+2 per level) 17,19,21,23,25,27,29,31,33,35, (final boss dies +5)
  (+3 per level) 43,46,49,52 ...

  difficulty mode scales these numbers
  easy: x1,  normal: x2,  hard: x4,  why: x6

  each time difficulty increases:
    game.dmgScale = 0.38 * game.difficulty //damage done by mobs increases each level
    b.dmgScale *= 0.93; // your damage goes down
    game.healScale = 1 / (1 + game.difficulty * 0.06) //healing goes down
    if (game.accelScale < 5) game.accelScale *= 1.02 //mob acceleration increases each level, but is capped
    if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.98 //mob cycles between looks decreases each level, but is capped
    if (game.CDScale > 0.2) game.CDScale *= 0.97 //mob ability cooldown time decreases each level, but is capped
This commit is contained in:
landgreen
2020-12-13 14:41:07 -08:00
parent b6cf21dee9
commit 92c5670369
6 changed files with 435 additions and 229 deletions

View File

@@ -678,6 +678,262 @@ const b = {
});
World.add(engine.world, bullet[me]); //add bullet to world
},
lastAngle: 0,
extruder() {
const color = "#f07"
const DRAIN = 0.00014 + mech.fieldRegen
if (mech.energy > DRAIN) {
mech.energy -= DRAIN
if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
ctx.lineWidth = 5;
ctx.strokeStyle = color
ctx.beginPath(); //draw all the wave bullets
for (let i = 0, len = bullet.length; i < len; i++) {
if (bullet[i].isBranch) {
ctx.stroke();
ctx.beginPath(); //draw all the wave bullets
} else if (bullet[i].isWave) ctx.lineTo(bullet[i].position.x, bullet[i].position.y)
}
ctx.lineTo(mech.pos.x + 15 * Math.cos(mech.angle), mech.pos.y + 15 * Math.sin(mech.angle))
ctx.stroke();
} else {
mech.fireCDcycle = mech.cycle + 60; // cool down
for (let i = 0, len = bullet.length; i < len; i++) { //remove all bullets
if (bullet[i].isWave) {
bullet[i].isWave = false
bullet[i].endCycle = 0
}
}
return
}
const SPEED = 13
const me = bullet.length;
const where = Vector.add(mech.pos, player.velocity)
bullet[me] = Bodies.polygon(where.x + 20 * Math.cos(mech.angle), where.y + 20 * Math.sin(mech.angle), 3, 0.01, {
cycle: -0.5,
isWave: true,
endCycle: game.cycle + 50 * mod.isPlasmaRange,
inertia: Infinity,
frictionAir: 0,
isInHole: true, //this keeps the bullet from entering wormholes
minDmgSpeed: 0,
dmg: b.dmgScale * 1.4, //damage also changes when you divide by mob.mass on in .do()
isJustReflected: false,
classType: "bullet",
isBranch: false,
restitution: 0,
collisionFilter: {
// category: 0,
// mask: 0, //cat.mob | cat.mobBullet | cat.mobShield
category: cat.bullet,
mask: cat.map, //cat.mob | cat.mobBullet | cat.mobShield
},
beforeDmg() {},
onEnd() {},
do() {
mech.fireCDcycle = mech.cycle //this is here to trigger cloaking field
if (!input.field) {
this.endCycle = 0;
this.isWave = false
return
}
if (!mech.isBodiesAsleep) {
if (this.endCycle < game.cycle + 1) this.isWave = false
if (Matter.Query.point(map, this.position).length) { //check if inside map
this.isBranch = true;
// for (let i = 0, len = bullet.length; i < len; i++) { //remove all bullets
// if (bullet[i].isWave && bullet[i].cycle > this.cycle) {
// bullet[i].isWave = false
// bullet[i].endCycle = 0
// }
// }
} else { //check if inside a body
const q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
Matter.Body.setVelocity(q[i], {
x: q[i].velocity.x * 0.7,
y: q[i].velocity.y * 0.7
});
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = this.dmg / Math.min(10, q[i].mass)
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: Math.log(2 * dmg + 1.4) * 40,
color: color,
time: game.drawTime
});
}
}
this.cycle++
const wiggleMag = (mech.crouch ? 6 : 12) * Math.cos(game.cycle * 0.09)
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(game.cycle * 0.3))
const velocity = Vector.mult(player.velocity, 0.3) //move with player
Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle)))
// Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
}
}
});
World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(mech.angle),
y: SPEED * Math.sin(mech.angle)
});
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
const angleDifference = 180 - Math.abs(Math.abs(b.lastAngle - mech.angle) - 180); //find the difference between current and previous angle
b.lastAngle = mech.angle
if (angleDifference > 0.5) { //don't draw stroke for this bullet
bullet[me].isBranch = true;
// for (let i = 0, len = bullet.length; i < len; i++) { //remove all bullets
// if (bullet[i].isWave) {
// bullet[i].isWave = false
// bullet[i].endCycle = 0
// }
// }
// return
}
},
plasma() {
const DRAIN = 0.00008 + mech.fieldRegen
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
//calculate laser collision
let best;
let range = mod.isPlasmaRange * (120 + (mech.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(mech.cycle * 0.3);
// const dir = mech.angle // + 0.04 * (Math.random() - 0.5)
const path = [{
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
},
{
x: mech.pos.x + range * Math.cos(mech.angle),
y: mech.pos.y + range * Math.sin(mech.angle)
}
];
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[j],
v2: vertices[j + 1]
};
}
}
}
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[0],
v2: vertices[len]
};
}
}
}
};
//check for collisions
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
vertexCollision(path[0], path[1], mob);
vertexCollision(path[0], path[1], map);
vertexCollision(path[0], path[1], body);
if (best.dist2 != Infinity) { //if hitting something
path[path.length - 1] = {
x: best.x,
y: best.y
};
if (best.who.alive) {
const dmg = 0.8 * b.dmgScale; //********** SCALE DAMAGE HERE *********************
best.who.damage(dmg);
best.who.locatePlayer();
//push mobs away
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { //friction
x: best.who.velocity.x * 0.7,
y: best.who.velocity.y * 0.7
});
//draw mob damage circle
game.drawList.push({
x: path[1].x,
y: path[1].y,
radius: Math.sqrt(dmg) * 50,
color: "rgba(255,0,255,0.2)",
time: game.drawTime * 4
});
} else if (!best.who.isStatic) {
//push blocks away
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.007 * Math.sqrt(Math.sqrt(best.who.mass)))
Matter.Body.applyForce(best.who, path[1], force)
}
}
//draw blowtorch laser beam
ctx.strokeStyle = "rgba(255,0,255,0.1)"
ctx.lineWidth = 14
ctx.beginPath();
ctx.moveTo(path[0].x, path[0].y);
ctx.lineTo(path[1].x, path[1].y);
ctx.stroke();
ctx.strokeStyle = "#f0f";
ctx.lineWidth = 2
ctx.stroke();
//draw electricity
const Dx = Math.cos(mech.angle);
const Dy = Math.sin(mech.angle);
let x = mech.pos.x + 20 * Dx;
let y = mech.pos.y + 20 * Dy;
ctx.beginPath();
ctx.moveTo(x, y);
const step = Vector.magnitude(Vector.sub(path[0], path[1])) / 10
for (let i = 0; i < 8; i++) {
x += step * (Dx + 1.5 * (Math.random() - 0.5))
y += step * (Dy + 1.5 * (Math.random() - 0.5))
ctx.lineTo(x, y);
}
ctx.lineWidth = 2 * Math.random();
ctx.stroke();
}
},
laser(where = {
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
@@ -2565,7 +2821,7 @@ const b = {
frictionAir: 0,
slow: 0,
minDmgSpeed: 0,
dmg: 0,
dmg: b.dmgScale * (mod.waveHelix === 1 ? 0.6 : 0.75), //control damage also when you divide by mob.mass
isJustReflected: false,
classType: "bullet",
collisionFilter: {
@@ -2580,7 +2836,7 @@ const b = {
// check if inside a mob
q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
let dmg = b.dmgScale * 0.4 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
let dmg = this.dmg / Math.min(10, q[i].mass)
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
@@ -2613,7 +2869,7 @@ const b = {
for (let i = 0; i < q.length; i++) {
slowCheck = 0.3;
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = b.dmgScale * 0.4 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
let dmg = this.dmg / Math.min(10, q[i].mass)
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
@@ -2632,6 +2888,8 @@ const b = {
}
}
this.cycle++
//6 * Math.cos(this.cycle * 0.1) +
// Math.cos(game.cycle * 0.09) *
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.35) * ((i % 2) ? -1 : 1))
Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
}

View File

@@ -13,15 +13,15 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(99)
// level.difficultyIncrease(19)
// game.zoomScale = 1000;
// game.setZoom();
// mech.setField("wormhole")
// b.giveGuns("grenades")
// mod.isIncendiary = true
// mod.is3Missiles = true
// mod.giveMod("neutron bomb")
// mod.giveMod("causality bombs")
// mech.setField("plasma torch")
// b.giveGuns("wave beam")
// mod.giveMod("micro-extruder")
// for (let i = 0; i < 15; i++) mod.giveMod("supply chain")
level.intro(); //starting level
// level.testing(); //not in rotation
@@ -155,8 +155,8 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.boost(1500, 0, 900);
// spawn.starter(1900, -500, 320)
spawn.exploder(2900, -500)
spawn.starter(1900, -500, 200)
// spawn.exploder(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500)
@@ -3805,11 +3805,12 @@ const level = {
},
nextLevel() {
if (level.bossKilled) level.levelsCleared++;
level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes
if (level.levelsCleared > level.levels.length) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 1.25) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 1.5) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 2) level.difficultyIncrease(game.difficultyMode)
// level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes
//difficulty is increased 5 times when finalBoss dies
const len = level.levelsCleared / level.levels.length //add 1 extra difficulty step for each time you have cleared all the levels
for (let i = 0; i < len; i++) level.difficultyIncrease(game.difficultyMode)
level.onLevel++; //cycles map to next level
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
//reset lost mod display

View File

@@ -6,6 +6,12 @@ const mod = {
mod.mods[i].isLost = false
mod.mods[i].count = 0
}
// mod.nailBotCount = 0;
// mod.foamBotCount = 0;
// mod.boomBotCount = 0;
// mod.laserBotCount = 0;
// mod.orbitalBotCount = 0;
// mod.plasmaBotCount = 0;
mod.armorFromPowerUps = 0;
mod.totalCount = 0;
game.updateModHUD();
@@ -46,6 +52,14 @@ const mod = {
game.updateModHUD();
}
},
setModToNonRefundable(name) {
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods.name === name) {
mod.mods[i].isNonRefundable = true;
return
}
}
},
// giveBasicMod(index = 'random') {
// // if (isNaN(index)) { //find index by name
// // let found = false;
@@ -92,7 +106,7 @@ const mod = {
if (mod.isEnergyLoss) dmg *= 1.5;
if (mod.isAcidDmg && mech.health > 1) dmg *= 1.4;
if (mod.restDamage > 1 && player.speed < 1) dmg *= mod.restDamage
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 7;
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 8;
if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038
if (mod.isRerollDamage) dmg *= 1 + 0.04 * powerUps.reroll.rerolls
if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.25
@@ -109,7 +123,7 @@ const mod = {
},
mods: [{
name: "capacitor",
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>7</strong> stored <strong class='color-f'>energy</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>8</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1028,7 +1042,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.isStunField || mod.isPulseStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.isPilotFreeze || mod.haveGunCheck("ice IX") || mod.isCloakStun || mod.orbitBotCount > 1 || mod.isWormholeDamage
return mod.isStunField || mod.isPulseStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.haveGunCheck("ice IX") || mod.isCloakStun || mod.orbitBotCount > 1 || mod.isWormholeDamage
},
requires: "a freezing or stunning effect",
effect() {
@@ -1145,7 +1159,7 @@ const mod = {
allowed() {
return !mod.isEnergyLoss && !mod.isPiezo && !mod.isRewindAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
},
requires: "not piezoelectricity, acute stress response, 1st law, negative mass field",
requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass field",
effect: () => {
mech.health = 0
// mech.displayHealth();
@@ -1428,9 +1442,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.duplicationChance() > 0 && !mod.isDeterminism
return !mod.isDeterminism
},
requires: "a chance to duplicate power ups, not determinism",
requires: "not determinism",
effect() {
mod.isCancelDuplication = true
mod.cancelCount = 0
@@ -1823,7 +1837,6 @@ const mod = {
//remove active bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
let count = 0 //count mods
for (let i = 0, len = mod.mods.length; i < len; i++) { // spawn new mods power ups
if (!mod.mods[i].isNonRefundable) count += mod.mods[i].count
@@ -2304,7 +2317,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("wave beam")
return mod.haveGunCheck("wave beam") && !mod.isExtruder
},
requires: "wave beam",
effect() {
@@ -2320,7 +2333,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("wave beam") && !mod.isWaveReflect
return mod.haveGunCheck("wave beam") && !mod.isWaveReflect && !mod.isExtruder
},
requires: "wave beam",
effect() {
@@ -2338,7 +2351,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("wave beam") && mod.waveSpeedMap !== 3
return mod.haveGunCheck("wave beam") && mod.waveSpeedMap !== 3 && !mod.isExtruder
},
requires: "wave beam",
effect() {
@@ -3128,36 +3141,46 @@ const mod = {
mech.energy = 0.01;
//fill array of available bots
const notUpgradedBots = []
if (!mod.isNailBotUpgrade) {
notUpgradedBots.push(() => {
mod.giveMod("nail-bot upgrade")
for (let i = 0; i < 2; i++) mod.giveMod("nail-bot")
})
}
if (!mod.isFoamBotUpgrade) {
notUpgradedBots.push(() => {
mod.giveMod("foam-bot upgrade")
for (let i = 0; i < 2; i++) mod.giveMod("foam-bot")
})
}
if (!mod.isBoomBotUpgrade) {
notUpgradedBots.push(() => {
mod.giveMod("boom-bot upgrade")
for (let i = 0; i < 2; i++) mod.giveMod("boom-bot")
})
}
if (!mod.isLaserBotUpgrade) {
notUpgradedBots.push(() => {
mod.giveMod("laser-bot upgrade")
for (let i = 0; i < 2; i++) mod.giveMod("laser-bot")
})
}
if (!mod.isOrbitBotUpgrade) {
notUpgradedBots.push(() => {
mod.giveMod("orbital-bot upgrade")
for (let i = 0; i < 2; i++) mod.giveMod("orbital-bot")
})
}
if (!mod.isNailBotUpgrade) notUpgradedBots.push(() => {
mod.giveMod("nail-bot upgrade")
mod.setModToNonRefundable("nail-bot upgrade")
for (let i = 0; i < 2; i++) {
b.nailBot()
mod.nailBotCount++;
}
})
if (!mod.isFoamBotUpgrade) notUpgradedBots.push(() => {
mod.giveMod("foam-bot upgrade")
mod.setModToNonRefundable("foam-bot upgrade")
for (let i = 0; i < 2; i++) {
b.foamBot()
mod.foamBotCount++;
}
})
if (!mod.isBoomBotUpgrade) notUpgradedBots.push(() => {
mod.giveMod("boom-bot upgrade")
mod.setModToNonRefundable("boom-bot upgrade")
for (let i = 0; i < 2; i++) {
b.boomBot()
mod.boomBotCount++;
}
})
if (!mod.isLaserBotUpgrade) notUpgradedBots.push(() => {
mod.giveMod("laser-bot upgrade")
mod.setModToNonRefundable("laser-bot upgrade")
for (let i = 0; i < 2; i++) {
b.laserBot()
mod.laserBotCount++;
}
})
if (!mod.isOrbitBotUpgrade) notUpgradedBots.push(() => {
mod.giveMod("orbital-bot upgrade")
mod.setModToNonRefundable("orbital-bot upgrade")
for (let i = 0; i < 2; i++) {
b.orbitalBot()
mod.orbitalBotCount++;
}
})
//choose random function from the array and run it
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]()
},
@@ -3225,7 +3248,6 @@ const mod = {
},
remove() {
mod.isHarmReduce = false;
// if (mech.fieldUpgrades[mech.fieldMode].name === "negative mass field") mech.setField("negative mass field") //reset harm reduction
}
},
{
@@ -3245,19 +3267,19 @@ const mod = {
}
},
{
name: "negative temperature",
description: "<strong>negative mass field</strong> uses <strong class='color-f'>energy</strong><br>to <strong class='color-s'>freeze</strong> each mob caught in it's effect",
name: "Bose Einstein condensate",
description: "<strong>mobs</strong> inside your <strong class='color-f'>field</strong> are <strong class='color-s'>frozen</strong><br><em style = 'font-size: 100%'>pilot wave, negative mass, time dilation</em>",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name === "negative mass field"
return mech.fieldUpgrades[mech.fieldMode].name === "pilot wave" || mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" || mech.fieldUpgrades[mech.fieldMode].name === "time dilation field"
},
requires: "negative mass field",
requires: "pilot wave, negative mass field, time dilation field",
effect() {
mod.isFreezeMobs = true;
mod.isFreezeMobs = true
},
remove() {
mod.isFreezeMobs = false;
mod.isFreezeMobs = false
}
},
{
@@ -3293,6 +3315,22 @@ const mod = {
mod.plasmaBotCount = 0;
}
},
{
name: "micro-extruder",
description: "<strong class='color-plasma'>plasma</strong> torch ejects a thin <strong class='color-plasma'>hot</strong> wire<br>increases <strong class='color-d'>damage</strong>, and <strong class='color-f'>energy</strong> drain",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name === "plasma torch"
},
requires: "plasma torch",
effect() {
mod.isExtruder = true;
},
remove() {
mod.isExtruder = false;
}
},
{
name: "timelike world line",
description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you <strong>immune</strong> to <strong class='color-harm'>harm</strong>",
@@ -3401,22 +3439,6 @@ const mod = {
b.setFireCD();
}
},
{
name: "Bose Einstein condensate",
description: "<strong>mobs</strong> in superposition with the <strong>pilot wave</strong><br>are <strong class='color-s'>frozen</strong> for <strong>2</strong> seconds",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name === "pilot wave"
},
requires: "pilot wave",
effect() {
mod.isPilotFreeze = true
},
remove() {
mod.isPilotFreeze = false
}
},
{
name: "cosmic string",
description: "<strong>stun</strong> and do <strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> to <strong>mobs</strong><br>if you tunnel through them with a <strong class='color-worm'>wormhole</strong>",
@@ -3647,7 +3669,6 @@ const mod = {
isNailPoison: null,
isEnergyHealth: null,
isPulseStun: null,
isPilotFreeze: null,
restDamage: null,
isRPG: null,
is3Missiles: null,
@@ -3750,5 +3771,6 @@ const mod = {
isMaxEnergyMod: null,
isLowEnergyDamage: null,
isRewindBot: null,
isRewindGrenade: null
isRewindGrenade: null,
isExtruder: null
}

View File

@@ -491,7 +491,7 @@ const mech = {
},
rewind(steps) {
if (mod.isRewindGrenade) {
for (let i = 1, len = Math.floor(1.5 + steps / 40); i < len; i++) {
for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) {
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
const who = bullet[bullet.length - 1]
if (mod.isVacuumBomb) {
@@ -1163,6 +1163,8 @@ const mech = {
} else {
mech.drawHold(who);
}
// if (mod.isFreezeMobs) mobs.statusSlow(who, 60) //this works but doesn't have a fun effect
// mech.holdingTarget = null
//knock backs
if (mech.fieldShieldingScale > 0) {
@@ -1293,7 +1295,14 @@ const mech = {
}
}
}
wake(mob);
if (mod.isFreezeMobs) {
for (let i = 0, len = mob.length; i < len; ++i) {
Matter.Sleeping.set(mob[i], false)
mobs.statusSlow(mob[i], 60)
}
} else {
wake(mob);
}
wake(body);
wake(bullet);
for (let i = 0, len = cons.length; i < len; i++) {
@@ -1396,10 +1405,6 @@ const mech = {
effect: () => {
mech.fieldShieldingScale = 0;
mech.grabPowerUpRange2 = 10000000
// mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
// mech.fieldMeterColor = "#0af"
// mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
// mech.calculateFieldThreshold();
mech.hold = function() {
const wave = Math.sin(mech.cycle * 0.022);
mech.fieldRange = 170 + 12 * wave
@@ -1643,137 +1648,10 @@ const mech = {
} else if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
mech.grabPowerUp();
mech.lookForPickUp();
const DRAIN = 0.0012
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
//calculate laser collision
let best;
let range = mod.isPlasmaRange * (120 + (mech.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(mech.cycle * 0.3);
// const dir = mech.angle // + 0.04 * (Math.random() - 0.5)
const path = [{
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
},
{
x: mech.pos.x + range * Math.cos(mech.angle),
y: mech.pos.y + range * Math.sin(mech.angle)
}
];
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[j],
v2: vertices[j + 1]
};
}
}
}
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[0],
v2: vertices[len]
};
}
}
}
};
//check for collisions
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
vertexCollision(path[0], path[1], mob);
vertexCollision(path[0], path[1], map);
vertexCollision(path[0], path[1], body);
if (best.dist2 != Infinity) { //if hitting something
path[path.length - 1] = {
x: best.x,
y: best.y
};
if (best.who.alive) {
const dmg = 0.8 * b.dmgScale; //********** SCALE DAMAGE HERE *********************
best.who.damage(dmg);
best.who.locatePlayer();
//push mobs away
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { //friction
x: best.who.velocity.x * 0.7,
y: best.who.velocity.y * 0.7
});
//draw mob damage circle
game.drawList.push({
x: path[1].x,
y: path[1].y,
radius: Math.sqrt(dmg) * 50,
color: "rgba(255,0,255,0.2)",
time: game.drawTime * 4
});
} else if (!best.who.isStatic) {
//push blocks away
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.007 * Math.sqrt(Math.sqrt(best.who.mass)))
Matter.Body.applyForce(best.who, path[1], force)
}
}
//draw blowtorch laser beam
ctx.strokeStyle = "rgba(255,0,255,0.1)"
ctx.lineWidth = 14
ctx.beginPath();
ctx.moveTo(path[0].x, path[0].y);
ctx.lineTo(path[1].x, path[1].y);
ctx.stroke();
ctx.strokeStyle = "#f0f";
ctx.lineWidth = 2
ctx.stroke();
//draw electricity
const Dx = Math.cos(mech.angle);
const Dy = Math.sin(mech.angle);
let x = mech.pos.x + 20 * Dx;
let y = mech.pos.y + 20 * Dy;
ctx.beginPath();
ctx.moveTo(x, y);
const step = Vector.magnitude(Vector.sub(path[0], path[1])) / 10
for (let i = 0; i < 8; i++) {
x += step * (Dx + 1.5 * (Math.random() - 0.5))
y += step * (Dy + 1.5 * (Math.random() - 0.5))
ctx.lineTo(x, y);
}
ctx.lineWidth = 2 * Math.random();
ctx.stroke();
if (mod.isExtruder) {
b.extruder();
} else {
b.plasma();
}
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
mech.pickUp();
@@ -2270,7 +2148,7 @@ const mech = {
}
}
if (mod.isPilotFreeze) {
if (mod.isFreezeMobs) {
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, mech.fieldPosition)) < mech.fieldRadius) {
mobs.statusSlow(mob[i], 120)

View File

@@ -101,6 +101,16 @@ const spawn = {
level.bossKilled = true;
level.exit.x = 5500;
level.exit.y = -330;
//pull in particles
for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65)
const pushUp = Vector.add(velocity, { x: 0, y: -0.3 })
Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp));
}
//ramp up damage
for (let i = 0; i < 5; i++) level.difficultyIncrease(game.difficultyMode)
};
me.onDamage = function() {};
me.cycle = 420;
@@ -132,7 +142,7 @@ const spawn = {
Matter.Body.scale(this, 10, 10);
Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger
if (!this.isShielded) spawn.shield(this, x, y, 1); // regen shield to also prevent stun
for (let i = 0, len = body.length; i < len; ++i) {
for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally
if (body[i].position.x > this.position.x) {
body[i].force.x = 0.5
} else {

View File

@@ -1,17 +1,43 @@
******************************************************** NEXT PATCH ********************************************************
catabolism - 2% (was 2.3%) of max health removed
many worlds - spawns 2 rerolls (was 1)
pilot wave field- now has access to several mods that normally require other fields
this plus the fragmenting block mod are a big buff for late game pilot wave
let me know if it is too strong
wave beam damage works better vs. high mass mobs
also more damage and ammo
mod plasma torch: extruder - plasma torch ejects a thin hot wire, does more damage, but drains more energy
mod: Bose Einstein condensate - freeze mobs inside your field
pilot wave, negative mass field, time dilation field
difficulty - after you clear the finalBoss, difficulty increase per level is now lower
but, when the finalBoss dies difficulty immediately increases greatly
difficulty used to work like this:
(+1 per level) 0,1,2,3,4,5,6,7,8,9,10, (final boss dies)
(+2,3,4 per level) 12,14,16,19,22,25,29,33,37,41, (final boss dies)
(+4 per level) 44,48,52,56 ...
difficulty works like this now:
(+1 per level) 0,1,2,3,4,5,6,7,8,9,10, (final boss dies +5)
(+2 per level) 17,19,21,23,25,27,29,31,33,35, (final boss dies +5)
(+3 per level) 43,46,49,52 ...
difficulty mode scales these numbers
easy: x1, normal: x2, hard: x4, why: x6
each time difficulty increases:
game.dmgScale = 0.38 * game.difficulty //damage done by mobs increases each level
b.dmgScale *= 0.93; // your damage goes down
game.healScale = 1 / (1 + game.difficulty * 0.06) //healing goes down
if (game.accelScale < 5) game.accelScale *= 1.02 //mob acceleration increases each level, but is capped
if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.98 //mob cycles between looks decreases each level, but is capped
if (game.CDScale > 0.2) game.CDScale *= 0.97 //mob ability cooldown time decreases each level, but is capped
mod nano-scale: bot prototypes - upgrade a bot type and build 2 of that bot
mod nano-scale: bot manufacturing - build 3 random bots
these mods don't show up in custom
******************************************************** BUGS ********************************************************
entering custom, after dieing makes all mods look white (not disabled)
this goes away after clicking something so it seems to be only a graphical issue
(not able to reproduce, might be fixed) possible bug with neutron rewind
status doesn't apply correctly for spawned neutron bombs that are stuck to a shield
also saw neutron bombs bounce off shield, for normal bullets
@@ -42,6 +68,17 @@ mod and mob are too similar
******************************************************** TODO ********************************************************
mod plasma torch: extruder speed is improved
color/highlight field or gun mods in selection menu (or custom)
to show that they are special
mechanic - Your energy regen is only active when field and gun have not been used for 5 seconds.
divide supercapacitator into 2-3 stacks
smaller effect for stack 1, but overall bigger effect at 3
be able to open up custom mode in the normal game
might need to be rebuilt from scratch
while in through testing mode?