flechettes pierce

above level 20 boss power ups only drop on even levels
removed mod ablative mines  (was buggy, and too similar to ablative drones)
flechettes get stuck in walls
flechettes do no damage to mobs on hit
flechettes do more damage over time, and have more ammo
mod - flechettes pierce mobs
mod - mutualism: each spore does 2x damage but they borrow 1% life from player
This commit is contained in:
landgreen
2020-05-31 09:11:53 -07:00
parent 7a89051384
commit e14a56f362
9 changed files with 249 additions and 113 deletions

View File

@@ -475,7 +475,7 @@ const b = {
friction: 0,
frictionAir: 0.025,
thrust: mod.isFastSpores ? 0.001 : 0.0004,
dmg: 2.8, //damage done in addition to the damage from momentum
dmg: mod.isMutualism ? 5.6 : 2.8, //2x bonus damage from mod.isMutualism
lookFrequency: 97 + Math.floor(117 * Math.random()),
classType: "bullet",
collisionFilter: {
@@ -491,7 +491,18 @@ const b = {
onDmg() {
this.endCycle = 0; //bullet ends cycle after doing damage
},
onEnd() {},
onEnd() {
if (mod.isMutualism && this.isMutualismActive) {
if (mod.isEnergyHealth) {
mech.energy += 0.01;
} else {
mech.health += 0.01
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mod.onHealthChange();
mech.displayHealth();
}
}
},
do() {
if (!(game.cycle % this.lookFrequency)) { //find mob targets
this.closestTarget = null;
@@ -535,6 +546,20 @@ const b = {
y: SPEED * Math.sin(ANGLE)
});
World.add(engine.world, bullet[bIndex]); //add bullet to world
if (mod.isMutualism) {
if (mod.isEnergyHealth) {
if (mech.energy > 0.02) {
mech.energy -= 0.01; //energy takes an extra 25% damage for balancing purposes
bullet[bIndex].isMutualismActive = true
}
} else if (mech.health > 0.02) {
mech.health -= 0.01
mod.onHealthChange();
mech.displayHealth();
bullet[bIndex].isMutualismActive = true
}
}
},
iceIX(speed = 0, spread = 2 * Math.PI) {
const me = bullet.length;
@@ -1306,42 +1331,72 @@ const b = {
name: "flechettes",
description: "fire a volley of <strong class='color-p'>uranium-235</strong> <strong>needles</strong><br>does <strong class='color-d'>damage</strong> over <strong>3</strong> seconds",
ammo: 0,
ammoPack: 23,
defaultAmmoPack: 23,
ammoPack: 30,
defaultAmmoPack: 30,
have: false,
isStarterGun: true,
isEasyToAim: false,
count: 0, //used to track how many shots are in a volley before a big CD
lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
fire() {
const CD = (mech.crouch) ? 50 : 30
if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD
this.lastFireCycle = mech.cycle
if (this.count > ((mech.crouch) ? 6 : 1)) {
this.count = 0
mech.fireCDcycle = mech.cycle + Math.floor(CD * mod.fireRate); // cool down
} else {
this.count++
mech.fireCDcycle = mech.cycle + Math.floor(3 * mod.fireRate); // cool down
}
function makeFlechette(angle = mech.angle) {
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45, 1.4, b.fireAttributes(angle));
// Matter.Body.setDensity(bullet[me], 0.0001); //0.001 is normal
bullet[me].collisionFilter.mask = cat.body; //cat.mobShield | //cat.map | cat.body |
Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal
bullet[me].endCycle = game.cycle + 180;
bullet[me].dmg = 0;
bullet[me].onDmg = function (who) {
bullet[me].immuneList = []
bullet[me].do = function () {
const whom = Matter.Query.collides(this, mob)
if (whom.length && this.speed > 20) { //if touching a mob
who = whom[0].bodyA
if (who) {
function hit(that) {
who.foundPlayer();
if (mod.isDotFlechette) {
mobs.statusDoT(who, 0.33, 360) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
mobs.statusDoT(who, 0.5, 360)
} else {
mobs.statusDoT(who, 0.33, 180) // (2.3) / 6 ticks (3 seconds)
mobs.statusDoT(who, 0.5, 180)
}
game.drawList.push({ //add dmg to draw queue
x: that.position.x,
y: that.position.y,
radius: 40,
color: "rgba(0,80,80,0.3)",
time: game.drawTime
});
}
if (mod.pierce) {
let immune = false
for (let i = 0; i < this.immuneList.length; i++) {
if (this.immuneList[i] === who.id) immune = true
}
if (!immune) {
this.immuneList.push(who.id)
hit(this)
}
} else {
this.endCycle = 0;
hit(this)
}
}
} else if (Matter.Query.collides(this, map).length) { //stick in walls
this.collisionFilter.mask = 0;
Matter.Body.setAngularVelocity(this, 0)
Matter.Body.setVelocity(this, {
x: 0,
y: 0
});
this.do = function () {}
} else if (this.speed < 30) {
this.force.y += this.mass * 0.0007; //no gravity until it slows down to improve aiming
}
};
bullet[me].do = function () {
if (this.speed < 10) this.force.y += this.mass * 0.0003; //no gravity until it slows don to improve aiming
};
const SPEED = 50
Matter.Body.setVelocity(bullet[me], {
x: mech.Vx / 2 + SPEED * Math.cos(angle),
@@ -1351,9 +1406,46 @@ const b = {
}
makeFlechette()
if (mod.isFlechetteMultiShot) {
makeFlechette(mech.angle + 0.01 + 0.01 * Math.random())
makeFlechette(mech.angle - 0.01 - 0.01 * Math.random())
makeFlechette(mech.angle + 0.02 + 0.005 * Math.random())
makeFlechette(mech.angle - 0.02 - 0.005 * Math.random())
}
const CD = (mech.crouch) ? 60 : 30
if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD
this.lastFireCycle = mech.cycle
if (this.count > ((mech.crouch) ? 7 : 1)) {
this.count = 0
mech.fireCDcycle = mech.cycle + Math.floor(CD * mod.fireRate); // cool down
const who = bullet[bullet.length - 1]
Matter.Body.setDensity(who, 0.00001);
// who.onDmg = function (who) {
// if (mod.isDotFlechette) {
// mobs.statusDoT(who, 0.33, 360) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
// mobs.statusSlow(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
// } else {
// mobs.statusDoT(who, 0.33, 180) // (2.3) / 6 ticks (3 seconds)
// mobs.statusSlow(who, 60) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
// }
// this.endCycle = 0;
// };
// who.onEnd = function () {
// b.explosion(this.position, 220); //makes bullet do explosive damage at end
// }
// who.do = function () {
// if (this.speed < 10) this.force.y += this.mass * 0.0003; //no gravity until it slows don to improve aiming
// if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
// this.endCycle = 0; //explode if touching map or blocks
// }
// }
} else {
this.count++
mech.fireCDcycle = mech.cycle + Math.floor(3 * mod.fireRate); // cool down
}
}
},
{
@@ -1956,7 +2048,7 @@ const b = {
},
{
name: "spores",
description: "fire a <strong>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong>",
description: "fire a <strong>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
ammo: 0,
ammoPack: 5,
have: false,
@@ -2069,7 +2161,6 @@ const b = {
b.spore(this)
}
}
}
},
{

View File

@@ -208,6 +208,7 @@ function collisionChecks(event) {
if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
mob[k].foundPlayer();
mob[k].damage(dmg);
// console.log(dmg)
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
game.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,

View File

@@ -644,6 +644,21 @@ const game = {
}
}
if (mod.isMutualism) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) {
if (mod.isEnergyHealth) {
mech.energy += 0.01;
} else {
mech.health += 0.01
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mod.onHealthChange();
mech.displayHealth();
}
}
}
}
//if player is holding something this remembers it before it gets deleted
let holdTarget;
if (mech.holdingTarget) {

View File

@@ -17,9 +17,9 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(9)
// mech.setField("time dilation field")
// mod.giveMod("brushless motor");
// mod.giveMod("mutualism");
// b.giveGuns("drones")
// b.giveGuns("mine")
// b.giveGuns("spores")
// mech.setField("pilot wave")
// mech.setField("phase decoherence field")
@@ -60,10 +60,10 @@ const level = {
// if (level.isBuildRun) num++
for (let i = 0; i < num; i++) {
game.difficulty++
game.dmgScale += 0.205; //damage done by mobs increases each level
game.dmgScale += 0.21; //damage done by mobs increases each level
b.dmgScale *= 0.91; //damage done by player decreases each level
game.accelScale *= 1.024 //mob acceleration increases each level
game.lookFreqScale *= 0.976 //mob cycles between looks decreases each level
game.accelScale *= 1.027 //mob acceleration increases each level
game.lookFreqScale *= 0.974 //mob cycles between looks decreases each level
game.CDScale *= 0.964 //mob CD time decreases each level
}
game.healScale = 1 / (1 + game.difficulty * 0.09) //a higher denominator makes for lower heals // mech.health += heal * game.healScale;
@@ -71,11 +71,11 @@ const level = {
difficultyDecrease(num = 1) { //used in easy mode for game.reset()
for (let i = 0; i < num; i++) {
game.difficulty--
game.dmgScale -= 0.205; //damage done by mobs increases each level
game.dmgScale -= 0.21; //damage done by mobs increases each level
if (game.dmgScale < 0.1) game.dmgScale = 0.1;
b.dmgScale /= 0.91; //damage done by player decreases each level
game.accelScale /= 1.024 //mob acceleration increases each level
game.lookFreqScale /= 0.976 //mob cycles between looks decreases each level
game.accelScale /= 1.027 //mob acceleration increases each level
game.lookFreqScale /= 0.974 //mob cycles between looks decreases each level
game.CDScale /= 0.964 //mob CD time decreases each level
}
if (game.difficulty < 1) game.difficulty = 0;
@@ -187,6 +187,8 @@ const level = {
// spawn.laserTargetingBoss(1600, -400)
// spawn.spawner(1600, -500)
spawn.sniper(1700, -120)
// spawn.sniper(1600, -120)
// spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500)
// spawn.shooter(1600, -500)
// spawn.striker(1600, -500)

View File

@@ -374,29 +374,29 @@ const mod = {
},
remove() {}
},
{
name: "ablative mines",
description: "rebuild your broken parts as a <strong>mine</strong><br>chance to occur after being <strong>harmed</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.isMineOnDamage = true;
b.mine({
x: mech.pos.x,
y: mech.pos.y - 80
}, {
x: 0,
y: 0
})
},
remove() {
mod.isMineOnDamage = false;
}
},
// {
// name: "ablative mines",
// description: "rebuild your broken parts as a <strong>mine</strong><br>chance to occur after being <strong>harmed</strong>",
// maxCount: 1,
// count: 0,
// allowed() {
// return true
// },
// requires: "",
// effect() {
// mod.isMineOnDamage = true;
// b.mine({
// x: mech.pos.x,
// y: mech.pos.y - 80
// }, {
// x: 0,
// y: 0
// })
// },
// remove() {
// mod.isMineOnDamage = false;
// }
// },
{
name: "ablative drones",
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after being <strong>harmed</strong>",
@@ -767,7 +767,7 @@ const mod = {
},
{
name: "catabolism",
description: "gain <strong>ammo</strong> when you <strong>fire</strong> while <strong>out</strong> of <strong>ammo</strong><br>drains <strong>3%</strong> of current remaining <strong class='color-h'>health</strong>",
description: "gain <strong>ammo</strong> when you <strong>fire</strong> while <strong>out</strong> of <strong>ammo</strong><br>drains <strong>3%</strong> of current remaining <strong>health</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1143,6 +1143,22 @@ const mod = {
mod.isDotFlechette = false;
}
},
{
name: "piercing needles",
description: "<strong>needles</strong> penetrate <strong>mobs</strong><br>potentially hitting <strong>multiple</strong> targets",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("flechettes")
},
requires: "flechettes",
effect() {
mod.pierce = true;
},
remove() {
mod.pierce = false;
}
},
{
name: "wave packet",
description: "<strong>wave beam</strong> emits <strong>two</strong> oscillating particles<br>wave particles do <strong>40%</strong> less <strong class='color-d'>damage</strong>",
@@ -1421,6 +1437,22 @@ const mod = {
mod.isSporeFollow = false
}
},
{
name: "mutualism",
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> do <strong>2x</strong> <strong class='color-d'>damage</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>1%</strong> <strong>health</strong> until they <strong>die</strong>",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("spores") || mod.sporesOnDeath > 0 || mod.isSporeField
},
requires: "spores",
effect() {
mod.isMutualism = true
},
remove() {
mod.isMutualism = false
}
},
{
name: "brushless motor",
description: "<strong>drones</strong> accelerate <strong>50%</strong> faster",
@@ -1785,7 +1817,7 @@ const mod = {
isImmuneExplosion: null,
isExplodeMob: null,
isDroneOnDamage: null,
isMineOnDamage: null,
// isMineOnDamage: null,
acidDmg: null,
isAcidDmg: null,
isAnnihilation: null,

View File

@@ -478,15 +478,15 @@ const mech = {
if (Math.random() < 0.5) b.drone() //spawn drone
}
}
if (mod.isMineOnDamage && dmg > 0.004 + 0.05 * Math.random()) {
b.mine({
x: mech.pos.x,
y: mech.pos.y - 80
}, {
x: 0,
y: 0
})
}
// if (mod.isMineOnDamage && dmg > 0.004 + 0.05 * Math.random()) {
// b.mine({
// x: mech.pos.x,
// y: mech.pos.y - 80
// }, {
// x: 0,
// y: 0
// })
// }
dmg *= mech.harmReduction()
if (mod.isEnergyHealth) {
@@ -543,14 +543,13 @@ const mech = {
return;
}
}
}
if (dmg > 0.2 * mech.holdingMassScale) mech.drop(); //drop block if holding
mod.onHealthChange();
mech.displayHealth();
document.getElementById("dmg").style.transition = "opacity 0s";
document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4);
}
if (dmg > 0.2 * mech.holdingMassScale) mech.drop(); //drop block if holding
const normalFPS = function () {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
@@ -698,10 +697,10 @@ const mech = {
fieldMode: 0, //basic field mode before upgrades
maxEnergy: 1, //can be increased by a mod
holdingTarget: null,
fieldShieldingScale: 1,
timeSkipLastCycle: 0,
// these values are set on reset by setHoldDefaults()
fieldRange: 155,
fieldShieldingScale: 1,
energy: 0,
fieldRegen: 0,
fieldMode: 0,
@@ -1220,9 +1219,10 @@ const mech = {
},
{
name: "standing wave harmonics",
description: "three oscillating <strong>shields</strong> are permanently active<br><strong class='color-f'>energy</strong> regenerates while field is active",
description: "three oscillating <strong>shields</strong> are permanently active<br>reduce <strong>harm</strong> by <strong>33%</strong>",
isEasyToAim: true,
effect: () => {
mech.fieldHarmReduction = 0.67;
mech.fieldBlockCD = 0;
mech.hold = function () {
if (mech.isHolding) {
@@ -1510,11 +1510,10 @@ const mech = {
},
{
name: "plasma torch",
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br>reduce <strong>harm</strong> by <strong>20%</strong>",
description: "use <strong class='color-f'>energy</strong> to emit short range plasma<br>plasma <strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs",
isEasyToAim: false,
effect: () => {
mech.fieldMeterColor = "#f0f"
mech.fieldHarmReduction = 0.80;
mech.hold = function () {
if (mech.isHolding) {

View File

@@ -389,6 +389,7 @@ const powerUps = {
}
},
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
if (level.levelsCleared < 20 || level.levelsCleared % 2 == 0) { //drop only on even levels above level 20
if (game.difficultyMode > 1 || Math.random() < 0.66) { //easy and normal have only a 66% chance for a power up
spawnPowerUps()
if (game.difficultyMode > 2 && level.levelsCleared % 2 == 0) spawnPowerUps() //why? has an extra power up on even numbered levels
@@ -405,6 +406,7 @@ const powerUps = {
powerUps.spawn(x, y, "ammo");
}
}
}
function spawnPowerUps() {
if (mech.fieldMode === 0) {

View File

@@ -83,8 +83,7 @@ const spawn = {
},
randomLevelBoss(x, y) {
// other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included
// "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss",
const options = ["laserTargetingBoss"] // , "timeSkipBoss"
const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss"] // , "timeSkipBoss"
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
//mob templates *********************************************************************************************
@@ -893,17 +892,17 @@ const spawn = {
};
}
},
laserTargetingBoss(x, y, radius = 70) {
laserTargetingBoss(x, y, radius = 65) {
const color = "#05f"
mobs.spawn(x, y, 3, radius, color);
let me = mob[mob.length - 1];
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);
me.accelMag = 0.0006 * game.accelScale;
me.accelMag = 0.0005 * game.accelScale;
me.seePlayerFreq = Math.floor(25 * game.lookFreqScale);
me.memory = 600;
me.restitution = 1;
me.frictionAir = 0.06;
me.frictionAir = 0.05;
me.frictionStatic = 0;
me.friction = 0;
@@ -913,7 +912,7 @@ const spawn = {
x: 0,
y: 0
}
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.025); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1);
me.onHit = function () {
//run this function on hitting player

View File

@@ -1,19 +1,21 @@
harmonic field now has no cooldown after blocking
negative mass field accelerates slower, but with a higher top speed
negative mass field harm reduction is now 60% and always on
mod degenerate matter increases the damage reduction from 60% to 80%
falling damage and damage from blocks have been removed
(I'm trying it out, let me know if you want it back)
above level 20 boss power ups only drop on even levels
removed mod ablative mines (was buggy, and too similar to ablative drones)
flechettes get stuck in walls
flechettes do no damage to mobs on hit
flechettes do more damage over time, and have more ammo
mod - flechettes pierce mobs
mod - mutualism: each spore does 2x damage but they borrow 1% life from player
************** TODO - n-gon **************
shrink font on small screens (so you can see 5 options on power ups)
graphic idea: bezier curve that moves smoothly from mob to mob
loops around player
add air control check box
set mech.airSpeedLimit to 0? to disable
on damage mines mod needs a nerf
spawns 2 mines every time... (from on dmg effects)
give rail gun projectile a trail
only draw above speed 5
track previous positions?
@@ -32,13 +34,6 @@ movement fluidity
wall grab?
maybe remove falling damage and block damage?
rays can have width, how to use this?
Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
wide lasers?
new type of mob vision that uses ray query with thickness
maybe use for bosses
bug - mines spawn extra mines when fired at thin map wall while jumping
what about a neutron bomb mod, that causes the bomb to activate right after you fire and slowly move forward with no gravity