@bardway/trpg-pixi 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +10 -0
  3. package/NOTICE.md +1 -0
  4. package/README.md +25 -2
  5. package/dist/AnimationMilestones.d.ts +17 -0
  6. package/dist/BattleActionMotionMath.d.ts +24 -0
  7. package/dist/BattleActionPresentationRecipes.d.ts +11 -0
  8. package/dist/BattleFxLibrary.d.ts +16 -0
  9. package/dist/BattlePresentationEngine.d.ts +26 -0
  10. package/dist/BattlePresentationPoseRegistry.d.ts +25 -0
  11. package/dist/BattlePresentationRecipe.d.ts +48 -0
  12. package/dist/BattleSequenceScheduler.d.ts +11 -0
  13. package/dist/DisplayEventQueue.d.ts +24 -0
  14. package/dist/PixiAnimationActivity.d.ts +7 -0
  15. package/dist/PixiAnimationDirector.d.ts +21 -0
  16. package/dist/PixiApplicationFactory.d.ts +17 -0
  17. package/dist/PixiAssetManager.d.ts +70 -0
  18. package/dist/PixiBattleActionRecipes.d.ts +75 -0
  19. package/dist/PixiBattleCinematicSurface.d.ts +23 -0
  20. package/dist/PixiBattleEntryTransition.d.ts +87 -0
  21. package/dist/PixiBattleFieldSurface.d.ts +125 -0
  22. package/dist/PixiBattleFxResources.d.ts +154 -0
  23. package/dist/PixiBattleGrid.d.ts +13 -0
  24. package/dist/PixiBattleHudPorts.d.ts +192 -0
  25. package/dist/PixiBattleHudSurface.d.ts +159 -0
  26. package/dist/PixiBattleLightningResources.d.ts +57 -0
  27. package/dist/PixiBattleMapDissolve.d.ts +38 -0
  28. package/dist/PixiBattleSceneTransition.d.ts +30 -0
  29. package/dist/PixiBattleTokenLifecycleCoordinator.d.ts +44 -0
  30. package/dist/PixiBattleVisualLayout.d.ts +284 -0
  31. package/dist/PixiBattleWhipGeometry.d.ts +18 -0
  32. package/dist/PixiBattleWhipMotion.d.ts +63 -0
  33. package/dist/PixiBattleWhipResources.d.ts +53 -0
  34. package/dist/PixiCameraFocusController.d.ts +40 -0
  35. package/dist/PixiCombatMotion.d.ts +223 -0
  36. package/dist/PixiCurrentActorCardGlow.d.ts +37 -0
  37. package/dist/PixiCurrentActorHalo.d.ts +55 -0
  38. package/dist/PixiDirectionalMotionBlur.d.ts +12 -0
  39. package/dist/PixiDisplayRenderer.d.ts +85 -0
  40. package/dist/PixiEffectPlugin.d.ts +25 -0
  41. package/dist/PixiEndingSurface.d.ts +104 -0
  42. package/dist/PixiInvestigatorDossierInsanityFilter.d.ts +14 -0
  43. package/dist/PixiLocalGlowMesh.d.ts +38 -0
  44. package/dist/PixiMapEdgeShadow.d.ts +36 -0
  45. package/dist/PixiMapMediaSurface.d.ts +71 -0
  46. package/dist/PixiMapWorldUtils.d.ts +24 -0
  47. package/dist/PixiMediaBreathRuntime.d.ts +69 -0
  48. package/dist/PixiMotion.d.ts +42 -0
  49. package/dist/PixiObjectiveBreathingGlow.d.ts +39 -0
  50. package/dist/PixiPartyHudSurface.d.ts +58 -0
  51. package/dist/PixiPersistentEffectTransition.d.ts +23 -0
  52. package/dist/PixiPortraitResourceCard.d.ts +147 -0
  53. package/dist/PixiPreludeStoryTransition.d.ts +35 -0
  54. package/dist/PixiPreludeSurface.d.ts +203 -0
  55. package/dist/PixiProgressCinematic.d.ts +65 -0
  56. package/dist/PixiResultEffectSurface.d.ts +101 -0
  57. package/dist/PixiRetainedMeterAnimator.d.ts +44 -0
  58. package/dist/PixiRuntimeContext.d.ts +21 -0
  59. package/dist/PixiSceneGraph.d.ts +42 -0
  60. package/dist/PixiSceneMotion.d.ts +41 -0
  61. package/dist/PixiSceneMotionPorts.d.ts +83 -0
  62. package/dist/PixiScenePresentationDirector.d.ts +118 -0
  63. package/dist/PixiSessionLayout.d.ts +61 -0
  64. package/dist/PixiSessionSkin.d.ts +30 -0
  65. package/dist/PixiShaderRuntime.d.ts +191 -0
  66. package/dist/PixiStageFontLoader.d.ts +2 -0
  67. package/dist/PixiStageMetrics.d.ts +25 -0
  68. package/dist/PixiStageTheme.d.ts +26 -0
  69. package/dist/PixiStoryArchiveMotion.d.ts +19 -0
  70. package/dist/PixiStoryCardCut.d.ts +58 -0
  71. package/dist/PixiStorySurface.d.ts +285 -0
  72. package/dist/PixiStoryWorkspaceSurface.d.ts +64 -0
  73. package/dist/PixiSummaryBoardSurface.d.ts +112 -0
  74. package/dist/PixiSystemHudSurface.d.ts +73 -0
  75. package/dist/PixiTeamCheckCinematic.d.ts +34 -0
  76. package/dist/PixiTextTransitionEffect.d.ts +54 -0
  77. package/dist/PixiTokenPersistentStatus.d.ts +101 -0
  78. package/dist/PixiTokenWorld.d.ts +170 -0
  79. package/dist/PixiTypography.d.ts +96 -0
  80. package/dist/PixiVideoRuntime.d.ts +61 -0
  81. package/dist/PixiViewportController.d.ts +25 -0
  82. package/dist/ResultEffectTuning.d.ts +57 -0
  83. package/dist/RetainedStageSurface.d.ts +50 -0
  84. package/dist/SessionFieldEffectRuntime.d.ts +45 -0
  85. package/dist/SessionSceneHistory.d.ts +10 -0
  86. package/dist/SessionSceneRegistry.d.ts +31 -0
  87. package/dist/StoryEventCoordinator.d.ts +61 -0
  88. package/dist/effects/PixiEffectLayerRegistry.d.ts +54 -0
  89. package/dist/effects/PixiEffectScope.d.ts +20 -0
  90. package/dist/effects/PixiStableRandom.d.ts +2 -0
  91. package/dist/index.d.ts +92 -0
  92. package/dist/index.js +24184 -0
  93. package/dist/index.js.map +7 -0
  94. package/dist/recipes/EffectPrimitiveRuntimeRegistry.d.ts +28 -0
  95. package/dist/recipes/EffectRecipeExecutor.d.ts +73 -0
  96. package/dist/recipes/primitives.d.ts +39 -0
  97. package/dist/recipes/registry.d.ts +57 -0
  98. package/dist/recipes/schema.d.ts +93 -0
  99. package/dist/recipes.d.ts +5 -0
  100. package/dist/recipes.js +1384 -0
  101. package/dist/recipes.js.map +7 -0
  102. package/dist/story/PixiStoryPresentationEngine.d.ts +90 -0
  103. package/dist/story/StoryContentSurface.d.ts +34 -0
  104. package/dist/story/StoryImageFilter.d.ts +15 -0
  105. package/dist/story/StoryTimelineClock.d.ts +22 -0
  106. package/dist/story/StoryVisualMath.d.ts +6 -0
  107. package/dist/tuning/SessionTuningResolver.d.ts +1 -0
  108. package/dist/tuning/SessionTuningTypes.d.ts +1 -0
  109. package/dist/ui/PixiStagePrimitives.d.ts +36 -0
  110. package/dist/uniforms.d.ts +1 -0
  111. package/package.json +44 -4
