@terrafirmagreg-team/game 0.1.0 → 1.2.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/package.json +15 -14
- package/src/components/entry/atlas-sprite.tsx +22 -35
- package/src/components/entry/copy-id-menu.tsx +22 -29
- package/src/components/entry/entry.tsx +99 -20
- package/src/components/entry/group.tsx +27 -46
- package/src/components/entry/icon.tsx +21 -27
- package/src/components/entry/list.tsx +15 -18
- package/src/components/entry/mc-text.tsx +3 -89
- package/src/components/entry/stack-count.tsx +12 -8
- package/src/components/entry/tooltip.tsx +52 -44
- package/src/components/mdx/item-icon.tsx +23 -15
- package/src/components/preview-icon.tsx +2 -1
- package/src/hooks/use-dump-location.ts +4 -2
- package/src/hooks/use-entry-context.ts +3 -1
- package/src/hooks/use-icon-source.ts +22 -13
- package/src/hooks/use-lang-map.ts +4 -2
- package/src/lib/entry/display.ts +2 -1
- package/src/lib/entry/entry.ts +5 -3
- package/src/lib/entry/formula.ts +1 -0
- package/src/lib/entry/href.ts +20 -12
- package/src/lib/entry/icon-load.ts +67 -31
- package/src/lib/entry/icon.ts +3 -2
- package/src/lib/entry/tooltip.ts +12 -10
- package/src/lib/preview.ts +4 -2
- package/src/lib/search.ts +18 -19
- package/src/locales/en_us.json +3 -7
- package/src/locales/ru_ru.json +3 -7
- package/src/locales.ts +1 -0
- package/src/types/entry.ts +41 -2
- package/styles/fonts.css +18 -2
- package/src/components/entry/frame.tsx +0 -32
- package/src/components/entry/icon/tabs.tsx +0 -118
- package/src/lib/dump/assets/atlas/dto.ts +0 -49
- package/src/lib/dump/assets/atlas/lookup.ts +0 -206
- package/src/lib/dump/assets/atlas/sprites.ts +0 -130
- package/src/lib/dump/assets/lang/load.ts +0 -17
- package/src/lib/dump/assets/lang/names.ts +0 -244
- package/src/lib/dump/assets/urls.ts +0 -143
- package/src/lib/dump/client/atlases.ts +0 -83
- package/src/lib/dump/client/dump.ts +0 -188
- package/src/lib/dump/client/groups.ts +0 -31
- package/src/lib/dump/client/keybinds.ts +0 -11
- package/src/lib/dump/client/mods.ts +0 -16
- package/src/lib/dump/client/registry.ts +0 -125
- package/src/lib/dump/client/tabs.ts +0 -27
- package/src/lib/dump/client/tags.ts +0 -64
- package/src/lib/dump/contract/kind.ts +0 -61
- package/src/lib/dump/contract/read.ts +0 -77
- package/src/lib/dump/contract/ref.ts +0 -262
- package/src/lib/dump/contract/text.ts +0 -86
- package/src/lib/dump/data/registry/dto.ts +0 -56
- package/src/lib/dump/data/registry/parse.ts +0 -291
- package/src/lib/dump/data/tab/dto.ts +0 -13
- package/src/lib/dump/data/tab/parse.ts +0 -26
- package/src/lib/dump/data/tag/dto.ts +0 -7
- package/src/lib/dump/data/tag/parse.ts +0 -57
- package/src/lib/dump/gen/data/guides/book.ts +0 -56
- package/src/lib/dump/gen/data/guides/category.ts +0 -30
- package/src/lib/dump/gen/data/guides/entry.ts +0 -48
- package/src/lib/dump/gen/data/models/model.ts +0 -3
- package/src/lib/dump/gen/data/quests/chapter.ts +0 -126
- package/src/lib/dump/gen/data/quests/chapter_groups.ts +0 -11
- package/src/lib/dump/gen/data/quests/data.ts +0 -40
- package/src/lib/dump/gen/data/recipes/recipe.ts +0 -78
- package/src/lib/dump/gen/index.ts +0 -20
- package/src/lib/dump/gen/keybinds.ts +0 -3
- package/src/lib/dump/gen/lang.ts +0 -3
- package/src/lib/dump/gen/manifest.ts +0 -59
- package/src/lib/dump/gen/registry/blocks.ts +0 -60
- package/src/lib/dump/gen/registry/entities.ts +0 -49
- package/src/lib/dump/gen/registry/fluids.ts +0 -48
- package/src/lib/dump/gen/registry/groups.ts +0 -14
- package/src/lib/dump/gen/registry/items.ts +0 -51
- package/src/lib/dump/gen/registry/recipe_categories.ts +0 -64
- package/src/lib/dump/gen/registry/recipes.ts +0 -3
- package/src/lib/dump/gen/registry/tabs.ts +0 -46
- package/src/lib/dump/gen/registry/tags.ts +0 -11
- package/src/lib/dump/json-reader.ts +0 -231
- package/src/lib/dump/manifest/dto.ts +0 -11
- package/src/lib/dump/manifest/parse.ts +0 -167
- package/src/lib/dump/mods/dto.ts +0 -40
- package/src/lib/dump/mods/index.ts +0 -81
- package/src/lib/dump/mods/load.ts +0 -61
- package/src/lib/dump/paths.ts +0 -171
- package/src/lib/dump/reader.ts +0 -15
- package/src/lib/snbt.ts +0 -246
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
4
|
-
import {
|
|
5
|
+
import { SpriteList } from '@terrafirmagreg-team/ui/components/blocks/sprite';
|
|
5
6
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
6
|
-
import type { TaggedReference } from '@terrafirmagreg-team/
|
|
7
|
+
import type { TaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
7
8
|
|
|
8
9
|
export function EntryList({
|
|
9
10
|
items,
|
|
@@ -18,7 +19,7 @@ export function EntryList({
|
|
|
18
19
|
className,
|
|
19
20
|
}: {
|
|
20
21
|
items: TaggedReference[];
|
|
21
|
-
dataset?:
|
|
22
|
+
dataset?: DatasetRef;
|
|
22
23
|
lang?: Lang;
|
|
23
24
|
langMap?: Record<string, string>;
|
|
24
25
|
tab?: string;
|
|
@@ -31,17 +32,13 @@ export function EntryList({
|
|
|
31
32
|
className?: string;
|
|
32
33
|
}) {
|
|
33
34
|
return (
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
>
|
|
42
|
-
{items.map((item, index) => (
|
|
43
|
-
<li key={`${item.kind}:${item.id}:${index}`}>
|
|
44
|
-
{variant === 'grid' ? (
|
|
35
|
+
<SpriteList
|
|
36
|
+
variant={variant}
|
|
37
|
+
className={className}
|
|
38
|
+
items={items.map((item, index) => ({
|
|
39
|
+
key: `${item.kind}:${item.id}:${index}`,
|
|
40
|
+
node:
|
|
41
|
+
variant === 'grid' ? (
|
|
45
42
|
<Entry
|
|
46
43
|
reference={item}
|
|
47
44
|
dataset={dataset}
|
|
@@ -62,9 +59,9 @@ export function EntryList({
|
|
|
62
59
|
labeled={labeled}
|
|
63
60
|
href={href}
|
|
64
61
|
/>
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
</ul>
|
|
62
|
+
),
|
|
63
|
+
}))}
|
|
64
|
+
/>
|
|
69
65
|
);
|
|
70
66
|
}
|
|
67
|
+
|
|
@@ -1,92 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const isCode = (char: string | undefined): char is string =>
|
|
5
|
-
char !== undefined && /[0-9a-fklmnor]/.test(char);
|
|
6
|
-
|
|
7
|
-
type Run = { text: string; style?: CSSProperties };
|
|
1
|
+
import { FormatText } from '@terrafirmagreg-team/ui/components/blocks/text/format-text';
|
|
2
|
+
import { MC_FORMAT } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
8
3
|
|
|
9
4
|
export function McText({ text }: { text: string }) {
|
|
10
|
-
|
|
11
|
-
let style: CSSProperties | undefined;
|
|
12
|
-
let buf = '';
|
|
13
|
-
const flush = () => {
|
|
14
|
-
if (!buf) return;
|
|
15
|
-
runs.push(style ? { text: buf, style } : { text: buf });
|
|
16
|
-
buf = '';
|
|
17
|
-
};
|
|
18
|
-
for (let i = 0; i < text.length; i += 1) {
|
|
19
|
-
const ch = text[i];
|
|
20
|
-
if (ch !== '§') {
|
|
21
|
-
buf += ch;
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
const code = text[i + 1]?.toLowerCase();
|
|
25
|
-
if (code === 'x') {
|
|
26
|
-
let hex = '';
|
|
27
|
-
let j = i + 2;
|
|
28
|
-
while (
|
|
29
|
-
hex.length < 6 &&
|
|
30
|
-
text[j] === '§' &&
|
|
31
|
-
/^[0-9a-f]$/.test(text[j + 1]?.toLowerCase() ?? '')
|
|
32
|
-
) {
|
|
33
|
-
hex += (text[j + 1] ?? '').toLowerCase();
|
|
34
|
-
j += 2;
|
|
35
|
-
}
|
|
36
|
-
if (hex.length === 6) {
|
|
37
|
-
flush();
|
|
38
|
-
i = j - 1;
|
|
39
|
-
const next: CSSProperties = { ...(style ?? {}), color: `#${hex}` };
|
|
40
|
-
delete next.fontWeight;
|
|
41
|
-
delete next.fontStyle;
|
|
42
|
-
delete next.textDecoration;
|
|
43
|
-
style = next;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
buf += ch;
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (!isCode(code)) {
|
|
50
|
-
buf += ch;
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
flush();
|
|
54
|
-
i += 1;
|
|
55
|
-
if (code === 'r') {
|
|
56
|
-
style = undefined;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const next: CSSProperties = { ...(style ?? {}) };
|
|
60
|
-
const color = MC_FORMAT_COLORS[code];
|
|
61
|
-
if (color) {
|
|
62
|
-
next.color = color;
|
|
63
|
-
delete next.fontWeight;
|
|
64
|
-
delete next.fontStyle;
|
|
65
|
-
delete next.textDecoration;
|
|
66
|
-
} else if (code === 'l') next.fontWeight = 600;
|
|
67
|
-
else if (code === 'o') next.fontStyle = 'italic';
|
|
68
|
-
else if (code === 'n')
|
|
69
|
-
next.textDecoration = next.textDecoration
|
|
70
|
-
? `${next.textDecoration} underline`
|
|
71
|
-
: 'underline';
|
|
72
|
-
else if (code === 'm')
|
|
73
|
-
next.textDecoration = next.textDecoration
|
|
74
|
-
? `${next.textDecoration} line-through`
|
|
75
|
-
: 'line-through';
|
|
76
|
-
style = Object.keys(next).length ? next : undefined;
|
|
77
|
-
}
|
|
78
|
-
flush();
|
|
79
|
-
return (
|
|
80
|
-
<>
|
|
81
|
-
{runs.map((run, index) =>
|
|
82
|
-
run.style ? (
|
|
83
|
-
<span key={index} style={run.style}>
|
|
84
|
-
{run.text}
|
|
85
|
-
</span>
|
|
86
|
-
) : (
|
|
87
|
-
<Fragment key={index}>{run.text}</Fragment>
|
|
88
|
-
),
|
|
89
|
-
)}
|
|
90
|
-
</>
|
|
91
|
-
);
|
|
5
|
+
return <FormatText text={text} format={MC_FORMAT} />;
|
|
92
6
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpriteCount } from '@terrafirmagreg-team/ui/components/blocks/sprite';
|
|
2
2
|
|
|
3
|
-
export function StackCount({
|
|
4
|
-
|
|
3
|
+
export function StackCount({
|
|
4
|
+
count,
|
|
5
|
+
limit,
|
|
6
|
+
}: {
|
|
7
|
+
count: number;
|
|
8
|
+
limit?: number;
|
|
9
|
+
}) {
|
|
5
10
|
return (
|
|
6
|
-
<
|
|
7
|
-
|
|
11
|
+
<SpriteCount
|
|
12
|
+
count={count}
|
|
13
|
+
limit={limit}
|
|
8
14
|
className="font-mc pointer-events-none leading-none text-white"
|
|
9
15
|
style={{ fontSize: 9, textShadow: '1px 1px 0 var(--color-mc-arrow)' }}
|
|
10
|
-
|
|
11
|
-
{formatCount(count)}
|
|
12
|
-
</span>
|
|
16
|
+
/>
|
|
13
17
|
);
|
|
14
18
|
}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { useState, type ReactElement, type ReactNode } from 'react';
|
|
4
|
-
import { useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
|
|
5
5
|
import { useModifierKeys } from '@terrafirmagreg-team/ui/hooks/use-modifier-keys';
|
|
6
|
-
import {
|
|
7
|
-
Tooltip,
|
|
8
|
-
TooltipContent,
|
|
9
|
-
TooltipTrigger,
|
|
10
|
-
} from '@terrafirmagreg-team/ui/components/ui/tooltip';
|
|
6
|
+
import { LazyTooltip } from '@terrafirmagreg-team/ui/components/blocks/tooltip/lazy';
|
|
11
7
|
import { stackTooltip } from '@terrafirmagreg-team/game/lib/entry/tooltip';
|
|
12
8
|
import { formulaRuns } from '@terrafirmagreg-team/game/lib/entry/formula';
|
|
13
9
|
import { McText } from '@terrafirmagreg-team/game/components/entry/mc-text';
|
|
14
|
-
import { stripMcFormat } from '@terrafirmagreg-team/
|
|
10
|
+
import { stripMcFormat } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
15
11
|
|
|
16
12
|
const ENCHANTED_TEXT_COLOR = 'var(--color-mc-enchant)';
|
|
17
13
|
|
|
@@ -51,7 +47,7 @@ export function EntryTooltip({
|
|
|
51
47
|
footer,
|
|
52
48
|
children,
|
|
53
49
|
}: {
|
|
54
|
-
dataset:
|
|
50
|
+
dataset: DatasetRef;
|
|
55
51
|
id: string;
|
|
56
52
|
name: string;
|
|
57
53
|
kind?: 'item' | 'fluid' | 'entity';
|
|
@@ -65,44 +61,43 @@ export function EntryTooltip({
|
|
|
65
61
|
}) {
|
|
66
62
|
const [open, setOpen] = useState(false);
|
|
67
63
|
const held = useModifierKeys(open && (level === 'full' || level === 'adaptive'));
|
|
68
|
-
const tooltip =
|
|
69
|
-
useAsyncValue(
|
|
70
|
-
open ? () => stackTooltip(dataset, id, lang, langMap, kind) : false,
|
|
71
|
-
[open, dataset, id, lang, langMap, kind],
|
|
72
|
-
) ?? { lines: [], mods: {} };
|
|
73
64
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
const renderLines = (value?: {
|
|
66
|
+
lines: string[];
|
|
67
|
+
mods: Record<string, string[]>;
|
|
68
|
+
}) => {
|
|
69
|
+
const tooltip = value ?? { lines: [], mods: {} };
|
|
70
|
+
const base = tooltip.lines;
|
|
71
|
+
const modLine =
|
|
72
|
+
base.length > 1 && !base[base.length - 1].includes('§')
|
|
73
|
+
? base[base.length - 1]
|
|
74
|
+
: undefined;
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
76
|
+
let extra: string[];
|
|
77
|
+
if (level === 'compact') extra = modLine ? [modLine] : [];
|
|
78
|
+
else if (level === 'extended') extra = base;
|
|
79
|
+
else if (level === 'full') {
|
|
80
|
+
const activeMod = held.shift
|
|
81
|
+
? 'shift'
|
|
82
|
+
: held.ctrl
|
|
83
|
+
? 'ctrl'
|
|
84
|
+
: held.alt
|
|
85
|
+
? 'alt'
|
|
86
|
+
: null;
|
|
87
|
+
extra = (activeMod ? tooltip.mods[activeMod] : undefined) ?? base;
|
|
88
|
+
} else if (held.ctrl || held.alt)
|
|
89
|
+
extra = (held.ctrl ? tooltip.mods.ctrl : tooltip.mods.alt) ?? base;
|
|
90
|
+
else if (held.shift) extra = base;
|
|
91
|
+
else extra = modLine ? [modLine] : [];
|
|
96
92
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
const lines = extra.length
|
|
94
|
+
? [name, ...extra.filter((line) => line !== name)]
|
|
95
|
+
: [name];
|
|
96
|
+
const lastIsMod =
|
|
97
|
+
lines.length > 1 && !lines[lines.length - 1].includes('§');
|
|
101
98
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<TooltipTrigger render={children} delay={150} closeDelay={100} />
|
|
105
|
-
<TooltipContent className="flex-col items-start gap-0.5 p-3 text-sm break-words whitespace-pre-wrap">
|
|
99
|
+
return (
|
|
100
|
+
<>
|
|
106
101
|
{lines.map((line, index) => (
|
|
107
102
|
<p
|
|
108
103
|
key={`${index}:${line}`}
|
|
@@ -123,7 +118,20 @@ export function EntryTooltip({
|
|
|
123
118
|
</p>
|
|
124
119
|
))}
|
|
125
120
|
{footer}
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
</>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<LazyTooltip
|
|
127
|
+
load={() => stackTooltip(dataset, id, lang, langMap, kind)}
|
|
128
|
+
deps={[dataset, id, lang, langMap, kind]}
|
|
129
|
+
onOpenChange={setOpen}
|
|
130
|
+
trigger={children}
|
|
131
|
+
contentClassName="flex-col items-start gap-0.5 p-3 text-sm break-words whitespace-pre-wrap"
|
|
132
|
+
>
|
|
133
|
+
{renderLines}
|
|
134
|
+
</LazyTooltip>
|
|
128
135
|
);
|
|
129
136
|
}
|
|
137
|
+
|
|
@@ -2,35 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
import { usePathname } from 'next/navigation';
|
|
4
4
|
import type { ComponentProps } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
6
6
|
import { useEntryContext } from '@terrafirmagreg-team/game/hooks/use-entry-context';
|
|
7
7
|
import { useLangMap } from '@terrafirmagreg-team/game/hooks/use-lang-map';
|
|
8
8
|
import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
|
|
9
9
|
import { useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
import {
|
|
11
|
+
type DatasetRef,
|
|
12
|
+
parseSectionLocation,
|
|
13
|
+
} from '@terrafirmagreg-team/sites/location';
|
|
14
|
+
import { lookupSpriteInBundle } from '@terrafirmagreg-team/dump/lib/dump/assets/atlas/lookup';
|
|
15
|
+
import { stackDisplayName } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
16
|
+
import { loadClientModAtlases } from '@terrafirmagreg-team/dump/lib/dump/client/atlases';
|
|
14
17
|
import { fetchTagItem } from '@terrafirmagreg-team/game/lib/entry/icon-load';
|
|
15
18
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
16
19
|
|
|
20
|
+
export type ItemIconProps = {
|
|
21
|
+
id?: string;
|
|
22
|
+
dataset?: DatasetRef;
|
|
23
|
+
lang?: Lang;
|
|
24
|
+
label?: string;
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
} & ComponentProps<'div'>;
|
|
27
|
+
|
|
17
28
|
export function ItemIcon({
|
|
18
29
|
id,
|
|
19
30
|
dataset: datasetProp,
|
|
20
31
|
lang: langProp,
|
|
21
32
|
label,
|
|
22
33
|
children,
|
|
23
|
-
}: {
|
|
24
|
-
id?: string;
|
|
25
|
-
dataset?: string;
|
|
26
|
-
lang?: Lang;
|
|
27
|
-
label?: string;
|
|
28
|
-
children?: React.ReactNode;
|
|
29
|
-
} & ComponentProps<'div'>) {
|
|
34
|
+
}: ItemIconProps) {
|
|
30
35
|
const ctx = useEntryContext();
|
|
31
36
|
const pathname = usePathname();
|
|
37
|
+
const locId = parseSectionLocation(pathname).dataset;
|
|
32
38
|
const dataset =
|
|
33
|
-
datasetProp ?? ctx?.dataset ??
|
|
39
|
+
datasetProp ?? ctx?.dataset ?? (locId ? { id: locId } : undefined);
|
|
34
40
|
const resolvedLang = useResolvedLang();
|
|
35
41
|
const lang = langProp ?? ctx?.lang ?? resolvedLang;
|
|
36
42
|
const iconId = useAsyncValue(
|
|
@@ -54,7 +60,8 @@ export function ItemIcon({
|
|
|
54
60
|
label ?? (iconId ? stackDisplayName(map, iconId, undefined, langKey) : undefined);
|
|
55
61
|
if (!iconId) return children ? <>{children}</> : null;
|
|
56
62
|
return (
|
|
57
|
-
<
|
|
63
|
+
<Entry
|
|
64
|
+
kind="item"
|
|
58
65
|
id={iconId}
|
|
59
66
|
dataset={dataset}
|
|
60
67
|
lang={lang}
|
|
@@ -64,6 +71,7 @@ export function ItemIcon({
|
|
|
64
71
|
href={false}
|
|
65
72
|
>
|
|
66
73
|
{children}
|
|
67
|
-
</
|
|
74
|
+
</Entry>
|
|
68
75
|
);
|
|
69
76
|
}
|
|
77
|
+
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { DynamicIcon, type IconName } from 'lucide-react/dynamic';
|
|
4
4
|
import { EntryIcon } from '@terrafirmagreg-team/game/components/entry/icon';
|
|
5
|
-
import type { ReferenceKind } from '@terrafirmagreg-team/
|
|
5
|
+
import type { ReferenceKind } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
6
6
|
import type { PreviewIcon } from '@terrafirmagreg-team/ui/types/preview';
|
|
7
7
|
|
|
8
8
|
export function PagePreviewIcon({ icon }: { icon: PreviewIcon }) {
|
|
@@ -23,3 +23,4 @@ export function PagePreviewIcon({ icon }: { icon: PreviewIcon }) {
|
|
|
23
23
|
/>
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
|
+
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { useSyncExternalStore } from 'react';
|
|
4
5
|
import {
|
|
5
6
|
dumpLocation,
|
|
6
7
|
subscribeDumpLocations,
|
|
7
8
|
type DumpLocation,
|
|
8
|
-
} from '@terrafirmagreg-team/
|
|
9
|
+
} from '@terrafirmagreg-team/dump/lib/dump/paths';
|
|
9
10
|
|
|
10
11
|
export function useDumpLocation(
|
|
11
|
-
dataset:
|
|
12
|
+
dataset: DatasetRef | undefined,
|
|
12
13
|
): DumpLocation | undefined {
|
|
13
14
|
return useSyncExternalStore(
|
|
14
15
|
subscribeDumpLocations,
|
|
@@ -16,3 +17,4 @@ export function useDumpLocation(
|
|
|
16
17
|
() => undefined,
|
|
17
18
|
);
|
|
18
19
|
}
|
|
20
|
+
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
createContext,
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
11
12
|
|
|
12
13
|
type EntryContextValue = {
|
|
13
|
-
dataset:
|
|
14
|
+
dataset: DatasetRef;
|
|
14
15
|
lang?: Lang;
|
|
15
16
|
langMap?: Record<string, string>;
|
|
16
17
|
};
|
|
@@ -33,3 +34,4 @@ export function EntryProvider({
|
|
|
33
34
|
export function useEntryContext(): EntryContextValue | null {
|
|
34
35
|
return useContext(EntryContext);
|
|
35
36
|
}
|
|
37
|
+
|
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
isTagKind,
|
|
8
8
|
parseStackId,
|
|
9
9
|
tagKindOf,
|
|
10
|
-
} from '@terrafirmagreg-team/
|
|
11
|
-
import { texturePublicUrl } from '@terrafirmagreg-team/
|
|
10
|
+
} from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
11
|
+
import { texturePublicUrl } from '@terrafirmagreg-team/dump/lib/dump/assets/urls';
|
|
12
12
|
import { useDumpLocation } from '@terrafirmagreg-team/game/hooks/use-dump-location';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
13
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
14
|
+
import { lookupSpriteInBundle } from '@terrafirmagreg-team/dump/lib/dump/assets/atlas/lookup';
|
|
15
|
+
import type { AtlasLookup } from '@terrafirmagreg-team/dump/lib/dump/assets/atlas/dto';
|
|
15
16
|
import {
|
|
16
17
|
blockItemId,
|
|
17
18
|
fetchAtlases,
|
|
@@ -21,13 +22,13 @@ import {
|
|
|
21
22
|
peekEntityTexture,
|
|
22
23
|
peekTagMembers,
|
|
23
24
|
} from '@terrafirmagreg-team/game/lib/entry/icon-load';
|
|
24
|
-
import { loadClientModAtlases } from '@terrafirmagreg-team/
|
|
25
|
+
import { loadClientModAtlases } from '@terrafirmagreg-team/dump/lib/dump/client/atlases';
|
|
25
26
|
import { stackKindOf } from '@terrafirmagreg-team/game/lib/entry/icon';
|
|
26
27
|
import type {
|
|
27
28
|
DumpNbt,
|
|
28
29
|
ReferenceKind,
|
|
29
30
|
TaggedReference,
|
|
30
|
-
} from '@terrafirmagreg-team/
|
|
31
|
+
} from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
31
32
|
|
|
32
33
|
export const ENTRY_CYCLE_MS = 1500;
|
|
33
34
|
|
|
@@ -61,14 +62,16 @@ export function useIconSource({
|
|
|
61
62
|
tag,
|
|
62
63
|
missing,
|
|
63
64
|
preferVariant,
|
|
65
|
+
entityView = 'auto',
|
|
64
66
|
}: {
|
|
65
|
-
dataset?:
|
|
67
|
+
dataset?: DatasetRef;
|
|
66
68
|
reference?: TaggedReference;
|
|
67
69
|
id?: string;
|
|
68
70
|
kind?: ReferenceKind;
|
|
69
71
|
tag?: DumpNbt;
|
|
70
72
|
missing: 'placeholder' | 'item' | 'hide';
|
|
71
73
|
preferVariant?: boolean;
|
|
74
|
+
entityView?: 'auto' | 'texture' | 'egg';
|
|
72
75
|
}): IconSource {
|
|
73
76
|
const ref = reference ?? (id ? classifyRefId(id, kind) : undefined);
|
|
74
77
|
const refKind = ref?.kind;
|
|
@@ -77,7 +80,7 @@ export function useIconSource({
|
|
|
77
80
|
const tagMemberKind = tagKindOf(refKind);
|
|
78
81
|
const tagKey =
|
|
79
82
|
dataset && rawId && isTagKind(refKind)
|
|
80
|
-
? `${dataset}/${tagMemberKind ?? 'item'}/${rawId}`
|
|
83
|
+
? `${dataset.id}/${dataset.version ?? ''}/${tagMemberKind ?? 'item'}/${rawId}`
|
|
81
84
|
: null;
|
|
82
85
|
const tagMembersPeek = tagKey
|
|
83
86
|
? peekTagMembers(dataset!, rawId, tagMemberKind ?? 'item')
|
|
@@ -130,7 +133,7 @@ export function useIconSource({
|
|
|
130
133
|
: refKind;
|
|
131
134
|
const blockKey =
|
|
132
135
|
dataset && memberKind === 'block' && itemId && !itemId.startsWith('#')
|
|
133
|
-
? `${dataset}/${itemId}`
|
|
136
|
+
? `${dataset.id}/${dataset.version ?? ''}/${itemId}`
|
|
134
137
|
: null;
|
|
135
138
|
const blockPeek = blockKey ? peekBlockItem(dataset!, itemId!) : undefined;
|
|
136
139
|
const blockHit = useAsyncResult(
|
|
@@ -159,7 +162,7 @@ export function useIconSource({
|
|
|
159
162
|
const parsed = parseStackId(resolvedId.replace(/^#/, ''));
|
|
160
163
|
const spriteId = parsed.id;
|
|
161
164
|
const eggId =
|
|
162
|
-
isEntity && spriteId && !spriteId.startsWith('#')
|
|
165
|
+
isEntity && entityView !== 'texture' && spriteId && !spriteId.startsWith('#')
|
|
163
166
|
? `${spriteId}_spawn_egg`
|
|
164
167
|
: undefined;
|
|
165
168
|
const usesAtlas =
|
|
@@ -185,18 +188,22 @@ export function useIconSource({
|
|
|
185
188
|
[atlasNeedsLoad, atlasPeek, dataset, modId],
|
|
186
189
|
);
|
|
187
190
|
const atlasValue = atlasPeek === undefined ? atlases.value : atlasBundle;
|
|
188
|
-
const sourceKey = `${dataset}:${displayKind}:${resolvedId}`;
|
|
191
|
+
const sourceKey = `${dataset?.id}/${dataset?.version ?? ''}:${displayKind}:${resolvedId}`;
|
|
189
192
|
const dumpLoc = useDumpLocation(dataset);
|
|
193
|
+
const wantEntityTexture = isEntity && entityView !== 'egg';
|
|
190
194
|
const texturePeek =
|
|
191
195
|
dataset && isTexture && rawId
|
|
192
196
|
? texturePublicUrl(dataset, rawId)
|
|
193
|
-
: dataset &&
|
|
197
|
+
: dataset && wantEntityTexture && resolvedId
|
|
194
198
|
? peekEntityTexture(dataset, resolvedId, nbt)
|
|
195
199
|
: null;
|
|
196
200
|
const textureSrc = useAsyncResult(
|
|
197
201
|
dataset && isTexture && rawId
|
|
198
202
|
? false
|
|
199
|
-
: dataset &&
|
|
203
|
+
: dataset &&
|
|
204
|
+
wantEntityTexture &&
|
|
205
|
+
resolvedId &&
|
|
206
|
+
texturePeek === undefined
|
|
200
207
|
? async () => ({
|
|
201
208
|
key: sourceKey,
|
|
202
209
|
url:
|
|
@@ -206,6 +213,7 @@ export function useIconSource({
|
|
|
206
213
|
[
|
|
207
214
|
isTexture,
|
|
208
215
|
isEntity,
|
|
216
|
+
wantEntityTexture,
|
|
209
217
|
dataset,
|
|
210
218
|
rawId,
|
|
211
219
|
resolvedId,
|
|
@@ -295,3 +303,4 @@ export function useIconSource({
|
|
|
295
303
|
isEntity,
|
|
296
304
|
};
|
|
297
305
|
}
|
|
306
|
+
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { useAsyncResult } from '@terrafirmagreg-team/ui/hooks/use-async-value';
|
|
4
|
-
import { dumpReader } from '@terrafirmagreg-team/
|
|
5
|
+
import { dumpReader } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
5
6
|
|
|
6
7
|
export function useLangMap(
|
|
7
|
-
dataset:
|
|
8
|
+
dataset: DatasetRef | undefined,
|
|
8
9
|
lang: string | undefined,
|
|
9
10
|
enabled = true,
|
|
10
11
|
): Record<string, string> | undefined {
|
|
@@ -16,3 +17,4 @@ export function useLangMap(
|
|
|
16
17
|
);
|
|
17
18
|
return pending ? undefined : value;
|
|
18
19
|
}
|
|
20
|
+
|
package/src/lib/entry/display.ts
CHANGED
package/src/lib/entry/entry.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { entryHref } from '@terrafirmagreg-team/game/lib/entry/href';
|
|
2
|
-
import { tagKindOf } from '@terrafirmagreg-team/
|
|
3
|
-
import type { ReferenceKind } from '@terrafirmagreg-team/
|
|
3
|
+
import { tagKindOf } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
4
|
+
import type { ReferenceKind } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
4
5
|
import type { EntryProps } from '@terrafirmagreg-team/game/types/entry';
|
|
5
6
|
|
|
6
7
|
export function usesStackTooltip(kind: ReferenceKind | undefined): boolean {
|
|
@@ -27,7 +28,7 @@ export function tooltipLoadKind(
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export function resolveEntryHref(
|
|
30
|
-
props: EntryProps & { dataset:
|
|
31
|
+
props: EntryProps & { dataset: DatasetRef },
|
|
31
32
|
): string | undefined {
|
|
32
33
|
if (props.href === false) return undefined;
|
|
33
34
|
if (typeof props.href === 'string') return props.href;
|
|
@@ -55,3 +56,4 @@ export function resolveEntryHref(
|
|
|
55
56
|
},
|
|
56
57
|
);
|
|
57
58
|
}
|
|
59
|
+
|
package/src/lib/entry/formula.ts
CHANGED