@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
|
@@ -1755,7 +1755,7 @@ function TileRenderer({
|
|
|
1755
1755
|
children: /* @__PURE__ */ jsx(
|
|
1756
1756
|
ModelLoader,
|
|
1757
1757
|
{
|
|
1758
|
-
url: tile.modelUrl,
|
|
1758
|
+
url: tile.modelUrl?.url,
|
|
1759
1759
|
position,
|
|
1760
1760
|
scale: cellSize * 0.9,
|
|
1761
1761
|
fallbackGeometry: "box",
|
|
@@ -2157,7 +2157,7 @@ function FeatureModel({
|
|
|
2157
2157
|
onHover
|
|
2158
2158
|
}) {
|
|
2159
2159
|
const groupRef = useRef(null);
|
|
2160
|
-
const { model: loadedModel, isLoading } = useGLTFModel2(feature.assetUrl);
|
|
2160
|
+
const { model: loadedModel, isLoading } = useGLTFModel2(feature.assetUrl?.url);
|
|
2161
2161
|
const model = useMemo(() => {
|
|
2162
2162
|
if (!loadedModel) return null;
|
|
2163
2163
|
const cloned = loadedModel.clone();
|
|
@@ -2292,12 +2292,7 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
|
2292
2292
|
|
|
2293
2293
|
// components/game/molecules/useUnitSpriteAtlas.ts
|
|
2294
2294
|
function unitAtlasUrl(unit) {
|
|
2295
|
-
|
|
2296
|
-
const sprite = unit.sprite;
|
|
2297
|
-
if (!sprite) return null;
|
|
2298
|
-
const match = /^(.*-sprite-sheet)(?:-(?:se|sw))?(?:-v\d+)?\.png$/.exec(sprite);
|
|
2299
|
-
if (!match) return null;
|
|
2300
|
-
return `${match[1]}.json`;
|
|
2295
|
+
return unit.spriteSheet?.url ?? null;
|
|
2301
2296
|
}
|
|
2302
2297
|
function resolveSheetUrl(atlasUrl, relativeSheetPath) {
|
|
2303
2298
|
try {
|
|
@@ -2708,7 +2703,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2708
2703
|
children: /* @__PURE__ */ jsx(
|
|
2709
2704
|
ModelLoader,
|
|
2710
2705
|
{
|
|
2711
|
-
url: tile.modelUrl,
|
|
2706
|
+
url: tile.modelUrl.url,
|
|
2712
2707
|
scale: 0.95,
|
|
2713
2708
|
fallbackGeometry: "box",
|
|
2714
2709
|
castShadow: true,
|
|
@@ -2773,7 +2768,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2773
2768
|
/* @__PURE__ */ jsx(
|
|
2774
2769
|
ModelLoader,
|
|
2775
2770
|
{
|
|
2776
|
-
url: unit.modelUrl,
|
|
2771
|
+
url: unit.modelUrl.url,
|
|
2777
2772
|
scale: modelScale,
|
|
2778
2773
|
fallbackGeometry: "box",
|
|
2779
2774
|
castShadow: true
|
|
@@ -2833,7 +2828,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2833
2828
|
return /* @__PURE__ */ jsx(
|
|
2834
2829
|
ModelLoader,
|
|
2835
2830
|
{
|
|
2836
|
-
url: feature.assetUrl,
|
|
2831
|
+
url: feature.assetUrl.url,
|
|
2837
2832
|
position,
|
|
2838
2833
|
scale: 0.5,
|
|
2839
2834
|
rotation: [0, feature.rotation ?? 0, 0],
|
|
@@ -4201,7 +4196,18 @@ function GameBoard3D({
|
|
|
4201
4196
|
const row = boardEntity(entity);
|
|
4202
4197
|
const eventBus = useEventBus();
|
|
4203
4198
|
const entityUnits = row ? rows(row.units) : [];
|
|
4204
|
-
const units = entityUnits
|
|
4199
|
+
const units = entityUnits.map((r) => ({
|
|
4200
|
+
id: str(r.id),
|
|
4201
|
+
x: num(r.x),
|
|
4202
|
+
y: num(r.y),
|
|
4203
|
+
z: num(r.z),
|
|
4204
|
+
faction: str(r.faction) || "neutral",
|
|
4205
|
+
team: str(r.team) || str(r.faction) || "neutral",
|
|
4206
|
+
unitType: r.unitType == null ? void 0 : str(r.unitType),
|
|
4207
|
+
name: r.name == null ? void 0 : str(r.name),
|
|
4208
|
+
health: r.health == null ? void 0 : num(r.health),
|
|
4209
|
+
maxHealth: r.maxHealth == null ? void 0 : num(r.maxHealth)
|
|
4210
|
+
}));
|
|
4205
4211
|
const selectedUnitId = row ? str(row.selectedUnitId) || null : null;
|
|
4206
4212
|
const phase = row ? str(row.phase) : "observation";
|
|
4207
4213
|
const result = row ? str(row.result) : "none";
|
|
@@ -4593,16 +4599,31 @@ var Box = React11.forwardRef(
|
|
|
4593
4599
|
);
|
|
4594
4600
|
Box.displayName = "Box";
|
|
4595
4601
|
|
|
4596
|
-
// components/game/
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4602
|
+
// components/game/organisms/utils/makeAsset.ts
|
|
4603
|
+
var ROLE_DEFAULTS = {
|
|
4604
|
+
tile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4605
|
+
decoration: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4606
|
+
effect: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4607
|
+
item: { dimension: "2d", animations: ["static"], aspect: "5:7" },
|
|
4608
|
+
player: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4609
|
+
enemy: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4610
|
+
npc: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
|
|
4611
|
+
projectile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
|
|
4612
|
+
vehicle: { dimension: "2d", animations: ["idle", "walk"], aspect: "1:1" },
|
|
4613
|
+
ui: { dimension: "2d", animations: ["static"], aspect: "1:1" }
|
|
4614
|
+
};
|
|
4615
|
+
function makeAsset(url, role, overrides = {}) {
|
|
4616
|
+
const defaults = ROLE_DEFAULTS[role] ?? { dimension: "2d", animations: ["static"], aspect: "1:1" };
|
|
4617
|
+
return {
|
|
4618
|
+
url,
|
|
4619
|
+
role,
|
|
4620
|
+
category: url.split("/").pop()?.replace(/\.[^.]+$/, "") ?? role,
|
|
4621
|
+
...defaults,
|
|
4622
|
+
...overrides
|
|
4623
|
+
};
|
|
4605
4624
|
}
|
|
4625
|
+
|
|
4626
|
+
// components/game/templates/game3dAssetManifest.ts
|
|
4606
4627
|
function tileKind(type, passable) {
|
|
4607
4628
|
if (passable === false) return "wall";
|
|
4608
4629
|
if (type === "dirt" || type === "road") return "dirt";
|
|
@@ -4618,7 +4639,7 @@ function resolveTilesWithModels(layout, manifest) {
|
|
|
4618
4639
|
z: t.z,
|
|
4619
4640
|
type: t.type,
|
|
4620
4641
|
passable: t.passable,
|
|
4621
|
-
modelUrl:
|
|
4642
|
+
modelUrl: manifest?.models?.[kind]
|
|
4622
4643
|
};
|
|
4623
4644
|
});
|
|
4624
4645
|
}
|
|
@@ -4627,7 +4648,7 @@ function resolvePropTiles(tiles, manifest) {
|
|
|
4627
4648
|
const kind = tileKind(t.type ?? "", t.passable);
|
|
4628
4649
|
return {
|
|
4629
4650
|
...t,
|
|
4630
|
-
modelUrl: t.modelUrl ??
|
|
4651
|
+
modelUrl: t.modelUrl ?? manifest?.models?.[kind]
|
|
4631
4652
|
};
|
|
4632
4653
|
});
|
|
4633
4654
|
}
|
|
@@ -4638,7 +4659,8 @@ function resolveEntityTiles(entity, manifest) {
|
|
|
4638
4659
|
const type = str(r.type) || str(r.terrain);
|
|
4639
4660
|
const passable = r.passable !== false;
|
|
4640
4661
|
const kind = tileKind(type, passable);
|
|
4641
|
-
const
|
|
4662
|
+
const explicitModelUrl = r.modelUrl == null ? void 0 : str(r.modelUrl);
|
|
4663
|
+
const explicitModel = explicitModelUrl ? makeAsset(explicitModelUrl, "decoration", { dimension: "3d" }) : void 0;
|
|
4642
4664
|
return {
|
|
4643
4665
|
id: r.id == null ? void 0 : str(r.id),
|
|
4644
4666
|
x: num(r.x),
|
|
@@ -4646,14 +4668,14 @@ function resolveEntityTiles(entity, manifest) {
|
|
|
4646
4668
|
z: r.z == null ? void 0 : num(r.z),
|
|
4647
4669
|
type,
|
|
4648
4670
|
passable,
|
|
4649
|
-
modelUrl: explicitModel ??
|
|
4671
|
+
modelUrl: explicitModel ?? manifest?.models?.[kind]
|
|
4650
4672
|
};
|
|
4651
4673
|
});
|
|
4652
4674
|
}
|
|
4653
4675
|
function resolveFeaturesWithModels(features, manifest) {
|
|
4654
4676
|
return features.map((f) => ({
|
|
4655
4677
|
...f,
|
|
4656
|
-
assetUrl: f.assetUrl ??
|
|
4678
|
+
assetUrl: f.assetUrl ?? manifest?.features?.[f.type]
|
|
4657
4679
|
}));
|
|
4658
4680
|
}
|
|
4659
4681
|
function resolveEntityFeatures(entity, manifest) {
|
|
@@ -4661,7 +4683,8 @@ function resolveEntityFeatures(entity, manifest) {
|
|
|
4661
4683
|
if (!row) return [];
|
|
4662
4684
|
return rows(row.features).map((r) => {
|
|
4663
4685
|
const type = str(r.type);
|
|
4664
|
-
const
|
|
4686
|
+
const explicitUrl = r.assetUrl == null ? void 0 : str(r.assetUrl);
|
|
4687
|
+
const explicit = explicitUrl ? makeAsset(explicitUrl, "decoration", { dimension: "3d" }) : void 0;
|
|
4665
4688
|
return {
|
|
4666
4689
|
id: r.id == null ? void 0 : str(r.id),
|
|
4667
4690
|
x: num(r.x),
|
|
@@ -4669,7 +4692,7 @@ function resolveEntityFeatures(entity, manifest) {
|
|
|
4669
4692
|
z: r.z == null ? void 0 : num(r.z),
|
|
4670
4693
|
type,
|
|
4671
4694
|
color: r.color == null ? void 0 : str(r.color),
|
|
4672
|
-
assetUrl: explicit ??
|
|
4695
|
+
assetUrl: explicit ?? manifest?.features?.[type]
|
|
4673
4696
|
};
|
|
4674
4697
|
});
|
|
4675
4698
|
}
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import type { AssetUrl } from '@almadar/core';
|
|
2
1
|
import type { IsometricUnit } from '../organisms/types/isometric';
|
|
3
2
|
import type { ResolvedFrame } from '../organisms/types/spriteAnimation';
|
|
4
3
|
/**
|
|
5
4
|
* Resolve the sprite-sheet atlas-JSON URL for a unit.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the deterministic naming convention used in `shared/sprite-sheets/`:
|
|
10
|
-
* the shared atlas drops the `-se` / `-sw` direction suffix and any `-vN`
|
|
11
|
-
* variant suffix, then swaps `.png` → `.json`
|
|
12
|
-
* (`amir-sprite-sheet-se.png` → `amir-sprite-sheet.json`).
|
|
13
|
-
*
|
|
14
|
-
* Returns null when no atlas can be resolved (the unit keeps its static draw).
|
|
6
|
+
* A unit has an atlas iff `unit.spriteSheet.url` is set (explicit metadata wins).
|
|
7
|
+
* No filename-pattern matching — a unit without a `spriteSheet` Asset keeps its static draw.
|
|
15
8
|
*/
|
|
16
|
-
export declare function unitAtlasUrl(unit: Pick<IsometricUnit, 'spriteSheet'
|
|
9
|
+
export declare function unitAtlasUrl(unit: Pick<IsometricUnit, 'spriteSheet'>): string | null;
|
|
17
10
|
export interface UseUnitSpriteAtlasResult {
|
|
18
11
|
/** Atlas-JSON URLs successfully loaded — feed these to no one; sheet PNGs are returned below. */
|
|
19
12
|
sheetUrls: string[];
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
20
|
import React from 'react';
|
|
21
|
-
import type { AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
21
|
+
import type { Asset, AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
22
22
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
23
23
|
import type { IsometricTile, IsometricUnit, IsometricFeature } from './types/isometric';
|
|
24
24
|
import type { ResolvedFrame } from './types/spriteAnimation';
|
|
@@ -48,11 +48,10 @@ export type BattleSlotContext = {
|
|
|
48
48
|
};
|
|
49
49
|
/** Asset manifest shape for BattleBoard. */
|
|
50
50
|
type BattleAssetManifest = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
effects?: Record<string, AssetUrl>;
|
|
51
|
+
terrains?: Record<string, Asset>;
|
|
52
|
+
units?: Record<string, Asset>;
|
|
53
|
+
features?: Record<string, Asset>;
|
|
54
|
+
effects?: Record<string, Asset>;
|
|
56
55
|
};
|
|
57
56
|
export interface BattleBoardProps extends DisplayStateProps {
|
|
58
57
|
/** Entity (single board state) containing all board data */
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
|
-
/** Manifest of
|
|
4
|
+
/** Manifest of per-card sprite map (UI value DTO). */
|
|
5
5
|
type CardBattlerAssetManifest = {
|
|
6
|
-
|
|
7
|
-
cards?: Record<string, AssetUrl>;
|
|
6
|
+
cards?: Record<string, Asset>;
|
|
8
7
|
};
|
|
9
8
|
/** One card as carried on the entity / passed as a prop. */
|
|
10
9
|
export interface CardBattlerCard {
|
|
@@ -13,14 +13,13 @@
|
|
|
13
13
|
* @packageDocumentation
|
|
14
14
|
*/
|
|
15
15
|
import React from 'react';
|
|
16
|
-
import type {
|
|
16
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
17
17
|
import type { IsometricTile, IsometricUnit, IsometricFeature } from './types/isometric';
|
|
18
|
-
/** Manifest of
|
|
18
|
+
/** Manifest of per-kind sprite maps (UI value DTO). */
|
|
19
19
|
type CastleAssetManifest = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
features?: Record<string, AssetUrl>;
|
|
20
|
+
terrains?: Record<string, Asset>;
|
|
21
|
+
units?: Record<string, Asset>;
|
|
22
|
+
features?: Record<string, Asset>;
|
|
24
23
|
};
|
|
25
24
|
/** Context exposed to render-prop slots */
|
|
26
25
|
export type CastleSlotContext = {
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
|
-
/** Manifest of
|
|
4
|
+
/** Manifest of per-kind sprite maps (UI value DTO). */
|
|
5
5
|
type CityBuilderAssetManifest = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
features?: Record<string, AssetUrl>;
|
|
6
|
+
terrains?: Record<string, Asset>;
|
|
7
|
+
units?: Record<string, Asset>;
|
|
8
|
+
features?: Record<string, Asset>;
|
|
10
9
|
};
|
|
11
10
|
export interface CityBuilderTile {
|
|
12
11
|
x: number;
|
|
13
12
|
y: number;
|
|
14
13
|
terrain?: string;
|
|
15
|
-
terrainSprite?:
|
|
14
|
+
terrainSprite?: Asset;
|
|
16
15
|
passable?: boolean;
|
|
17
16
|
}
|
|
18
17
|
export interface CityBuilderBuilding {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
4
|
export interface FishingBoardProps extends DisplayStateProps {
|
|
5
|
-
/** Background image
|
|
6
|
-
backgroundImage?:
|
|
7
|
-
/** Base URL prepended to asset paths */
|
|
8
|
-
assetBaseUrl?: AssetUrl;
|
|
5
|
+
/** Background image asset for the fishing scene */
|
|
6
|
+
backgroundImage?: Asset;
|
|
9
7
|
/** Render scale */
|
|
10
8
|
scale?: number;
|
|
11
9
|
/** Show minimap overlay */
|
|
@@ -26,7 +24,7 @@ export interface FishingBoardProps extends DisplayStateProps {
|
|
|
26
24
|
unitId: string;
|
|
27
25
|
}>;
|
|
28
26
|
}
|
|
29
|
-
export declare function FishingBoard({ backgroundImage,
|
|
27
|
+
export declare function FishingBoard({ backgroundImage, scale, showMinimap, enableCamera, width, height, isLoading, error, className, }: FishingBoardProps): React.ReactElement;
|
|
30
28
|
export declare namespace FishingBoard {
|
|
31
29
|
var displayName: string;
|
|
32
30
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { PlatformerPlatform, PlatformerPlayer } from '../molecules/PlatformerCanvas';
|
|
4
4
|
export interface PlatformerBoardProps {
|
|
5
5
|
/** Entity containing all board state (result, lives, score, level, player, platforms) */
|
|
@@ -21,10 +21,10 @@ export interface PlatformerBoardProps {
|
|
|
21
21
|
worldHeight?: number;
|
|
22
22
|
canvasWidth?: number;
|
|
23
23
|
canvasHeight?: number;
|
|
24
|
-
/** Player sprite
|
|
25
|
-
playerSprite?:
|
|
26
|
-
/** Map of platform type to tile sprite
|
|
27
|
-
tileSprites?: Record<string,
|
|
24
|
+
/** Player sprite */
|
|
25
|
+
playerSprite?: Asset;
|
|
26
|
+
/** Map of platform type to tile sprite */
|
|
27
|
+
tileSprites?: Record<string, Asset>;
|
|
28
28
|
/** Canvas background color */
|
|
29
29
|
bgColor?: string;
|
|
30
30
|
/** Event names forwarded to PlatformerCanvas */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
4
|
import type { IsometricTile } from './types/isometric';
|
|
5
5
|
type PlayerPos = {
|
|
@@ -20,10 +20,9 @@ type ItemRow = {
|
|
|
20
20
|
kind: 'health_potion' | 'sword' | 'shield';
|
|
21
21
|
};
|
|
22
22
|
type RoguelikeAssetManifest = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
features?: Record<string, AssetUrl>;
|
|
23
|
+
terrains?: Record<string, Asset>;
|
|
24
|
+
units?: Record<string, Asset>;
|
|
25
|
+
features?: Record<string, Asset>;
|
|
27
26
|
};
|
|
28
27
|
export interface RoguelikeBoardProps extends DisplayStateProps {
|
|
29
28
|
entity?: EntityRow | readonly EntityRow[];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
/**
|
|
2
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
3
|
+
/** Per-kind sprite maps (organism owns asset choice; UI value DTO). */
|
|
4
4
|
type ShooterAssetManifest = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
background?: AssetUrl;
|
|
5
|
+
units?: Record<string, Asset>;
|
|
6
|
+
features?: Record<string, Asset>;
|
|
7
|
+
background?: Asset;
|
|
9
8
|
};
|
|
10
9
|
export interface ShooterPlayer {
|
|
11
10
|
x: number;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
2
|
+
import type { Asset, AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
|
-
/** Manifest of
|
|
4
|
+
/** Manifest of per-kind sprite maps (UI value DTO). */
|
|
5
5
|
type TowerDefenseAssetManifest = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
features?: Record<string, AssetUrl>;
|
|
6
|
+
terrains?: Record<string, Asset>;
|
|
7
|
+
units?: Record<string, Asset>;
|
|
8
|
+
features?: Record<string, Asset>;
|
|
10
9
|
};
|
|
11
10
|
export interface TowerDefenseTile {
|
|
12
11
|
x: number;
|
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
* the `assetManifest` prop (organism owns asset choice — no hardcoded URLs).
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import type {
|
|
10
|
+
import type { Asset, EventEmit, EntityRow } from '@almadar/core';
|
|
11
11
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
12
|
-
/** Manifest of
|
|
12
|
+
/** Manifest of per-key scene + portrait maps (UI value DTO). */
|
|
13
13
|
type VisualNovelAssetManifest = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
portraits?: Record<string, AssetUrl>;
|
|
14
|
+
backgrounds?: Record<string, Asset>;
|
|
15
|
+
portraits?: Record<string, Asset>;
|
|
17
16
|
};
|
|
18
17
|
export interface VisualNovelChoice {
|
|
19
18
|
label: string;
|
|
@@ -19,16 +19,15 @@
|
|
|
19
19
|
* @packageDocumentation
|
|
20
20
|
*/
|
|
21
21
|
import React from 'react';
|
|
22
|
-
import type { AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
22
|
+
import type { Asset, AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
23
23
|
import type { IsometricTile, IsometricUnit, IsometricFeature } from './types/isometric';
|
|
24
24
|
import type { ResolvedFrame } from './types/spriteAnimation';
|
|
25
25
|
import type { UiError } from '../../core/atoms/types';
|
|
26
|
-
/** Manifest of
|
|
26
|
+
/** Manifest of per-kind sprite maps (UI value DTO). */
|
|
27
27
|
type WorldMapAssetManifest = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
features?: Record<string, AssetUrl>;
|
|
28
|
+
terrains?: Record<string, Asset>;
|
|
29
|
+
units?: Record<string, Asset>;
|
|
30
|
+
features?: Record<string, Asset>;
|
|
32
31
|
};
|
|
33
32
|
/** Context exposed to render-prop slots. Hex / hero rows are `EntityRow`. */
|
|
34
33
|
export type WorldMapSlotContext = {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AssetUrl } from '@almadar/core';
|
|
2
1
|
/**
|
|
3
2
|
* Canvas Effect Types
|
|
4
3
|
*
|
|
@@ -12,7 +11,7 @@ import type { AssetUrl } from '@almadar/core';
|
|
|
12
11
|
*/
|
|
13
12
|
export interface CanvasParticle {
|
|
14
13
|
/** Sprite URL (white-on-transparent particle) */
|
|
15
|
-
spriteUrl:
|
|
14
|
+
spriteUrl: string;
|
|
16
15
|
/** Current position in screen pixels */
|
|
17
16
|
x: number;
|
|
18
17
|
y: number;
|
|
@@ -51,7 +50,7 @@ export interface CanvasParticle {
|
|
|
51
50
|
*/
|
|
52
51
|
export interface ParticleEmitterConfig {
|
|
53
52
|
/** Array of sprite URLs to randomly pick from */
|
|
54
|
-
spriteUrls:
|
|
53
|
+
spriteUrls: string[];
|
|
55
54
|
/** Number of particles to spawn */
|
|
56
55
|
count: number;
|
|
57
56
|
/** Spawn origin in screen pixels */
|
|
@@ -96,7 +95,7 @@ export interface ParticleEmitterConfig {
|
|
|
96
95
|
*/
|
|
97
96
|
export interface CanvasSequence {
|
|
98
97
|
/** Ordered array of frame sprite URLs */
|
|
99
|
-
frameUrls:
|
|
98
|
+
frameUrls: string[];
|
|
100
99
|
/** Position in screen pixels (top-left of sprite) */
|
|
101
100
|
x: number;
|
|
102
101
|
y: number;
|
|
@@ -123,7 +122,7 @@ export interface CanvasSequence {
|
|
|
123
122
|
* Configuration for spawning a frame sequence.
|
|
124
123
|
*/
|
|
125
124
|
export interface SequenceConfig {
|
|
126
|
-
frameUrls:
|
|
125
|
+
frameUrls: string[];
|
|
127
126
|
originX: number;
|
|
128
127
|
originY: number;
|
|
129
128
|
frameDuration: number;
|
|
@@ -142,7 +141,7 @@ export interface SequenceConfig {
|
|
|
142
141
|
*/
|
|
143
142
|
export interface CanvasOverlay {
|
|
144
143
|
/** Sprite URL */
|
|
145
|
-
spriteUrl:
|
|
144
|
+
spriteUrl: string;
|
|
146
145
|
/** Center position in screen pixels */
|
|
147
146
|
x: number;
|
|
148
147
|
y: number;
|
|
@@ -167,7 +166,7 @@ export interface CanvasOverlay {
|
|
|
167
166
|
* Configuration for spawning an overlay.
|
|
168
167
|
*/
|
|
169
168
|
export interface OverlayConfig {
|
|
170
|
-
spriteUrl:
|
|
169
|
+
spriteUrl: string;
|
|
171
170
|
originX: number;
|
|
172
171
|
originY: number;
|
|
173
172
|
alpha?: number;
|
|
@@ -217,7 +216,7 @@ export interface CombatPreset {
|
|
|
217
216
|
*/
|
|
218
217
|
export interface EffectAssetManifest {
|
|
219
218
|
/** Base URL for all asset paths */
|
|
220
|
-
baseUrl:
|
|
219
|
+
baseUrl: string;
|
|
221
220
|
/** Particle sprite groups (white-on-transparent, tinted at runtime) */
|
|
222
221
|
particles?: {
|
|
223
222
|
slash?: string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Asset } from '@almadar/core';
|
|
2
2
|
import type { AnimationName } from './spriteAnimation';
|
|
3
3
|
/**
|
|
4
4
|
* Isometric Game Types
|
|
@@ -34,7 +34,7 @@ export interface IsometricTile {
|
|
|
34
34
|
/** Tile type for visual rendering (3D) */
|
|
35
35
|
type?: string;
|
|
36
36
|
/** Direct sprite URL override (bypasses getTerrainSprite resolver) */
|
|
37
|
-
terrainSprite?:
|
|
37
|
+
terrainSprite?: Asset;
|
|
38
38
|
/** Whether units can traverse this tile (default true) */
|
|
39
39
|
passable?: boolean;
|
|
40
40
|
/** Movement cost for pathfinding (default 1) */
|
|
@@ -44,7 +44,7 @@ export interface IsometricTile {
|
|
|
44
44
|
/** Elevation offset for 3D rendering */
|
|
45
45
|
elevation?: number;
|
|
46
46
|
/** 3D model URL (GLB format) for GameCanvas3D — rendered via ModelLoader with box fallback */
|
|
47
|
-
modelUrl?:
|
|
47
|
+
modelUrl?: Asset;
|
|
48
48
|
}
|
|
49
49
|
/** A unit positioned on the isometric grid */
|
|
50
50
|
export type IsometricUnit = {
|
|
@@ -62,13 +62,13 @@ export type IsometricUnit = {
|
|
|
62
62
|
/** Grid z coordinate (3D format) */
|
|
63
63
|
z?: number;
|
|
64
64
|
/** Static sprite URL (used when no sprite sheet animation) */
|
|
65
|
-
sprite?:
|
|
65
|
+
sprite?: Asset;
|
|
66
66
|
/** Sprite-sheet atlas JSON URL (e.g. `.../guardian-sprite-sheet.json`).
|
|
67
67
|
* When set, the canvas loads the atlas and crops/animates a single frame
|
|
68
68
|
* by animation state instead of drawing the whole sheet. */
|
|
69
|
-
spriteSheet?:
|
|
69
|
+
spriteSheet?: Asset;
|
|
70
70
|
/** 3D model URL (GLB format) for GameCanvas3D — rendered via ModelLoader with box fallback */
|
|
71
|
-
modelUrl?:
|
|
71
|
+
modelUrl?: Asset;
|
|
72
72
|
/** Unit archetype key for sprite resolution */
|
|
73
73
|
unitType?: string;
|
|
74
74
|
/** Hero identifier for sprite sheet lookup */
|
|
@@ -115,9 +115,9 @@ export type IsometricFeature = {
|
|
|
115
115
|
/** Feature type key (e.g., 'goldMine', 'castle', 'portal') */
|
|
116
116
|
type: string;
|
|
117
117
|
/** Direct sprite URL override (bypasses getFeatureSprite resolver) */
|
|
118
|
-
sprite?:
|
|
118
|
+
sprite?: Asset;
|
|
119
119
|
/** 3D model URL (GLB format) for GameCanvas3D */
|
|
120
|
-
assetUrl?:
|
|
120
|
+
assetUrl?: Asset;
|
|
121
121
|
/** Color override for 3D rendering */
|
|
122
122
|
color?: string;
|
|
123
123
|
/** Elevation offset for 3D rendering */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AssetUrl } from '@almadar/core';
|
|
2
1
|
/**
|
|
3
2
|
* Sprite Sheet Animation Types
|
|
4
3
|
*
|
|
@@ -27,7 +26,7 @@ export interface AnimationDef {
|
|
|
27
26
|
/** A resolved frame ready to draw on canvas */
|
|
28
27
|
export interface ResolvedFrame {
|
|
29
28
|
/** URL of the sprite sheet image */
|
|
30
|
-
sheetUrl:
|
|
29
|
+
sheetUrl: string;
|
|
31
30
|
/** Source X in the sheet (pixel offset) */
|
|
32
31
|
sx: number;
|
|
33
32
|
/** Source Y in the sheet (pixel offset) */
|
|
@@ -68,9 +67,9 @@ export interface SpriteFrameDims {
|
|
|
68
67
|
/** Sheet URLs for both directions */
|
|
69
68
|
export interface SpriteSheetUrls {
|
|
70
69
|
/** Southeast-facing sheet URL */
|
|
71
|
-
se:
|
|
70
|
+
se: string;
|
|
72
71
|
/** Southwest-facing sheet URL */
|
|
73
|
-
sw:
|
|
72
|
+
sw: string;
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
75
|
* Parsed sprite-sheet atlas JSON (e.g. `guardian-sprite-sheet.json`).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Asset, EntityRole } from '@almadar/core';
|
|
2
|
+
/** Build an Asset from a url + the slot's role. Slot-fixed defaults by role. */
|
|
3
|
+
export declare function makeAsset(url: string, role: EntityRole, overrides?: Partial<Asset>): Asset;
|
|
4
|
+
/** Map a name→url record to name→Asset. */
|
|
5
|
+
export declare function makeAssetMap(record: Record<string, string>, role: EntityRole, overrides?: Partial<Asset>): Record<string, Asset>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { Asset } from '@almadar/core';
|
|
2
3
|
import type { TemplateProps } from '../../core/templates/types';
|
|
3
4
|
import type { PlatformerBoardProps } from '../organisms/PlatformerBoard';
|
|
4
5
|
export interface PlatformerTemplateProps extends TemplateProps {
|
|
@@ -10,10 +11,10 @@ export interface PlatformerTemplateProps extends TemplateProps {
|
|
|
10
11
|
/** Canvas display size */
|
|
11
12
|
canvasWidth?: number;
|
|
12
13
|
canvasHeight?: number;
|
|
13
|
-
/** Player sprite
|
|
14
|
-
playerSprite?:
|
|
15
|
-
/** Map of platform type to tile sprite
|
|
16
|
-
tileSprites?: Record<string,
|
|
14
|
+
/** Player sprite asset */
|
|
15
|
+
playerSprite?: Asset;
|
|
16
|
+
/** Map of platform type to tile sprite asset */
|
|
17
|
+
tileSprites?: Record<string, Asset>;
|
|
17
18
|
/** Canvas background color */
|
|
18
19
|
bgColor?: string;
|
|
19
20
|
/** Forwarded to PlatformerBoard to emit GAME_END into the FSM */
|
|
@@ -9,16 +9,14 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @packageDocumentation
|
|
11
11
|
*/
|
|
12
|
-
import type {
|
|
12
|
+
import type { Asset, EntityRow } from '@almadar/core';
|
|
13
13
|
import type { IsometricTile, IsometricFeature } from '../organisms/types/isometric';
|
|
14
|
-
/** GLB model
|
|
14
|
+
/** GLB model assets for a 3D board, keyed by terrain "kind" and (optionally) feature type. */
|
|
15
15
|
export interface Game3DAssetManifest {
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
/** Feature/structure model URLs by feature type ('gold_mine', 'portal', …). */
|
|
21
|
-
features?: Record<string, AssetUrl>;
|
|
16
|
+
/** Floor model assets by terrain kind ('wall' | 'dirt' | 'open'). */
|
|
17
|
+
models?: Record<string, Asset>;
|
|
18
|
+
/** Feature/structure model assets by feature type ('gold_mine', 'portal', …). */
|
|
19
|
+
features?: Record<string, Asset>;
|
|
22
20
|
}
|
|
23
21
|
/** Layout-only tile (no model URL): position + terrain kind. */
|
|
24
22
|
export interface Tile3DLayout {
|