@almadar/ui 5.72.0 → 5.73.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.
- package/dist/avl/index.cjs +402 -362
- package/dist/avl/index.js +402 -362
- package/dist/components/game/atoms/ActionButton.d.ts +3 -3
- package/dist/components/game/atoms/ChoiceButton.d.ts +3 -3
- package/dist/components/game/atoms/ComboCounter.d.ts +3 -3
- package/dist/components/game/atoms/ControlButton.d.ts +3 -3
- package/dist/components/game/atoms/DamageNumber.d.ts +3 -3
- package/dist/components/game/atoms/DialogueBubble.d.ts +3 -3
- package/dist/components/game/atoms/ItemSlot.d.ts +3 -3
- package/dist/components/game/atoms/ResourceCounter.d.ts +3 -3
- package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -3
- package/dist/components/game/atoms/Sprite.d.ts +3 -20
- package/dist/components/game/atoms/StateIndicator.d.ts +2 -2
- package/dist/components/game/atoms/StatusEffect.d.ts +3 -3
- package/dist/components/game/atoms/TurnIndicator.d.ts +3 -3
- package/dist/components/game/atoms/WaypointMarker.d.ts +3 -3
- package/dist/components/game/molecules/CardHand.d.ts +2 -2
- package/dist/components/game/molecules/DialogueBox.d.ts +3 -3
- package/dist/components/game/molecules/EnemyPlate.d.ts +3 -3
- package/dist/components/game/molecules/GameCanvas2D.d.ts +3 -3
- package/dist/components/game/molecules/HealthPanel.d.ts +3 -3
- package/dist/components/game/molecules/IsometricCanvas.d.ts +8 -12
- package/dist/components/game/molecules/PowerupSlots.d.ts +3 -3
- package/dist/components/game/molecules/StatBadge.d.ts +5 -5
- package/dist/components/game/molecules/TurnPanel.d.ts +3 -3
- package/dist/components/game/molecules/three/index.cjs +51 -28
- package/dist/components/game/molecules/three/index.js +51 -28
- package/dist/components/game/molecules/useUnitSpriteAtlas.d.ts +3 -10
- package/dist/components/game/organisms/BattleBoard.d.ts +5 -6
- package/dist/components/game/organisms/CardBattlerBoard.d.ts +3 -4
- package/dist/components/game/organisms/CastleBoard.d.ts +5 -6
- package/dist/components/game/organisms/CityBuilderBoard.d.ts +6 -7
- package/dist/components/game/organisms/FishingBoard.d.ts +4 -6
- package/dist/components/game/organisms/PlatformerBoard.d.ts +5 -5
- package/dist/components/game/organisms/RoguelikeBoard.d.ts +4 -5
- package/dist/components/game/organisms/TopDownShooterBoard.d.ts +5 -6
- package/dist/components/game/organisms/TowerDefenseBoard.d.ts +5 -6
- package/dist/components/game/organisms/VisualNovelBoard.d.ts +4 -5
- package/dist/components/game/organisms/WorldMapBoard.d.ts +5 -6
- package/dist/components/game/organisms/types/effects.d.ts +7 -8
- package/dist/components/game/organisms/types/isometric.d.ts +8 -8
- package/dist/components/game/organisms/types/spriteAnimation.d.ts +3 -4
- package/dist/components/game/organisms/utils/makeAsset.d.ts +5 -0
- package/dist/components/game/templates/PlatformerTemplate.d.ts +5 -4
- package/dist/components/game/templates/game3dAssetManifest.d.ts +6 -8
- package/dist/components/index.cjs +417 -363
- package/dist/components/index.js +417 -363
- package/dist/providers/index.cjs +402 -362
- package/dist/providers/index.js +402 -362
- package/dist/runtime/index.cjs +402 -362
- package/dist/runtime/index.js +402 -362
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface ActionButtonProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Button label text */
|
|
7
7
|
label: string;
|
|
8
8
|
/** Icon displayed before the label */
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface ChoiceButtonProps {
|
|
4
4
|
/** Choice text content */
|
|
5
5
|
text: string;
|
|
6
6
|
/** Choice index number (displayed as prefix) */
|
|
7
7
|
index?: number;
|
|
8
|
-
/** Sprite
|
|
9
|
-
assetUrl?:
|
|
8
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
9
|
+
assetUrl?: Asset;
|
|
10
10
|
/** Icon displayed before the text */
|
|
11
11
|
icon?: IconInput;
|
|
12
12
|
/** Whether the choice is disabled */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Asset } from '@almadar/core';
|
|
2
2
|
export interface ComboCounterProps {
|
|
3
|
-
/** Sprite
|
|
4
|
-
assetUrl?:
|
|
3
|
+
/** Sprite asset displayed alongside the combo number */
|
|
4
|
+
assetUrl?: Asset;
|
|
5
5
|
/** Current combo count */
|
|
6
6
|
combo: number;
|
|
7
7
|
/** Score multiplier */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { EventKey,
|
|
1
|
+
import type { EventKey, Asset } from "@almadar/core";
|
|
2
2
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
3
3
|
export interface ControlButtonProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Button label text */
|
|
7
7
|
label?: string;
|
|
8
8
|
/** Icon component or emoji */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Asset } from '@almadar/core';
|
|
2
2
|
export interface DamageNumberProps {
|
|
3
|
-
/** Sprite
|
|
4
|
-
assetUrl?:
|
|
3
|
+
/** Sprite asset — displayed as a hit-effect icon alongside the number */
|
|
4
|
+
assetUrl?: Asset;
|
|
5
5
|
/** The damage/heal value to display */
|
|
6
6
|
value: number;
|
|
7
7
|
/** Type of number display */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Asset } from '@almadar/core';
|
|
2
2
|
export interface DialogueBubbleProps {
|
|
3
3
|
/** Speaker name displayed at the top */
|
|
4
4
|
speaker?: string;
|
|
5
5
|
/** Dialogue text content */
|
|
6
6
|
text: string;
|
|
7
|
-
/**
|
|
8
|
-
portrait?:
|
|
7
|
+
/** Speaker portrait asset */
|
|
8
|
+
portrait?: Asset;
|
|
9
9
|
/** Position of the bubble on screen */
|
|
10
10
|
position?: 'top' | 'bottom';
|
|
11
11
|
/** Additional CSS classes */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface ItemSlotProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Icon component or emoji — shown only when assetUrl is absent */
|
|
7
7
|
icon?: IconInput;
|
|
8
8
|
/** Item label */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ColorToken } from '../../core/atoms/types';
|
|
2
2
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Asset } from '@almadar/core';
|
|
4
4
|
export interface ResourceCounterProps {
|
|
5
|
-
/** Sprite
|
|
6
|
-
assetUrl?:
|
|
5
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
6
|
+
assetUrl?: Asset;
|
|
7
7
|
/** Icon component or emoji */
|
|
8
8
|
icon?: IconInput;
|
|
9
9
|
/** Resource label */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface ScoreDisplayProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Current score value */
|
|
7
7
|
value: number;
|
|
8
8
|
/** Alias for value — common schema binding name */
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Renders a single frame from a spritesheet with transform support.
|
|
5
5
|
*/
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import type { EventKey,
|
|
7
|
+
import type { EventKey, Asset } from "@almadar/core";
|
|
8
8
|
import type { AnimationName } from '../organisms/types/spriteAnimation';
|
|
9
9
|
export interface SpriteProps {
|
|
10
|
-
/** Spritesheet
|
|
11
|
-
spritesheet:
|
|
10
|
+
/** Spritesheet asset */
|
|
11
|
+
spritesheet: Asset;
|
|
12
12
|
/** Width of each frame in pixels */
|
|
13
13
|
frameWidth: number;
|
|
14
14
|
/** Height of each frame in pixels */
|
|
@@ -44,23 +44,6 @@ export interface SpriteProps {
|
|
|
44
44
|
/** Declarative event name emitted on click via useEventBus */
|
|
45
45
|
action?: EventKey;
|
|
46
46
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Sprite component for rendering spritesheet frames
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```tsx
|
|
52
|
-
* <Sprite
|
|
53
|
-
* spritesheet="/sprites/player.png"
|
|
54
|
-
* frameWidth={32}
|
|
55
|
-
* frameHeight={32}
|
|
56
|
-
* frame={currentFrame}
|
|
57
|
-
* x={player.x}
|
|
58
|
-
* y={player.y}
|
|
59
|
-
* flipX={player.facingLeft}
|
|
60
|
-
* scale={2}
|
|
61
|
-
* />
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
47
|
export declare function Sprite({ spritesheet, frameWidth, frameHeight, frame, x, y, scale, flipX, flipY, rotation, opacity, zIndex, columns, animState: _animState, frameRate: _frameRate, className, onClick, action, }: SpriteProps): React.JSX.Element;
|
|
65
48
|
/**
|
|
66
49
|
* Canvas-based sprite renderer for better performance in game loops
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Asset } from '@almadar/core';
|
|
4
4
|
export interface StateStyle {
|
|
5
5
|
icon: IconInput;
|
|
6
6
|
bgClass: string;
|
|
7
7
|
}
|
|
8
8
|
export interface StateIndicatorProps {
|
|
9
9
|
/** Sprite image URL — takes precedence over the state icon when provided */
|
|
10
|
-
assetUrl?:
|
|
10
|
+
assetUrl?: Asset;
|
|
11
11
|
/** The current state name */
|
|
12
12
|
state: string;
|
|
13
13
|
/** Optional label override (defaults to capitalized state name) */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface StatusEffectProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Lucide icon name or component */
|
|
7
7
|
icon: IconInput;
|
|
8
8
|
/** Label describing the effect */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Asset } from '@almadar/core';
|
|
2
2
|
export interface TurnIndicatorProps {
|
|
3
|
-
/** Sprite
|
|
4
|
-
assetUrl?:
|
|
3
|
+
/** Sprite asset — takes precedence over the dot indicator when provided */
|
|
4
|
+
assetUrl?: Asset;
|
|
5
5
|
/** Current turn number */
|
|
6
6
|
currentTurn: number;
|
|
7
7
|
/** Maximum number of turns */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface WaypointMarkerProps {
|
|
4
|
-
/** Sprite
|
|
5
|
-
assetUrl?:
|
|
4
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
5
|
+
assetUrl?: Asset;
|
|
6
6
|
/** Label text below the marker */
|
|
7
7
|
label?: string;
|
|
8
8
|
/** Custom icon to render inside the marker */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit } from '@almadar/core';
|
|
3
3
|
/** One playable card (icon + title + a few stat numbers). UI value DTO. */
|
|
4
4
|
export interface CardHandCard {
|
|
5
5
|
id: string;
|
|
6
|
-
iconUrl?:
|
|
6
|
+
iconUrl?: Asset;
|
|
7
7
|
title?: string;
|
|
8
8
|
cost?: number;
|
|
9
9
|
attack?: number;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* concern analogous to Form's `formData`.
|
|
13
13
|
*/
|
|
14
14
|
import React from 'react';
|
|
15
|
-
import type {
|
|
15
|
+
import type { Asset, EventEmit, EventPayload } from '@almadar/core';
|
|
16
16
|
export type DialogueChoice = EventPayload & {
|
|
17
17
|
text: string;
|
|
18
18
|
action?: string;
|
|
@@ -54,9 +54,9 @@ export interface DialogueBoxProps {
|
|
|
54
54
|
/** Declarative event: emits UI:{advanceEvent} when dialogue is advanced */
|
|
55
55
|
advanceEvent?: EventEmit<Record<string, never>>;
|
|
56
56
|
/** Optional full-frame scene image rendered behind the dialogue (visual-novel mode). */
|
|
57
|
-
backgroundImage?:
|
|
57
|
+
backgroundImage?: Asset;
|
|
58
58
|
/** Optional larger character portrait rendered standing over the scene (visual-novel mode). */
|
|
59
|
-
portraitUrl?:
|
|
59
|
+
portraitUrl?: Asset;
|
|
60
60
|
/** Multiplier for the large `portraitUrl` height relative to its default (default 1). */
|
|
61
61
|
portraitScale?: number;
|
|
62
62
|
/** Optional className */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IconInput } from '../../core/atoms';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface EnemyPlateEffect {
|
|
4
4
|
/** Effect icon */
|
|
5
5
|
icon: IconInput;
|
|
@@ -9,8 +9,8 @@ export interface EnemyPlateEffect {
|
|
|
9
9
|
variant?: 'buff' | 'debuff' | 'neutral';
|
|
10
10
|
}
|
|
11
11
|
export interface EnemyPlateProps {
|
|
12
|
-
/** Portrait sprite
|
|
13
|
-
assetUrl?:
|
|
12
|
+
/** Portrait sprite asset — takes precedence over the default avatar slot */
|
|
13
|
+
assetUrl?: Asset;
|
|
14
14
|
/** Enemy name */
|
|
15
15
|
name: string;
|
|
16
16
|
/** Current health */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssetUrl } from '@almadar/core';
|
|
1
|
+
import type { Asset, AssetUrl } from '@almadar/core';
|
|
2
2
|
export interface GameCanvas2DProps {
|
|
3
3
|
/** Canvas width in pixels */
|
|
4
4
|
width?: number;
|
|
@@ -14,8 +14,8 @@ export interface GameCanvas2DProps {
|
|
|
14
14
|
drawEvent?: string;
|
|
15
15
|
/** Target frames per second */
|
|
16
16
|
fps?: number;
|
|
17
|
-
/** Background image
|
|
18
|
-
backgroundImage?:
|
|
17
|
+
/** Background image asset */
|
|
18
|
+
backgroundImage?: Asset;
|
|
19
19
|
/** Base URL prefix for asset URLs */
|
|
20
20
|
assetBaseUrl?: AssetUrl;
|
|
21
21
|
/** Additional CSS classes */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { IconInput } from '../../core/atoms';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface HealthEffect {
|
|
4
4
|
icon: IconInput;
|
|
5
|
-
/** Sprite
|
|
6
|
-
assetUrl?:
|
|
5
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
6
|
+
assetUrl?: Asset;
|
|
7
7
|
label?: string;
|
|
8
8
|
variant?: 'buff' | 'debuff' | 'neutral';
|
|
9
9
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* @packageDocumentation
|
|
25
25
|
*/
|
|
26
26
|
import * as React from 'react';
|
|
27
|
-
import type { AssetUrl, EventEmit } from '@almadar/core';
|
|
27
|
+
import type { Asset, AssetUrl, EventEmit } from '@almadar/core';
|
|
28
28
|
import type { IsometricTile, IsometricUnit, IsometricFeature, ActiveEffect } from '../organisms/types/isometric';
|
|
29
29
|
import type { ResolvedFrame } from '../organisms/types/spriteAnimation';
|
|
30
30
|
import type { TileLayout } from '../organisms/utils/isometric';
|
|
@@ -121,20 +121,16 @@ export interface IsometricCanvasProps {
|
|
|
121
121
|
onDrawEffects?: (ctx: CanvasRenderingContext2D, animTime: number, getImage: (url: string) => HTMLImageElement | undefined) => void;
|
|
122
122
|
/** Whether there are active effects — keeps RAF loop alive */
|
|
123
123
|
hasActiveEffects?: boolean;
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
assetBaseUrl?: AssetUrl;
|
|
127
|
-
/** Manifest mapping entity keys to relative sprite paths.
|
|
128
|
-
* Combined with assetBaseUrl to produce full URLs.
|
|
129
|
-
* Used as a fallback when inline URLs and callbacks don't resolve. */
|
|
124
|
+
/** Manifest mapping entity keys to resolved Asset objects.
|
|
125
|
+
* Used as a fallback when inline assets and callbacks don't resolve. */
|
|
130
126
|
assetManifest?: {
|
|
131
|
-
terrains?: Record<string,
|
|
132
|
-
units?: Record<string,
|
|
133
|
-
features?: Record<string,
|
|
134
|
-
effects?: Record<string,
|
|
127
|
+
terrains?: Record<string, Asset>;
|
|
128
|
+
units?: Record<string, Asset>;
|
|
129
|
+
features?: Record<string, Asset>;
|
|
130
|
+
effects?: Record<string, Asset>;
|
|
135
131
|
};
|
|
136
132
|
}
|
|
137
|
-
export declare function IsometricCanvas({ className, isLoading, error, tiles: _tilesPropRaw, units: _unitsPropRaw, features: _featuresPropRaw, effects: _effectsPropRaw, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, tileLayout, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, spriteHeightRatio, spriteMaxWidthRatio, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects: _hasActiveEffects, diamondTopY: diamondTopYProp,
|
|
133
|
+
export declare function IsometricCanvas({ className, isLoading, error, tiles: _tilesPropRaw, units: _unitsPropRaw, features: _featuresPropRaw, effects: _effectsPropRaw, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, tileLayout, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, spriteHeightRatio, spriteMaxWidthRatio, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects: _hasActiveEffects, diamondTopY: diamondTopYProp, assetManifest, }: IsometricCanvasProps): React.JSX.Element;
|
|
138
134
|
export declare namespace IsometricCanvas {
|
|
139
135
|
var displayName: string;
|
|
140
136
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { IconInput } from '../../core/atoms';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface ActivePowerup {
|
|
4
4
|
/** Unique powerup ID */
|
|
5
5
|
id: string;
|
|
6
|
-
/** Sprite
|
|
7
|
-
assetUrl?:
|
|
6
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
7
|
+
assetUrl?: Asset;
|
|
8
8
|
/** Icon component or emoji */
|
|
9
9
|
icon?: IconInput;
|
|
10
10
|
/** Powerup label */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IconInput } from '../../core/atoms/Icon';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
/**
|
|
4
4
|
* StatBadge — game stat display molecule (distinct from core Badge atom).
|
|
5
5
|
* Badge shows a text label/status token. StatBadge shows a numeric value
|
|
@@ -7,10 +7,10 @@ import type { AssetUrl } from '@almadar/core';
|
|
|
7
7
|
* a named label — purpose-built for HUD stat rows, not general status tags.
|
|
8
8
|
*/
|
|
9
9
|
export interface StatBadgeProps {
|
|
10
|
-
/** Sprite
|
|
11
|
-
assetUrl?:
|
|
12
|
-
/** Asset
|
|
13
|
-
iconUrl?:
|
|
10
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
11
|
+
assetUrl?: Asset;
|
|
12
|
+
/** Asset image (board ui/ PNG); takes precedence over the Lucide icon. */
|
|
13
|
+
iconUrl?: Asset;
|
|
14
14
|
/** Stat label */
|
|
15
15
|
label: string;
|
|
16
16
|
/** Current value (defaults to 0 if not provided) */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { IconInput } from '../../core/atoms';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
3
3
|
export interface TurnPanelAction {
|
|
4
4
|
/** Action button label */
|
|
5
5
|
label: string;
|
|
6
|
-
/** Sprite
|
|
7
|
-
assetUrl?:
|
|
6
|
+
/** Sprite asset — takes precedence over icon when provided */
|
|
7
|
+
assetUrl?: Asset;
|
|
8
8
|
/** Icon for the button */
|
|
9
9
|
icon?: IconInput;
|
|
10
10
|
/** Event name to emit when clicked */
|
|
@@ -1779,7 +1779,7 @@ function TileRenderer({
|
|
|
1779
1779
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1780
1780
|
ModelLoader,
|
|
1781
1781
|
{
|
|
1782
|
-
url: tile.modelUrl,
|
|
1782
|
+
url: tile.modelUrl?.url,
|
|
1783
1783
|
position,
|
|
1784
1784
|
scale: cellSize * 0.9,
|
|
1785
1785
|
fallbackGeometry: "box",
|
|
@@ -2181,7 +2181,7 @@ function FeatureModel({
|
|
|
2181
2181
|
onHover
|
|
2182
2182
|
}) {
|
|
2183
2183
|
const groupRef = React11.useRef(null);
|
|
2184
|
-
const { model: loadedModel, isLoading } = useGLTFModel2(feature.assetUrl);
|
|
2184
|
+
const { model: loadedModel, isLoading } = useGLTFModel2(feature.assetUrl?.url);
|
|
2185
2185
|
const model = React11.useMemo(() => {
|
|
2186
2186
|
if (!loadedModel) return null;
|
|
2187
2187
|
const cloned = loadedModel.clone();
|
|
@@ -2316,12 +2316,7 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
|
2316
2316
|
|
|
2317
2317
|
// components/game/molecules/useUnitSpriteAtlas.ts
|
|
2318
2318
|
function unitAtlasUrl(unit) {
|
|
2319
|
-
|
|
2320
|
-
const sprite = unit.sprite;
|
|
2321
|
-
if (!sprite) return null;
|
|
2322
|
-
const match = /^(.*-sprite-sheet)(?:-(?:se|sw))?(?:-v\d+)?\.png$/.exec(sprite);
|
|
2323
|
-
if (!match) return null;
|
|
2324
|
-
return `${match[1]}.json`;
|
|
2319
|
+
return unit.spriteSheet?.url ?? null;
|
|
2325
2320
|
}
|
|
2326
2321
|
function resolveSheetUrl(atlasUrl, relativeSheetPath) {
|
|
2327
2322
|
try {
|
|
@@ -2732,7 +2727,7 @@ var GameCanvas3D = React11.forwardRef(
|
|
|
2732
2727
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2733
2728
|
ModelLoader,
|
|
2734
2729
|
{
|
|
2735
|
-
url: tile.modelUrl,
|
|
2730
|
+
url: tile.modelUrl.url,
|
|
2736
2731
|
scale: 0.95,
|
|
2737
2732
|
fallbackGeometry: "box",
|
|
2738
2733
|
castShadow: true,
|
|
@@ -2797,7 +2792,7 @@ var GameCanvas3D = React11.forwardRef(
|
|
|
2797
2792
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2798
2793
|
ModelLoader,
|
|
2799
2794
|
{
|
|
2800
|
-
url: unit.modelUrl,
|
|
2795
|
+
url: unit.modelUrl.url,
|
|
2801
2796
|
scale: modelScale,
|
|
2802
2797
|
fallbackGeometry: "box",
|
|
2803
2798
|
castShadow: true
|
|
@@ -2857,7 +2852,7 @@ var GameCanvas3D = React11.forwardRef(
|
|
|
2857
2852
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2858
2853
|
ModelLoader,
|
|
2859
2854
|
{
|
|
2860
|
-
url: feature.assetUrl,
|
|
2855
|
+
url: feature.assetUrl.url,
|
|
2861
2856
|
position,
|
|
2862
2857
|
scale: 0.5,
|
|
2863
2858
|
rotation: [0, feature.rotation ?? 0, 0],
|
|
@@ -4225,7 +4220,18 @@ function GameBoard3D({
|
|
|
4225
4220
|
const row = boardEntity(entity);
|
|
4226
4221
|
const eventBus = useEventBus();
|
|
4227
4222
|
const entityUnits = row ? rows(row.units) : [];
|
|
4228
|
-
const units = entityUnits
|
|
4223
|
+
const units = entityUnits.map((r) => ({
|
|
4224
|
+
id: str(r.id),
|
|
4225
|
+
x: num(r.x),
|
|
4226
|
+
y: num(r.y),
|
|
4227
|
+
z: num(r.z),
|
|
4228
|
+
faction: str(r.faction) || "neutral",
|
|
4229
|
+
team: str(r.team) || str(r.faction) || "neutral",
|
|
4230
|
+
unitType: r.unitType == null ? void 0 : str(r.unitType),
|
|
4231
|
+
name: r.name == null ? void 0 : str(r.name),
|
|
4232
|
+
health: r.health == null ? void 0 : num(r.health),
|
|
4233
|
+
maxHealth: r.maxHealth == null ? void 0 : num(r.maxHealth)
|
|
4234
|
+
}));
|
|
4229
4235
|
const selectedUnitId = row ? str(row.selectedUnitId) || null : null;
|
|
4230
4236
|
const phase = row ? str(row.phase) : "observation";
|
|
4231
4237
|
const result = row ? str(row.result) : "none";
|
|
@@ -4617,16 +4623,31 @@ var Box = React11__default.default.forwardRef(
|
|
|
4617
4623
|
);
|
|
4618
4624
|
Box.displayName = "Box";
|
|
4619
4625
|
|
|
4620
|
-
// components/game/
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4626
|
+
// components/game/organisms/utils/makeAsset.ts
|
|
4627
|
+
var ROLE_DEFAULTS = {
|
|
4628
|
+
tile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4629
|
+
decoration: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4630
|
+
effect: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4631
|
+
item: { dimension: "2d", animations: ["static"], aspect: "5:7" },
|
|
4632
|
+
player: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4633
|
+
enemy: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4634
|
+
npc: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4635
|
+
projectile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4636
|
+
vehicle: { dimension: "2d", animations: ["idle", "walk"], aspect: "1:1" },
|
|
4637
|
+
ui: { dimension: "2d", animations: ["static"], aspect: "1:1" }
|
|
4638
|
+
};
|
|
4639
|
+
function makeAsset(url, role, overrides = {}) {
|
|
4640
|
+
const defaults = ROLE_DEFAULTS[role] ?? { dimension: "2d", animations: ["static"], aspect: "1:1" };
|
|
4641
|
+
return {
|
|
4642
|
+
url,
|
|
4643
|
+
role,
|
|
4644
|
+
category: url.split("/").pop()?.replace(/\.[^.]+$/, "") ?? role,
|
|
4645
|
+
...defaults,
|
|
4646
|
+
...overrides
|
|
4647
|
+
};
|
|
4629
4648
|
}
|
|
4649
|
+
|
|
4650
|
+
// components/game/templates/game3dAssetManifest.ts
|
|
4630
4651
|
function tileKind(type, passable) {
|
|
4631
4652
|
if (passable === false) return "wall";
|
|
4632
4653
|
if (type === "dirt" || type === "road") return "dirt";
|
|
@@ -4642,7 +4663,7 @@ function resolveTilesWithModels(layout, manifest) {
|
|
|
4642
4663
|
z: t.z,
|
|
4643
4664
|
type: t.type,
|
|
4644
4665
|
passable: t.passable,
|
|
4645
|
-
modelUrl:
|
|
4666
|
+
modelUrl: manifest?.models?.[kind]
|
|
4646
4667
|
};
|
|
4647
4668
|
});
|
|
4648
4669
|
}
|
|
@@ -4651,7 +4672,7 @@ function resolvePropTiles(tiles, manifest) {
|
|
|
4651
4672
|
const kind = tileKind(t.type ?? "", t.passable);
|
|
4652
4673
|
return {
|
|
4653
4674
|
...t,
|
|
4654
|
-
modelUrl: t.modelUrl ??
|
|
4675
|
+
modelUrl: t.modelUrl ?? manifest?.models?.[kind]
|
|
4655
4676
|
};
|
|
4656
4677
|
});
|
|
4657
4678
|
}
|
|
@@ -4662,7 +4683,8 @@ function resolveEntityTiles(entity, manifest) {
|
|
|
4662
4683
|
const type = str(r.type) || str(r.terrain);
|
|
4663
4684
|
const passable = r.passable !== false;
|
|
4664
4685
|
const kind = tileKind(type, passable);
|
|
4665
|
-
const
|
|
4686
|
+
const explicitModelUrl = r.modelUrl == null ? void 0 : str(r.modelUrl);
|
|
4687
|
+
const explicitModel = explicitModelUrl ? makeAsset(explicitModelUrl, "decoration", { dimension: "3d" }) : void 0;
|
|
4666
4688
|
return {
|
|
4667
4689
|
id: r.id == null ? void 0 : str(r.id),
|
|
4668
4690
|
x: num(r.x),
|
|
@@ -4670,14 +4692,14 @@ function resolveEntityTiles(entity, manifest) {
|
|
|
4670
4692
|
z: r.z == null ? void 0 : num(r.z),
|
|
4671
4693
|
type,
|
|
4672
4694
|
passable,
|
|
4673
|
-
modelUrl: explicitModel ??
|
|
4695
|
+
modelUrl: explicitModel ?? manifest?.models?.[kind]
|
|
4674
4696
|
};
|
|
4675
4697
|
});
|
|
4676
4698
|
}
|
|
4677
4699
|
function resolveFeaturesWithModels(features, manifest) {
|
|
4678
4700
|
return features.map((f) => ({
|
|
4679
4701
|
...f,
|
|
4680
|
-
assetUrl: f.assetUrl ??
|
|
4702
|
+
assetUrl: f.assetUrl ?? manifest?.features?.[f.type]
|
|
4681
4703
|
}));
|
|
4682
4704
|
}
|
|
4683
4705
|
function resolveEntityFeatures(entity, manifest) {
|
|
@@ -4685,7 +4707,8 @@ function resolveEntityFeatures(entity, manifest) {
|
|
|
4685
4707
|
if (!row) return [];
|
|
4686
4708
|
return rows(row.features).map((r) => {
|
|
4687
4709
|
const type = str(r.type);
|
|
4688
|
-
const
|
|
4710
|
+
const explicitUrl = r.assetUrl == null ? void 0 : str(r.assetUrl);
|
|
4711
|
+
const explicit = explicitUrl ? makeAsset(explicitUrl, "decoration", { dimension: "3d" }) : void 0;
|
|
4689
4712
|
return {
|
|
4690
4713
|
id: r.id == null ? void 0 : str(r.id),
|
|
4691
4714
|
x: num(r.x),
|
|
@@ -4693,7 +4716,7 @@ function resolveEntityFeatures(entity, manifest) {
|
|
|
4693
4716
|
z: r.z == null ? void 0 : num(r.z),
|
|
4694
4717
|
type,
|
|
4695
4718
|
color: r.color == null ? void 0 : str(r.color),
|
|
4696
|
-
assetUrl: explicit ??
|
|
4719
|
+
assetUrl: explicit ?? manifest?.features?.[type]
|
|
4697
4720
|
};
|
|
4698
4721
|
});
|
|
4699
4722
|
}
|