launcher rework; wave, minigun balance

This commit is contained in:
landgreen
2020-05-23 11:17:27 -07:00
parent b053269e71
commit e265b0aade
8 changed files with 270 additions and 302 deletions

View File

@@ -798,7 +798,6 @@ const b = {
const SCALE = 1.06
Matter.Body.scale(this, SCALE, SCALE);
this.radius *= SCALE;
console.log(this.radius)
} else {
//shrink
const SCALE = 1 - 0.005 / mod.isBulletsLastLonger
@@ -1164,28 +1163,20 @@ const b = {
isEasyToAim: false,
fire() {
const me = bullet.length;
const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.03 : 0.1);
bullet[me] = Bodies.rectangle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20 * mod.bulletSize, 6 * mod.bulletSize, b.fireAttributes(dir));
b.fireProps(mech.crouch ? 8 : 4, mech.crouch ? 52 : 38, dir, me); //cd , speed
const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.01 : 0.1);
bullet[me] = Bodies.rectangle(mech.pos.x + 23 * Math.cos(mech.angle), mech.pos.y + 23 * Math.sin(mech.angle), 20 * mod.bulletSize, 6 * mod.bulletSize, b.fireAttributes(dir));
b.fireProps(mech.crouch ? 7 : 4, mech.crouch ? 40 : 34, dir, me); //cd , speed
bullet[me].endCycle = game.cycle + 70;
bullet[me].dmg = 0.07;
bullet[me].frictionAir = mech.crouch ? 0.007 : 0.01;
bullet[me].dmg = 0.25;
bullet[me].frictionAir = mech.crouch ? 0.001 : 0.003;
if (mod.isIceCrystals && mech.energy > 0.01) {
mech.energy -= mech.fieldRegen + 0.007
mech.energy -= mech.fieldRegen + 0.005
bullet[me].onDmg = function (who) {
mobs.statusSlow(who, 30)
};
//ice muzzleFlash
ctx.fillStyle = "rgb(0,100,255)";
ctx.beginPath();
ctx.arc(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 15, 0, 2 * Math.PI);
ctx.fill();
} else {
b.muzzleFlash(15);
}
bullet[me].do = function () {
this.force.y += this.mass * 0.0005;
this.force.y += this.mass * 0.0003;
};
}
},
@@ -1425,7 +1416,7 @@ const b = {
for (let i = 0; i < q.length; i++) {
slowCheck = 0.3;
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = b.dmgScale * 0.43 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.6) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
let dmg = b.dmgScale * 0.37 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.6) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
@@ -1443,7 +1434,6 @@ const b = {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(this.velocity), SPEED * slowCheck));
}
}
this.cycle++
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.35) * ((i % 2) ? -1 : 1))
Matter.Body.setPosition(this, Vector.add(this.position, wiggle))

View File

