first commmit
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { AttackType } from '../data/Interfaces';
|
||||
import { PlayerStateMachine, DamageOutcome } from './PlayerStateMachine';
|
||||
|
||||
/**
|
||||
* DamageSystem — the single funnel through which **every** player-facing
|
||||
* damage event must flow (req 10.1-10.6).
|
||||
*
|
||||
* Decision precedence (req 10.3):
|
||||
* 1. i-frames → no effect
|
||||
* 2. sword parry → no effect (only vs. shuriken/sword; see PSM)
|
||||
* 3. attack type × distance → dispatch to PlayerStateMachine.takeHit
|
||||
*
|
||||
* Distance thresholds:
|
||||
* - fireball: lethal within 100px (req 10.4)
|
||||
* - smoke bomb: lethal within 80px (req 10.5)
|
||||
* - shuriken / sword: any contact is eligible
|
||||
*
|
||||
* Enemy-facing damage is a separate, simpler `applyToEnemy` helper.
|
||||
*/
|
||||
|
||||
export interface IDamageContext {
|
||||
attackType: AttackType;
|
||||
attackerX: number;
|
||||
attackerY: number;
|
||||
victimX: number;
|
||||
victimY: number;
|
||||
}
|
||||
|
||||
export const FIREBALL_KILL_RADIUS = 100;
|
||||
export const SMOKE_KILL_RADIUS = 80;
|
||||
|
||||
export class DamageSystem {
|
||||
constructor(private readonly psm: PlayerStateMachine) {}
|
||||
|
||||
/** Try to damage the player. Returns `null` if the attack missed by distance. */
|
||||
public applyToPlayer(ctx: IDamageContext): DamageOutcome | null {
|
||||
const distance = Math.hypot(ctx.attackerX - ctx.victimX, ctx.attackerY - ctx.victimY);
|
||||
if (ctx.attackType === 'fireball' && distance > FIREBALL_KILL_RADIUS) return null;
|
||||
if (ctx.attackType === 'smoke_bomb' && distance > SMOKE_KILL_RADIUS) return null;
|
||||
// shuriken / sword rely on caller-side hitbox; reaching here means "hit".
|
||||
return this.psm.takeHit(ctx.attackType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply flat damage to an enemy HP bucket. The damage number comes from
|
||||
* the active weapon config. Returns the remaining HP (0 means killed).
|
||||
*/
|
||||
public applyToEnemy(currentHp: number, damage: number): number {
|
||||
return Math.max(0, currentHp - damage);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user