@nice2dev/game-engine 0.1.0 → 1.0.2
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/CHANGELOG.md +193 -1
- package/dist/cjs/audio/AudioBridge.js +454 -0
- package/dist/cjs/audio/AudioBridge.js.map +1 -0
- package/dist/cjs/devtools/GameplayAnalytics.js +651 -0
- package/dist/cjs/devtools/GameplayAnalytics.js.map +1 -0
- package/dist/cjs/dialogue/DialogueSystem.js +1023 -0
- package/dist/cjs/dialogue/DialogueSystem.js.map +1 -0
- package/dist/cjs/editor/NiceGameEditor.js +569 -71
- package/dist/cjs/editor/NiceGameEditor.js.map +1 -1
- package/dist/cjs/engine/SaveSystemV2.js +494 -0
- package/dist/cjs/engine/SaveSystemV2.js.map +1 -0
- package/dist/cjs/i18n/useTranslation.js +11 -11
- package/dist/cjs/index.js +90 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/input/GamepadNavigation.js +21 -21
- package/dist/cjs/input/useGamepads.js +6 -6
- package/dist/cjs/integration/IconSprite.js +281 -0
- package/dist/cjs/integration/IconSprite.js.map +1 -0
- package/dist/cjs/inventory/InventorySystem.js +930 -0
- package/dist/cjs/inventory/InventorySystem.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -1
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -1
- package/dist/cjs/quest/QuestSystem.js +924 -0
- package/dist/cjs/quest/QuestSystem.js.map +1 -0
- package/dist/cjs/rendering/WebGPURenderPipeline.js +658 -0
- package/dist/cjs/rendering/WebGPURenderPipeline.js.map +1 -0
- package/dist/cjs/xr/ARVR.js.map +1 -1
- package/dist/esm/audio/AudioBridge.js +446 -0
- package/dist/esm/audio/AudioBridge.js.map +1 -0
- package/dist/esm/devtools/GameplayAnalytics.js +639 -0
- package/dist/esm/devtools/GameplayAnalytics.js.map +1 -0
- package/dist/esm/dialogue/DialogueSystem.js +1008 -0
- package/dist/esm/dialogue/DialogueSystem.js.map +1 -0
- package/dist/esm/editor/NiceGameEditor.js +556 -58
- package/dist/esm/editor/NiceGameEditor.js.map +1 -1
- package/dist/esm/engine/SaveSystemV2.js +487 -0
- package/dist/esm/engine/SaveSystemV2.js.map +1 -0
- package/dist/esm/index.js +11 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integration/IconSprite.js +266 -0
- package/dist/esm/integration/IconSprite.js.map +1 -0
- package/dist/esm/inventory/InventorySystem.js +924 -0
- package/dist/esm/inventory/InventorySystem.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -1
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -1
- package/dist/esm/quest/QuestSystem.js +916 -0
- package/dist/esm/quest/QuestSystem.js.map +1 -0
- package/dist/esm/rendering/WebGPURenderPipeline.js +642 -0
- package/dist/esm/rendering/WebGPURenderPipeline.js.map +1 -0
- package/dist/esm/xr/ARVR.js.map +1 -1
- package/dist/types/__tests__/setup.d.ts +1 -1
- package/dist/types/audio/AudioBridge.d.ts +199 -0
- package/dist/types/devtools/GameplayAnalytics.d.ts +279 -0
- package/dist/types/dialogue/DialogueSystem.d.ts +326 -0
- package/dist/types/dialogue/index.d.ts +2 -0
- package/dist/types/editor/NiceGameEditor.d.ts +12 -1
- package/dist/types/engine/SaveSystemV2.d.ts +155 -0
- package/dist/types/index.d.ts +19 -3
- package/dist/types/integration/IconSprite.d.ts +196 -0
- package/dist/types/inventory/InventorySystem.d.ts +336 -0
- package/dist/types/performance/WebGPUCompute.d.ts +0 -10
- package/dist/types/quest/QuestSystem.d.ts +287 -0
- package/dist/types/rendering/WebGPURenderPipeline.d.ts +255 -0
- package/package.json +7 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import type { EntityId, Color } from '../core/types';
|
|
2
|
+
import type { World, AnimatorComponent, SpriteAnimation } from '../ecs/World';
|
|
3
|
+
import type { Renderer2D } from '../rendering/Renderer2D';
|
|
4
|
+
/** Minimal icon component contract (matches @nice2dev/icons-gaming) */
|
|
5
|
+
export interface IconComponent {
|
|
6
|
+
(props: IconComponentProps): unknown;
|
|
7
|
+
displayName?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface IconComponentProps {
|
|
10
|
+
size?: number;
|
|
11
|
+
animation?: string;
|
|
12
|
+
color?: string;
|
|
13
|
+
secondaryColor?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Options for registering an icon as a sprite texture */
|
|
16
|
+
export interface IconSpriteOptions {
|
|
17
|
+
/** Render size in px (icons will be rasterized at this resolution) */
|
|
18
|
+
size?: number;
|
|
19
|
+
/** Primary SVG fill color */
|
|
20
|
+
color?: string;
|
|
21
|
+
/** Secondary SVG fill color */
|
|
22
|
+
secondaryColor?: string;
|
|
23
|
+
/** Animation state to bake into the texture (default: 'none') */
|
|
24
|
+
animation?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Configuration for creating an icon-based entity */
|
|
27
|
+
export interface IconEntityOptions extends IconSpriteOptions {
|
|
28
|
+
/** Entity name override (defaults to icon displayName) */
|
|
29
|
+
name?: string;
|
|
30
|
+
/** World position X */
|
|
31
|
+
x?: number;
|
|
32
|
+
/** World position Y */
|
|
33
|
+
y?: number;
|
|
34
|
+
/** Display width in the game world (default: same as size) */
|
|
35
|
+
displayWidth?: number;
|
|
36
|
+
/** Display height in the game world (default: same as size) */
|
|
37
|
+
displayHeight?: number;
|
|
38
|
+
/** Sprite layer for depth sorting */
|
|
39
|
+
layer?: number;
|
|
40
|
+
/** Tint color multiply */
|
|
41
|
+
tint?: Color;
|
|
42
|
+
/** Opacity 0-1 */
|
|
43
|
+
opacity?: number;
|
|
44
|
+
}
|
|
45
|
+
/** Frame definition for icon animation sheets */
|
|
46
|
+
export interface IconAnimationFrame {
|
|
47
|
+
animation: string;
|
|
48
|
+
color?: string;
|
|
49
|
+
secondaryColor?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Options for creating a multi-frame animation from icon states */
|
|
52
|
+
export interface IconAnimationSheetOptions {
|
|
53
|
+
/** Icon size per frame */
|
|
54
|
+
size?: number;
|
|
55
|
+
/** Base color (can be overridden per frame) */
|
|
56
|
+
color?: string;
|
|
57
|
+
/** Frames per second for playback */
|
|
58
|
+
fps?: number;
|
|
59
|
+
/** Whether the animation loops */
|
|
60
|
+
loop?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Render an icon component to an SVG string using React's static markup API.
|
|
64
|
+
* This function must be called with the result of ReactDOMServer.renderToStaticMarkup().
|
|
65
|
+
*/
|
|
66
|
+
export declare function iconToSvgString(svgMarkup: string, size: number): string;
|
|
67
|
+
/**
|
|
68
|
+
* Convert an SVG string to a data URL suitable for Image loading.
|
|
69
|
+
*/
|
|
70
|
+
export declare function svgToDataUrl(svgString: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Load an SVG data URL into an HTMLImageElement (async).
|
|
73
|
+
*/
|
|
74
|
+
export declare function loadSvgImage(dataUrl: string): Promise<HTMLImageElement>;
|
|
75
|
+
/**
|
|
76
|
+
* Rasterize an SVG string to an OffscreenCanvas / HTMLCanvasElement.
|
|
77
|
+
*/
|
|
78
|
+
export declare function rasterizeSvg(svgString: string, size: number): Promise<HTMLCanvasElement>;
|
|
79
|
+
/**
|
|
80
|
+
* Generate a deterministic texture ID for an icon + options combination.
|
|
81
|
+
*/
|
|
82
|
+
export declare function getIconTextureId(displayName: string, options?: IconSpriteOptions): string;
|
|
83
|
+
/**
|
|
84
|
+
* Register an SVG icon as a texture in the game-engine renderer.
|
|
85
|
+
*
|
|
86
|
+
* @param renderer The Renderer2D instance
|
|
87
|
+
* @param textureId Unique texture identifier
|
|
88
|
+
* @param svgMarkup Static SVG markup from ReactDOMServer.renderToStaticMarkup(<Icon ... />)
|
|
89
|
+
* @param size Rasterization size in px
|
|
90
|
+
* @returns Promise that resolves when the texture is ready
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* import { renderToStaticMarkup } from 'react-dom/server';
|
|
95
|
+
* import { GiWarrior } from '@nice2dev/icons-gaming';
|
|
96
|
+
* import { registerIconTexture, getIconTextureId } from '@nice2dev/game-engine';
|
|
97
|
+
*
|
|
98
|
+
* const id = getIconTextureId('GiWarrior', { size: 64 });
|
|
99
|
+
* const svg = renderToStaticMarkup(<GiWarrior size={64} color="#e74c3c" />);
|
|
100
|
+
* await registerIconTexture(renderer, id, svg, 64);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function registerIconTexture(renderer: Renderer2D, textureId: string, svgMarkup: string, size: number): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Register an SVG icon as a rasterized canvas texture (sync-safe after await).
|
|
106
|
+
* Useful when you need pixel-perfect rendering without scaling artifacts.
|
|
107
|
+
*/
|
|
108
|
+
export declare function registerIconCanvasTexture(renderer: Renderer2D, textureId: string, svgMarkup: string, size: number): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Create a game entity with Sprite component sourced from an icon texture.
|
|
111
|
+
*
|
|
112
|
+
* The texture must already be registered via `registerIconTexture()`.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const entityId = createIconEntity(world, 'GiWarrior', textureId, {
|
|
117
|
+
* x: 200, y: 150, displayWidth: 64, displayHeight: 64, layer: 1,
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export declare function createIconEntity(world: World, name: string, textureId: string, options?: Omit<IconEntityOptions, 'size' | 'color' | 'secondaryColor' | 'animation'>): EntityId;
|
|
122
|
+
/**
|
|
123
|
+
* Create a SpriteAnimation clip from multiple icon animation frames.
|
|
124
|
+
*
|
|
125
|
+
* Each frame is a separate registered texture. The AnimatorComponent
|
|
126
|
+
* switches `assetId` each frame to show different icon states.
|
|
127
|
+
*
|
|
128
|
+
* @param frames Array of { assetId, duration } for each frame
|
|
129
|
+
* @param loop Whether animation loops
|
|
130
|
+
*/
|
|
131
|
+
export declare function createIconAnimationClip(frames: Array<{
|
|
132
|
+
assetId: string;
|
|
133
|
+
duration?: number;
|
|
134
|
+
}>, fps?: number, loop?: boolean): SpriteAnimation;
|
|
135
|
+
/**
|
|
136
|
+
* Predefined character animation state sequences.
|
|
137
|
+
* Maps game animation concepts to sets of icon animation states
|
|
138
|
+
* that can be baked into textures.
|
|
139
|
+
*/
|
|
140
|
+
export declare const CHARACTER_ANIMATION_STATES: readonly ["idle", "move", "jump", "attack-melee", "attack-ranged", "attack-magic", "damage", "death"];
|
|
141
|
+
export declare const OBJECT_ANIMATION_STATES: readonly ["idle", "spin", "float", "shake", "glow", "bounce", "flicker"];
|
|
142
|
+
/**
|
|
143
|
+
* Batch-register all animation states of an icon as separate textures.
|
|
144
|
+
*
|
|
145
|
+
* @returns Map of animation state → texture ID
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* const textures = await registerIconAnimationSet(
|
|
150
|
+
* renderer,
|
|
151
|
+
* 'GiWarrior',
|
|
152
|
+
* (anim) => renderToStaticMarkup(<GiWarrior size={64} animation={anim} color="#e74c3c" />),
|
|
153
|
+
* CHARACTER_ANIMATION_STATES,
|
|
154
|
+
* 64,
|
|
155
|
+
* );
|
|
156
|
+
* // textures = { idle: 'icon:GiWarrior:s64:aidle', move: 'icon:GiWarrior:s64:amove', ... }
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
export declare function registerIconAnimationSet(renderer: Renderer2D, displayName: string, renderFn: (animation: string) => string, states: readonly string[], size: number): Promise<Record<string, string>>;
|
|
160
|
+
/**
|
|
161
|
+
* Create an Animator component configuration from a registered animation set.
|
|
162
|
+
*
|
|
163
|
+
* @param textureMap Result from `registerIconAnimationSet()`
|
|
164
|
+
* @param defaultState Initial animation state (default: 'idle')
|
|
165
|
+
* @param fps Frames per second for each clip
|
|
166
|
+
*/
|
|
167
|
+
export declare function createIconAnimator(textureMap: Record<string, string>, defaultState?: string, fps?: number): Partial<AnimatorComponent>;
|
|
168
|
+
/** Entry in a resolved icon catalog */
|
|
169
|
+
export interface IconCatalogEntry {
|
|
170
|
+
name: string;
|
|
171
|
+
textureId: string;
|
|
172
|
+
category: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Register an entire icon map (e.g. `characterIcons`, `weaponIcons`)
|
|
176
|
+
* and return a catalog array for the asset manager / picker.
|
|
177
|
+
*
|
|
178
|
+
* @param renderer Renderer2D
|
|
179
|
+
* @param iconMap Map of name→icon render functions (SVG markup generators)
|
|
180
|
+
* @param category Category label for the asset catalog
|
|
181
|
+
* @param size Texture size
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const catalog = await registerIconCatalog(
|
|
186
|
+
* renderer,
|
|
187
|
+
* {
|
|
188
|
+
* GiWarrior: () => renderToStaticMarkup(<GiWarrior size={64} color="#e74c3c" />),
|
|
189
|
+
* GiMage: () => renderToStaticMarkup(<GiMage size={64} color="#3498db" />),
|
|
190
|
+
* },
|
|
191
|
+
* 'characters',
|
|
192
|
+
* 64,
|
|
193
|
+
* );
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export declare function registerIconCatalog(renderer: Renderer2D, iconMap: Record<string, () => string>, category: string, size: number): Promise<IconCatalogEntry[]>;
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import type { EntityId } from '../core/types';
|
|
2
|
+
import { EventBus } from '../core/EventBus';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
/** Item rarity levels */
|
|
5
|
+
export type ItemRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary' | 'mythic' | 'unique';
|
|
6
|
+
/** Item categories */
|
|
7
|
+
export type ItemCategory = 'weapon' | 'armor' | 'accessory' | 'consumable' | 'material' | 'currency' | 'quest' | 'key' | 'tool' | 'mount' | 'pet' | 'cosmetic' | 'container' | 'misc';
|
|
8
|
+
/** Equipment slot types */
|
|
9
|
+
export type EquipmentSlot = 'head' | 'chest' | 'legs' | 'feet' | 'hands' | 'shoulders' | 'back' | 'waist' | 'mainHand' | 'offHand' | 'twoHand' | 'ring1' | 'ring2' | 'neck' | 'trinket1' | 'trinket2';
|
|
10
|
+
/** Stat modifier types */
|
|
11
|
+
export type StatType = 'health' | 'mana' | 'stamina' | 'attack' | 'defense' | 'magic' | 'speed' | 'critRate' | 'critDamage' | 'dodge' | 'accuracy' | 'luck' | 'custom';
|
|
12
|
+
/** Container types */
|
|
13
|
+
export type ContainerType = 'player' | 'chest' | 'shop' | 'bank' | 'guild' | 'mail' | 'crafting' | 'loot';
|
|
14
|
+
export interface StatModifier {
|
|
15
|
+
stat: StatType;
|
|
16
|
+
/** Flat value added */
|
|
17
|
+
flat?: number;
|
|
18
|
+
/** Percentage modifier (0.1 = +10%) */
|
|
19
|
+
percent?: number;
|
|
20
|
+
/** Custom stat name if type is 'custom' */
|
|
21
|
+
customName?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ItemDefinition {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
category: ItemCategory;
|
|
28
|
+
rarity: ItemRarity;
|
|
29
|
+
/** Icon URL or icon key */
|
|
30
|
+
icon: string;
|
|
31
|
+
/** Maximum stack size (1 = not stackable) */
|
|
32
|
+
maxStack: number;
|
|
33
|
+
/** Item weight for capacity systems */
|
|
34
|
+
weight: number;
|
|
35
|
+
/** Base value in currency */
|
|
36
|
+
value: number;
|
|
37
|
+
/** Level requirement to use/equip */
|
|
38
|
+
levelRequirement?: number;
|
|
39
|
+
/** Class/role requirements */
|
|
40
|
+
classRequirement?: string[];
|
|
41
|
+
/** Stat requirements (e.g., min strength) */
|
|
42
|
+
statRequirements?: StatModifier[];
|
|
43
|
+
/** Whether item can be traded */
|
|
44
|
+
tradable: boolean;
|
|
45
|
+
/** Whether item can be sold */
|
|
46
|
+
sellable: boolean;
|
|
47
|
+
/** Whether item is destroyed on use */
|
|
48
|
+
consumeOnUse: boolean;
|
|
49
|
+
/** Equipment slot if equippable */
|
|
50
|
+
equipSlot?: EquipmentSlot;
|
|
51
|
+
/** Stat bonuses when equipped/active */
|
|
52
|
+
stats?: StatModifier[];
|
|
53
|
+
/** Max durability (undefined = indestructible) */
|
|
54
|
+
maxDurability?: number;
|
|
55
|
+
/** Set ID if part of a set */
|
|
56
|
+
setId?: string;
|
|
57
|
+
/** Soulbound type */
|
|
58
|
+
binding?: 'none' | 'onPickup' | 'onEquip' | 'account';
|
|
59
|
+
/** Cool-down in milliseconds for consumables */
|
|
60
|
+
cooldown?: number;
|
|
61
|
+
/** Effect ID when consumed */
|
|
62
|
+
effectId?: string;
|
|
63
|
+
/** Tags for filtering/searching */
|
|
64
|
+
tags?: string[];
|
|
65
|
+
/** Custom data */
|
|
66
|
+
customData?: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
export interface ItemInstance {
|
|
69
|
+
/** Unique instance ID */
|
|
70
|
+
instanceId: string;
|
|
71
|
+
/** Reference to item definition */
|
|
72
|
+
itemId: string;
|
|
73
|
+
/** Current stack count */
|
|
74
|
+
count: number;
|
|
75
|
+
/** Current durability */
|
|
76
|
+
durability?: number;
|
|
77
|
+
/** Bound to player ID */
|
|
78
|
+
boundTo?: string;
|
|
79
|
+
/** Enchantments applied */
|
|
80
|
+
enchantments?: string[];
|
|
81
|
+
/** Socket gems */
|
|
82
|
+
sockets?: string[];
|
|
83
|
+
/** Custom display name override */
|
|
84
|
+
customName?: string;
|
|
85
|
+
/** Last used timestamp (for cooldown) */
|
|
86
|
+
lastUsed?: number;
|
|
87
|
+
/** Created timestamp */
|
|
88
|
+
createdAt: number;
|
|
89
|
+
/** Custom instance data */
|
|
90
|
+
customData?: Record<string, unknown>;
|
|
91
|
+
}
|
|
92
|
+
export interface InventorySlot {
|
|
93
|
+
/** Slot index */
|
|
94
|
+
index: number;
|
|
95
|
+
/** Item in this slot (null if empty) */
|
|
96
|
+
item: ItemInstance | null;
|
|
97
|
+
/** Whether slot is locked */
|
|
98
|
+
locked?: boolean;
|
|
99
|
+
}
|
|
100
|
+
export interface Container {
|
|
101
|
+
id: string;
|
|
102
|
+
type: ContainerType;
|
|
103
|
+
name: string;
|
|
104
|
+
/** Owner entity ID */
|
|
105
|
+
ownerId?: EntityId;
|
|
106
|
+
/** Maximum number of slots */
|
|
107
|
+
maxSlots: number;
|
|
108
|
+
/** Maximum weight capacity (undefined = unlimited) */
|
|
109
|
+
maxWeight?: number;
|
|
110
|
+
/** Slots array */
|
|
111
|
+
slots: InventorySlot[];
|
|
112
|
+
/** Currency stored in container */
|
|
113
|
+
currency?: Map<string, number>;
|
|
114
|
+
/** Whether container is sorted */
|
|
115
|
+
sorted?: boolean;
|
|
116
|
+
/** Filter for allowed item categories */
|
|
117
|
+
allowedCategories?: ItemCategory[];
|
|
118
|
+
/** Filter for disallowed item categories */
|
|
119
|
+
disallowedCategories?: ItemCategory[];
|
|
120
|
+
}
|
|
121
|
+
export interface EquipmentState {
|
|
122
|
+
ownerId: EntityId;
|
|
123
|
+
slots: Map<EquipmentSlot, ItemInstance | null>;
|
|
124
|
+
/** Calculated total stats from all equipped items */
|
|
125
|
+
totalStats: Map<StatType, number>;
|
|
126
|
+
}
|
|
127
|
+
export interface CraftingIngredient {
|
|
128
|
+
itemId: string;
|
|
129
|
+
count: number;
|
|
130
|
+
consumed: boolean;
|
|
131
|
+
}
|
|
132
|
+
export interface CraftingRecipe {
|
|
133
|
+
id: string;
|
|
134
|
+
name: string;
|
|
135
|
+
description: string;
|
|
136
|
+
/** Required ingredients */
|
|
137
|
+
ingredients: CraftingIngredient[];
|
|
138
|
+
/** Output item ID */
|
|
139
|
+
outputItemId: string;
|
|
140
|
+
/** Output quantity */
|
|
141
|
+
outputCount: number;
|
|
142
|
+
/** Crafting time in milliseconds */
|
|
143
|
+
craftTime: number;
|
|
144
|
+
/** Required skill/profession */
|
|
145
|
+
requiredSkill?: string;
|
|
146
|
+
/** Required skill level */
|
|
147
|
+
requiredSkillLevel?: number;
|
|
148
|
+
/** Whether recipe is learned or always available */
|
|
149
|
+
requiresLearning: boolean;
|
|
150
|
+
/** Success rate (0-1) */
|
|
151
|
+
successRate: number;
|
|
152
|
+
/** XP granted on success */
|
|
153
|
+
experienceGrant?: number;
|
|
154
|
+
}
|
|
155
|
+
export interface LootEntry {
|
|
156
|
+
itemId: string;
|
|
157
|
+
/** Drop weight (relative to other entries) */
|
|
158
|
+
weight: number;
|
|
159
|
+
/** Minimum quantity */
|
|
160
|
+
minCount: number;
|
|
161
|
+
/** Maximum quantity */
|
|
162
|
+
maxCount: number;
|
|
163
|
+
/** Per-item drop chance (0-1) after selection */
|
|
164
|
+
dropChance: number;
|
|
165
|
+
/** Conditions for this entry to be included */
|
|
166
|
+
conditions?: {
|
|
167
|
+
minLevel?: number;
|
|
168
|
+
maxLevel?: number;
|
|
169
|
+
requiredTags?: string[];
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
export interface LootTable {
|
|
173
|
+
id: string;
|
|
174
|
+
name: string;
|
|
175
|
+
/** Entries with drop weights */
|
|
176
|
+
entries: LootEntry[];
|
|
177
|
+
/** Number of rolls on this table */
|
|
178
|
+
rolls: number;
|
|
179
|
+
/** Guaranteed drops (always included) */
|
|
180
|
+
guaranteedDrops?: {
|
|
181
|
+
itemId: string;
|
|
182
|
+
count: number;
|
|
183
|
+
}[];
|
|
184
|
+
}
|
|
185
|
+
export interface ShopListing {
|
|
186
|
+
itemId: string;
|
|
187
|
+
/** Override price (uses item.value if undefined) */
|
|
188
|
+
price?: number;
|
|
189
|
+
/** Currency type for this listing */
|
|
190
|
+
currencyId: string;
|
|
191
|
+
/** Available stock (-1 = unlimited) */
|
|
192
|
+
stock: number;
|
|
193
|
+
/** Restock interval in milliseconds */
|
|
194
|
+
restockInterval?: number;
|
|
195
|
+
/** Requirements to see/buy */
|
|
196
|
+
requirements?: {
|
|
197
|
+
level?: number;
|
|
198
|
+
reputation?: {
|
|
199
|
+
factionId: string;
|
|
200
|
+
minLevel: number;
|
|
201
|
+
};
|
|
202
|
+
questCompleted?: string;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export interface Shop {
|
|
206
|
+
id: string;
|
|
207
|
+
name: string;
|
|
208
|
+
/** NPC or location ID owning this shop */
|
|
209
|
+
ownerId?: string;
|
|
210
|
+
/** Buy rate (percentage of item value) */
|
|
211
|
+
buyRate: number;
|
|
212
|
+
/** Sell rate (percentage of item value) */
|
|
213
|
+
sellRate: number;
|
|
214
|
+
/** Available listings */
|
|
215
|
+
listings: ShopListing[];
|
|
216
|
+
/** Currencies accepted */
|
|
217
|
+
acceptedCurrencies: string[];
|
|
218
|
+
}
|
|
219
|
+
export type InventoryEventType = 'item:added' | 'item:removed' | 'item:moved' | 'item:stacked' | 'item:split' | 'item:equipped' | 'item:unequipped' | 'item:used' | 'item:destroyed' | 'item:repaired' | 'item:enchanted' | 'craft:started' | 'craft:completed' | 'craft:failed' | 'shop:bought' | 'shop:sold' | 'loot:generated' | 'currency:changed' | 'container:created' | 'container:destroyed' | 'container:sorted';
|
|
220
|
+
export interface InventoryEvent {
|
|
221
|
+
type: InventoryEventType;
|
|
222
|
+
containerId?: string;
|
|
223
|
+
ownerId?: EntityId;
|
|
224
|
+
item?: ItemInstance;
|
|
225
|
+
itemId?: string;
|
|
226
|
+
slot?: number;
|
|
227
|
+
fromSlot?: number;
|
|
228
|
+
toSlot?: number;
|
|
229
|
+
count?: number;
|
|
230
|
+
currencyId?: string;
|
|
231
|
+
amount?: number;
|
|
232
|
+
recipeId?: string;
|
|
233
|
+
shopId?: string;
|
|
234
|
+
timestamp: number;
|
|
235
|
+
customData?: Record<string, unknown>;
|
|
236
|
+
}
|
|
237
|
+
export interface InventoryManagerConfig {
|
|
238
|
+
/** Default container size */
|
|
239
|
+
defaultSlots: number;
|
|
240
|
+
/** Enable weight system */
|
|
241
|
+
enableWeight: boolean;
|
|
242
|
+
/** Enable durability system */
|
|
243
|
+
enableDurability: boolean;
|
|
244
|
+
/** Auto-stack on pickup */
|
|
245
|
+
autoStack: boolean;
|
|
246
|
+
/** Auto-sort after changes */
|
|
247
|
+
autoSort: boolean;
|
|
248
|
+
/** Maximum containers per entity */
|
|
249
|
+
maxContainersPerEntity: number;
|
|
250
|
+
}
|
|
251
|
+
export declare class InventoryManager {
|
|
252
|
+
private config;
|
|
253
|
+
private eventBus;
|
|
254
|
+
private itemDefinitions;
|
|
255
|
+
private containers;
|
|
256
|
+
private equipment;
|
|
257
|
+
private recipes;
|
|
258
|
+
private lootTables;
|
|
259
|
+
private shops;
|
|
260
|
+
private learnedRecipes;
|
|
261
|
+
private cooldowns;
|
|
262
|
+
constructor(config?: Partial<InventoryManagerConfig>);
|
|
263
|
+
setEventBus(bus: EventBus): void;
|
|
264
|
+
private emit;
|
|
265
|
+
registerItem(definition: ItemDefinition): void;
|
|
266
|
+
registerItems(definitions: ItemDefinition[]): void;
|
|
267
|
+
getItemDefinition(itemId: string): ItemDefinition | undefined;
|
|
268
|
+
getAllItemDefinitions(): ItemDefinition[];
|
|
269
|
+
createContainer(type: ContainerType, ownerId?: EntityId, options?: Partial<Container>): Container;
|
|
270
|
+
getContainer(containerId: string): Container | undefined;
|
|
271
|
+
getContainersByOwner(ownerId: EntityId): Container[];
|
|
272
|
+
destroyContainer(containerId: string): boolean;
|
|
273
|
+
createItemInstance(itemId: string, count?: number, options?: Partial<ItemInstance>): ItemInstance | null;
|
|
274
|
+
addItem(containerId: string, itemId: string, count?: number, options?: Partial<ItemInstance>): ItemInstance | null;
|
|
275
|
+
removeItem(containerId: string, slotIndex: number, count?: number): ItemInstance | null;
|
|
276
|
+
moveItem(fromContainerId: string, fromSlot: number, toContainerId: string, toSlot: number): boolean;
|
|
277
|
+
splitStack(containerId: string, slotIndex: number, splitCount: number): boolean;
|
|
278
|
+
getContainerWeight(containerId: string): number;
|
|
279
|
+
getContainerFreeSlots(containerId: string): number;
|
|
280
|
+
initializeEquipment(ownerId: EntityId): EquipmentState;
|
|
281
|
+
getEquipment(ownerId: EntityId): EquipmentState | undefined;
|
|
282
|
+
equipItem(ownerId: EntityId, containerId: string, slotIndex: number): boolean;
|
|
283
|
+
unequipItem(ownerId: EntityId, equipSlot: EquipmentSlot, containerId: string): boolean;
|
|
284
|
+
private unequipToContainer;
|
|
285
|
+
private recalculateEquipmentStats;
|
|
286
|
+
damageDurability(instance: ItemInstance, damage: number): boolean;
|
|
287
|
+
repairItem(instance: ItemInstance, amount?: number): boolean;
|
|
288
|
+
useItem(containerId: string, slotIndex: number, targetEntityId?: EntityId): boolean;
|
|
289
|
+
registerRecipe(recipe: CraftingRecipe): void;
|
|
290
|
+
learnRecipe(entityId: EntityId, recipeId: string): boolean;
|
|
291
|
+
canCraft(entityId: EntityId, recipeId: string, containerId: string): boolean;
|
|
292
|
+
craft(entityId: EntityId, recipeId: string, containerId: string): ItemInstance | null;
|
|
293
|
+
registerLootTable(table: LootTable): void;
|
|
294
|
+
generateLoot(tableId: string, modifiers?: {
|
|
295
|
+
luckBonus?: number;
|
|
296
|
+
levelContext?: number;
|
|
297
|
+
}): ItemInstance[];
|
|
298
|
+
registerShop(shop: Shop): void;
|
|
299
|
+
getShop(shopId: string): Shop | undefined;
|
|
300
|
+
buyFromShop(shopId: string, listingIndex: number, quantity: number, buyerContainerId: string): boolean;
|
|
301
|
+
sellToShop(shopId: string, sellerContainerId: string, slotIndex: number, quantity: number): boolean;
|
|
302
|
+
addCurrency(containerId: string, currencyId: string, amount: number): boolean;
|
|
303
|
+
removeCurrency(containerId: string, currencyId: string, amount: number): boolean;
|
|
304
|
+
getCurrency(containerId: string, currencyId: string): number;
|
|
305
|
+
sortContainer(containerId: string, criteria?: 'category' | 'rarity' | 'name' | 'value'): void;
|
|
306
|
+
countItemsInContainer(containerId: string, itemId: string): number;
|
|
307
|
+
private removeItemsByIdFromContainer;
|
|
308
|
+
findItem(containerId: string, itemId: string): {
|
|
309
|
+
slot: InventorySlot;
|
|
310
|
+
instance: ItemInstance;
|
|
311
|
+
} | null;
|
|
312
|
+
serialize(): InventorySnapshot;
|
|
313
|
+
deserialize(snapshot: InventorySnapshot): void;
|
|
314
|
+
}
|
|
315
|
+
export interface InventorySnapshot {
|
|
316
|
+
containers: Array<Omit<Container, 'currency'> & {
|
|
317
|
+
currency: [string, number][];
|
|
318
|
+
}>;
|
|
319
|
+
equipment: Array<{
|
|
320
|
+
ownerId: EntityId;
|
|
321
|
+
slots: [EquipmentSlot, ItemInstance | null][];
|
|
322
|
+
totalStats: [StatType, number][];
|
|
323
|
+
}>;
|
|
324
|
+
learnedRecipes: Array<{
|
|
325
|
+
entityId: EntityId;
|
|
326
|
+
recipes: string[];
|
|
327
|
+
}>;
|
|
328
|
+
}
|
|
329
|
+
export declare const InventoryProvider: React.FC<{
|
|
330
|
+
manager: InventoryManager;
|
|
331
|
+
children: React.ReactNode;
|
|
332
|
+
}>;
|
|
333
|
+
export declare function useInventoryManager(): InventoryManager;
|
|
334
|
+
export declare function useContainer(containerId: string): Container | undefined;
|
|
335
|
+
export declare function useEquipment(ownerId: EntityId): EquipmentState | undefined;
|
|
336
|
+
export default InventoryManager;
|
|
@@ -72,16 +72,6 @@ declare global {
|
|
|
72
72
|
interface GPUDeviceLostInfo {
|
|
73
73
|
readonly message: string;
|
|
74
74
|
}
|
|
75
|
-
namespace GPUBufferUsage {
|
|
76
|
-
const STORAGE: number;
|
|
77
|
-
const COPY_SRC: number;
|
|
78
|
-
const COPY_DST: number;
|
|
79
|
-
const MAP_READ: number;
|
|
80
|
-
const UNIFORM: number;
|
|
81
|
-
}
|
|
82
|
-
namespace GPUMapMode {
|
|
83
|
-
const READ: number;
|
|
84
|
-
}
|
|
85
75
|
interface GPU {
|
|
86
76
|
requestAdapter(options?: {
|
|
87
77
|
powerPreference?: string;
|