diff --git a/js/bullets.js b/js/bullets.js
index a44e720..5af08a4 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -1056,6 +1056,22 @@ const b = {
}
}
},
+ {
+ name: "fragmentation grenade",
+ description: "grenades are loaded with +5 nails
on detonation nails are ejected towards mobs",
+ maxCount: 9,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("grenades")
+ },
+ requires: "grenades",
+ effect() {
+ b.modGrenadeFragments += 5
+ },
+ remove() {
+ b.modGrenadeFragments = 0
+ }
+ },
{
name: "electromagnetic pulse",
description: "vacuum bomb's explosion destroys shields
and does 20% more damage",
@@ -1154,7 +1170,7 @@ const b = {
},
{
name: "fragmenting projectiles",
- description: "rail gun fragments into nails after hitting mobs at high speeds",
+ description: "rail gun fragments into nails
after hitting mobs at high speeds",
maxCount: 1,
count: 0,
allowed() {
@@ -1170,7 +1186,7 @@ const b = {
},
{
name: "specular reflection",
- description: "the laser gains +1 reflection
+50% laser damage and energy drain",
+ description: "laser beams gain +1 reflection
+50% laser damage and energy drain",
maxCount: 9,
count: 0,
allowed() {
@@ -1889,7 +1905,7 @@ const b = {
friction: 0,
frictionAir: 0.025,
thrust: b.isModFastSpores ? 0.0008 : 0.0004,
- dmg: 2.2, //damage done in addition to the damage from momentum
+ dmg: 2.4, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
@@ -1952,7 +1968,7 @@ const b = {
friction: 0,
frictionAir: 0.10,
restitution: 0.3,
- dmg: 0.3, //damage done in addition to the damage from momentum
+ dmg: 0.2, //damage done in addition to the damage from momentum
lookFrequency: 10 + Math.floor(7 * Math.random()),
endCycle: game.cycle + 120 * b.isModBulletsLastLonger, //Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
@@ -2022,7 +2038,7 @@ const b = {
friction: 0.05,
frictionAir: 0.0005,
restitution: 1,
- dmg: 0.15, //damage done in addition to the damage from momentum
+ dmg: 0.17, //damage done in addition to the damage from momentum
lookFrequency: 83 + Math.floor(41 * Math.random()),
endCycle: game.cycle + Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
@@ -2418,7 +2434,7 @@ const b = {
name: "super balls", //2
description: "fire four balls in a wide arc
balls bounce with no momentum loss",
ammo: 0,
- ammoPack: 13,
+ ammoPack: 14,
have: false,
num: 5,
isStarterGun: true,
@@ -2724,6 +2740,37 @@ const b = {
bullet[me].explodeRad = 275;
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
+ if (b.modGrenadeFragments) {
+ const targets = [] //target nearby mobs
+ for (let i = 0, len = mob.length; i < len; i++) {
+ if (mob[i].dropPowerUp) {
+ const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
+ if (dist < 1440000 && //1200*1200
+ Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
+ Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
+ targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
+ }
+ }
+ }
+ for (let i = 0; i < b.modGrenadeFragments; i++) {
+ const speed = 53 + 10 * Math.random()
+ if (targets.length > 0) { // aim near a random target in array
+ const index = Math.floor(Math.random() * targets.length)
+ const SPREAD = 150 / targets.length
+ const WHERE = {
+ x: targets[index].x + SPREAD * (Math.random() - 0.5),
+ y: targets[index].y + SPREAD * (Math.random() - 0.5)
+ }
+ b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1.1)
+ } else { // aim in random direction
+ const ANGLE = 2 * Math.PI * Math.random()
+ b.nail(this.position, {
+ x: speed * Math.cos(ANGLE),
+ y: speed * Math.sin(ANGLE)
+ })
+ }
+ }
+ }
}
bullet[me].minDmgSpeed = 1;
bullet[me].onDmg = function () {
diff --git a/js/index.js b/js/index.js
index b3cce54..d2b694e 100644
--- a/js/index.js
+++ b/js/index.js
@@ -126,6 +126,7 @@ const build = {
document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
+ window.scrollTo(0, 0);
},
isCustomSelection: true,
choosePowerUp(who, index, type) {
@@ -337,10 +338,10 @@ const build = {
game.makeGunHUD();
}
- //remove any bullets that might have spawned from mods
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
- bullet = [];
- const levelsCleared = Number(document.getElementById("starting-level").value) - 1
+ bullet = []; //remove any bullets that might have spawned from mods
+
+ const levelsCleared = Number(document.getElementById("starting-level").value)
level.difficultyIncrease(Math.min(99, levelsCleared * game.difficultyMode)) //increase difficulty based on modes
level.levelsCleared += levelsCleared;
diff --git a/js/player.js b/js/player.js
index 730bf9f..1312b90 100644
--- a/js/player.js
+++ b/js/player.js
@@ -723,8 +723,8 @@ const mech = {
fieldEnergyMax: 1, //can be increased by a mod
holdingTarget: null,
fieldShieldingScale: 1,
- fieldRange: 155,
// these values are set on reset by setHoldDefaults()
+ fieldRange: 155,
energy: 0,
fieldRegen: 0,
fieldMode: 0,
@@ -742,6 +742,7 @@ const mech = {
mech.fieldMeterColor = "#0cf"
mech.fieldShieldingScale = 1;
mech.fieldDamageResistance = 1;
+ mech.fieldRange = 155;
mech.fieldFire = false;
mech.fieldCDcycle = 0;
mech.isStealth = false;
@@ -1519,7 +1520,7 @@ const mech = {
},
{
name: "negative mass field",
- description: "use energy to nullify gravity
reduce harm by 66% while field is active", //
launch larger blocks at much higher speeds
+ description: "use energy to nullify gravity
reduce harm by 75% while field is active", //
launch larger blocks at much higher speeds
fieldDrawRadius: 0,
isEasyToAim: true,
effect: () => {
@@ -1538,7 +1539,7 @@ const mech = {
mech.lookForPickUp();
const DRAIN = 0.00035
if (mech.energy > DRAIN) {
- mech.fieldDamageResistance = 0.33; // 1 - 0.66
+ mech.fieldDamageResistance = 0.25; // 1 - 0.75
// mech.pushMobs360();
//repulse mobs
@@ -1746,14 +1747,40 @@ const mech = {
},
{
name: "phase decoherence field",
- description: "use energy to become intangible
moving and touching shields amplifies cost",
+ description: "use energy to become intangible
firing and touching shields increases drain",
isEasyToAim: true,
effect: () => {
+ mech.fieldFire = true;
mech.fieldMeterColor = "#fff"
+ mech.fieldPhase = 0
+
mech.hold = function () {
+ function drawField(radius) {
+ radius *= 0.7 + 0.7 * mech.energy
+ const rotate = mech.cycle * 0.005
+ const amplitude = 0.06
+ mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.min(mech.energy, 1))
+ const off1 = 1 + amplitude * Math.sin(mech.fieldPhase) //+ 0.07 * Math.sin(mech.cycle * 0.05)
+ const off2 = 1 - amplitude * Math.sin(mech.fieldPhase) //+ 0.07 * Math.sin(mech.cycle * 0.05)
+ ctx.beginPath();
+ ctx.ellipse(mech.pos.x, mech.pos.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI);
+ ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*mech.energy})`;
+ ctx.globalCompositeOperation = "destination-in"; //in or atop
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+ ctx.clip();
+
+ if (mech.fireCDcycle > mech.cycle) {
+ ctx.lineWidth = 5;
+ ctx.strokeStyle = `rgba(0, 204, 255,1)`
+ ctx.stroke()
+ }
+ }
+
mech.isStealth = false //isStealth disables most uses of foundPlayer()
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
if (mech.isHolding) {
+ this.fieldRange = 2000;
mech.drawHold(mech.holdingTarget);
mech.holding();
mech.throwBlock();
@@ -1761,66 +1788,51 @@ const mech = {
mech.grabPowerUp();
mech.lookForPickUp();
- const DRAIN = 0.00004 + 0.00009 * player.speed
+ const DRAIN = (0.0005 + 0.0001 * player.speed) * (mech.fireCDcycle > mech.cycle ? 4 : 1) //game.mouseDown
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
if (mech.energy < 0.001) {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
}
-
+ this.fieldRange = this.fieldRange * 0.9 + 0.1 * 160
+ drawField(this.fieldRange)
mech.isStealth = true //isStealth disables most uses of foundPlayer()
player.collisionFilter.mask = cat.map
- if (!game.isTimeSkipping) {
- // game.timeSkip(1)
- const drawRadius = 125
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, drawRadius, 0, 2 * Math.PI);
- ctx.fillStyle = `rgba(255,255,255,${mech.energy*0.5})`;
- ctx.globalCompositeOperation = "destination-in"; //in or atop
- ctx.fill();
- ctx.globalCompositeOperation = "source-over";
- ctx.strokeStyle = "#000"
- ctx.lineWidth = 2;
- ctx.stroke();
- ctx.beginPath();
- ctx.arc(mech.pos.x, mech.pos.y, drawRadius, 0, 2 * Math.PI);
- ctx.clip();
- let inPlayer = Matter.Query.region(mob, player.bounds)
- if (inPlayer.length > 0) {
- for (let i = 0; i < inPlayer.length; i++) {
- if (inPlayer[i].shield) {
- mech.energy -= 0.005; //shields drain player energy
- //draw outline of shield
- ctx.fillStyle = `rgba(0, 204, 255,0.6)`
- ctx.fill()
- } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) {
- inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
- mech.energy -= 0.002;
+ let inPlayer = Matter.Query.region(mob, player.bounds)
+ if (inPlayer.length > 0) {
+ for (let i = 0; i < inPlayer.length; i++) {
+ if (inPlayer[i].shield) {
+ mech.energy -= 0.005; //shields drain player energy
+ //draw outline of shield
+ ctx.fillStyle = `rgba(0, 204, 255,0.6)`
+ ctx.fill()
+ } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) {
+ inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
+ mech.energy -= 0.002;
- //draw outline of mob in a few random locations to show blurriness
- const vertices = inPlayer[i].vertices;
- const off = 30
- for (let k = 0; k < 3; k++) {
- const xOff = off * (Math.random() - 0.5)
- const yOff = off * (Math.random() - 0.5)
- ctx.beginPath();
- ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
- for (let j = 1, len = vertices.length; j < len; ++j) {
- ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
- }
- ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
- // ctx.strokeStyle = "#000"
- // ctx.lineWidth = 1
- // ctx.stroke()
- ctx.fillStyle = "rgba(0,0,0,0.3)"
- ctx.fill()
+ //draw outline of mob in a few random locations to show blurriness
+ const vertices = inPlayer[i].vertices;
+ const off = 30
+ for (let k = 0; k < 3; k++) {
+ const xOff = off * (Math.random() - 0.5)
+ const yOff = off * (Math.random() - 0.5)
+ ctx.beginPath();
+ ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
+ for (let j = 1, len = vertices.length; j < len; ++j) {
+ ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
}
- break;
+ ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
+ ctx.fillStyle = "rgba(0,0,0,0.3)"
+ ctx.fill()
+ // ctx.strokeStyle = "#000"
+ // ctx.lineWidth = 1
+ // ctx.stroke()
}
+ break;
}
}
}
@@ -1828,6 +1840,11 @@ const mech = {
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
mech.pickUp();
} else {
+ // this.fieldRange = 3000
+ if (this.fieldRange < 2000 && mech.holdingTarget === null) {
+ this.fieldRange += 200
+ drawField(this.fieldRange)
+ }
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
// mech.drawFieldMeter()
diff --git a/todo.txt b/todo.txt
index cc89132..8a8333c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,13 @@
+phase decoherence field - updated graphics, can fire gun while active
+mod - fragmentation grenade fires nails
+
************** TODO - n-gon **************
+pulse and time dilation only ones left with no dedicated mod
+
+mod - renormalization: you can shoot bullets while in phase field
+
lore - a robot (the player) gains self awareness
each mod/gun/field is a new tech
all the technology leads to the singularity
@@ -13,8 +20,6 @@ lore - a robot (the player) gains self awareness
make a global variable that goes up by one every time you play
show text at start, loading simulation #...
-mod - spores with no target hang out about player
-
mod - status effects last 1 second longer
cryonics : a mod that increases the freezing time of mobs.
wait until you have more status effects written
@@ -26,10 +31,6 @@ add a way to run player submitted maps.
MOB stabber - extends one vector like the shooter, but quickly in order to stab
-mod - frag grenades fire nails on explosion
-
-mod - drop a mine after taking damage
-
work on burn status effect
graphics don't look right
how is it different from the chemical dot