Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
Half-Shot committed Mar 10, 2025
1 parent 040e713 commit 1cab1a3
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 106 deletions.
72 changes: 38 additions & 34 deletions src/entities/playable/conditions/index.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
import { ColorSource } from "pixi.js";

export enum PlayableCondition {
Sickness = "sickness",
Metallic = "metallic",
Sickness = "sickness",
Metallic = "metallic",
}

export interface PlayableConditonAttributes {
takeDamagePerRound?: number;
hue?: ColorSource,
cannotDieFromDamage?: boolean;
damageMultiplier?: number;
forceMultiplier?: number;
takeDamagePerRound?: number;
hue?: ColorSource;
cannotDieFromDamage?: boolean;
damageMultiplier?: number;
forceMultiplier?: number;
}

export function getConditionEffect(condition: PlayableCondition): PlayableConditonAttributes {
switch (condition) {
case PlayableCondition.Sickness:
return {
takeDamagePerRound: 5,
cannotDieFromDamage: true,
hue: 'rgba(34, 204, 0, 0.47)'
}
case PlayableCondition.Metallic:
return {
hue: 'rgba(100, 100, 100, 0.6)',
damageMultiplier: 0.75,
forceMultiplier: 0.25,
}
}
export function getConditionEffect(
condition: PlayableCondition,
): PlayableConditonAttributes {
switch (condition) {
case PlayableCondition.Sickness:
return {
takeDamagePerRound: 5,
cannotDieFromDamage: true,
hue: "rgba(34, 204, 0, 0.47)",
};
case PlayableCondition.Metallic:
return {
hue: "rgba(100, 100, 100, 0.6)",
damageMultiplier: 0.75,
forceMultiplier: 0.25,
};
}
}

export function getConditionTint(conditions: Iterable<PlayableCondition>): ColorSource | null {
let tint = null;
// Priority ordering
for (const condition of conditions) {
switch (condition) {
case PlayableCondition.Sickness:
return 'rgba(34, 204, 0, 0.47)';
case PlayableCondition.Metallic:
tint = 'rgba(100, 100, 100, 0.6)';
}
export function getConditionTint(
conditions: Iterable<PlayableCondition>,
): ColorSource | null {
let tint = null;
// Priority ordering
for (const condition of conditions) {
switch (condition) {
case PlayableCondition.Sickness:
return "rgba(34, 204, 0, 0.47)";
case PlayableCondition.Metallic:
tint = "rgba(100, 100, 100, 0.6)";
}
return tint;
}
}
return tint;
}
91 changes: 52 additions & 39 deletions src/entities/playable/playable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { HEALTH_CHANGE_TENSION_TIMER_MS } from "../../consts";
import { first, skip, Subscription } from "rxjs";
import Logger from "../../log";
import { TiledSpriteAnimated } from "../../utils/tiledspriteanimated";
import { getConditionEffect, PlayableCondition, PlayableConditonAttributes } from "./conditions";
import { getConditionEffect, PlayableCondition } from "./conditions";

interface Opts {
explosionRadius: MetersValue;
Expand Down Expand Up @@ -246,37 +246,45 @@ export abstract class PlayableEntity<
}

public reduceHealth(damage: number) {
const damageMultiplier = this.conditions.values().map(v => getConditionEffect(v).damageMultiplier).reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return Math.min(v, c);
}) ?? 1;
this.wormIdent.setHealth(this.wormIdent.health - (damage * damageMultiplier));
const damageMultiplier =
this.conditions
.values()
.map((v) => getConditionEffect(v).damageMultiplier)
.reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return Math.min(v, c);
}) ?? 1;
this.wormIdent.setHealth(this.wormIdent.health - damage * damageMultiplier);
}

