Prout.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import { Anim, Character, type CharacterContext } from './Character';
  2. import { aimDir } from './Mamie';
  3. /**
  4. * Captain Prout.
  5. * - Attack: cape swipe.
  6. * - Special: a small jetpack thrust (toward the aim, mostly up) that leaves a toxic cloud
  7. * behind: players inside get blurred vision and cough.
  8. * - Flaw: every thrust is heard ("PROUT !" for everyone, giving away where he is).
  9. */
  10. export class Prout extends Character {
  11. private capeTimer = 0;
  12. private puffTimer = 0;
  13. onAttack(ctx: CharacterContext): void {
  14. const p = this.stats.params;
  15. const [dx, dy] = aimDir(ctx);
  16. const reach = this.size + p.capeReach;
  17. const cx = ctx.x + dx * reach;
  18. const cy = ctx.y + dy * reach;
  19. ctx.hit(cx, cy, p.capeRadius, p.capeKnockback, p.capeStun);
  20. ctx.emitOp({ kind: 'carve', x: Math.round(cx), y: Math.round(cy), r: Math.round(p.capeCarve), power: Math.round(p.capePower) });
  21. this.capeTimer = p.capeAnim;
  22. }
  23. onSpecial(ctx: CharacterContext): void {
  24. const p = this.stats.params;
  25. const [dx] = aimDir(ctx);
  26. ctx.setVelocity(ctx.vx + dx * p.puffSide, Math.min(ctx.vy, 0) - p.puffLift);
  27. ctx.cloud(ctx.x, ctx.y + this.size * 0.8, p.cloudRadius, p.cloudLife);
  28. ctx.cue('prout');
  29. this.puffTimer = p.puffAnim;
  30. }
  31. override onTick(_ctx: CharacterContext, dt: number): void {
  32. this.capeTimer = Math.max(0, this.capeTimer - dt);
  33. this.puffTimer = Math.max(0, this.puffTimer - dt);
  34. }
  35. override anim(): number {
  36. return (this.capeTimer > 0 ? Anim.Attack : 0) | (this.puffTimer > 0 ? Anim.Special : 0);
  37. }
  38. }