laser mod

mod: stimulated emission - 8% chance to duplicate power ups
laser mod: diffuse beam - laser is wide but doesn't reflect, 150% damage and energy drain
This commit is contained in:
landgreen
2020-10-03 07:44:27 -07:00
parent 0a15a7748a
commit b22bd12529
8 changed files with 321 additions and 226 deletions

View File

@@ -376,6 +376,164 @@ const b = {
}
}
},
laser(where = {
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
}, angle = mech.angle, dmg = mod.laserDamage, reflections = mod.laserReflections, isThickBeam = false) {
const reflectivity = 1 - 1 / (reflections * 1.5)
let damage = b.dmgScale * dmg
let best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
const color = "#f00";
const range = 3000;
const path = [{
x: where.x,
y: where.y
},
{
x: where.x + range * Math.cos(angle),
y: where.y + range * Math.sin(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]
};
}
}
}
};
const checkForCollisions = function () {
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
vertexCollision(path[path.length - 2], path[path.length - 1], mob);
vertexCollision(path[path.length - 2], path[path.length - 1], map);
vertexCollision(path[path.length - 2], path[path.length - 1], body);
};
const laserHitMob = function () {
if (best.who.alive) {
best.who.damage(damage);
best.who.locatePlayer();
ctx.fillStyle = color; //draw mob damage circle
ctx.beginPath();
ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(damage) * 100, 0, 2 * Math.PI);
ctx.fill();
}
};
const reflection = function () { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
const r = Vector.normalise(Vector.sub(d, nn));
path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]);
};
checkForCollisions();
let lastBestOdd
let lastBestEven = best.who //used in hack below
if (best.dist2 !== Infinity) { //if hitting something
path[path.length - 1] = {
x: best.x,
y: best.y
};
laserHitMob();
for (let i = 0; i < reflections; i++) {
reflection();
checkForCollisions();
if (best.dist2 !== Infinity) { //if hitting something
lastReflection = best
path[path.length - 1] = {
x: best.x,
y: best.y
};
damage *= reflectivity
laserHitMob();
//I'm not clear on how this works, but it gets ride of a bug where the laser reflects inside a block, often vertically.
//I think it checks to see if the laser is reflecting off a different part of the same block, if it is "inside" a block
if (i % 2) {
if (lastBestOdd === best.who) break
} else {
lastBestOdd = best.who
if (lastBestEven === best.who) break
}
} else {
break
}
}
}
if (isThickBeam) {
ctx.strokeStyle = color;
ctx.lineWidth = 8
ctx.globalAlpha = 0.5;
for (let i = 1, len = path.length; i < len; ++i) {
ctx.beginPath();
ctx.moveTo(path[i - 1].x, path[i - 1].y);
ctx.lineTo(path[i].x, path[i].y);
ctx.stroke();
}
ctx.globalAlpha = 1;
} else {
ctx.strokeStyle = color;
ctx.lineWidth = 2
ctx.lineDashOffset = 300 * Math.random()
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
for (let i = 1, len = path.length; i < len; ++i) {
ctx.beginPath();
ctx.moveTo(path[i - 1].x, path[i - 1].y);
ctx.lineTo(path[i].x, path[i].y);
ctx.stroke();
ctx.globalAlpha *= reflectivity; //reflections are less intense
}
ctx.setLineDash([0, 0]);
ctx.globalAlpha = 1;
}
},
mine(where, velocity, angle = 0, isAmmoBack = false) {
const bIndex = bullet.length;
bullet[bIndex] = Bodies.rectangle(where.x, where.y, 45, 16, {
@@ -1544,11 +1702,9 @@ const b = {
do() {
//check for damage
if (!mech.isCloak && !mech.isBodiesAsleep) { //if time dilation isn't active
// q = Matter.Query.point(mob, this.position)
// q = Matter.Query.collides(this, mob)
const size = 30
const size = 33
q = Matter.Query.region(mob, {
min: {
x: this.position.x - size,
@@ -1560,8 +1716,8 @@ const b = {
}
})
for (let i = 0; i < q.length; i++) {
mobs.statusStun(q[i], this.isUpgraded ? 240 : 120)
const dmg = 1 * b.dmgScale * (this.isUpgraded ? 2.25 : 1)
mobs.statusStun(q[i], 180)
const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.25 : 1) * (mod.isCrit ? 4 : 1)
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
@@ -3066,159 +3222,40 @@ const b = {
ammoPack: Infinity,
have: false,
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
holdDamage: 1,
holdCount: 0,
healthLost: 0,
fire() {
mech.fireCDcycle = mech.cycle
const reflectivity = 1 - 1 / (mod.laserReflections * 1.5)
let damage = b.dmgScale * mod.laserDamage * this.holdDamage
if (mech.energy < mod.laserFieldDrain) {
mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy
} else {
mech.fireCDcycle = mech.cycle
mech.energy -= mech.fieldRegen + mod.laserFieldDrain * mod.isLaserDiode
let best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
const color = "#f00";
const range = 3000;
const path = [{
if (mod.isWideLaser) {
const off = 8
const dmg = 0.6 * mod.laserDamage // 5 * 0.4 = 200% more damage
// ctx.lineCap = 'butt';
b.laser({
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]
};
}
}
}
};
const checkForCollisions = function () {
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
vertexCollision(path[path.length - 2], path[path.length - 1], mob);
vertexCollision(path[path.length - 2], path[path.length - 1], map);
vertexCollision(path[path.length - 2], path[path.length - 1], body);
};
const laserHitMob = function () {
if (best.who.alive) {
best.who.damage(damage);
best.who.locatePlayer();
ctx.fillStyle = color; //draw mob damage circle
ctx.beginPath();
ctx.arc(path[path.length - 1].x, path[path.length - 1].y, Math.sqrt(damage) * 100, 0, 2 * Math.PI);
ctx.fill();
}
};
const reflection = function () { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
const r = Vector.normalise(Vector.sub(d, nn));
path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]);
};
checkForCollisions();
let lastBestOdd
let lastBestEven = best.who //used in hack below
if (best.dist2 !== Infinity) {
//if hitting something
path[path.length - 1] = {
x: best.x,
y: best.y
};
laserHitMob();
for (let i = 0; i < mod.laserReflections; i++) {
reflection();
checkForCollisions();
if (best.dist2 !== Infinity) { //if hitting something
lastReflection = best
path[path.length - 1] = {
x: best.x,
y: best.y
};
damage *= reflectivity
laserHitMob();
//I'm not clear on how this works, but it gets ride of a bug where the laser reflects inside a block, often vertically.
//I think it checks to see if the laser is reflecting off a different part of the same block, if it is "inside" a block
if (i % 2) {
if (lastBestOdd === best.who) break
} else {
lastBestOdd = best.who
if (lastBestEven === best.who) break
}
} else {
break
}
}, mech.angle, dmg, 0, true)
for (let i = 1; i < 3; i++) {
b.laser(Vector.add({
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
}, {
x: i * off * Math.cos(mech.angle + Math.PI / 2),
y: i * off * Math.sin(mech.angle + Math.PI / 2)
}), mech.angle, dmg, 0, true)
b.laser(Vector.add({
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
}, {
x: i * off * Math.cos(mech.angle - Math.PI / 2),
y: i * off * Math.sin(mech.angle - Math.PI / 2)
}), mech.angle, dmg, 0, true)
}
// ctx.lineCap = 'round';
} else {
b.laser()
}
ctx.fillStyle = color;
ctx.strokeStyle = color;
ctx.lineWidth = 2 * this.holdDamage;
ctx.lineDashOffset = 300 * Math.random()
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
for (let i = 1, len = path.length; i < len; ++i) {
ctx.beginPath();
ctx.moveTo(path[i - 1].x, path[i - 1].y);
ctx.lineTo(path[i].x, path[i].y);
ctx.stroke();
ctx.globalAlpha *= reflectivity; //reflections are less intense
}
ctx.setLineDash([0, 0]);
ctx.globalAlpha = 1;
}
}
},

View File

@@ -153,8 +153,8 @@ function collisionChecks(event) {
const choose = have[Math.floor(Math.random() * have.length)]
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> ejected by Bayesian statistics`, 600) //message about what mod was lost
for (let i = 0; i < mod.mods[choose].count; i++) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
mod.mods[choose].count = 0;
mod.mods[choose].remove(); // remove a random mod form the list of mods you have
mod.mods[choose].count = 0;
mod.mods[choose].isLost = true;
game.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod

View File

@@ -978,6 +978,43 @@ const game = {
}
ctx.globalAlpha = 1;
},
powerUpBonus() { //draws crackle effect for bonus power ups
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
if (powerUp[i].isBonus && Math.random() < 0.1) {
//draw electricity
const mag = 5 + powerUp[i].size / 5
let unit = Vector.rotate({
x: mag,
y: mag
}, 2 * Math.PI * Math.random())
let path = {
x: powerUp[i].position.x + unit.x,
y: powerUp[i].position.y + unit.y
}
ctx.beginPath();
ctx.moveTo(path.x, path.y);
for (let i = 0; i < 6; i++) {
unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
path = Vector.add(path, unit)
ctx.lineTo(path.x, path.y);
}
ctx.lineWidth = 0.5 + 2 * Math.random();
ctx.strokeStyle = "#000"
ctx.stroke();
}
}
// ctx.globalAlpha = 1;
},
// map: function() {
// ctx.beginPath();
// for (let i = 0, len = map.length; i < len; ++i) {

View File

@@ -62,6 +62,7 @@ window.addEventListener('load', (event) => {
for (const property in set) {
// console.log(set[property], property);
set[property] = set[property].replace(/%20/g, " ")
set[property] = set[property].replace(/%CE%A8/g, "Ψ")
if (property === "field") {
let found = false

View File

@@ -17,9 +17,9 @@ const level = {
// mech.isCloak = true;
// mech.setField("metamaterial cloaking")
// b.giveGuns("laser")
for (let i = 0; i < 1; i++) {
mod.giveMod("orbital-bot");
}
// for (let i = 0; i < 1; i++) {
// mod.giveMod("diffuse beam");
// }
// mod.giveMod("orbit-bot upgrade")
@@ -80,7 +80,10 @@ const level = {
//******************************************************************************************************************
//******************************************************************************************************************
testing() {
const button = level.button(200, -700)
level.custom = () => {
button.query();
button.draw();
level.playerExitCheck();
};
level.customTopLayer = () => {};
@@ -147,7 +150,7 @@ const level = {
// spawn.sniper(1800, -120)
// spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500)
spawn.starter(1600, -500, 60)
spawn.starter(1600, -500, 160)
// spawn.powerUpBoss(1600, -500)
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
@@ -4206,18 +4209,24 @@ const level = {
width: width,
height: 20,
query() {
// if (Matter.Query.collides(buttonSensor, body).length === 0 && Matter.Query.collides(buttonSensor, [player]).length === 0) {
if (Matter.Query.region(body, this).length === 0 && Matter.Query.region([player], this).length === 0) {
this.isUp = true;
} else {
this.isUp = false;
// const list = Matter.Query.collides(buttonSensor, body)
// if (list.length > 0) {
// Matter.Body.setVelocity(list[0].bodyB, {
// x: 0,
// y: 0
// });
// if (this.isUp === true) {
// const list = Matter.Query.region(body, this)
// console.log(list)
// if (list.length > 0) {
// Matter.Body.setPosition(list[0], {
// x: this.min.x + width / 2,
// y: list[0].position.y
// })
// Matter.Body.setVelocity(list[0], {
// x: 0,
// y: 0
// });
// }
// }
this.isUp = false;
}
},
draw() {

View File

@@ -261,7 +261,7 @@ const mod = {
},
{
name: "Ψ(t) collapse",
description: "<strong>50%</strong> decreased <strong>delay</strong> after firing<br>if you have no <strong class='color-r'>rerolls</strong>",
description: "<strong>60%</strong> decreased <strong>delay</strong> after firing<br>if you have no <strong class='color-r'>rerolls</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -270,7 +270,7 @@ const mod = {
requires: "no rerolls",
effect() {
mod.isRerollHaste = true;
mod.rerollHaste = 0.5;
mod.rerollHaste = 0.4;
b.setFireCD();
},
remove() {
@@ -298,7 +298,7 @@ const mod = {
},
{
name: "auto-loading heuristics",
description: "<strong>25%</strong> decreased <strong>delay</strong> after firing",
description: "<strong>30%</strong> decreased <strong>delay</strong> after firing",
maxCount: 9,
count: 0,
allowed() {
@@ -306,7 +306,7 @@ const mod = {
},
requires: "",
effect() {
mod.fireRate *= 0.75
mod.fireRate *= 0.7
b.setFireCD();
},
remove() {
@@ -642,7 +642,7 @@ const mod = {
},
{
name: "orbital-bot",
description: "a bot is locked in <strong>orbit</strong> around you<br><strong class='color-d'>damages</strong> and <strong>stuns</strong> mobs on <strong>contact</strong>",
description: "a bot is locked in <strong>orbit</strong> around you<br><strong>stuns</strong> and <strong class='color-d'>damages</strong> mobs on <strong>contact</strong>",
maxCount: 9,
count: 0,
allowed() {
@@ -659,7 +659,7 @@ const mod = {
},
{
name: "orbital-bot upgrade",
description: "<strong>125%</strong> increased <strong class='color-d'>damage</strong> and <strong>stun</strong> duration<br><em>applies to all current and future orbit-bots</em>",
description: "<strong>125%</strong> increased <strong class='color-d'>damage</strong><br><em>applies to all current and future orbit-bots</em>",
maxCount: 1,
count: 0,
allowed() {
@@ -897,7 +897,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.isStunField || mod.isPulseStun || mod.isNeutronStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.isPilotFreeze || mod.haveGunCheck("ice IX") || mod.isCloakStun
return mod.isStunField || mod.isPulseStun || mod.isNeutronStun || 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
},
requires: "a freezing or stunning effect",
effect() {
@@ -1201,48 +1201,37 @@ const mod = {
requires: "",
effect: () => {
mod.isBayesian = true
//change power up draw
game.draw.powerUp = function () {
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
if (powerUp[i].isBayesian && Math.random() < 0.1) {
//draw electricity
const mag = 5 + powerUp[i].size / 5
let unit = Vector.rotate({
x: mag,
y: mag
}, 2 * Math.PI * Math.random())
let path = {
x: powerUp[i].position.x + unit.x,
y: powerUp[i].position.y + unit.y
}
ctx.beginPath();
ctx.moveTo(path.x, path.y);
for (let i = 0; i < 6; i++) {
unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
path = Vector.add(path, unit)
ctx.lineTo(path.x, path.y);
}
ctx.lineWidth = 0.5 + 2 * Math.random();
ctx.strokeStyle = "#000"
ctx.stroke();
}
}
// ctx.globalAlpha = 1;
}
mod.duplicateChance += 0.17
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
},
remove() {
if (mod.isBayesian) {
mod.duplicateChance -= 0.17
if (mod.duplicateChance < 0) mod.duplicateChance = 0
}
mod.isBayesian = false
game.draw.powerUp = game.draw.powerUpNormal
if (mod.duplicateChance)
if (!mod.duplicateChance) game.draw.powerUp = game.draw.powerUpNormal
}
},
{
name: "stimulated emission",
description: "<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong>",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect: () => {
mod.duplicateChance += 0.08
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
},
remove() {
mod.duplicateChance -= 0.08 * this.count
if (!mod.duplicateChance) game.draw.powerUp = game.draw.powerUpNormal
}
},
{
@@ -2345,22 +2334,40 @@ const mod = {
},
{
name: "specular reflection",
description: "<strong>laser</strong> beams gain <strong>1</strong> reflection<br><strong>50%</strong> laser <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain",
description: "<strong>laser</strong> beams gain <strong>1</strong> reflection<br>increase <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain by <strong>50%</strong>",
maxCount: 9,
count: 0,
allowed() {
return mod.haveGunCheck("laser")
return mod.haveGunCheck("laser") && !mod.isWideLaser
},
requires: "laser",
requires: "laser, not wide beam",
effect() {
mod.laserReflections++;
mod.laserDamage += 0.06; //base is 0.12
mod.laserFieldDrain += 0.0008 //base is 0.002
mod.laserDamage += 0.08; //base is 0.12
mod.laserFieldDrain += 0.0006 //base is 0.002
},
remove() {
mod.laserReflections = 2;
mod.laserDamage = 0.12;
mod.laserFieldDrain = 0.0016;
mod.laserDamage = 0.16;
mod.laserFieldDrain = 0.0012;
}
},
{
name: "diffuse beam",
description: "<strong>laser</strong> beam is <strong>wider</strong> but doesn't <strong>reflect</strong><br>increase <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> drain by <strong>150%</strong>",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("laser") && mod.laserReflections < 3
},
requires: "laser, not specular reflection",
effect() {
mod.isWideLaser = true
mod.laserFieldDrain = 0.0012 * 2.5 //base is 0.002
},
remove() {
mod.isWideLaser = false
mod.laserFieldDrain = 0.0012;
}
},
// {
@@ -2438,7 +2445,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.isStunField || mod.oneSuperBall || mod.isCloakStun
return mod.isStunField || mod.oneSuperBall || mod.isCloakStun || mod.orbitBotCount > 1
},
requires: "flux pinning or super ball<br>or flashbang",
effect() {
@@ -2965,5 +2972,6 @@ const mod = {
healMaxEnergyBonus: null,
aimDamage: null,
isNoFireDefense: null,
isNoFireDamage: null
isNoFireDamage: null,
duplicateChance: null
}

View File

@@ -577,9 +577,9 @@ const powerUps = {
!(mod.isEnergyNoAmmo && target === 'ammo')
) {
powerUps.directSpawn(x, y, target, moving, mode, size)
if (mod.isBayesian && Math.random() < 0.17) {
if (mod.duplicateChance && Math.random() < mod.duplicateChance) {
powerUps.directSpawn(x, y, target, moving, mode)
powerUp[powerUp.length - 1].isBayesian = true
powerUp[powerUp.length - 1].isBonus = true
}
}
},

View File

@@ -1,16 +1,21 @@
mod: orbital-bot - back to just 1 bot, but the bot can stun and hit mobs from a larger range
mod: stimulated emission - 8% chance to duplicate power ups
laser mod: diffuse beam - laser is wide but doesn't reflect, 150% damage and energy drain
************** TODO - n-gon **************
Ψ(t) collapse doesn't seem to work properly on custom links
write a function that returns collisions
mod: laser gets increased damage with each reflection
mod: laser is 3 thick beams that look like one, but can separate into three at corners
mod set a max speed cap based on distance from player while field is active
mod for a field, or bot?
name: something about speed of light being the top speed
vacuum bomb applies status effect to mobs that makes blocks attracted to them
mod: take less harm if you are moving fast
require squirrel cage rotor
mod: laser gets increased damage with each reflection
mod: laser is 3 thick beams that look like one, but can separate into three at corners
getting stuck above a mob can immobilize player
just allow player to jump on mobs again?
occurs with Pauli exclusion, and time dilation field immunity - mod time-like world line
@@ -55,8 +60,6 @@ a bot that eats up health and ammo, but poops a reroll after picking up 2 power
disable crystalized armor?
could convert rerolls, ammo, and health into mods instead
mod: radiation effects can spread to nearby mobs
mod: foam is attracted to mobs