throwing blocks are buffed
thrown blocks can damage intangible mobs for a couple seconds after they are thrown they are set to act like bullets for a few seconds after being thrown all blocks do 50% more damage to mobs and 50% longer stun blocks do more damage vs. shielded mobs (damage penalty is 40%, was 66%)) mass driver - damage increase set to 200% (up from 100%) negative mass field can lift blocks twice as heavy as before with little movement reduction tech: flywheel - when mobs die their body is spun and flung at nearby mobs requires mass driver, no other mob death tech
This commit is contained in:
25
js/bullet.js
25
js/bullet.js
@@ -2301,17 +2301,32 @@ const b = {
|
|||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
Matter.Body.setVelocity(bullet[me], velocity);
|
Matter.Body.setVelocity(bullet[me], velocity);
|
||||||
},
|
},
|
||||||
|
targetedBlock(who, isSpin = false, speed = 50 - Math.min(20, who.mass * 2), range = 1600) {
|
||||||
|
let closestMob, dist
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (who !== mob[i]) {
|
||||||
|
dist = Vector.magnitude(Vector.sub(who.position, mob[i].position));
|
||||||
|
if (dist < range && Matter.Query.ray(map, who.position, mob[i].position).length === 0) { //&& Matter.Query.ray(body, position, mob[i].position).length === 0
|
||||||
|
closestMob = mob[i]
|
||||||
|
range = dist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (closestMob) {
|
||||||
|
const where = Vector.add(closestMob.position, Vector.mult(closestMob.velocity, dist / 60))
|
||||||
|
const velocity = Vector.mult(Vector.normalise(Vector.sub(where, who.position)), speed)
|
||||||
|
velocity.y -= Math.abs(who.position.x - closestMob.position.x) / 150; //gives an arc, but not a good one
|
||||||
|
Matter.Body.setVelocity(who, velocity);
|
||||||
|
if (isSpin) Matter.Body.setAngularVelocity(who, 2 + 2 * Math.random() * (Math.random() < 0.5 ? -1 : 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true) {
|
targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true) {
|
||||||
const targets = [] //target nearby mobs
|
const targets = [] //target nearby mobs
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
// if (mob[i].isDropPowerUp) {
|
|
||||||
const dist = Vector.magnitude(Vector.sub(position, mob[i].position));
|
const dist = Vector.magnitude(Vector.sub(position, mob[i].position));
|
||||||
if (dist < range &&
|
if (dist < range && Matter.Query.ray(map, position, mob[i].position).length === 0 && Matter.Query.ray(body, position, mob[i].position).length === 0) {
|
||||||
Matter.Query.ray(map, position, mob[i].position).length === 0 &&
|
|
||||||
Matter.Query.ray(body, position, mob[i].position).length === 0) {
|
|
||||||
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles
|
targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
if (targets.length > 0) { // aim near a random target in array
|
if (targets.length > 0) { // aim near a random target in array
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ function collisionChecks(event) {
|
|||||||
if (obj.classType === "body" && obj.speed > 6) {
|
if (obj.classType === "body" && obj.speed > 6) {
|
||||||
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) {
|
||||||
let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
|
let dmg = 0.075 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
|
||||||
if (mob[k].isShielded) dmg *= 0.35
|
if (mob[k].isShielded) dmg *= 0.6
|
||||||
mob[k].damage(dmg, true);
|
mob[k].damage(dmg, true);
|
||||||
if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp) {
|
if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp) {
|
||||||
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
|
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
|
||||||
@@ -196,7 +196,7 @@ function collisionChecks(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const stunTime = dmg / Math.sqrt(obj.mass)
|
const stunTime = dmg / Math.sqrt(obj.mass)
|
||||||
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
|
if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
|
||||||
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||||
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
||||||
obj.hasFragmented = true;
|
obj.hasFragmented = true;
|
||||||
|
|||||||
11
js/level.js
11
js/level.js
@@ -16,7 +16,7 @@ const level = {
|
|||||||
// simulation.zoomScale = 1000;
|
// simulation.zoomScale = 1000;
|
||||||
// simulation.setZoom();
|
// simulation.setZoom();
|
||||||
// m.setField("nano-scale manufacturing")
|
// m.setField("nano-scale manufacturing")
|
||||||
// b.giveGuns("shotgun")
|
// b.giveGuns("laser")
|
||||||
// tech.isExplodeRadio = true
|
// tech.isExplodeRadio = true
|
||||||
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
||||||
// tech.giveTech("incendiary ammunition")
|
// tech.giveTech("incendiary ammunition")
|
||||||
@@ -1111,13 +1111,16 @@ const level = {
|
|||||||
// spawn.grower(1900, -500)
|
// spawn.grower(1900, -500)
|
||||||
// spawn.pulsarBoss(1900, -500)
|
// spawn.pulsarBoss(1900, -500)
|
||||||
// spawn.shooterBoss(1900, -500)
|
// spawn.shooterBoss(1900, -500)
|
||||||
spawn.spawns(2900, -500)
|
|
||||||
// spawn.launcherBoss(1200, -500)
|
// spawn.launcherBoss(1200, -500)
|
||||||
// spawn.laserTargetingBoss(1600, -400)
|
// spawn.laserTargetingBoss(1600, -400)
|
||||||
// spawn.striker(4600, -500)
|
spawn.striker(1600, -500)
|
||||||
|
spawn.striker(1600, -500)
|
||||||
|
spawn.striker(1600, -500)
|
||||||
// spawn.laserTargetingBoss(1700, -120)
|
// spawn.laserTargetingBoss(1700, -120)
|
||||||
// spawn.bomberBoss(1400, -500)
|
// spawn.bomberBoss(1400, -500)
|
||||||
// spawn.sniper(1800, -120)
|
spawn.sniper(1800, -120)
|
||||||
|
spawn.sniper(1800, -120)
|
||||||
|
spawn.sniper(2800, -120)
|
||||||
// spawn.streamBoss(1600, -500)
|
// spawn.streamBoss(1600, -500)
|
||||||
// spawn.orbitalBoss(1600, -500)
|
// spawn.orbitalBoss(1600, -500)
|
||||||
// spawn.spawnerBossCulture(1600, -500)
|
// spawn.spawnerBossCulture(1600, -500)
|
||||||
|
|||||||
11
js/mob.js
11
js/mob.js
@@ -1073,10 +1073,7 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
if (tech.isBotSpawnerReset) {
|
if (tech.isBotSpawnerReset) {
|
||||||
for (let i = 0, len = bullet.length; i < len; i++) {
|
for (let i = 0, len = bullet.length; i < len; i++) {
|
||||||
if (bullet[i].botType && bullet[i].endCycle !== Infinity) {
|
if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun
|
||||||
console.log(bullet[i].endCycle)
|
|
||||||
bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Math.random() < tech.botSpawner) {
|
if (Math.random() < tech.botSpawner) {
|
||||||
@@ -1199,9 +1196,13 @@ const mobs = {
|
|||||||
};
|
};
|
||||||
shrink(body[len], 7 + 4 * Math.random())
|
shrink(body[len], 7 + 4 * Math.random())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Matter.World.remove(engine.world, this);
|
Matter.World.remove(engine.world, this);
|
||||||
mob.splice(i, 1);
|
mob.splice(i, 1);
|
||||||
|
if (tech.isMobBlockFling) b.targetedBlock(body[body.length - 1], true)
|
||||||
|
} else {
|
||||||
|
Matter.World.remove(engine.world, this);
|
||||||
|
mob.splice(i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mob[i].alertRange2 = Math.pow(mob[i].radius * 3 + 550, 2);
|
mob[i].alertRange2 = Math.pow(mob[i].radius * 3 + 550, 2);
|
||||||
|
|||||||
10
js/player.js
10
js/player.js
@@ -1145,14 +1145,14 @@ const m = {
|
|||||||
m.fieldCDcycle = m.cycle + 15;
|
m.fieldCDcycle = m.cycle + 15;
|
||||||
m.isHolding = false;
|
m.isHolding = false;
|
||||||
//bullet-like collisions
|
//bullet-like collisions
|
||||||
m.holdingTarget.collisionFilter.category = cat.body; //cat.bullet;
|
m.holdingTarget.collisionFilter.category = cat.bullet; //cat.body;
|
||||||
m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
|
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
|
//check every second to see if player is away from thrown body, and make solid
|
||||||
const solid = function(that) {
|
const solid = function(that) {
|
||||||
const dx = that.position.x - player.position.x;
|
const dx = that.position.x - player.position.x;
|
||||||
const dy = that.position.y - player.position.y;
|
const dy = that.position.y - player.position.y;
|
||||||
if (dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
|
if (dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
|
||||||
// that.collisionFilter.category = cat.body; //make solid
|
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
|
that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
|
||||||
} else {
|
} else {
|
||||||
setTimeout(solid, 25, that);
|
setTimeout(solid, 25, that);
|
||||||
@@ -1650,14 +1650,14 @@ const m = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "negative mass field",
|
name: "negative mass field",
|
||||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>50%</strong><br><strong>blocks</strong> held by the field have a lower <strong>mass</strong>",
|
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br><strong>blocks</strong> held by the field have a lower <strong>mass</strong>",
|
||||||
fieldDrawRadius: 0,
|
fieldDrawRadius: 0,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
m.fieldFire = true;
|
m.fieldFire = true;
|
||||||
m.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
|
||||||
m.fieldMeterColor = "#333"
|
m.fieldMeterColor = "#333"
|
||||||
m.eyeFillColor = m.fieldMeterColor
|
m.eyeFillColor = m.fieldMeterColor
|
||||||
m.fieldHarmReduction = 0.5;
|
m.fieldHarmReduction = 0.55;
|
||||||
m.fieldDrawRadius = 0;
|
m.fieldDrawRadius = 0;
|
||||||
|
|
||||||
m.hold = function() {
|
m.hold = function() {
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ const spawn = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const len = (this.totalCycles / 400 + simulation.difficulty / 2 - 30) / 15
|
const len = (this.totalCycles / 400 + simulation.difficulty / 2 - 30) / 15
|
||||||
// console.log(len)
|
|
||||||
for (let i = 0; i < len; i++) {
|
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))
|
||||||
}
|
}
|
||||||
|
|||||||
37
js/tech.js
37
js/tech.js
@@ -833,7 +833,7 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
allowed() {
|
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
|
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
|
||||||
},
|
},
|
||||||
requires: "an explosive damage source, no other mob death tech",
|
requires: "an explosive damage source, no other mob death tech",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -850,7 +850,7 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner
|
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
|
||||||
},
|
},
|
||||||
requires: "no other mob death tech",
|
requires: "no other mob death tech",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -867,7 +867,7 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner
|
return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling
|
||||||
},
|
},
|
||||||
requires: "no other mob death tech",
|
requires: "no other mob death tech",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -887,7 +887,7 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner
|
return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner || tech.isMobBlockFling
|
||||||
},
|
},
|
||||||
requires: "any mob death tech",
|
requires: "any mob death tech",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -944,7 +944,7 @@
|
|||||||
frequency: 1,
|
frequency: 1,
|
||||||
isBotTech: true,
|
isBotTech: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob //b.totalBots() > 0 &&
|
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob && !tech.isMobBlockFling
|
||||||
},
|
},
|
||||||
requires: "no other mob death tech",
|
requires: "no other mob death tech",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -1380,16 +1380,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mass driver",
|
name: "mass driver",
|
||||||
description: "increase <strong>block</strong> collision <strong class='color-d'>damage</strong> by <strong>100%</strong><br>charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong>",
|
description: "increase <strong>block</strong> collision <strong class='color-d'>damage</strong> by <strong>200%</strong><br>charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return m.fieldUpgrades[m.fieldMode].name !== "wormhole"
|
return m.fieldUpgrades[m.fieldMode].name !== "wormhole"
|
||||||
},
|
},
|
||||||
requires: "not wormhole",
|
requires: "not wormhole",
|
||||||
effect() {
|
effect() {
|
||||||
tech.throwChargeRate = 2
|
tech.throwChargeRate = 3
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
tech.throwChargeRate = 1
|
tech.throwChargeRate = 1
|
||||||
@@ -1413,6 +1413,24 @@
|
|||||||
tech.isBlockPowerUps = false
|
tech.isBlockPowerUps = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "flywheel",
|
||||||
|
description: "after a mob <strong>dies</strong> its body is <strong>spun</strong> and <strong>flung</strong><br>in the general direction of a nearby mob",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 4,
|
||||||
|
frequencyDefault: 4,
|
||||||
|
allowed() {
|
||||||
|
return tech.throwChargeRate > 1 && !tech.nailsDeathMob && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner
|
||||||
|
},
|
||||||
|
requires: "mass driver, no other mob death tech",
|
||||||
|
effect() {
|
||||||
|
tech.isMobBlockFling = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isMobBlockFling = false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "inelastic collision",
|
name: "inelastic collision",
|
||||||
description: "while you are <strong>holding</strong> a <strong>block</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>85%</strong>",
|
description: "while you are <strong>holding</strong> a <strong>block</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>85%</strong>",
|
||||||
@@ -6414,5 +6432,6 @@
|
|||||||
frequencyResonance: null,
|
frequencyResonance: null,
|
||||||
isAlwaysFire: null,
|
isAlwaysFire: null,
|
||||||
isDroneRespawn: null,
|
isDroneRespawn: null,
|
||||||
deathSpawns: null
|
deathSpawns: null,
|
||||||
|
isMobBlockFling: null
|
||||||
}
|
}
|
||||||
22
todo.txt
22
todo.txt
@@ -1,14 +1,15 @@
|
|||||||
******************************************************** NEXT PATCH ********************************************************
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
bots are now nonrefundable, so they don't display as a tech when you select them
|
thrown blocks can damage intangible mobs for a couple seconds after they are thrown
|
||||||
this might introduce some errors, please let me know if you see something
|
they are set to act like bullets for a few seconds after being thrown
|
||||||
bot counts can be seen in pause menu
|
all blocks do 50% more damage to mobs and 50% longer stun
|
||||||
|
blocks do more damage vs. shielded mobs (damage penalty is 40%, was 66%))
|
||||||
|
mass driver - damage increase set to 200% (up from 100%)
|
||||||
|
negative mass field can lift blocks twice as heavy as before with little movement reduction
|
||||||
|
|
||||||
the final boss will spawn progressively more mobs if you don't kill it quickly enough
|
tech: flywheel - when mobs die their body is spun and flung at nearby mobs
|
||||||
levelBosses are also more likely to spawn on the final boss
|
requires mass driver, no other mob death tech
|
||||||
|
|
||||||
added community map - crossfire
|
|
||||||
by iNoobBoi
|
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
@@ -40,9 +41,12 @@ fix door.isOpen actually meaning isClosed?
|
|||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
import the procedural level generation from one of the older versions of the game as one single level
|
chance for the block resulting from a slain enemy to be thrown at the nearest mob.
|
||||||
|
tech: flywheel - after a mob dies their body is fired towards a nearby mob
|
||||||
|
requires: block throwing technology?
|
||||||
|
adjust for gravity
|
||||||
|
|
||||||
Tech: "Spacial Continuity": 12% chance for the block resulting from a slain enemy to be thrown at the nearest mob.
|
import the procedural level generation from one of the older versions of the game as one single level
|
||||||
|
|
||||||
tech plasma field - plasma field becomes an aoe damage field with the same radius
|
tech plasma field - plasma field becomes an aoe damage field with the same radius
|
||||||
200% more energy drain, 100% more damage
|
200% more energy drain, 100% more damage
|
||||||
|
|||||||
Reference in New Issue
Block a user