phase field graphics, grenade nail mod
This commit is contained in:
@@ -1056,6 +1056,22 @@ const b = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "fragmentation grenade",
|
||||
description: "<strong>grenades</strong> are loaded with <strong>+5</strong> nails<br>on detonation <strong>nails</strong> 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: "<strong>vacuum bomb's </strong> <strong class='color-e'>explosion</strong> destroys <strong>shields</strong><br>and does <strong>20%</strong> more <strong class='color-d'>damage</strong>",
|
||||
@@ -1154,7 +1170,7 @@ const b = {
|
||||
},
|
||||
{
|
||||
name: "fragmenting projectiles",
|
||||
description: "<strong>rail gun</strong> fragments into nails after hitting mobs at high speeds",
|
||||
description: "<strong>rail gun</strong> fragments into nails<br> after hitting mobs at high speeds",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -1170,7 +1186,7 @@ const b = {
|
||||
},
|
||||
{
|
||||
name: "specular reflection",
|
||||
description: "the <strong>laser</strong> gains <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><strong>+50%</strong> laser <strong class='color-d'>damage</strong> and <strong class='color-f'>energy</strong> 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 <strong>four</strong> balls in a wide arc<br>balls <strong>bounce</strong> 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 () {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
117
js/player.js
117
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 <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>66%</strong> while field is active", //<br><strong>launch</strong> larger blocks at much higher speeds
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>75%</strong> while field is active", //<br><strong>launch</strong> 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 <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>moving</strong> and touching <strong>shields</strong> amplifies <strong>cost</strong>",
|
||||
description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>firing</strong> and touching <strong>shields</strong> increases <strong>drain</strong>",
|
||||
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()
|
||||
|
||||
13
todo.txt
13
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
|
||||
|
||||
Reference in New Issue
Block a user