Hey Listen!

snakeBoss is now dragonFlyBoss
  snakeSpitBoss till exists, don't worry

flutter and beetle mobs changes

Noether violation has 50% less forward recoil for shotgun
This commit is contained in:
landgreen
2022-08-01 08:54:24 -07:00
parent 746e86cc4a
commit 05a263e31f
6 changed files with 112 additions and 64 deletions

View File

@@ -5433,8 +5433,8 @@ const b = {
}
if (tech.isShotgunReversed) {
player.force.x += 4 * knock * Math.cos(m.angle)
player.force.y += 4 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g
player.force.x += 1.6 * knock * Math.cos(m.angle)
player.force.y += 1.6 * knock * Math.sin(m.angle) - 3 * player.mass * simulation.g
} else if (tech.isShotgunRecoil) {
m.fireCDcycle -= 0.66 * (56 * b.fireCDscale)
player.force.x -= 2 * knock * Math.cos(m.angle)
@@ -5585,16 +5585,16 @@ const b = {
b.iceIX(25 + 20 * Math.random(), m.angle + spread * (Math.random() - 0.5))
}
} else if (tech.isFoamShot) {
const spread = (input.down ? 0.2 : 0.6)
const spread = (input.down ? 0.15 : 0.4)
const where = {
x: m.pos.x + 25 * Math.cos(m.angle),
y: m.pos.y + 25 * Math.sin(m.angle)
}
const number = 15 * (tech.isShotgunReversed ? 1.6 : 1)
const number = 16 * (tech.isShotgunReversed ? 1.6 : 1)
for (let i = 0; i < number; i++) {
const SPEED = 13 + 4 * Math.random();
const SPEED = 11 + 4 * Math.random();
const angle = m.angle + spread * (Math.random() - 0.5)
b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 6 + 8 * Math.random())
b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 8 + 7 * Math.random())
}
} else if (tech.isNeedles) {
const number = 9 * (tech.isShotgunReversed ? 1.6 : 1)

View File

@@ -16,7 +16,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(8 * 4) //30 is near max on hard //60 is near max on why
// level.difficultyIncrease(2 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100
// powerUps.research.changeRerolls(100000)
@@ -24,8 +24,9 @@ const level = {
// powerUps.research.changeRerolls(100)
// tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.giveTech("infrared diode");
// tech.giveTech("active cooling");
// tech.giveTech("pulse")
@@ -35,10 +36,12 @@ const level = {
// for (let i = 0; i < 1; i++) tech.giveTech("dynamic equilibrium")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
// spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500, 50)
// spawn.dragonFlyBoss(1900, -400)
// spawn.beetleBoss(1900, -400)
// for (let i = 0; i < 10; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// for (let i = 0; i < 2; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
@@ -2805,7 +2808,7 @@ const level = {
// spawn.laserTargetingBoss(1700, -500)
// spawn.powerUpBoss(1900, -500)
// spawn.powerUpBossBaby(3200, -500)
// spawn.snakeBoss(1700, -500)
// spawn.dragonFlyBoss(1700, -500)
// spawn.streamBoss(3200, -500)
// spawn.pulsarBoss(1700, -500)
// spawn.spawnerBossCulture(3200, -500)
@@ -5863,10 +5866,10 @@ const level = {
spawn.randomSmallMob(-900, 825);
if (simulation.difficulty > 1) {
if (Math.random() < 0.70) {
if (Math.random() < 0.80) {
spawn.randomLevelBoss(-800, -1300)
} else {
spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head
spawn.dragonFlyBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head
}
}
powerUps.addResearchToLevel() //needs to run after mobs are spawned
@@ -6546,7 +6549,7 @@ const level = {
spawn.tetherBoss(2300, -1300, { x: 2300, y: -1750 })
if (simulation.difficulty > 4) spawn.nodeGroup(2350, -1300, "spawns", 8, 20, 105);
} else {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss", "pulsarBoss"]);
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "dragonFlyBoss", "pulsarBoss"]);
}
}
}
@@ -7394,7 +7397,7 @@ const level = {
spawn.tetherBoss(3380, -1775, { x: 3775, y: -1775 })
if (simulation.difficulty > 4) spawn.nodeGroup(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else {
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "dragonFlyBoss", "laserBoss"]);
}
}
},
@@ -7843,7 +7846,7 @@ const level = {
// spawn.randomGroup(7700, -1100, 0.5);
spawn.randomGroup(9800, -1100, 0.5);
if (simulation.difficulty > 3) spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "snakeBoss", "spiderBoss", "historyBoss"])
if (simulation.difficulty > 3) spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "dragonFlyBoss", "spiderBoss", "historyBoss"])
spawn.secondaryBossChance(7900, -400)
//Boss Spawning

View File