public roundTick() {
const { takeDamagePerRound, cannotDieFromDamage } = this.conditions.values().map(v => {
const condtion = getConditionEffect(v);
return {
takeDamagePerRound: condtion.takeDamagePerRound ?? 0,
cannotDieFromDamage: condtion.cannotDieFromDamage ?? false,
}
}).reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return {
cannotDieFromDamage: v.cannotDieFromDamage || c.cannotDieFromDamage,
takeDamagePerRound: v.takeDamagePerRound + c.takeDamagePerRound,
};
}) ?? 0;
const { takeDamagePerRound, cannotDieFromDamage } =
this.conditions
.values()
.map((v) => {
const condtion = getConditionEffect(v);
return {
takeDamagePerRound: condtion.takeDamagePerRound ?? 0,
cannotDieFromDamage: condtion.cannotDieFromDamage ?? false,
};
})
.reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return {
cannotDieFromDamage: v.cannotDieFromDamage || c.cannotDieFromDamage,
takeDamagePerRound: v.takeDamagePerRound + c.takeDamagePerRound,
};
}) ?? 0;
if (takeDamagePerRound) {
if (cannotDieFromDamage && this.wormIdent.health > takeDamagePerRound) {
this.reduceHealth(takeDamagePerRound);
Expand All @@ -298,16 +306,21 @@ export abstract class PlayableEntity<
);
const damage = maxDamage / distance;
this.reduceHealth(damage);
const forceMultiplier = this.conditions.values().map(v => getConditionEffect(v).forceMultiplier).reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return Math.min(v, c);
}) ?? 1;
const forceMag = Math.abs((radius.value * 10) / (1 / distance)) * forceMultiplier;
const forceMultiplier =
this.conditions
.values()
.map((v) => getConditionEffect(v).forceMultiplier)
.reduce((v, c) => {
if (c === undefined) {
return v;
}
if (v === undefined) {
return c;
}
return Math.min(v, c);
}) ?? 1;
const forceMag =
Math.abs((radius.value * 10) / (1 / distance)) * forceMultiplier;
const massagedY = point.y + 5;
const force = mult(
{
Expand Down
4 changes: 2 additions & 2 deletions src/entities/playable/worm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ export class Worm extends PlayableEntity<WormRecordedState> {
}
(this.sprite as TiledSpriteAnimated).update(dMs);
this.wireframe.setDebugText(
`worm_state: ${this.state.stateName}, velocity: ${this.body.linvel().y} ${this.impactVelocity}, aim: ${this.fireAngle}, friction: ${this.collider.friction()}, conditions: ${this.conditions.values().toArray().join(', ')}`,
`worm_state: ${this.state.stateName}, velocity: ${this.body.linvel().y} ${this.impactVelocity}, aim: ${this.fireAngle}, friction: ${this.collider.friction()}, conditions: ${this.conditions.values().toArray().join(", ")}`,
);
this.weaponSprite.visible = this.state.showWeapon;
this.arrowSprite.visible = this.state.canMove && !this.hasPerformedAction;
Expand Down Expand Up @@ -750,7 +750,7 @@ export class Worm extends PlayableEntity<WormRecordedState> {
} else {
this.weaponSprite.position.set(
this.sprite.x -
(this.sprite.width + this.currentWeapon.sprite.offset.x),
(this.sprite.width + this.currentWeapon.sprite.offset.x),
this.sprite.y + this.currentWeapon.sprite.offset.y,
);
this.weaponSprite.rotation = this.fireAngle - Math.PI;
Expand Down
24 changes: 16 additions & 8 deletions src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const tickEveryMs = 1000 / 90;

const logger = new Logger("Game");

export class Game<ReloadedGameState extends object = {}> {
export class Game<ReloadedGameState extends object = object> {
public readonly viewport: Viewport;
private readonly rapierWorld: RAPIER.World;
public readonly world: GameWorld;
Expand All @@ -45,7 +45,9 @@ export class Game<ReloadedGameState extends object = {}> {
public readonly ready$ = this.ready.asObservable();
private lastPhysicsTick: number = 0;
public overlay?: GameDebugOverlay;
private readonly reloadState = new BehaviorSubject<ReloadedGameState | null>(null);
private readonly reloadState = new BehaviorSubject<ReloadedGameState | null>(
null,
);
public readonly needsReload$ = this.reloadState.pipe(filter((s) => !!s));

public get pixiRoot() {
Expand All @@ -63,7 +65,14 @@ export class Game<ReloadedGameState extends object = {}> {
await RAPIER.init();
const pixiApp = new Application();
await pixiApp.init({ resizeTo: window, preference: "webgl" });
return new Game(pixiApp, scenario, gameReactChannel, gameInstance, level, previousGameState);
return new Game(
pixiApp,
scenario,
gameReactChannel,
gameInstance,
level,
previousGameState,
);
}

constructor(
Expand All @@ -90,10 +99,10 @@ export class Game<ReloadedGameState extends object = {}> {
this.world =
netGameInstance instanceof RunningNetGameInstance
? new NetGameWorld(
this.rapierWorld,
this.pixiApp.ticker,
netGameInstance,
)
this.rapierWorld,
this.pixiApp.ticker,
netGameInstance,
)
: new GameWorld(this.rapierWorld, this.pixiApp.ticker);
this.pixiApp.stage.addChild(this.viewport);
this.viewport.decelerate().drag();
Expand Down Expand Up @@ -127,7 +136,6 @@ export class Game<ReloadedGameState extends object = {}> {
throw new CriticalGameError(Error("Invalid level name"));
}


this.overlay = new GameDebugOverlay(
this.rapierWorld,
this.pixiApp.ticker,
Expand Down
10 changes: 8 additions & 2 deletions src/interop/gamechannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ type GameReactChannelEvents<ReloadedGameState extends object> = {
saveGameState: (callback: (state: ReloadedGameState) => void) => void;
};

export class GameReactChannel<ReloadedGameState extends object = object> extends (EventEmitter as new () => TypedEmitter<GameReactChannelEvents<object>>) {
export class GameReactChannel<
ReloadedGameState extends object = object,
> extends (EventEmitter as new () => TypedEmitter<
GameReactChannelEvents<object>
>) {
constructor() {
super();
}
Expand All @@ -45,7 +49,9 @@ export class GameReactChannel<ReloadedGameState extends object = object> extends

public async saveGameState(): Promise<ReloadedGameState> {
return new Promise((resolve) =>
this.emit("saveGameState", (state) => resolve(state as ReloadedGameState)),
this.emit("saveGameState", (state) =>
resolve(state as ReloadedGameState),
),
);
}
}
12 changes: 10 additions & 2 deletions src/overlays/debugOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class GameDebugOverlay {
Math.ceil(
(this.physicsSamples.reduce((a, b) => a + b, 0) /
(this.physicsSamples.length || 1)) *
100,
100,
) / 100;

this.text.text = [
Expand All @@ -121,7 +121,15 @@ export class GameDebugOverlay {
`Total bodies: ${this.rapierWorld.bodies.len()}`,
`Mouse: ${Math.round(this.mouse.x)} ${Math.round(this.mouse.y)}`,
`Ticker fns: ${this.ticker.count}`,
].concat(this.textFields.values().filter(v => !!v.text).map(v => v.text).toArray()).join(' | ')
]
.concat(
this.textFields
.values()
.filter((v) => !!v.text)
.map((v) => v.text)
.toArray(),
)
.join(" | ");

this.skippedUpdatesTarget = 180 / avgFps;

Expand Down
37 changes: 18 additions & 19 deletions src/scenarios/netGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default async function runScenario(game: Game<HotReloadGameState>) {

game.gameReactChannel.on("saveGameState", (cb) => {
cb({
iteration: iteration + 1
iteration: iteration + 1,
} satisfies HotReloadGameState);
});

Expand Down Expand Up @@ -236,22 +236,22 @@ export default async function runScenario(game: Game<HotReloadGameState>) {
const wormEnt = world.addEntity(
wormInstance.team.playerUserId === myUserId
? Worm.create(
parent,
world,
pos,
wormInstance,
fireFn,
overlay.toaster,
stateRecorder,
)
parent,
world,
pos,
wormInstance,
fireFn,
overlay.toaster,
stateRecorder,
)
: RemoteWorm.create(
parent,
world,
pos,
wormInstance,
fireFn,
overlay.toaster,
),
parent,
world,
pos,
wormInstance,
fireFn,
overlay.toaster,
),
wormInstance.uuid,
);
wormEnt.addCondition(PlayableCondition.Sickness);
Expand Down Expand Up @@ -316,12 +316,11 @@ export default async function runScenario(game: Game<HotReloadGameState>) {
}
}


combineLatest([gameState.roundState$])
.pipe(filter(([state]) => state === RoundState.Finished))
.subscribe(() => {
log.info("Round tick")
wormInstances.forEach(w => w.roundTick());
log.info("Round tick");
wormInstances.forEach((w) => w.roundTick());
});

combineLatest([gameState.roundState$, gameState.remainingRoundTimeSeconds$])
Expand Down

0 comments on commit 1cab1a3

Please sign in to comment.