@@ -184,7 +184,7 @@ const level = {
// spawn.bomberBoss(2900, -500)
spawn.launcherBoss(1200, -500)
// spawn.launcher(1600, -400)
spawn.launcher(1600, -400)
// spawn.spawner(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.shooter(1600, -500)

View File

@@ -187,7 +187,7 @@ const mobs = {
index: i,
health: 1,
showHealthBar: true,
accelMag: 0.001,
accelMag: 0.001 * game.accelScale,
cd: 0, //game cycle when cooldown will be over
delay: 60, //static: time between cooldowns
fill: color,

View File

@@ -44,6 +44,25 @@ const mod = {
game.updateModHUD();
}
},
giveBasicMod(index = 'random') {
// if (isNaN(index)) { //find index by name
// let found = false;
// for (let i = 0; i < mod.mods.length; i++) {
// if (index === mod.mods[i].name) {
// index = i;
// found = true;
// break;
// }
// }
// if (!found) return //if name not found don't give any mod
// }
mod.basicMods[index].effect(); //give specific mod
mod.mods[index].count++
mod.totalCount++ //used in power up randomization
game.updateModHUD();
},
haveGunCheck(name) {
for (i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].name === name) return true
@@ -90,6 +109,7 @@ const mod = {
if (document.getElementById("mod-low-health-damage")) document.getElementById("mod-low-health-damage").innerHTML = "";
}, 10);
},
mods: [{
name: "capacitor",
// nameInfo: "<span id='mod-capacitor'></span>",
@@ -156,26 +176,6 @@ const mod = {
mod.isCrit = false;
}
},
{
name: "fluoroantimonic acid",
nameInfo: "<span id='mod-acid'></span>",
description: "each <strong>bullet</strong> does instant <strong class='color-p'>acid</strong> <strong class='color-d'>damage</strong><br><strong>active</strong> when you are above <strong>80%</strong> base health",
maxCount: 1,
count: 0,
allowed() {
return mech.health > 0.8 || build.isCustomSelection
},
requires: "health above 80%",
effect() {
mod.isAcidDmg = true;
mod.onHealthChange();
},
remove() {
mod.acidDmg = 0;
mod.isAcidDmg = false;
game.playerDmgColor = "rgba(0,0,0,0.7)"
}
},
{
name: "negative feedback",
// nameInfo: "<span id='mod-low-health-damage'></span>",
@@ -929,6 +929,27 @@ const mod = {
mod.isDamageFromBulletCount = false
}
},
{
name: "fluoroantimonic acid",
nameInfo: "<span id='mod-acid'></span>",
description: "each <strong>bullet</strong> does instant <strong class='color-p'>acid</strong> <strong class='color-d'>damage</strong><br><strong>active</strong> when you are above <strong>80%</strong> base health",
maxCount: 1,
count: 0,
allowed() {
return (mech.health > 0.8 || build.isCustomSelection) &&
(mod.haveGunCheck("mine") || mod.haveGunCheck("minigun") || mod.haveGunCheck("shotgun") || mod.haveGunCheck("super balls") || mod.haveGunCheck("spores") || mod.haveGunCheck("drones") || mod.haveGunCheck("ice IX"))
},
requires: "health above 80%",
effect() {
mod.isAcidDmg = true;
mod.onHealthChange();
},
remove() {
mod.acidDmg = 0;
mod.isAcidDmg = false;
game.playerDmgColor = "rgba(0,0,0,0.7)"
}
},
{
name: "depleted uranium rounds",
description: `your <strong>bullets</strong> are <strong>+16%</strong> larger<br>increased mass and physical <strong class='color-d'>damage</strong>`,

View File

@@ -358,15 +358,13 @@ const mech = {
alive: false,
death() {
if (mod.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
spawn.setSpawnList(); //new mob types
game.clearNow = true; //triggers a map reset
powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 12)
//count mods
let totalMods = 0;
for (let i = 0; i < mod.mods.length; i++) {
totalMods += mod.mods[i].count
}
const totalGuns = b.inventory.length //count guns
function randomizeMods() {
for (let i = 0; i < totalMods; i++) {
@@ -394,18 +392,16 @@ const mech = {
}
function randomizeField() {
mech.setField(Math.floor(Math.random() * (mech.fieldUpgrades.length)))
mech.setField(Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1)))
}
function randomizeHealth() {
mech.health = 0.6 + Math.random()
mech.health = 0.7 + Math.random()
if (mech.health > 1) mech.health = 1;
mech.displayHealth();
}
function randomizeGuns() {
// const length = Math.round(b.inventory.length * (1 + 0.4 * (Math.random() - 0.5)))
const length = b.inventory.length
//removes guns and ammo
b.inventory = [];
b.activeGun = null;
@@ -415,11 +411,11 @@ const mech = {
if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
}
//give random guns
for (let i = 0; i < length; i++) b.giveGuns()
for (let i = 0; i < totalGuns; i++) b.giveGuns()
//randomize ammo
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) {
b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(5 * b.guns[b.inventory[i]].ammo * (Math.random() - 0.1)))
b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(6 * b.guns[b.inventory[i]].ammo * Math.sqrt(Math.random())))
}
}
game.makeGunHUD(); //update gun HUD
@@ -431,6 +427,9 @@ const mech = {
}
function randomizeEverything() {
spawn.setSpawnList(); //new mob types
game.clearNow = true; //triggers a map reset
mod.setupAllMods(); //remove all mods
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove all bullets
@@ -442,7 +441,7 @@ const mech = {
randomizeEverything()
const swapPeriod = 1000
for (let i = 0, len = 7; i < len; i++) {
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function () {
randomizeEverything()
game.replaceTextLog = true;
@@ -460,7 +459,7 @@ const mech = {
}
game.replaceTextLog = true;
game.makeTextLog("your quantum probability has stabilized", 1000);
}, 8 * swapPeriod);
}, 6 * swapPeriod);
} else if (mech.alive) { //normal death code here
mech.alive = false;
@@ -1873,62 +1872,66 @@ const mech = {
mech.drawHold(mech.holdingTarget);
mech.holding();
mech.throwBlock();
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
} else if (keys[32] || game.mouseDownRight) {
mech.grabPowerUp();
mech.lookForPickUp();
const DRAIN = 0.0003 + 0.00015 * player.speed + ((!mod.renormalization && mech.fireCDcycle > mech.cycle) ? 0.005 : 0.001)
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
// if (mech.energy < 0.001) {
// mech.fieldCDcycle = mech.cycle + 120;
// mech.energy = 0;
// 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)
// }
this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160
drawField(this.fieldRange)
mech.isStealth = true //isStealth disables most uses of foundPlayer()
player.collisionFilter.mask = cat.map
if (mech.fieldCDcycle < mech.cycle) {
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(140,217,255,0.5)`
ctx.fill()
} else if (mod.superposition && inPlayer[i].dropPowerUp) {
// inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
// mech.energy += 0.005;
const DRAIN = 0.0003 + 0.00015 * player.speed + ((!mod.renormalization && mech.fireCDcycle > mech.cycle) ? 0.005 : 0.001)
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
// if (mech.energy < 0.001) {
// mech.fieldCDcycle = mech.cycle + 120;
// mech.energy = 0;
// 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)
// }
this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160
drawField(this.fieldRange)
mobs.statusStun(inPlayer[i], 240)
//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.fillStyle = "rgba(0,0,0,0.1)"
mech.isStealth = true //isStealth disables most uses of foundPlayer()
player.collisionFilter.mask = cat.map
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(140,217,255,0.5)`
ctx.fill()
} else if (mod.superposition && inPlayer[i].dropPowerUp) {
// inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
// mech.energy += 0.005;
mobs.statusStun(inPlayer[i], 240)
//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.fillStyle = "rgba(0,0,0,0.1)"
ctx.fill()
}
break;
}
break;
}
}
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
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)
drawField(this.fieldRange)
}
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.energy = 0;
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)
drawField(this.fieldRange)
}
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
mech.pickUp();
@@ -1983,128 +1986,134 @@ const mech = {
mech.fieldRadius = 0;
mech.drop();
mech.hold = function () {
if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) {
const scale = 25
const bounds = {
min: {
x: mech.fieldPosition.x - scale,
y: mech.fieldPosition.y - scale
},
max: {
x: mech.fieldPosition.x + scale,
y: mech.fieldPosition.y + scale
}
}
const isInMap = Matter.Query.region(map, bounds).length
// const isInMap = Matter.Query.point(map, mech.fieldPosition).length
if (!mech.fieldOn) { // if field was off, and it starting up, teleport to new mouse location
mech.fieldOn = true;
mech.fieldPosition = { //smooth the mouse position
x: game.mouseInGame.x,
y: game.mouseInGame.y
}
mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x,
y: mech.fieldPosition.y
}
} else { //when field is on it smoothly moves towards the mouse
mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x,
y: mech.fieldPosition.y
}
const smooth = isInMap ? 0.985 : 0.96;
mech.fieldPosition = { //smooth the mouse position
x: mech.fieldPosition.x * smooth + game.mouseInGame.x * (1 - smooth),
y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth),
}
}
//grab power ups into the field
for (let i = 0, len = powerUp.length; i < len; ++i) {
const dxP = mech.fieldPosition.x - powerUp[i].position.x;
const dyP = mech.fieldPosition.y - powerUp[i].position.y;
const dist2 = dxP * dxP + dyP * dyP;
// float towards field if looking at and in range or if very close to player
if (dist2 < mech.fieldRadius * mech.fieldRadius && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
//extra friction
Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 0.11,
y: powerUp[i].velocity.y * 0.11
});
if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough
if (mod.isMassEnergy) mech.energy = mech.maxEnergy * 2;
powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
// mech.fieldRadius += 50
break; //because the array order is messed up after splice
if (keys[32] || game.mouseDownRight) {
if (mech.fieldCDcycle < mech.cycle) {
const scale = 25
const bounds = {
min: {
x: mech.fieldPosition.x - scale,
y: mech.fieldPosition.y - scale
},
max: {
x: mech.fieldPosition.x + scale,
y: mech.fieldPosition.y + scale
}
}
}
const isInMap = Matter.Query.region(map, bounds).length
// const isInMap = Matter.Query.point(map, mech.fieldPosition).length
if (mech.energy > 0.01) {
//find mouse velocity
const diff = Vector.sub(mech.fieldPosition, mech.lastFieldPosition)
const speed = Vector.magnitude(diff)
const velocity = Vector.mult(Vector.normalise(diff), Math.min(speed, 45)) //limit velocity
let radius, radiusSmooth
if (Matter.Query.ray(map, mech.fieldPosition, player.position).length) { //is there something block the player's view of the field
radius = 0
radiusSmooth = Math.max(0, isInMap ? 0.96 - 0.02 * speed : 0.995); //0.99
if (!mech.fieldOn) { // if field was off, and it starting up, teleport to new mouse location
mech.fieldOn = true;
mech.fieldPosition = { //smooth the mouse position
x: game.mouseInGame.x,
y: game.mouseInGame.y
}
mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x,
y: mech.fieldPosition.y
}
} else { //when field is on it smoothly moves towards the mouse
mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x,
y: mech.fieldPosition.y
}
const smooth = isInMap ? 0.985 : 0.96;
mech.fieldPosition = { //smooth the mouse position
x: mech.fieldPosition.x * smooth + game.mouseInGame.x * (1 - smooth),
y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth),
}
}
//grab power ups into the field
for (let i = 0, len = powerUp.length; i < len; ++i) {
const dxP = mech.fieldPosition.x - powerUp[i].position.x;
const dyP = mech.fieldPosition.y - powerUp[i].position.y;
const dist2 = dxP * dxP + dyP * dyP;
// float towards field if looking at and in range or if very close to player
if (dist2 < mech.fieldRadius * mech.fieldRadius && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
//extra friction
Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 0.11,
y: powerUp[i].velocity.y * 0.11
});
if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough
if (mod.isMassEnergy) mech.energy = mech.maxEnergy * 2;
powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
// mech.fieldRadius += 50
break; //because the array order is messed up after splice
}
}
}
//grab power ups normally too
mech.grabPowerUp();
if (mech.energy > 0.01) {
//find mouse velocity
const diff = Vector.sub(mech.fieldPosition, mech.lastFieldPosition)
const speed = Vector.magnitude(diff)
const velocity = Vector.mult(Vector.normalise(diff), Math.min(speed, 45)) //limit velocity
let radius, radiusSmooth
if (Matter.Query.ray(map, mech.fieldPosition, player.position).length) { //is there something block the player's view of the field
radius = 0
radiusSmooth = Math.max(0, isInMap ? 0.96 - 0.02 * speed : 0.995); //0.99
} else {
radius = Math.max(50, 250 - 2 * speed)
radiusSmooth = 0.97
}
mech.fieldRadius = mech.fieldRadius * radiusSmooth + radius * (1 - radiusSmooth)
for (let i = 0, len = body.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(body[i].position, mech.fieldPosition)) < mech.fieldRadius) {
const DRAIN = speed * body[i].mass * 0.000022
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8)
body[i].force.y -= body[i].mass * game.g; //remove gravity effects
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false
mech.fieldRadius = 0
break
}
}
}
if (mod.isPilotFreeze) {
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, mech.fieldPosition)) < mech.fieldRadius) {
mobs.statusSlow(mob[i], 120)
}
}
}
ctx.beginPath();
const rotate = mech.cycle * 0.008;
mech.fieldPhase += 0.2 // - 0.5 * Math.sqrt(Math.min(mech.energy, 1));
const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase);
const off2 = 1 - 0.06 * Math.sin(mech.fieldPhase);
ctx.beginPath();
ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, 2 * Math.PI);
ctx.globalCompositeOperation = "exclusion"; //"exclusion" "difference";
ctx.fillStyle = "#fff"; //"#eef";
ctx.fill();
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, mech.energy * 2 * Math.PI);
ctx.strokeStyle = "#000";
ctx.lineWidth = 4;
ctx.stroke();
} else {
radius = Math.max(50, 250 - 2 * speed)
radiusSmooth = 0.97
mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false
mech.fieldRadius = 0
}
mech.fieldRadius = mech.fieldRadius * radiusSmooth + radius * (1 - radiusSmooth)
for (let i = 0, len = body.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(body[i].position, mech.fieldPosition)) < mech.fieldRadius) {
const DRAIN = speed * body[i].mass * 0.000022
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8)
body[i].force.y -= body[i].mass * game.g; //remove gravity effects
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false
mech.fieldRadius = 0
break
}
}
}
if (mod.isPilotFreeze) {
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, mech.fieldPosition)) < mech.fieldRadius) {
mobs.statusSlow(mob[i], 120)
}
}
}
ctx.beginPath();
const rotate = mech.cycle * 0.008;
mech.fieldPhase += 0.2 // - 0.5 * Math.sqrt(Math.min(mech.energy, 1));
const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase);
const off2 = 1 - 0.06 * Math.sin(mech.fieldPhase);
ctx.beginPath();
ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, 2 * Math.PI);
ctx.globalCompositeOperation = "exclusion"; //"exclusion" "difference";
ctx.fillStyle = "#fff"; //"#eef";
ctx.fill();
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, mech.energy * 2 * Math.PI);
ctx.strokeStyle = "#000";
ctx.lineWidth = 4;
ctx.stroke();
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false
mech.fieldRadius = 0
mech.grabPowerUp();
}
} else {
mech.fieldOn = false

View File

@@ -211,6 +211,8 @@ const powerUps = {
},
choiceLog: [], //records all previous choice options
effect() {
function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 0; i < mod.mods.length; i++) {
@@ -232,28 +234,30 @@ const powerUps = {
}
}
}
if (options.length > 0) {
return options[Math.floor(Math.random() * options.length)]
}
}
if (options.length > 0) {
const choose = options[Math.floor(Math.random() * options.length)]
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choose].name}</div> ${mod.mods[choose].description}</div>`
return choose
}
}
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
let choice1 = pick()
let choice2 = -1
let choice3 = -1
if (choice1 > -1) {
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice1})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice1].name}</div> ${mod.mods[choice1].description}</div>`
if (!mod.isDeterminism) {
choice2 = pick(choice1)
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice2})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice2].name}</div> ${mod.mods[choice2].description}</div>`
// if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice2})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice2].name}</div> ${mod.mods[choice2].description}</div>`
choice3 = pick(choice1, choice2)
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice3})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice3].name}</div> ${mod.mods[choice3].description}</div>`
// if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice3})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice3].name}</div> ${mod.mods[choice3].description}</div>`
}
if (mod.isExtraChoice) {
let choice4 = pick(choice1, choice2, choice3)
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice4})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice4].name}</div> ${mod.mods[choice4].description}</div>`
// if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice4})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice4].name}</div> ${mod.mods[choice4].description}</div>`
let choice5 = pick(choice1, choice2, choice3, choice4)
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice5})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice5].name}</div> ${mod.mods[choice5].description}</div>`
// if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice5})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice5].name}</div> ${mod.mods[choice5].description}</div>`
powerUps.mod.choiceLog.push(choice4)
powerUps.mod.choiceLog.push(choice5)
}