@@ -0,0 +1,38 @@
1
+ import type { Filter, Sprite, UniformGroup } from 'pixi.js';
2
+ import type { PixiAnimationActivity } from './PixiAnimationActivity.js';
3
+ import type { PixiAnimationDirector } from './PixiAnimationDirector.js';
4
+ export declare const MAP_DISSOLVE_FRAGMENT = "\nin vec2 vTextureCoord;\nout vec4 finalColor;\nuniform sampler2D uTexture;\nuniform float uProgress;\nuniform float uEdgeSoftness;\nuniform float uHighlightWidth;\nuniform float uHighlightIntensity;\nuniform float uGrainAmount;\nuniform float uGrainScale;\nuniform float uSeed;\nuniform vec3 uHighlightColor;\n\nfloat stableNoise(vec2 point) {\n return fract(sin(dot(point, vec2(127.1, 311.7)) + uSeed * 91.7) * 43758.5453123);\n}\n\nvoid main(void) {\n vec4 source = texture(uTexture, vTextureCoord);\n float progress = clamp(uProgress, 0.0, 1.0);\n float luminance = dot(source.rgb, vec3(0.2126, 0.7152, 0.0722));\n float darkness = 1.0 - luminance;\n float grain = (stableNoise(floor(vTextureCoord * max(1.0, uGrainScale))) - 0.5) * uGrainAmount;\n float signal = clamp(darkness + grain, 0.0, 1.0);\n float threshold = 1.0 - progress;\n float softness = max(0.0001, uEdgeSoftness);\n float reveal = smoothstep(threshold - softness, threshold + softness, signal);\n reveal *= smoothstep(0.0, 0.02, progress);\n reveal = mix(reveal, 1.0, smoothstep(0.98, 1.0, progress));\n float bandDistance = abs(signal - threshold);\n float highlight = 1.0 - smoothstep(uHighlightWidth, uHighlightWidth + softness, bandDistance);\n highlight *= (1.0 - smoothstep(0.92, 1.0, progress)) * smoothstep(0.0, 0.08, progress);\n float visible = max(reveal, highlight);\n vec3 highlighted = mix(source.rgb, uHighlightColor, highlight * uHighlightIntensity);\n finalColor = vec4(highlighted, source.a * visible);\n}\n";
5
+ export interface PixiBattleMapDissolveSettings {
6
+ readonly durationMs: number;
7
+ readonly edgeSoftness: number;
8
+ readonly highlightWidth: number;
9
+ readonly highlightIntensity: number;
10
+ readonly grainAmount: number;
11
+ readonly grainScale: number;
12
+ readonly highlightColor: string;
13
+ }
14
+ export declare const DEFAULT_PIXI_BATTLE_MAP_DISSOLVE_SETTINGS: PixiBattleMapDissolveSettings;
15
+ interface Constructors {
16
+ readonly Filter: typeof Filter;
17
+ readonly UniformGroup: typeof UniformGroup;
18
+ }
19
+ /** Retained, single-pass darkness-first dissolve used only by the incoming battle-map sprite. */
20
+ export declare class PixiBattleMapDissolve {
21
+ private readonly director;
22
+ private readonly activity;
23
+ private readonly requestRender;
24
+ private readonly filter;
25
+ private readonly uniforms;
26
+ private settings;
27
+ private active;
28
+ private reducedMotion;
29
+ private destroyed;
30
+ constructor(constructors: Constructors, director: PixiAnimationDirector, activity: PixiAnimationActivity | undefined, requestRender: (() => void) | undefined, settings?: PixiBattleMapDissolveSettings);
31
+ setReducedMotion(reducedMotion: boolean): void;
32
+ updateSettings(settings: PixiBattleMapDissolveSettings): void;
33
+ play(sprite: Sprite, seed: number): Promise<void>;
34
+ commit(): void;
35
+ destroy(): void;
36
+ private cleanup;
37
+ }
38
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { Container, Filter, Graphics, Sprite, Texture } from 'pixi.js';
2
+ import type { PixiAnimationDirector } from './PixiAnimationDirector.js';
3
+ import type { PixiStageTheme } from './PixiStageTheme.js';
4
+ import type { SessionTuningResolver } from './tuning/SessionTuningResolver.js';
5
+ interface Constructors {
6
+ Container: typeof Container;
7
+ Filter?: typeof Filter;
8
+ Graphics: typeof Graphics;
9
+ Sprite: new (texture?: Texture | import('pixi.js').SpriteOptions) => Sprite;
10
+ }
11
+ /** One captured image, translated horizontally. It never owns the live scene or a ticker. */
12
+ export declare class PixiBattleSceneTransition {
13
+ private readonly constructors;
14
+ private readonly animation;
15
+ private readonly render;
16
+ private readonly texture;
17
+ private readonly pixiStageTheme;
18
+ private readonly tuning?;
19
+ readonly node: Container;
20
+ private readonly veil;
21
+ private readonly slide;
22
+ private blur;
23
+ private destroyed;
24
+ constructor(constructors: Constructors, animation: PixiAnimationDirector, render: () => void, texture: Texture | null, pixiStageTheme: PixiStageTheme, tuning?: SessionTuningResolver | undefined);
25
+ play(signal: AbortSignal, reducedMotion: boolean, commit: () => void, onStart?: () => void): Promise<void>;
26
+ destroy(): void;
27
+ private releaseBlur;
28
+ private number;
29
+ }
30
+ export {};
@@ -0,0 +1,44 @@
1
+ export interface TokenLifecyclePoint {
2
+ col: number;
3
+ row: number;
4
+ }
5
+ export interface TokenLifecycleSnapshot {
6
+ id: string;
7
+ gridPosition: TokenLifecyclePoint;
8
+ }
9
+ export interface TokenMovementTransition {
10
+ id: string;
11
+ from: TokenLifecyclePoint;
12
+ to: TokenLifecyclePoint;
13
+ generation: number;
14
+ }
15
+ export interface BattleSnapshotTransition {
16
+ revision: number;
17
+ added: Array<{
18
+ id: string;
19
+ generation: number;
20
+ }>;
21
+ removed: Array<{
22
+ id: string;
23
+ generation: number;
24
+ }>;
25
+ moved: TokenMovementTransition[];
26
+ skipAnim: boolean;
27
+ }
28
+ export interface TokenLifecycleLease {
29
+ generation: number;
30
+ signal: AbortSignal;
31
+ }
32
+ /** Computes renderer-local snapshot transitions and guards async completion by token generation. */
33
+ export declare class PixiBattleTokenLifecycleCoordinator {
34
+ private readonly known;
35
+ private readonly generations;
36
+ private readonly controllers;
37
+ diff(revision: number, tokens: readonly TokenLifecycleSnapshot[], skipAnim?: boolean): BattleSnapshotTransition;
38
+ begin(id: string): TokenLifecycleLease;
39
+ isCurrent(id: string, lease: TokenLifecycleLease): boolean;
40
+ complete(id: string, lease: TokenLifecycleLease): void;
41
+ settle(id: string, position: TokenLifecyclePoint): void;
42
+ abort(id: string): void;
43
+ reset(): void;
44
+ }
@@ -0,0 +1,284 @@
1
+ import type { SessionTuningResolver } from './tuning/SessionTuningResolver.js';
2
+ export type BattleHpColorTone = 'healthy' | 'wounded' | 'critical' | 'empty';
3
+ export declare const resolveBattleHpColor: (tone: BattleHpColorTone, tuning: SessionTuningResolver | undefined, battleHpColors: Readonly<Record<BattleHpColorTone, string>>) => string;
4
+ export declare const resolveUnitCardHpGradientAlpha: (segmentIndex: number, segmentCount: number) => number;
5
+ export declare const UNIT_CARD_LAYOUT: {
6
+ readonly source: {
7
+ readonly width: 724;
8
+ readonly height: 166;
9
+ };
10
+ readonly rowGap: 6;
11
+ readonly maxVisibleRows: 13;
12
+ readonly avatar: {
13
+ readonly x: 14;
14
+ readonly y: 13;
15
+ readonly width: 136;
16
+ readonly height: 140;
17
+ readonly radius: 5;
18
+ };
19
+ readonly order: {
20
+ readonly x: 205;
21
+ readonly y: 83;
22
+ readonly fontSize: 27;
23
+ };
24
+ readonly name: {
25
+ readonly x: 238;
26
+ readonly y: 83;
27
+ readonly fontSize: 25;
28
+ readonly minFontSize: 17;
29
+ readonly rightPadding: 12;
30
+ };
31
+ readonly status: {
32
+ readonly right: 700;
33
+ readonly y: 32;
34
+ readonly radius: 10;
35
+ readonly paddingX: 12;
36
+ readonly fontSize: 15;
37
+ };
38
+ readonly hp: {
39
+ readonly x: 695;
40
+ readonly y: 91;
41
+ readonly fontSize: 17;
42
+ };
43
+ readonly hpBar: {
44
+ readonly x: 238;
45
+ readonly y: 130;
46
+ readonly width: 455;
47
+ readonly height: 7;
48
+ };
49
+ readonly activeOutline: {
50
+ readonly inset: 5;
51
+ readonly width: 2.65;
52
+ };
53
+ };
54
+ export declare const BATTLE_TYPOGRAPHY_DEFAULTS: {
55
+ readonly round: {
56
+ readonly fontSize: 29;
57
+ };
58
+ readonly roster: {
59
+ readonly order: {
60
+ readonly x: 205;
61
+ readonly y: 83;
62
+ readonly fontSize: 27;
63
+ };
64
+ readonly name: {
65
+ readonly x: 238;
66
+ readonly y: 83;
67
+ readonly fontSize: 25;
68
+ readonly minFontSize: 17;
69
+ };
70
+ readonly hp: {
71
+ readonly x: 695;
72
+ readonly y: 91;
73
+ readonly fontSize: 17;
74
+ };
75
+ readonly status: {
76
+ readonly right: 700;
77
+ readonly y: 32;
78
+ readonly paddingX: 12;
79
+ readonly paddingY: 4;
80
+ readonly fontSize: 10;
81
+ readonly text: {
82
+ readonly x: 0;
83
+ readonly y: 0;
84
+ };
85
+ readonly icon: {
86
+ readonly x: 0;
87
+ readonly y: 0;
88
+ readonly size: 12;
89
+ };
90
+ };
91
+ };
92
+ readonly objective: {
93
+ readonly title: {
94
+ readonly x: 42;
95
+ readonly y: 28;
96
+ readonly fontSize: 23;
97
+ };
98
+ readonly percent: {
99
+ readonly x: 505;
100
+ readonly y: 28;
101
+ readonly fontSize: 22;
102
+ };
103
+ };
104
+ readonly token: {
105
+ readonly x: 0;
106
+ readonly y: 0;
107
+ readonly fontSize: 14;
108
+ };
109
+ readonly distance: {
110
+ readonly x: 27;
111
+ readonly y: 13.5;
112
+ readonly fontSize: 14;
113
+ readonly ruler: {
114
+ readonly x: 7;
115
+ readonly y: 5.5;
116
+ };
117
+ };
118
+ };
119
+ export type BattleTypographyTuning = {
120
+ round: {
121
+ fontSize: number;
122
+ };
123
+ roster: {
124
+ order: {
125
+ x: number;
126
+ y: number;
127
+ fontSize: number;
128
+ };
129
+ name: {
130
+ x: number;
131
+ y: number;
132
+ fontSize: number;
133
+ minFontSize: number;
134
+ };
135
+ hp: {
136
+ x: number;
137
+ y: number;
138
+ fontSize: number;
139
+ };
140
+ status: {
141
+ right: number;
142
+ y: number;
143
+ paddingX: number;
144
+ paddingY: number;
145
+ fontSize: number;
146
+ text: {
147
+ x: number;
148
+ y: number;
149
+ };
150
+ icon: {
151
+ x: number;
152
+ y: number;
153
+ size: number;
154
+ };
155
+ };
156
+ };
157
+ objective: {
158
+ title: {
159
+ x: number;
160
+ y: number;
161
+ fontSize: number;
162
+ };
163
+ percent: {
164
+ x: number;
165
+ y: number;
166
+ fontSize: number;
167
+ };
168
+ };
169
+ token: {
170
+ x: number;
171
+ y: number;
172
+ fontSize: number;
173
+ };
174
+ distance: {
175
+ x: number;
176
+ y: number;
177
+ fontSize: number;
178
+ ruler: {
179
+ x: number;
180
+ y: number;
181
+ };
182
+ };
183
+ };
184
+ export declare const resolveBattleTypography: (value: BattleTypographyTuning | undefined) => BattleTypographyTuning;
185
+ export declare const resolveBattleStatusPillLayout: (style: BattleTypographyTuning["roster"]["status"], options: {
186
+ hasIcon: boolean;
187
+ labelWidth: number;
188
+ labelHeight: number;
189
+ }) => {
190
+ width: number;
191
+ height: number;
192
+ label: {
193
+ x: number;
194
+ y: number;
195
+ };
196
+ icon: {
197
+ x: number;
198
+ y: number;
199
+ } | null;
200
+ };
201
+ export declare const TOKEN_RING_LAYOUT: {
202
+ readonly textureDiameter: 1254;
203
+ readonly outerDiameterByCell: 1.2;
204
+ readonly svgInnerDiameterRatio: 0.728;
205
+ readonly avatarApertureInset: 1.02;
206
+ readonly shadow: {
207
+ readonly offsetXRatio: 0.08;
208
+ readonly offsetYRatio: 0.11;
209
+ readonly radiusRatio: 0.455;
210
+ };
211
+ };
212
+ export declare const resolveBattleTokenVisualLayout: (cellDiameter: number) => {
213
+ ringDiameter: number;
214
+ avatarAperture: number;
215
+ };
216
+ export declare const DISTANCE_RULER_STYLE: {
217
+ readonly leadingWidth: 40;
218
+ readonly x: 7;
219
+ readonly y: 5.5;
220
+ readonly width: 9;
221
+ readonly height: 16;
222
+ readonly tickLengths: readonly [4, 7, 4, 7];
223
+ readonly textX: 27;
224
+ };
225
+ export declare const OBJECTIVE_LAYOUT: {
226
+ readonly source: {
227
+ readonly width: 550;
228
+ readonly height: 110;
229
+ };
230
+ readonly maxWidth: 275;
231
+ readonly gap: 10;
232
+ readonly title: {
233
+ readonly x: 42;
234
+ readonly y: 28;
235
+ readonly fontSize: 23;
236
+ };
237
+ readonly percent: {
238
+ readonly x: 505;
239
+ readonly y: 28;
240
+ readonly fontSize: 22;
241
+ };
242
+ readonly track: {
243
+ readonly x: 60;
244
+ readonly y: 63;
245
+ readonly width: 430;
246
+ readonly height: 10;
247
+ readonly radius: 2;
248
+ };
249
+ };
250
+ export declare const OBJECTIVE_PROGRESS_STYLE: {
251
+ readonly smallTickEvery: 0.05;
252
+ readonly majorTicks: readonly [0, 0.25, 0.5, 0.75, 1];
253
+ readonly smallTickHeight: 4;
254
+ readonly majorTickHeight: 8;
255
+ readonly endMarkerWidth: 2;
256
+ readonly highlightHeight: 1;
257
+ readonly shadowHeight: 1;
258
+ };
259
+ export declare const clampProgress: (value: number) => number;
260
+ export interface BattleTeamCheckIconLayoutOptions {
261
+ areaWidth: number;
262
+ areaHeight: number;
263
+ iconHeight: number;
264
+ gap: number;
265
+ textureAspectRatio: number;
266
+ }
267
+ export interface BattleTeamCheckIconLayout {
268
+ x: number;
269
+ y: number;
270
+ width: number;
271
+ height: number;
272
+ }
273
+ export declare const resolveBattleTeamCheckIconLayouts: (count: number, options: BattleTeamCheckIconLayoutOptions) => BattleTeamCheckIconLayout[];
274
+ export interface BattleRosterCardLayoutOptions {
275
+ maxVisibleRows?: number;
276
+ rowGap?: number;
277
+ }
278
+ export declare const resolveBattleRosterCardLayout: (availableWidth: number, availableHeight: number, textureWidth: number, textureHeight: number, options?: BattleRosterCardLayoutOptions) => {
279
+ scale: number;
280
+ width: number;
281
+ height: number;
282
+ gap: number;
283
+ pitch: number;
284
+ };
@@ -0,0 +1,18 @@
1
+ /** Fixed topology: one narrow ribbon, updated in place for the entire attack. */
2
+ export declare const WHIP_SEGMENTS = 40;
3
+ export interface WhipShape {
4
+ length: number;
5
+ reach: number;
6
+ bend: number;
7
+ phase: number;
8
+ width: number;
9
+ tipRatio: number;
10
+ }
11
+ export declare const createWhipBuffers: () => {
12
+ positions: Float32Array<ArrayBuffer>;
13
+ centers: Float32Array<ArrayBuffer>;
14
+ uvs: Float32Array<ArrayBuffer>;
15
+ indices: Uint32Array<ArrayBuffer>;
16
+ };
17
+ export type WhipBuffers = ReturnType<typeof createWhipBuffers>;
18
+ export declare const updateWhipPositions: (buffers: WhipBuffers, shape: WhipShape) => void;
@@ -0,0 +1,63 @@
1
+ import type { Container } from 'pixi.js';
2
+ import type { PixiAnimationDirector } from './PixiAnimationDirector.js';
3
+ import type { PixiBattleWhipResources } from './PixiBattleWhipResources.js';
4
+ import type { SessionTuningResolver } from './tuning/SessionTuningResolver.js';
5
+ interface WhipMotionContext {
6
+ resources: PixiBattleWhipResources;
7
+ parent: Container;
8
+ director: PixiAnimationDirector;
9
+ world: {
10
+ getCellSize?(): {
11
+ width: number;
12
+ height: number;
13
+ };
14
+ isReducedMotionEnabled?(): boolean;
15
+ getPresentationNode(id: string): {
16
+ position: {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ } | null;
21
+ };
22
+ style: {
23
+ widthCellRatio: number;
24
+ bendCellRatio: number;
25
+ tipRatio: number;
26
+ alpha: number;
27
+ bodyColor: string;
28
+ edgeColor: string;
29
+ };
30
+ tuning?: SessionTuningResolver;
31
+ attackerId: string;
32
+ from: {
33
+ x: number;
34
+ y: number;
35
+ };
36
+ target: {
37
+ x: number;
38
+ y: number;
39
+ };
40
+ miss: boolean;
41
+ onStrike?: () => void;
42
+ }
43
+ /** A single lease spans approach, contact and return; the caller releases it in finally. */
44
+ export declare class PixiBattleWhipMotion {
45
+ private readonly context;
46
+ private handle;
47
+ private generation;
48
+ private readonly pose;
49
+ private readonly cell;
50
+ private readonly reducedMotion;
51
+ private readonly settings;
52
+ constructor(context: WhipMotionContext);
53
+ get strikeSeconds(): number;
54
+ approach(signal: AbortSignal, dodge: () => Promise<void>): Promise<void>;
55
+ hold(signal: AbortSignal): Promise<void>;
56
+ retract(signal: AbortSignal): Promise<void>;
57
+ release(): void;
58
+ private number;
59
+ private color;
60
+ private tween;
61
+ private draw;
62
+ }
63
+ export {};
@@ -0,0 +1,53 @@
1
+ import type { Container, Mesh, MeshGeometry, Shader, UniformGroup } from 'pixi.js';
2
+ import type { PixiBattleFxCapabilities } from './PixiBattleFxResources.js';
3
+ import { type WhipBuffers, type WhipShape } from './PixiBattleWhipGeometry.js';
4
+ export interface PixiBattleWhipHandle {
5
+ mesh: Mesh<MeshGeometry, Shader>;
6
+ geometry: MeshGeometry;
7
+ shader: Shader;
8
+ buffers: WhipBuffers;
9
+ bodyColor: Float32Array;
10
+ edgeColor: Float32Array;
11
+ uniforms: UniformGroup<{
12
+ uBodyColor: {
13
+ value: Float32Array;
14
+ type: 'vec3<f32>';
15
+ };
16
+ uEdgeColor: {
17
+ value: Float32Array;
18
+ type: 'vec3<f32>';
19
+ };
20
+ uLength: {
21
+ value: number;
22
+ type: 'f32';
23
+ };
24
+ uLinkLength: {
25
+ value: number;
26
+ type: 'f32';
27
+ };
28
+ uBlur: {
29
+ value: number;
30
+ type: 'f32';
31
+ };
32
+ }>;
33
+ released: boolean;
34
+ generation: number;
35
+ }
36
+ /** Sub-pool owned exclusively by PixiBattleFxResourceOwner. */
37
+ export declare class PixiBattleWhipResources {
38
+ private readonly capabilities;
39
+ private readonly available;
40
+ private readonly active;
41
+ private readonly owned;
42
+ constructor(capabilities: PixiBattleFxCapabilities);
43
+ acquire(parent: Container, bodyColor: string, edgeColor: string): PixiBattleWhipHandle | null;
44
+ update(handle: PixiBattleWhipHandle, shape: WhipShape, detail?: {
45
+ linkLength: number;
46
+ blur: number;
47
+ }): void;
48
+ release(handle: PixiBattleWhipHandle | null, generation?: number | undefined): void;
49
+ reset(): void;
50
+ destroy(): void;
51
+ get activeCount(): number;
52
+ private create;
53
+ }
@@ -0,0 +1,40 @@
1
+ import type { PixiSceneGraph } from './PixiSceneGraph.js';
2
+ import type { PixiTokenWorld } from './PixiTokenWorld.js';
3
+ import type { PixiAnimationDirector } from './PixiAnimationDirector.js';
4
+ import type { BattleViewportGridLayout } from './PixiSessionLayout.js';
5
+ import type { SessionTuningResolver } from '@bardway/trpg-media/tuning';
6
+ export interface CameraFocusInput {
7
+ participantIds: readonly string[];
8
+ layout: BattleViewportGridLayout;
9
+ landingPoints?: readonly {
10
+ x: number;
11
+ y: number;
12
+ }[];
13
+ animateCamera: boolean;
14
+ signal: AbortSignal;
15
+ run(signal: AbortSignal): Promise<void>;
16
+ waitForBarriers?(): Promise<void>;
17
+ }
18
+ export declare const resolveConfinedCameraAxis: (focus: number, scale: number, viewportStart: number, viewportSize: number, mapStart: number, mapSize: number) => number;
19
+ export declare const resolveCameraFocusPosition: (layout: BattleViewportGridLayout, focusPivot: {
20
+ x: number;
21
+ y: number;
22
+ }, focusScale: {
23
+ x: number;
24
+ y: number;
25
+ }) => {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ export declare class PixiCameraFocusController {
30
+ private readonly scene;
31
+ private readonly world;
32
+ private readonly director;
33
+ private readonly getTuning;
34
+ private active;
35
+ constructor(scene: PixiSceneGraph, world: PixiTokenWorld, director: PixiAnimationDirector, getTuning: () => SessionTuningResolver | undefined);
36
+ reset(): void;
37
+ destroy(): void;
38
+ play(input: CameraFocusInput): Promise<void>;
39
+ private resolveTuningNumber;
40
+ }