@almadar/ui 5.143.0 → 5.145.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 +89 -9
- package/dist/avl/index.js +91 -11
- package/dist/{avl-schema-parser-0hkiHOq3.d.ts → avl-schema-parser-BRJ77Yze.d.ts} +12 -2
- package/dist/{avl-schema-parser-BZ8pICOS.d.cts → avl-schema-parser-DVmrgdwc.d.cts} +12 -2
- package/dist/{cn-CvImTgKH.d.cts → cn-BdGFhYe3.d.cts} +1 -1
- package/dist/{cn-DryTiahe.d.ts → cn-DNkqAWZK.d.ts} +1 -1
- package/dist/components/index.cjs +186 -135
- package/dist/components/index.d.cts +7 -5
- package/dist/components/index.d.ts +7 -5
- package/dist/components/index.js +187 -136
- package/dist/lib/drawable/three/index.cjs +187 -134
- package/dist/lib/drawable/three/index.d.cts +3 -3
- package/dist/lib/drawable/three/index.d.ts +3 -3
- package/dist/lib/drawable/three/index.js +162 -109
- package/dist/lib/index.d.cts +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/marketing/index.cjs +6 -1
- package/dist/marketing/index.js +6 -1
- package/dist/{paintDispatch-D3-5_cOb.d.cts → paintDispatch-Cb_hQj4Y.d.cts} +7 -1
- package/dist/{paintDispatch-D3-5_cOb.d.ts → paintDispatch-Cb_hQj4Y.d.ts} +7 -1
- package/dist/providers/index.cjs +82 -7
- package/dist/providers/index.js +83 -8
- package/dist/runtime/index.cjs +89 -9
- package/dist/runtime/index.js +91 -11
- package/package.json +5 -4
package/dist/components/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { useTranslate } from '@almadar/ui/hooks';
|
|
|
12
12
|
import { useUISlots, useTheme } from '@almadar/ui/context';
|
|
13
13
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
14
14
|
import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
|
|
15
|
-
import { mergeEntityFrame, isInlineTrait, isRenderBindingMarker } from '@almadar/core';
|
|
15
|
+
import { mergeEntityFrame, isInlineTrait, isRenderBindingMarker, ANIMATION_NAMES } from '@almadar/core';
|
|
16
16
|
import { createPortal } from 'react-dom';
|
|
17
17
|
import { wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
18
18
|
import { Link, Outlet, useLocation } from 'react-router-dom';
|
|
@@ -1451,6 +1451,10 @@ var init_Icon = __esm({
|
|
|
1451
1451
|
function isTilesheet(a) {
|
|
1452
1452
|
return typeof a.tileWidth === "number";
|
|
1453
1453
|
}
|
|
1454
|
+
function isSpriteSheetAtlas(a) {
|
|
1455
|
+
const s = a;
|
|
1456
|
+
return typeof s.frameWidth === "number" && typeof s.frameHeight === "number" && typeof s.animations === "object";
|
|
1457
|
+
}
|
|
1454
1458
|
function getAtlas(url, onReady) {
|
|
1455
1459
|
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
1456
1460
|
atlasCache.set(url, void 0);
|
|
@@ -1490,6 +1494,7 @@ function subRectFor(atlas, sprite) {
|
|
|
1490
1494
|
sh: atlas.tileHeight
|
|
1491
1495
|
};
|
|
1492
1496
|
}
|
|
1497
|
+
if (isSpriteSheetAtlas(atlas)) return null;
|
|
1493
1498
|
const st = atlas.subTextures[sprite];
|
|
1494
1499
|
if (!st) return null;
|
|
1495
1500
|
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
@@ -1799,7 +1804,7 @@ var init_Button = __esm({
|
|
|
1799
1804
|
"data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
|
|
1800
1805
|
children: [
|
|
1801
1806
|
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
1802
|
-
children
|
|
1807
|
+
(Array.isArray(children) ? children.length > 0 : Boolean(children)) ? children : label,
|
|
1803
1808
|
resolvedRightIcon && !isLoading && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
|
|
1804
1809
|
]
|
|
1805
1810
|
}
|
|
@@ -15946,6 +15951,138 @@ var init_contract = __esm({
|
|
|
15946
15951
|
"lib/drawable/contract.ts"() {
|
|
15947
15952
|
}
|
|
15948
15953
|
});
|
|
15954
|
+
|
|
15955
|
+
// lib/spriteSheetConstants.ts
|
|
15956
|
+
var SHEET_COLUMNS, SPRITE_SHEET_LAYOUT;
|
|
15957
|
+
var init_spriteSheetConstants = __esm({
|
|
15958
|
+
"lib/spriteSheetConstants.ts"() {
|
|
15959
|
+
SHEET_COLUMNS = 8;
|
|
15960
|
+
SPRITE_SHEET_LAYOUT = {
|
|
15961
|
+
idle: { row: 0, frames: 4, frameRate: 6, loop: true },
|
|
15962
|
+
walk: { row: 1, frames: 8, frameRate: 10, loop: true },
|
|
15963
|
+
attack: { row: 2, frames: 6, frameRate: 12, loop: false },
|
|
15964
|
+
hit: { row: 3, frames: 3, frameRate: 8, loop: false },
|
|
15965
|
+
death: { row: 4, frames: 6, frameRate: 8, loop: false }
|
|
15966
|
+
};
|
|
15967
|
+
}
|
|
15968
|
+
});
|
|
15969
|
+
function isAnimationName(name) {
|
|
15970
|
+
return ANIMATION_NAMES.includes(name);
|
|
15971
|
+
}
|
|
15972
|
+
function inferDirection(dx, dy) {
|
|
15973
|
+
if (dx === 0 && dy === 0) return "se";
|
|
15974
|
+
if (dx >= 0 && dy >= 0) return "se";
|
|
15975
|
+
if (dx <= 0 && dy >= 0) return "sw";
|
|
15976
|
+
if (dx >= 0 && dy <= 0) return "ne";
|
|
15977
|
+
return "nw";
|
|
15978
|
+
}
|
|
15979
|
+
function resolveSheetDirection(facing) {
|
|
15980
|
+
switch (facing) {
|
|
15981
|
+
case "se":
|
|
15982
|
+
return { sheetDir: "se", flipX: false };
|
|
15983
|
+
case "sw":
|
|
15984
|
+
return { sheetDir: "sw", flipX: false };
|
|
15985
|
+
case "ne":
|
|
15986
|
+
return { sheetDir: "sw", flipX: true };
|
|
15987
|
+
case "nw":
|
|
15988
|
+
return { sheetDir: "se", flipX: true };
|
|
15989
|
+
}
|
|
15990
|
+
}
|
|
15991
|
+
function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
15992
|
+
return {
|
|
15993
|
+
sx: frame % columns * frameWidth,
|
|
15994
|
+
sy: row * frameHeight,
|
|
15995
|
+
sw: frameWidth,
|
|
15996
|
+
sh: frameHeight
|
|
15997
|
+
};
|
|
15998
|
+
}
|
|
15999
|
+
function getCurrentFrameFromDef(def, elapsed) {
|
|
16000
|
+
const frameDuration = 1e3 / def.frameRate;
|
|
16001
|
+
const totalDuration = def.frames * frameDuration;
|
|
16002
|
+
if (def.loop) {
|
|
16003
|
+
const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
|
|
16004
|
+
return { frame: frame2, finished: false };
|
|
16005
|
+
}
|
|
16006
|
+
if (elapsed >= totalDuration) {
|
|
16007
|
+
return { frame: def.frames - 1, finished: true };
|
|
16008
|
+
}
|
|
16009
|
+
const frame = Math.floor(elapsed / frameDuration);
|
|
16010
|
+
return { frame, finished: false };
|
|
16011
|
+
}
|
|
16012
|
+
function getCurrentFrame(animName, elapsed) {
|
|
16013
|
+
return getCurrentFrameFromDef(SPRITE_SHEET_LAYOUT[animName], elapsed);
|
|
16014
|
+
}
|
|
16015
|
+
function resolveFrame(sheetUrls, frameDims, animState) {
|
|
16016
|
+
if (!sheetUrls) return null;
|
|
16017
|
+
const real = sheetUrls[animState.direction];
|
|
16018
|
+
const { sheetUrl, flipX } = real ? { sheetUrl: real, flipX: false } : (() => {
|
|
16019
|
+
const legacy = resolveSheetDirection(animState.direction);
|
|
16020
|
+
return { sheetUrl: sheetUrls[legacy.sheetDir], flipX: legacy.flipX };
|
|
16021
|
+
})();
|
|
16022
|
+
if (!sheetUrl) return null;
|
|
16023
|
+
const def = SPRITE_SHEET_LAYOUT[animState.animation];
|
|
16024
|
+
const { frame } = getCurrentFrame(animState.animation, animState.elapsed);
|
|
16025
|
+
const rect = frameRect(frame, def.row, def.frames, frameDims.width, frameDims.height);
|
|
16026
|
+
return {
|
|
16027
|
+
sheetUrl,
|
|
16028
|
+
sx: rect.sx,
|
|
16029
|
+
sy: rect.sy,
|
|
16030
|
+
sw: rect.sw,
|
|
16031
|
+
sh: rect.sh,
|
|
16032
|
+
flipX
|
|
16033
|
+
};
|
|
16034
|
+
}
|
|
16035
|
+
function createUnitAnimationState(unitId) {
|
|
16036
|
+
return {
|
|
16037
|
+
unitId,
|
|
16038
|
+
animation: "idle",
|
|
16039
|
+
direction: "se",
|
|
16040
|
+
frame: 0,
|
|
16041
|
+
elapsed: 0,
|
|
16042
|
+
queuedAnimation: null,
|
|
16043
|
+
finished: false
|
|
16044
|
+
};
|
|
16045
|
+
}
|
|
16046
|
+
function transitionAnimation(state, newAnim, direction) {
|
|
16047
|
+
if (state.animation === "death" && state.finished) return state;
|
|
16048
|
+
if (state.animation === newAnim && SPRITE_SHEET_LAYOUT[newAnim].loop) {
|
|
16049
|
+
return direction ? { ...state, direction } : state;
|
|
16050
|
+
}
|
|
16051
|
+
return {
|
|
16052
|
+
...state,
|
|
16053
|
+
animation: newAnim,
|
|
16054
|
+
direction: direction ?? state.direction,
|
|
16055
|
+
frame: 0,
|
|
16056
|
+
elapsed: 0,
|
|
16057
|
+
queuedAnimation: null,
|
|
16058
|
+
finished: false
|
|
16059
|
+
};
|
|
16060
|
+
}
|
|
16061
|
+
function tickAnimationState(state, deltaMs) {
|
|
16062
|
+
const newElapsed = state.elapsed + deltaMs;
|
|
16063
|
+
const { frame, finished } = getCurrentFrame(state.animation, newElapsed);
|
|
16064
|
+
const def = SPRITE_SHEET_LAYOUT[state.animation];
|
|
16065
|
+
if (finished && !def.loop && !state.finished) {
|
|
16066
|
+
if (state.animation === "death") {
|
|
16067
|
+
return { ...state, elapsed: newElapsed, frame, finished: true };
|
|
16068
|
+
}
|
|
16069
|
+
const nextAnim = state.queuedAnimation ?? "idle";
|
|
16070
|
+
return {
|
|
16071
|
+
...state,
|
|
16072
|
+
animation: nextAnim,
|
|
16073
|
+
elapsed: 0,
|
|
16074
|
+
frame: 0,
|
|
16075
|
+
queuedAnimation: null,
|
|
16076
|
+
finished: false
|
|
16077
|
+
};
|
|
16078
|
+
}
|
|
16079
|
+
return { ...state, elapsed: newElapsed, frame, finished };
|
|
16080
|
+
}
|
|
16081
|
+
var init_spriteAnimation = __esm({
|
|
16082
|
+
"lib/spriteAnimation.ts"() {
|
|
16083
|
+
init_spriteSheetConstants();
|
|
16084
|
+
}
|
|
16085
|
+
});
|
|
15949
16086
|
function warnMissingOnce(reason, node) {
|
|
15950
16087
|
const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
|
|
15951
16088
|
if (loggedMissing.has(key)) return;
|
|
@@ -15963,6 +16100,9 @@ function paintFallbackSquare(painter, node, dctx, reason) {
|
|
|
15963
16100
|
painter.strokeRect(rect.x, rect.y, rect.w, rect.h, "#5e564b", Math.max(1, tw / 32));
|
|
15964
16101
|
painter.restore();
|
|
15965
16102
|
}
|
|
16103
|
+
function isAnimatedSprite(node) {
|
|
16104
|
+
return node.animation !== void 0 && typeof node.asset?.atlas === "string";
|
|
16105
|
+
}
|
|
15966
16106
|
function DrawSprite(_props) {
|
|
15967
16107
|
return null;
|
|
15968
16108
|
}
|
|
@@ -15971,6 +16111,7 @@ var init_DrawSprite = __esm({
|
|
|
15971
16111
|
"components/game/atoms/DrawSprite.tsx"() {
|
|
15972
16112
|
"use client";
|
|
15973
16113
|
init_atlasSlice();
|
|
16114
|
+
init_spriteAnimation();
|
|
15974
16115
|
init_imageCache();
|
|
15975
16116
|
init_contract();
|
|
15976
16117
|
spriteLog = createLogger("almadar:ui:draw-sprite");
|
|
@@ -15984,6 +16125,23 @@ var init_DrawSprite = __esm({
|
|
|
15984
16125
|
return;
|
|
15985
16126
|
}
|
|
15986
16127
|
let src = typeof node.frame === "object" ? node.frame : void 0;
|
|
16128
|
+
if (!src && node.animation !== void 0 && typeof node.asset.atlas === "string") {
|
|
16129
|
+
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
16130
|
+
if (!atlas) {
|
|
16131
|
+
if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
|
|
16132
|
+
return;
|
|
16133
|
+
}
|
|
16134
|
+
if (isSpriteSheetAtlas(atlas)) {
|
|
16135
|
+
const def = isAnimationName(node.animation) ? atlas.animations[node.animation] : void 0;
|
|
16136
|
+
if (!def) {
|
|
16137
|
+
paintFallbackSquare(painter, node, dctx, "sprite-missing");
|
|
16138
|
+
return;
|
|
16139
|
+
}
|
|
16140
|
+
const { frame } = getCurrentFrameFromDef(node.loop === void 0 ? def : { ...def, loop: node.loop }, dctx.time);
|
|
16141
|
+
const r = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
|
|
16142
|
+
src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
|
|
16143
|
+
}
|
|
16144
|
+
}
|
|
15987
16145
|
if (!src && isAtlasAsset(node.asset)) {
|
|
15988
16146
|
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
15989
16147
|
if (!atlas) {
|
|
@@ -16701,9 +16859,11 @@ function Canvas2D({
|
|
|
16701
16859
|
const miniMapHeight = gridExtent.height || 10;
|
|
16702
16860
|
const drawableIsAnimated = (node) => {
|
|
16703
16861
|
if (node.type === "draw-shape") return isAnimatedShape(node);
|
|
16862
|
+
if (node.type === "draw-sprite") return isAnimatedSprite(node);
|
|
16704
16863
|
if (node.type === "draw-group")
|
|
16705
16864
|
return isAnimatedGroup(node) || Array.isArray(node.items) && node.items.some(drawableIsAnimated);
|
|
16706
16865
|
if (node.type === "draw-shape-layer") return Array.isArray(node.items) && node.items.some(isAnimatedShape);
|
|
16866
|
+
if (node.type === "draw-sprite-layer") return Array.isArray(node.items) && node.items.some(isAnimatedSprite);
|
|
16707
16867
|
return false;
|
|
16708
16868
|
};
|
|
16709
16869
|
const animRafRef = useRef(0);
|
|
@@ -17044,6 +17204,7 @@ var init_Canvas2D = __esm({
|
|
|
17044
17204
|
init_projector();
|
|
17045
17205
|
init_paintDispatch();
|
|
17046
17206
|
init_DrawShape();
|
|
17207
|
+
init_DrawSprite();
|
|
17047
17208
|
init_DrawGroup();
|
|
17048
17209
|
init_registry();
|
|
17049
17210
|
init_hitTest();
|
|
@@ -17117,6 +17278,7 @@ function Canvas({
|
|
|
17117
17278
|
cameraMode: to3DCameraMode(camera?.mode),
|
|
17118
17279
|
...zoom !== void 0 ? { scale: zoom } : {},
|
|
17119
17280
|
...camera?.fov !== void 0 ? { fov: camera.fov } : {},
|
|
17281
|
+
...camera?.azimuth !== void 0 ? { azimuth: camera.azimuth } : {},
|
|
17120
17282
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
17121
17283
|
unitScale,
|
|
17122
17284
|
backgroundColor,
|
|
@@ -20105,7 +20267,7 @@ var init_DashboardLayout = __esm({
|
|
|
20105
20267
|
}, [isMobile, sidebarOpen]);
|
|
20106
20268
|
const location = useLocation();
|
|
20107
20269
|
const ctxPagePath = useCurrentPagePath();
|
|
20108
|
-
const activePath = currentPath ?? ctxPagePath ?? location.pathname;
|
|
20270
|
+
const activePath = (currentPath || void 0) ?? ctxPagePath ?? location.pathname;
|
|
20109
20271
|
const { user: authUser, signOut: authSignOut } = useAuthContext();
|
|
20110
20272
|
const user = userProp || (authUser ? {
|
|
20111
20273
|
name: authUser.displayName || authUser.email?.split("@")[0] || "User",
|
|
@@ -20572,6 +20734,14 @@ var init_DashboardLayout = __esm({
|
|
|
20572
20734
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
20573
20735
|
}
|
|
20574
20736
|
});
|
|
20737
|
+
function downloadItemUrl(url, label) {
|
|
20738
|
+
const a = document.createElement("a");
|
|
20739
|
+
a.href = url;
|
|
20740
|
+
a.download = url.startsWith("data:") ? label : url.split("/").pop() ?? "download";
|
|
20741
|
+
document.body.appendChild(a);
|
|
20742
|
+
a.click();
|
|
20743
|
+
a.remove();
|
|
20744
|
+
}
|
|
20575
20745
|
function computeMenuStyle(position, triggerRect) {
|
|
20576
20746
|
const isTop = position.startsWith("top");
|
|
20577
20747
|
const isRight = position.endsWith("right") || position.endsWith("end");
|
|
@@ -20624,6 +20794,7 @@ function SubMenu({
|
|
|
20624
20794
|
onClick: () => {
|
|
20625
20795
|
if (item.disabled) return;
|
|
20626
20796
|
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20797
|
+
if (item.url) downloadItemUrl(item.url, item.label);
|
|
20627
20798
|
item.onClick?.();
|
|
20628
20799
|
},
|
|
20629
20800
|
"aria-disabled": item.disabled || void 0,
|
|
@@ -20777,6 +20948,7 @@ var init_Menu = __esm({
|
|
|
20777
20948
|
setActiveSubMenu(itemId);
|
|
20778
20949
|
} else {
|
|
20779
20950
|
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId, label: item.label });
|
|
20951
|
+
if (item.url) downloadItemUrl(item.url, item.label);
|
|
20780
20952
|
item.onClick?.();
|
|
20781
20953
|
setIsOpen(false);
|
|
20782
20954
|
}
|
|
@@ -20812,12 +20984,19 @@ var init_Menu = __esm({
|
|
|
20812
20984
|
"bottom-end": "bottom-start"
|
|
20813
20985
|
};
|
|
20814
20986
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
20815
|
-
const
|
|
20816
|
-
|
|
20817
|
-
|
|
20987
|
+
const triggerElement = React77__default.isValidElement(trigger) ? React77__default.cloneElement(trigger, {
|
|
20988
|
+
ref: triggerRef,
|
|
20989
|
+
onClick: handleToggle
|
|
20990
|
+
}) : /* @__PURE__ */ jsx(
|
|
20991
|
+
Box,
|
|
20818
20992
|
{
|
|
20819
|
-
|
|
20820
|
-
|
|
20993
|
+
as: "span",
|
|
20994
|
+
ref: (el) => {
|
|
20995
|
+
triggerRef.current = el;
|
|
20996
|
+
},
|
|
20997
|
+
onClick: handleToggle,
|
|
20998
|
+
className: "inline-flex",
|
|
20999
|
+
children: typeof trigger === "string" || typeof trigger === "number" ? /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger }) : trigger
|
|
20821
21000
|
}
|
|
20822
21001
|
);
|
|
20823
21002
|
const renderMenuItems = (menuItems) => menuItems.map((item, index) => {
|
|
@@ -26502,134 +26681,6 @@ var init_makeAsset = __esm({
|
|
|
26502
26681
|
}
|
|
26503
26682
|
});
|
|
26504
26683
|
|
|
26505
|
-
// lib/spriteSheetConstants.ts
|
|
26506
|
-
var SHEET_COLUMNS, SPRITE_SHEET_LAYOUT;
|
|
26507
|
-
var init_spriteSheetConstants = __esm({
|
|
26508
|
-
"lib/spriteSheetConstants.ts"() {
|
|
26509
|
-
SHEET_COLUMNS = 8;
|
|
26510
|
-
SPRITE_SHEET_LAYOUT = {
|
|
26511
|
-
idle: { row: 0, frames: 4, frameRate: 6, loop: true },
|
|
26512
|
-
walk: { row: 1, frames: 8, frameRate: 10, loop: true },
|
|
26513
|
-
attack: { row: 2, frames: 6, frameRate: 12, loop: false },
|
|
26514
|
-
hit: { row: 3, frames: 3, frameRate: 8, loop: false },
|
|
26515
|
-
death: { row: 4, frames: 6, frameRate: 8, loop: false }
|
|
26516
|
-
};
|
|
26517
|
-
}
|
|
26518
|
-
});
|
|
26519
|
-
|
|
26520
|
-
// lib/spriteAnimation.ts
|
|
26521
|
-
function inferDirection(dx, dy) {
|
|
26522
|
-
if (dx === 0 && dy === 0) return "se";
|
|
26523
|
-
if (dx >= 0 && dy >= 0) return "se";
|
|
26524
|
-
if (dx <= 0 && dy >= 0) return "sw";
|
|
26525
|
-
if (dx >= 0 && dy <= 0) return "ne";
|
|
26526
|
-
return "nw";
|
|
26527
|
-
}
|
|
26528
|
-
function resolveSheetDirection(facing) {
|
|
26529
|
-
switch (facing) {
|
|
26530
|
-
case "se":
|
|
26531
|
-
return { sheetDir: "se", flipX: false };
|
|
26532
|
-
case "sw":
|
|
26533
|
-
return { sheetDir: "sw", flipX: false };
|
|
26534
|
-
case "ne":
|
|
26535
|
-
return { sheetDir: "sw", flipX: true };
|
|
26536
|
-
case "nw":
|
|
26537
|
-
return { sheetDir: "se", flipX: true };
|
|
26538
|
-
}
|
|
26539
|
-
}
|
|
26540
|
-
function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
26541
|
-
return {
|
|
26542
|
-
sx: frame % columns * frameWidth,
|
|
26543
|
-
sy: row * frameHeight,
|
|
26544
|
-
sw: frameWidth,
|
|
26545
|
-
sh: frameHeight
|
|
26546
|
-
};
|
|
26547
|
-
}
|
|
26548
|
-
function getCurrentFrameFromDef(def, elapsed) {
|
|
26549
|
-
const frameDuration = 1e3 / def.frameRate;
|
|
26550
|
-
const totalDuration = def.frames * frameDuration;
|
|
26551
|
-
if (def.loop) {
|
|
26552
|
-
const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
|
|
26553
|
-
return { frame: frame2, finished: false };
|
|
26554
|
-
}
|
|
26555
|
-
if (elapsed >= totalDuration) {
|
|
26556
|
-
return { frame: def.frames - 1, finished: true };
|
|
26557
|
-
}
|
|
26558
|
-
const frame = Math.floor(elapsed / frameDuration);
|
|
26559
|
-
return { frame, finished: false };
|
|
26560
|
-
}
|
|
26561
|
-
function getCurrentFrame(animName, elapsed) {
|
|
26562
|
-
return getCurrentFrameFromDef(SPRITE_SHEET_LAYOUT[animName], elapsed);
|
|
26563
|
-
}
|
|
26564
|
-
function resolveFrame(sheetUrls, frameDims, animState) {
|
|
26565
|
-
if (!sheetUrls) return null;
|
|
26566
|
-
const { sheetDir, flipX } = resolveSheetDirection(animState.direction);
|
|
26567
|
-
const sheetUrl = sheetUrls[sheetDir];
|
|
26568
|
-
if (!sheetUrl) return null;
|
|
26569
|
-
const def = SPRITE_SHEET_LAYOUT[animState.animation];
|
|
26570
|
-
const { frame } = getCurrentFrame(animState.animation, animState.elapsed);
|
|
26571
|
-
const rect = frameRect(frame, def.row, def.frames, frameDims.width, frameDims.height);
|
|
26572
|
-
return {
|
|
26573
|
-
sheetUrl,
|
|
26574
|
-
sx: rect.sx,
|
|
26575
|
-
sy: rect.sy,
|
|
26576
|
-
sw: rect.sw,
|
|
26577
|
-
sh: rect.sh,
|
|
26578
|
-
flipX
|
|
26579
|
-
};
|
|
26580
|
-
}
|
|
26581
|
-
function createUnitAnimationState(unitId) {
|
|
26582
|
-
return {
|
|
26583
|
-
unitId,
|
|
26584
|
-
animation: "idle",
|
|
26585
|
-
direction: "se",
|
|
26586
|
-
frame: 0,
|
|
26587
|
-
elapsed: 0,
|
|
26588
|
-
queuedAnimation: null,
|
|
26589
|
-
finished: false
|
|
26590
|
-
};
|
|
26591
|
-
}
|
|
26592
|
-
function transitionAnimation(state, newAnim, direction) {
|
|
26593
|
-
if (state.animation === "death" && state.finished) return state;
|
|
26594
|
-
if (state.animation === newAnim && SPRITE_SHEET_LAYOUT[newAnim].loop) {
|
|
26595
|
-
return direction ? { ...state, direction } : state;
|
|
26596
|
-
}
|
|
26597
|
-
return {
|
|
26598
|
-
...state,
|
|
26599
|
-
animation: newAnim,
|
|
26600
|
-
direction: direction ?? state.direction,
|
|
26601
|
-
frame: 0,
|
|
26602
|
-
elapsed: 0,
|
|
26603
|
-
queuedAnimation: null,
|
|
26604
|
-
finished: false
|
|
26605
|
-
};
|
|
26606
|
-
}
|
|
26607
|
-
function tickAnimationState(state, deltaMs) {
|
|
26608
|
-
const newElapsed = state.elapsed + deltaMs;
|
|
26609
|
-
const { frame, finished } = getCurrentFrame(state.animation, newElapsed);
|
|
26610
|
-
const def = SPRITE_SHEET_LAYOUT[state.animation];
|
|
26611
|
-
if (finished && !def.loop && !state.finished) {
|
|
26612
|
-
if (state.animation === "death") {
|
|
26613
|
-
return { ...state, elapsed: newElapsed, frame, finished: true };
|
|
26614
|
-
}
|
|
26615
|
-
const nextAnim = state.queuedAnimation ?? "idle";
|
|
26616
|
-
return {
|
|
26617
|
-
...state,
|
|
26618
|
-
animation: nextAnim,
|
|
26619
|
-
elapsed: 0,
|
|
26620
|
-
frame: 0,
|
|
26621
|
-
queuedAnimation: null,
|
|
26622
|
-
finished: false
|
|
26623
|
-
};
|
|
26624
|
-
}
|
|
26625
|
-
return { ...state, elapsed: newElapsed, frame, finished };
|
|
26626
|
-
}
|
|
26627
|
-
var init_spriteAnimation = __esm({
|
|
26628
|
-
"lib/spriteAnimation.ts"() {
|
|
26629
|
-
init_spriteSheetConstants();
|
|
26630
|
-
}
|
|
26631
|
-
});
|
|
26632
|
-
|
|
26633
26684
|
// lib/gameShared.ts
|
|
26634
26685
|
var init_gameShared = __esm({
|
|
26635
26686
|
"lib/gameShared.ts"() {
|