View File

@@ -1440,38 +1440,22 @@ const spawn = {
launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) {
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1];
me.accelMag = 0.00002 * game.accelScale;
me.accelMag = 0.00004 * game.accelScale;
me.fireFreq = Math.floor(420 + 90 * Math.random() * game.CDScale)
me.frictionStatic = 0;
me.friction = 0;
// me.memory = 200;
me.delay = 770 * game.CDScale;
me.cd = Infinity;
me.frictionAir = 0.02;
spawn.shield(me, x, y);
me.onDamage = function () {};
me.do = function () {
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
if (
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
!mech.isStealth
) {
this.foundPlayer();
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.3;
} else if (this.seePlayer.recall) {
this.lostPlayer();
this.cd = Infinity
}
}
this.seePlayerCheck();
this.checkStatus();
this.attraction();
if (this.seePlayer.recall && this.cd < game.cycle) {
this.cd = game.cycle + this.delay;
// this.torque += 0.0002 * this.inertia;
if (this.seePlayer.recall && !(game.cycle % this.fireFreq)) {
Matter.Body.setAngularVelocity(this, 0.14)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 5)
spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6)
//give the bullet a rotational velocity as if they were attached to a vertex
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -8)
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -1482,40 +1466,29 @@ const spawn = {
}
};
},
launcherBoss(x, y, radius = 75 + Math.ceil(Math.random() * 20)) {
mobs.spawn(x, y, 7, radius, "rgb(150,150,255)");
launcherBoss(x, y, radius = 90) {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1];
me.accelMag = 0.000065 * game.accelScale;
me.memory = 720;
me.delay = 420 * game.CDScale;
me.cd = Infinity;
me.accelMag = 0.00008 * game.accelScale;
me.fireFreq = Math.floor(330 * game.CDScale)
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.02;
me.memory = 420 * game.CDScale;
me.repulsionRange = 1200000; //squared
spawn.shield(me, x, y, 1);
me.onDamage = function () {};
Matter.Body.setDensity(me, 0.002 + 0.0002 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.004 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
};
me.onDamage = function () {};
me.do = function () {
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
if (
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
!mech.isStealth
) {
this.foundPlayer();
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.2;
} else if (this.seePlayer.recall) {
this.lostPlayer();
this.cd = Infinity
}
}
this.seePlayerCheck();
this.checkStatus();
this.attraction();
if (this.seePlayer.recall && this.cd < game.cycle) {
this.cd = game.cycle + this.delay;
// this.torque += 0.0002 * this.inertia;
this.repulsion();
if (this.seePlayer.recall && !(game.cycle % this.fireFreq)) {
Matter.Body.setAngularVelocity(this, 0.11)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -1530,17 +1503,17 @@ const spawn = {
}
};
},
seeker(x, y, radius = 6, sides = 0) {
seeker(x, y, radius = 5, sides = 0) {
//bullets
mobs.spawn(x, y, sides, radius, "rgb(0,0,255)");
mobs.spawn(x, y, sides, radius, "rgb(100,100,255)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
me.onHit = function () {
this.explode(this.mass * 10);
};
Matter.Body.setDensity(me, 0.00005); //normal is 0.001
me.timeLeft = 380 * (0.8 + 0.4 * Math.random());
me.accelMag = 0.00012 * (0.8 + 0.4 * Math.random()) * game.accelScale;
me.timeLeft = 420 * (0.8 + 0.4 * Math.random());
me.accelMag = 0.00015 * (0.8 + 0.4 * Math.random()) * game.accelScale;
me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random());
me.restitution = 0.5;
me.leaveBody = false;

View File

@@ -1,34 +1,6 @@
mob: launchers now have a new fire mechanic
mob: launcher boss
huge rework of code organization, this might produce some new bugs around mods
************** TODO - n-gon **************
launchers shouldn't have to face the player
fire after a spin
give bullets velocity from spin
mob boss - launcher
lower tier of basic mods
33% chance for basic mod on each selection
make an odds variable that starts at 0% and gains 33% for each normal mod, resets to 0% after get a basic mod
don't track these mods for avoiding no repeats
make ball different color to indicate quality
basic: grey? smaller size?
also make gun/field specific mods have a different icon for top tier
don't include basic mods in custom mod?
basic mods can show on guns or fields?
ideas
+5% damage
+8% haste
+5% damage reduction
+25% max health
+25% max energy
spawn 2 ammo //or 3?
spawn 2 heal
spawn 2 reroll //or 1?
movement fluidity
let legs jump on mobs, but player will still take damage
like: ori and the blind forest, celeste
@@ -41,7 +13,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?