base2020/src/game/Death.ts

87 lines
2.6 KiB
TypeScript

import { PlaySfx } from "../applet/Audio";
import {
FixedPoint,
Floor,
Location,
Polygon,
PolygonComponent,
RenderBounds,
} from "../ecs/Components";
import { Create, Id, Join, Lookup, Remove } from "../ecs/Data";
import { Data, Lifetime, Teams, World } from "./GameComponents";
export function SelfDestructMinions(data: Data, world: World) {
const bossKilled = Join(data, "boss", "hp")
.filter(([_boss, {hp}]) => hp < 0)
.length > 0;
if(bossKilled) {
Join(data, "hp")
.filter(([hp]) => hp.team == Teams.ENEMY)
.forEach(([hp]) => hp.hp = 0);
}
}
export function CheckHp(data: Data, world: World) {
Join(data, "hp", "id").forEach(([hp, id]) => {
if(hp.hp <= 0) {
// remove from game
Remove(data, id);
}
});
}
export function CheckLifetime(data: Data, world: World, interval: number) {
let particles = 0;
Join(data, "lifetime", "id").forEach(([lifetime, id]) => {
lifetime.time -= interval;
if(lifetime.time <= 0) {
// remove from game
Remove(data, id);
}
particles++;
});
}
export function SmokeDamage(data: Data, world: World) {
Join(data, "hp", "location").forEach(([hp, {X, Y}]) => {
// convert dealt damage to particles
const puffs = Floor(hp.receivedDamage / 3);
SpawnBlast(data, world, X, Y, 2 as FixedPoint, "#000", puffs);
hp.receivedDamage = Floor(hp.receivedDamage % 3);
});
}
function SpawnBlast(data: Data, world: World, x: FixedPoint, y: FixedPoint, size: FixedPoint, color: string, count: FixedPoint) {
for(let puff = 0; puff < count; puff++) {
const angle = Math.PI * 2 * puff / count;
SpawnPuff(data, world, x, y, size, color, angle);
}
}
function SpawnPuff(data: Data, world: World, x: FixedPoint, y: FixedPoint, size: FixedPoint, color: string, angle: number): Id {
return Create(data, {
location: new Location({
X: x,
Y: y,
VX: (Math.random() + 0.5) * 400 * Math.cos(angle),
VY: (Math.random() + 0.5) * 400 * -Math.sin(angle)
}),
bounds: new PolygonComponent({points: [
-size, -size,
-size, size,
size, size,
size, -size
] as FixedPoint[]}),
renderBounds: new RenderBounds({
color,
// TODO: work out standard layers
layer: 1
}),
// TODO: randomization breaks determinism. Might be safe for a smoke puff that doesn't effect gameplay, but bad hygeine
lifetime: new Lifetime({
time: Math.random() / 3
})
});
}