@@ -589,7 +589,7 @@ const mobs = {
ctx.setLineDash([]);
}
},
wing(a, radius = 250, ellipticity = 0.4) {
wing(a, radius = 250, ellipticity = 0.4, dmg = 0.0004) {
const minorRadius = radius * ellipticity
const perp = { x: Math.cos(a), y: Math.sin(a) } //
const where = Vector.add(this.position, Vector.mult(perp, radius + 0.8 * this.radius))
@@ -601,8 +601,8 @@ const mobs = {
//check for wing -> player damage
const hitPlayer = Matter.Query.ray([player], this.position, Vector.add(this.position, Vector.mult(perp, radius * 2.05)), minorRadius)
if (hitPlayer.length && m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
m.damage(0.00008 * radius * simulation.dmgScale);
m.damage(dmg * simulation.dmgScale);
// m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
}
},
searchSpring() {

View File

@@ -5,8 +5,8 @@ const spawn = {
randomBossList: [
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss",
"beetleBoss"
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss", "timeSkipBoss",
"dragonFlyBoss", "beetleBoss"
],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -21,11 +21,11 @@ const spawn = {
},
pickList: ["starter", "starter"],
fullPickList: [
"flutter", "flutter", "flutter",
"hopper", "hopper", "hopper",
"slasher", "slasher", "slasher",
"stabber", "stabber", "stabber",
"springer", "springer", "springer",
"flutter", "flutter",
"shooter", "shooter",
"grenadier", "grenadier",
"striker", "striker",
@@ -2696,7 +2696,7 @@ const spawn = {
mobs.spawn(x, y, 7, radius, '#16576b');
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.0016); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
@@ -2714,7 +2714,7 @@ const spawn = {
// me.onDeath = function() {};
me.flapRate = 0.3 + Math.floor(3 * Math.random()) / 10 + 100 * me.accelMag
me.flapRadius = 100 + 75 * Math.random() + radius * 2
me.flapRadius = 75 + 50 * Math.random() + radius * 2
me.do = function() {
this.seePlayerByHistory()
this.checkStatus();
@@ -2764,9 +2764,12 @@ const spawn = {
me.nextHealthThreshold = 0.75
me.invulnerableCount = 0
me.flapRate = 0.25
me.wingSize = 0
me.wingGoal = 250
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 + 0.0006 * Math.sqrt(simulation.accelScale);
me.accelMag = 0.0005 + 0.0005 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.05;
me.seePlayerFreq = 30
me.memory = 420;
@@ -2777,22 +2780,53 @@ const spawn = {
me.fireDir = { x: 0, y: 0 }
spawn.shield(me, x, y);
// for (let i = 0, len = 4 + 0.2 * simulation.difficulty; i < len; ++i) {
// const phase = i / len * 2 * Math.PI
// const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
// spawn.flutter(where.x, where.y)
// len = 0.3 * simulation.difficulty //spawn some baby flutters
// if (len > 3) {
// for (let i = 0; i < len; ++i) {
// const phase = i / len * 2 * Math.PI
// const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
// spawn.flutter(where.x, where.y)
// }
// }
if (Math.random() < 0.3) {
const len = 0.1 * simulation.difficulty //spawn some baby flutters
let i = 0
let spawnFlutters = () => {
if (i < len) {
if (!(simulation.cycle % 30) && !simulation.paused && !simulation.isChoosing) {
const phase = i / len * 2 * Math.PI
const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
spawn.flutter(where.x, where.y)
i++
}
requestAnimationFrame(spawnFlutters);
}
}
requestAnimationFrame(spawnFlutters);
me.isAlreadyHadBabies = true
}
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
len = 0.2 * simulation.difficulty
if (len > 3) {
for (let i = 0; i < len; ++i) {
const phase = i / len * 2 * Math.PI
const where = Vector.add(this.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
spawn.flutter(where.x, where.y)
const len = 0.1 * simulation.difficulty //spawn some baby flutters
if (len > 3 && !this.isAlreadyHadBabies) {
let i = 0
let spawnFlutters = () => {
if (i < len) {
if (!(simulation.cycle % 20) && !simulation.paused && !simulation.isChoosing) {
const phase = i / len * 2 * Math.PI
const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
spawn.flutter(where.x, where.y)
i++
}
requestAnimationFrame(spawnFlutters);
}
}
requestAnimationFrame(spawnFlutters);
}
};
me.onDamage = function() {
@@ -2803,6 +2837,10 @@ const spawn = {
this.isInvulnerable = true
this.damageReduction = 0
this.frictionAir = 0
this.wingGoal = 0
this.wingSize = 0
this.flapRate += 0.1
this.accelMag *= 1.25
}
};
me.do = function() {
@@ -2814,6 +2852,7 @@ const spawn = {
this.isInvulnerable = false
this.damageReduction = this.startingDamageReduction
this.frictionAir = 0.05
this.wingGoal = 250
}
// //draw wings as if they are protecting
// const wingShield = (a, size) => {
@@ -2868,11 +2907,13 @@ const spawn = {
} else if (c < -threshold) {
this.torque -= turn;
}
const flapRate = 0.5
const flapArc = 0.7 //don't go past 1.57 for normal flaps
this.wingSize = 0.98 * this.wingSize + 0.02 * this.wingGoal
ctx.fillStyle = this.fill = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * flapRate), 250, 0.5)
this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * flapRate), 250, 0.5)
this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0008)
this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0008)
} else {
this.wingSize = 0.96 * this.wingSize + 0 //shrink while stunned
}
};
},
@@ -5944,13 +5985,13 @@ const spawn = {
Composite.add(engine.world, consBB[consBB.length - 1]);
// spawn.shield(me, x, y, 1);
},
snakeBoss(x, y, radius = 50) { //snake boss with a laser head
dragonFlyBoss(x, y, radius = 42) { //snake boss with a laser head
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
let angle = Math.PI
let mag = 300
const color1 = "#f27"
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
const color1 = "#00bfd9" //"#f27"
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, "#000"); //"rgb(55,170,170)"
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.0009 + 0.0002 * Math.sqrt(simulation.accelScale)
@@ -5971,18 +6012,34 @@ const spawn = {
this.seePlayerByHistory()
this.checkStatus();
this.attraction();
this.harmZone();
let a //used to set the angle of wings
if (this.isInvulnerable) {
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.lineWidth = 20;
ctx.strokeStyle = "rgba(255,255,255,0.7)";
ctx.lineWidth = 12;
ctx.strokeStyle = "rgba(255,255,255,0.9)";
ctx.stroke();
const sub = Vector.sub(this.position, this.snakeBody1.position)
a = Math.atan2(sub.y, sub.x)
} else {
a = Math.atan2(this.velocity.y, this.velocity.x)
}
ctx.fillStyle = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
this.wing(a + Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
this.wing(a - Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
this.wing(a - Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
this.wing(a + Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
};
me.flapRate = 0.4
me.flapArc = 0.2 //don't go past 1.57 for normal flaps
me.wingLength = 150
me.ellipticity = 0.3
me.angleOff = 0.4
//extra space to give head room
angle -= 0.1
mag -= 10
@@ -5992,16 +6049,13 @@ const spawn = {
mag -= (i < 2) ? -15 : 5
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), i === 0 ? 25 : 20);
if (i < 3) mob[mob.length - 1].snakeHeadID = me.id
if (i === 0) me.snakeBody1 = mob[mob.length - 1] //track this segment, so the difference in position between this segment and the head can be used to angle the wings
mob[mob.length - 1].previousTailID = previousTailID
previousTailID = mob[mob.length - 1].id
}
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
if (i % 2) {
mob[i].fill = "#333"
} else {
mob[i].fill = color1
}
mob[i].fill = `hsla(${160+40*Math.random()}, 100%, ${5 + 25*Math.random()*Math.random()}%, 0.9)`
}
//constraint with first 3 mobs in line
consBB[consBB.length] = Constraint.create({
@@ -6028,7 +6082,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1];
me.collisionFilter.mask = cat.bullet | cat.player | cat.mob //| cat.body
me.damageReduction = 0.2
me.damageReduction = 0.23
Matter.Body.setDensity(me, 0.005); //normal is 0.001
// me.accelMag = 0.0007 * simulation.accelScale;

View File

@@ -4164,7 +4164,7 @@ const tech = {
{
name: "Noether violation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Noether%27s_theorem' class="link">Noether violation</a>`,
description: "<strong>+60%</strong> <strong>shotgun</strong> <strong class='color-d'>damage</strong><br><strong>shotgun</strong> <strong>recoil</strong> is increased and <strong>reversed</strong>",
description: "<strong>+60%</strong> <strong>shotgun</strong> <strong class='color-d'>damage</strong><br><strong>shotgun</strong> <strong>recoil</strong> is <strong>reversed</strong>",
isGunTech: true,
maxCount: 1,
count: 0,

View File

@@ -1,27 +1,18 @@
******************************************************** NEXT PATCH **************************************************
mob: beetleBoss
mob: flutter
snakeBoss is now dragonFlyBoss
snakeSpitBoss till exists, don't worry
balance: all mobs at every level are about 2%-3% harder to kill
flutter and beetle mobs changes
Noether violation has 50% less forward recoil for shotgun
*********************************************************** TODO *****************************************************
wings
put in mob as a method?
add parameter for ellipticity
give snakeBoss wings?
mob mechanics
bullets hit player and stay attached for 4-5 seconds, slowing player
hopperBullets?
black hole sucker effect on tail
flickering wings
draw pair of circles at 2 different locations, like beetle wings flapping
draw as ellipse
damage player if caught in wings
vines
attached to map and grows, a series of spheres connected by vines
if node dies it's removed from tree