sniper mob balance, bot replication mod
This commit is contained in:
16
js/bullet.js
16
js/bullet.js
@@ -2077,7 +2077,7 @@ const b = {
|
|||||||
isEasyToAim: true,
|
isEasyToAim: true,
|
||||||
fire() {
|
fire() {
|
||||||
if (mech.crouch) {
|
if (mech.crouch) {
|
||||||
b.iceIX(20, 0.3)
|
b.iceIX(10, 0.3)
|
||||||
mech.fireCDcycle = mech.cycle + Math.floor(10 * mod.fireRate); // cool down
|
mech.fireCDcycle = mech.cycle + Math.floor(10 * mod.fireRate); // cool down
|
||||||
} else {
|
} else {
|
||||||
b.iceIX(2)
|
b.iceIX(2)
|
||||||
@@ -2160,13 +2160,23 @@ const b = {
|
|||||||
bullet[me].endCycle = Infinity
|
bullet[me].endCycle = Infinity
|
||||||
bullet[me].charge = 0;
|
bullet[me].charge = 0;
|
||||||
bullet[me].do = function () {
|
bullet[me].do = function () {
|
||||||
if ((!game.mouseDown && this.charge > 0.6)) { //fire on mouse release
|
if ((!game.mouseDown && this.charge > 0.6) || mech.energy < 0.005) { //fire on mouse release
|
||||||
|
if (mech.energy < 0.005) {
|
||||||
|
this.charge = 0.1;
|
||||||
|
mech.fireCDcycle = mech.cycle + 120; // cool down if out of energy
|
||||||
|
//normal bullet behavior occurs after firing, overwrite this function
|
||||||
|
this.do = function () {
|
||||||
|
this.force.y += this.mass * 0.001; //normal gravity
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mech.fireCDcycle = mech.cycle + 2; // set fire cool down
|
||||||
//normal bullet behavior occurs after firing, overwrite this function
|
//normal bullet behavior occurs after firing, overwrite this function
|
||||||
this.do = function () {
|
this.do = function () {
|
||||||
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mech.fireCDcycle = mech.cycle + 2; // set fire cool down
|
|
||||||
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
|
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
|
||||||
this.endCycle = game.cycle + 140
|
this.endCycle = game.cycle + 140
|
||||||
this.collisionFilter.category = cat.bullet
|
this.collisionFilter.category = cat.bullet
|
||||||
|
|||||||
19
js/engine.js
19
js/engine.js
@@ -136,6 +136,24 @@ function collisionChecks(event) {
|
|||||||
function collideMob(obj) {
|
function collideMob(obj) {
|
||||||
//player + mob collision
|
//player + mob collision
|
||||||
if (mech.immuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
|
if (mech.immuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
|
||||||
|
// const a = Object.values(event.pairs[0].contacts)
|
||||||
|
// contains = Matter.Bounds.contains({
|
||||||
|
// max: {
|
||||||
|
// x: player.position.x + 60,
|
||||||
|
// y: player.position.y + 120
|
||||||
|
// },
|
||||||
|
// min: {
|
||||||
|
// x: player.position.x - 60,
|
||||||
|
// y: player.position.y + 40
|
||||||
|
// }
|
||||||
|
// }, {
|
||||||
|
// x: a[0].vertex.x,
|
||||||
|
// y: a[0].vertex.y
|
||||||
|
// })
|
||||||
|
// // Matter.Query.point([jumpSensor], point)
|
||||||
|
// console.log(contains)
|
||||||
|
// if (!contains) {
|
||||||
|
|
||||||
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||||
mob[k].foundPlayer();
|
mob[k].foundPlayer();
|
||||||
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
||||||
@@ -179,6 +197,7 @@ function collisionChecks(event) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
//mob + bullet collisions
|
//mob + bullet collisions
|
||||||
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
||||||
|
|||||||
11
js/level.js
11
js/level.js
@@ -23,8 +23,8 @@ const level = {
|
|||||||
// mech.setField("pilot wave")
|
// mech.setField("pilot wave")
|
||||||
// mech.setField("phase decoherence field")
|
// mech.setField("phase decoherence field")
|
||||||
|
|
||||||
level.intro(); //starting level
|
// level.intro(); //starting level
|
||||||
// level.testing();
|
level.testing();
|
||||||
// level.stronghold()
|
// level.stronghold()
|
||||||
// level.bosses();
|
// level.bosses();
|
||||||
// level.satellite();
|
// level.satellite();
|
||||||
@@ -183,9 +183,10 @@ const level = {
|
|||||||
spawn.boost(1500, 0, 900);
|
spawn.boost(1500, 0, 900);
|
||||||
|
|
||||||
// spawn.bomberBoss(2900, -500)
|
// spawn.bomberBoss(2900, -500)
|
||||||
spawn.launcherBoss(1200, -500)
|
// spawn.launcherBoss(1200, -500)
|
||||||
spawn.launcher(1600, -400)
|
// spawn.sniper(1600, -400)
|
||||||
// spawn.spawner(1600, -500)
|
// spawn.sneaker(1600, -500)
|
||||||
|
spawn.sniper(1700, -120)
|
||||||
// spawn.cellBossCulture(1600, -500)
|
// spawn.cellBossCulture(1600, -500)
|
||||||
// spawn.shooter(1600, -500)
|
// spawn.shooter(1600, -500)
|
||||||
// spawn.striker(1600, -500)
|
// spawn.striker(1600, -500)
|
||||||
|
|||||||
61
js/mods.js
61
js/mods.js
@@ -330,7 +330,7 @@ const mod = {
|
|||||||
maxCount: 6,
|
maxCount: 6,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.foamBotCount > 0 || mod.nailBotCount > 0 || mod.laserBotCount > 0
|
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount > 0
|
||||||
},
|
},
|
||||||
requires: "a bot",
|
requires: "a bot",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -340,6 +340,38 @@ const mod = {
|
|||||||
mod.isBotSpawner = 0;
|
mod.isBotSpawner = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "self-replication",
|
||||||
|
description: "<strong>duplicate</strong> your permanent <strong>bots</strong><br>remove all your <strong>ammo</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
isNonRefundable: true,
|
||||||
|
allowed() {
|
||||||
|
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount > 1
|
||||||
|
},
|
||||||
|
requires: "2 or more bots",
|
||||||
|
effect() {
|
||||||
|
//remove ammo
|
||||||
|
for (let i = 0, len = b.guns.length; i < len; ++i) {
|
||||||
|
if (b.guns[i].ammo != Infinity) b.guns[i].ammo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//double bots
|
||||||
|
for (let i = 0; i < mod.nailBotCount; i++) {
|
||||||
|
b.nailBot();
|
||||||
|
}
|
||||||
|
mod.nailBotCount *= 2
|
||||||
|
for (let i = 0; i < mod.laserBotCount; i++) {
|
||||||
|
b.laserBot();
|
||||||
|
}
|
||||||
|
mod.laserBotCount *= 2
|
||||||
|
for (let i = 0; i < mod.foamBotCount; i++) {
|
||||||
|
b.foamBot();
|
||||||
|
}
|
||||||
|
mod.foamBotCount *= 2
|
||||||
|
},
|
||||||
|
remove() {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ablative mines",
|
name: "ablative mines",
|
||||||
description: "rebuild your broken parts as a <strong>mine</strong><br>chance to occur after being <strong>harmed</strong>",
|
description: "rebuild your broken parts as a <strong>mine</strong><br>chance to occur after being <strong>harmed</strong>",
|
||||||
@@ -769,6 +801,7 @@ const mod = {
|
|||||||
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong>power ups</strong> are limited to <strong>one choice</strong>",
|
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong>power ups</strong> are limited to <strong>one choice</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
// isNonRefundable: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !mod.isExtraChoice
|
return !mod.isExtraChoice
|
||||||
},
|
},
|
||||||
@@ -786,7 +819,7 @@ const mod = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "many-worlds",
|
name: "many-worlds",
|
||||||
description: "if you have <strong>zero</strong> <strong class='color-r'>rerolls</strong>, spawn a <strong class='color-r'>reroll</strong><br>after choosing a <strong>gun</strong>, <strong>field</strong>, or <strong class='color-m'>mod</strong>",
|
description: "after choosing a <strong>gun</strong>, <strong>field</strong>, or <strong class='color-m'>mod</strong><br>spawn a <strong class='color-r'>reroll</strong>, if you have none",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -844,6 +877,7 @@ const mod = {
|
|||||||
description: "<strong>remove</strong> all current <strong class='color-m'>mods</strong><br>spawn new <strong class='color-m'>mods</strong> to replace them",
|
description: "<strong>remove</strong> all current <strong class='color-m'>mods</strong><br>spawn new <strong class='color-m'>mods</strong> to replace them",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
isNonRefundable: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (mod.totalCount > 6) && !build.isCustomSelection
|
return (mod.totalCount > 6) && !build.isCustomSelection
|
||||||
},
|
},
|
||||||
@@ -853,23 +887,22 @@ const mod = {
|
|||||||
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
|
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
|
||||||
bullet = [];
|
bullet = [];
|
||||||
|
|
||||||
let count = mod.totalCount
|
let count = mod.totalCount + 1
|
||||||
if (mod.isDeterminism) count -= 4 //remove the 5 bonus mods when getting rid of determinism
|
if (mod.isDeterminism) count -= 5 //remove the 5 bonus mods when getting rid of determinism
|
||||||
for (let i = 0; i < count; i++) { // spawn new mods
|
mod.setupAllMods(); // remove all mods
|
||||||
|
for (let i = 0; i < count; i++) { // spawn new mods power ups
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
|
||||||
}
|
}
|
||||||
mod.setupAllMods(); // remove all mods
|
|
||||||
//have state is checked in mech.death()
|
//have state is checked in mech.death()
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {}
|
||||||
//nothing to undo
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reallocation",
|
name: "reallocation",
|
||||||
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods lose all stacks</em>",
|
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods lose all stacks</em>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
isNonRefundable: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (mod.totalCount > 0) && !build.isCustomSelection
|
return (mod.totalCount > 0) && !build.isCustomSelection
|
||||||
},
|
},
|
||||||
@@ -889,9 +922,7 @@ const mod = {
|
|||||||
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {}
|
||||||
//nothing to remove
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
//**************************************************
|
//**************************************************
|
||||||
//************************************************** gun
|
//************************************************** gun
|
||||||
@@ -1178,7 +1209,7 @@ const mod = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "self-replication",
|
name: "recursion",
|
||||||
description: "after <strong>missiles</strong> <strong class='color-e'>explode</strong><br>they launch <strong>+1</strong> smaller <strong>missile</strong>",
|
description: "after <strong>missiles</strong> <strong class='color-e'>explode</strong><br>they launch <strong>+1</strong> smaller <strong>missile</strong>",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -1674,7 +1705,7 @@ const mod = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "renormalization",
|
name: "renormalization",
|
||||||
description: "<strong>phase decoherence</strong> has increased <strong>visibility</strong><br>and <strong>5x</strong> less <strong class='color-f'>energy</strong> drain when <strong>firing</strong>",
|
description: "<strong>phase decoherence</strong> adds <strong>visibility</strong> to bullets<br><strong>5x</strong> less <strong class='color-f'>energy</strong> drain when <strong>firing</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -1691,7 +1722,7 @@ const mod = {
|
|||||||
{
|
{
|
||||||
name: "superposition",
|
name: "superposition",
|
||||||
// description: "<strong>phase decoherence field</strong> applies a <strong>stun</strong><br> to unshielded <strong>mobs</strong> for <strong>2</strong> seconds",
|
// description: "<strong>phase decoherence field</strong> applies a <strong>stun</strong><br> to unshielded <strong>mobs</strong> for <strong>2</strong> seconds",
|
||||||
description: "apply a <strong>4</strong> second <strong>stun</strong> to unshielded <strong>mobs</strong><br>that <strong>overlap</strong> with <strong>phase decoherence field</strong>",
|
description: "while <strong>phase decoherence field</strong> is active<br>mobs that <strong>overlap</strong> with the player are <strong>stunned</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
|
|||||||
@@ -372,11 +372,8 @@ const mech = {
|
|||||||
let options = [];
|
let options = [];
|
||||||
for (let i = 0, len = mod.mods.length; i < len; i++) {
|
for (let i = 0, len = mod.mods.length; i < len; i++) {
|
||||||
if (mod.mods[i].count < mod.mods[i].maxCount &&
|
if (mod.mods[i].count < mod.mods[i].maxCount &&
|
||||||
|
!mod.mods[i].isNonRefundable &&
|
||||||
mod.mods[i].name !== "quantum immortality" &&
|
mod.mods[i].name !== "quantum immortality" &&
|
||||||
mod.mods[i].name !== "Born rule" &&
|
|
||||||
mod.mods[i].name !== "determinism" &&
|
|
||||||
mod.mods[i].name !== "reallocation" &&
|
|
||||||
mod.mods[i].name !== "many-worlds" &&
|
|
||||||
mod.mods[i].allowed()
|
mod.mods[i].allowed()
|
||||||
) options.push(i);
|
) options.push(i);
|
||||||
}
|
}
|
||||||
|
|||||||
180
js/spawn.js
180
js/spawn.js
@@ -2,25 +2,26 @@
|
|||||||
const spawn = {
|
const spawn = {
|
||||||
pickList: ["starter", "starter"],
|
pickList: ["starter", "starter"],
|
||||||
fullPickList: [
|
fullPickList: [
|
||||||
"shooter", "shooter", "shooter", "shooter",
|
// "hopper", "hopper", "hopper", "hopper",
|
||||||
"hopper", "hopper", "hopper", "hopper",
|
// "shooter", "shooter", "shooter",
|
||||||
"chaser", "chaser", "chaser",
|
// "chaser", "chaser",
|
||||||
"striker", "striker",
|
// "striker", "striker",
|
||||||
"laser", "laser",
|
// "laser", "laser",
|
||||||
"exploder", "exploder",
|
// "exploder", "exploder",
|
||||||
"stabber", "stabber",
|
// "stabber", "stabber",
|
||||||
"launcher", "launcher",
|
// "launcher", "launcher",
|
||||||
"spinner",
|
"sniper",
|
||||||
"grower",
|
// "spinner",
|
||||||
"springer",
|
// "grower",
|
||||||
"beamer",
|
// "springer",
|
||||||
"focuser",
|
// "beamer",
|
||||||
"sucker",
|
// "focuser",
|
||||||
"spawner",
|
// "sucker",
|
||||||
"ghoster",
|
// "spawner",
|
||||||
"sneaker",
|
// "ghoster",
|
||||||
|
// "sneaker",
|
||||||
],
|
],
|
||||||
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber"],
|
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper"],
|
||||||
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||||
//each level has 2 mobs: one new mob and one from the last level
|
//each level has 2 mobs: one new mob and one from the last level
|
||||||
spawn.pickList.splice(0, 1);
|
spawn.pickList.splice(0, 1);
|
||||||
@@ -1353,7 +1354,8 @@ const spawn = {
|
|||||||
shooter(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
|
shooter(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
|
||||||
mobs.spawn(x, y, 3, radius, "rgb(255,100,150)");
|
mobs.spawn(x, y, 3, radius, "rgb(255,100,150)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.vertices = Matter.Vertices.clockwiseSort(Matter.Vertices.rotate(me.vertices, Math.PI, me.position)); //make the pointy side of triangle the front
|
// me.vertices = Matter.Vertices.clockwiseSort(Matter.Vertices.rotate(me.vertices, Math.PI, me.position)); //make the pointy side of triangle the front
|
||||||
|
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||||
me.isVerticesChange = true
|
me.isVerticesChange = true
|
||||||
// Matter.Body.rotate(me, Math.PI)
|
// Matter.Body.rotate(me, Math.PI)
|
||||||
|
|
||||||
@@ -1437,6 +1439,146 @@ const spawn = {
|
|||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
sniper(x, y, radius = 35 + Math.ceil(Math.random() * 30)) {
|
||||||
|
mobs.spawn(x, y, 3, radius, "transparent"); //"rgb(25,0,50)")
|
||||||
|
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
|
||||||
|
me.isVerticesChange = true
|
||||||
|
// Matter.Body.rotate(me, Math.PI)
|
||||||
|
me.stroke = "transparent"; //used for drawSneaker
|
||||||
|
me.alpha = 1; //used in drawSneaker
|
||||||
|
me.showHealthBar = false;
|
||||||
|
|
||||||
|
me.canTouchPlayer = false; //used in drawSneaker
|
||||||
|
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
|
|
||||||
|
me.memory = 60 //140;
|
||||||
|
me.fireFreq = 0.006 + Math.random() * 0.002;
|
||||||
|
me.noseLength = 0;
|
||||||
|
me.fireAngle = 0;
|
||||||
|
me.accelMag = 0.0005 * game.accelScale;
|
||||||
|
me.frictionAir = 0.05;
|
||||||
|
me.torque = 0.0001 * me.inertia;
|
||||||
|
me.fireDir = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
|
||||||
|
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
|
||||||
|
}
|
||||||
|
// spawn.shield(me, x, y);
|
||||||
|
me.do = function () {
|
||||||
|
// this.seePlayerByLookingAt();
|
||||||
|
this.seePlayerCheck();
|
||||||
|
this.checkStatus();
|
||||||
|
|
||||||
|
if (!mech.isBodiesAsleep) {
|
||||||
|
const setNoseShape = () => {
|
||||||
|
const mag = this.radius + this.radius * this.noseLength;
|
||||||
|
this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag;
|
||||||
|
this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag;
|
||||||
|
};
|
||||||
|
//throw a mob/bullet at player
|
||||||
|
if (this.seePlayer.recall) {
|
||||||
|
//set direction to turn to fire
|
||||||
|
if (!(game.cycle % this.seePlayerFreq)) {
|
||||||
|
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||||
|
// this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
|
||||||
|
}
|
||||||
|
//rotate towards fireAngle
|
||||||
|
const angle = this.angle + Math.PI / 2;
|
||||||
|
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||||
|
const threshold = 0.2;
|
||||||
|
if (c > threshold) {
|
||||||
|
this.torque += 0.000004 * this.inertia;
|
||||||
|
} else if (c < -threshold) {
|
||||||
|
this.torque -= 0.000004 * this.inertia;
|
||||||
|
} else if (this.noseLength > 1.5) {
|
||||||
|
//fire
|
||||||
|
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 4);
|
||||||
|
const v = 20 * game.accelScale;
|
||||||
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
|
x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
||||||
|
y: this.velocity.y + this.fireDir.y * v + Math.random()
|
||||||
|
});
|
||||||
|
this.noseLength = 0;
|
||||||
|
// recoil
|
||||||
|
this.force.x -= 0.005 * this.fireDir.x * this.mass;
|
||||||
|
this.force.y -= 0.005 * this.fireDir.y * this.mass;
|
||||||
|
} else {
|
||||||
|
this.torque += 0.000001 * this.inertia; //
|
||||||
|
}
|
||||||
|
if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
|
||||||
|
setNoseShape();
|
||||||
|
} else if (this.noseLength > 0.1) {
|
||||||
|
this.noseLength -= this.fireFreq / 2;
|
||||||
|
setNoseShape();
|
||||||
|
}
|
||||||
|
// else if (this.noseLength < -0.1) {
|
||||||
|
// this.noseLength += this.fireFreq / 4;
|
||||||
|
// setNoseShape();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (this.seePlayer.recall) {
|
||||||
|
if (this.alpha < 1) this.alpha += 0.01;
|
||||||
|
} else {
|
||||||
|
if (this.alpha > 0) this.alpha -= 0.03;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//draw
|
||||||
|
if (this.alpha > 0) {
|
||||||
|
if (this.alpha > 0.95) {
|
||||||
|
this.healthBar();
|
||||||
|
if (!this.canTouchPlayer) {
|
||||||
|
this.canTouchPlayer = true;
|
||||||
|
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//draw body
|
||||||
|
ctx.beginPath();
|
||||||
|
const vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1, len = vertices.length; j < len; ++j) {
|
||||||
|
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
ctx.fillStyle = `rgba(25,0,50,${this.alpha * this.alpha})`;
|
||||||
|
ctx.fill();
|
||||||
|
} else if (this.canTouchPlayer) {
|
||||||
|
this.canTouchPlayer = false;
|
||||||
|
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
sniperBullet(x, y, radius = 6, sides = 4) {
|
||||||
|
//bullets
|
||||||
|
mobs.spawn(x, y, sides, radius, "rgb(190,0,255)");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
me.stroke = "transparent";
|
||||||
|
me.onHit = function () {
|
||||||
|
this.explode(this.mass * 10);
|
||||||
|
};
|
||||||
|
Matter.Body.setDensity(me, 0.0001); //normal is 0.001
|
||||||
|
me.timeLeft = 240;
|
||||||
|
me.g = 0.001; //required if using 'gravity'
|
||||||
|
me.frictionAir = 0;
|
||||||
|
me.restitution = 0;
|
||||||
|
me.leaveBody = false;
|
||||||
|
me.dropPowerUp = false;
|
||||||
|
me.showHealthBar = false;
|
||||||
|
me.collisionFilter.category = cat.mobBullet;
|
||||||
|
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||||
|
me.do = function () {
|
||||||
|
// this.gravity();
|
||||||
|
this.timeLimit();
|
||||||
|
if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0) {
|
||||||
|
// this.timeLeft = 0
|
||||||
|
this.dropPowerUp = false;
|
||||||
|
this.death(); //death with no power up
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) {
|
launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) {
|
||||||
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
|
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
|
|||||||
5
todo.txt
5
todo.txt
@@ -1,6 +1,11 @@
|
|||||||
|
new mod: doubles current bots
|
||||||
|
|
||||||
************** TODO - n-gon **************
|
************** TODO - n-gon **************
|
||||||
|
|
||||||
|
shielded mobs don't knock back the same as unshielded mobs
|
||||||
|
|
||||||
|
buff harmonic field to cover legs
|
||||||
|
|
||||||
movement fluidity
|
movement fluidity
|
||||||
let legs jump on mobs, but player will still take damage
|
let legs jump on mobs, but player will still take damage
|
||||||
like: ori and the blind forest, celeste
|
like: ori and the blind forest, celeste
|
||||||
|
|||||||
Reference in New Issue
Block a user