lpc-forge 1.0.0 → 1.0.3
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/assets/manager.d.ts +69 -0
- package/dist/assets/manager.js +531 -0
- package/dist/assets/manager.js.map +1 -0
- package/dist/audio/index.d.ts +4 -0
- package/dist/audio/index.js +4 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/audio/music-catalog.d.ts +11 -0
- package/dist/audio/music-catalog.js +96 -0
- package/dist/audio/music-catalog.js.map +1 -0
- package/dist/audio/sfx-generator.d.ts +11 -0
- package/dist/audio/sfx-generator.js +77 -0
- package/dist/audio/sfx-generator.js.map +1 -0
- package/dist/audio/sfx-presets.d.ts +2 -0
- package/dist/audio/sfx-presets.js +286 -0
- package/dist/audio/sfx-presets.js.map +1 -0
- package/dist/audio/types.d.ts +39 -0
- package/dist/audio/types.js +2 -0
- package/dist/audio/types.js.map +1 -0
- package/dist/character/composer.d.ts +4 -1
- package/dist/character/composer.js +41 -7
- package/dist/character/composer.js.map +1 -1
- package/dist/cli.js +152 -31
- package/dist/export/godot.js +78 -19
- package/dist/export/godot.js.map +1 -1
- package/dist/license.js +1 -1
- package/dist/lighting/index.d.ts +16 -0
- package/dist/lighting/index.js +95 -0
- package/dist/lighting/index.js.map +1 -0
- package/dist/lighting/particles.d.ts +2 -0
- package/dist/lighting/particles.js +192 -0
- package/dist/lighting/particles.js.map +1 -0
- package/dist/lighting/presets.d.ts +2 -0
- package/dist/lighting/presets.js +146 -0
- package/dist/lighting/presets.js.map +1 -0
- package/dist/lighting/types.d.ts +36 -0
- package/dist/lighting/types.js +2 -0
- package/dist/lighting/types.js.map +1 -0
- package/dist/systems/day-night.d.ts +2 -0
- package/dist/systems/day-night.js +109 -0
- package/dist/systems/day-night.js.map +1 -0
- package/dist/systems/dialog.d.ts +2 -0
- package/dist/systems/dialog.js +266 -0
- package/dist/systems/dialog.js.map +1 -0
- package/dist/systems/enemy-ai.d.ts +2 -0
- package/dist/systems/enemy-ai.js +204 -0
- package/dist/systems/enemy-ai.js.map +1 -0
- package/dist/systems/hud-full.d.ts +2 -0
- package/dist/systems/hud-full.js +158 -0
- package/dist/systems/hud-full.js.map +1 -0
- package/dist/systems/index.d.ts +10 -0
- package/dist/systems/index.js +59 -0
- package/dist/systems/index.js.map +1 -0
- package/dist/systems/inventory.d.ts +2 -0
- package/dist/systems/inventory.js +324 -0
- package/dist/systems/inventory.js.map +1 -0
- package/dist/systems/loot.d.ts +2 -0
- package/dist/systems/loot.js +109 -0
- package/dist/systems/loot.js.map +1 -0
- package/dist/systems/menu.d.ts +2 -0
- package/dist/systems/menu.js +453 -0
- package/dist/systems/menu.js.map +1 -0
- package/dist/systems/quest.d.ts +2 -0
- package/dist/systems/quest.js +210 -0
- package/dist/systems/quest.js.map +1 -0
- package/dist/systems/save-load.d.ts +2 -0
- package/dist/systems/save-load.js +163 -0
- package/dist/systems/save-load.js.map +1 -0
- package/dist/systems/scene-transition.d.ts +2 -0
- package/dist/systems/scene-transition.js +107 -0
- package/dist/systems/scene-transition.js.map +1 -0
- package/dist/systems/types.d.ts +20 -0
- package/dist/systems/types.js +2 -0
- package/dist/systems/types.js.map +1 -0
- package/dist/systems/writer.d.ts +11 -0
- package/dist/systems/writer.js +31 -0
- package/dist/systems/writer.js.map +1 -0
- package/dist/ui/generator.d.ts +7 -0
- package/dist/ui/generator.js +307 -0
- package/dist/ui/generator.js.map +1 -0
- package/dist/ui/icons.d.ts +10 -0
- package/dist/ui/icons.js +320 -0
- package/dist/ui/icons.js.map +1 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +6 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/portrait.d.ts +12 -0
- package/dist/ui/portrait.js +72 -0
- package/dist/ui/portrait.js.map +1 -0
- package/dist/ui/props.d.ts +9 -0
- package/dist/ui/props.js +247 -0
- package/dist/ui/props.js.map +1 -0
- package/dist/ui/themes.d.ts +2 -0
- package/dist/ui/themes.js +69 -0
- package/dist/ui/themes.js.map +1 -0
- package/dist/ui/types.d.ts +58 -0
- package/dist/ui/types.js +2 -0
- package/dist/ui/types.js.map +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset manager — downloads, caches, and verifies LPC sprite assets
|
|
3
|
+
* for npm-installed CLI users who don't have the full repo checkout.
|
|
4
|
+
*/
|
|
5
|
+
export interface AssetManifest {
|
|
6
|
+
version: string;
|
|
7
|
+
generatedAt: string;
|
|
8
|
+
chunks: AssetChunk[];
|
|
9
|
+
totalSize: number;
|
|
10
|
+
}
|
|
11
|
+
export interface AssetChunk {
|
|
12
|
+
name: string;
|
|
13
|
+
filename: string;
|
|
14
|
+
url: string;
|
|
15
|
+
size: number;
|
|
16
|
+
sha256: string;
|
|
17
|
+
required: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Platform-aware asset cache directory */
|
|
20
|
+
export declare function getAssetDir(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the root directory where `spritesheets/` and `sheet_definitions/` live.
|
|
23
|
+
*
|
|
24
|
+
* Priority:
|
|
25
|
+
* 1. LPC_FORGE_ASSETS env var
|
|
26
|
+
* 2. Local repo checkout (spritesheets/ next to package root)
|
|
27
|
+
* 3. Cached asset directory (~/.lpc-forge/assets or platform equivalent)
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveAssetRoot(packageRoot: string): string;
|
|
30
|
+
/** Check if assets are installed and match the expected version */
|
|
31
|
+
export declare function isAssetsInstalled(version?: string): Promise<{
|
|
32
|
+
installed: boolean;
|
|
33
|
+
version?: string;
|
|
34
|
+
chunks?: string[];
|
|
35
|
+
path: string;
|
|
36
|
+
}>;
|
|
37
|
+
/** Fetch the remote asset manifest from the latest GitHub release */
|
|
38
|
+
export declare function fetchRemoteManifest(version?: string): Promise<AssetManifest>;
|
|
39
|
+
export interface DownloadOptions {
|
|
40
|
+
/** Only download required chunks (body + definitions) */
|
|
41
|
+
minimal?: boolean;
|
|
42
|
+
/** Custom asset directory (overrides default) */
|
|
43
|
+
path?: string;
|
|
44
|
+
/** Callback for progress updates */
|
|
45
|
+
onProgress?: (state: DownloadProgress) => void;
|
|
46
|
+
/** Skip interactive prompts */
|
|
47
|
+
nonInteractive?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface DownloadProgress {
|
|
50
|
+
phase: 'fetching-manifest' | 'downloading' | 'verifying' | 'extracting' | 'done';
|
|
51
|
+
currentChunk?: string;
|
|
52
|
+
chunkIndex?: number;
|
|
53
|
+
totalChunks?: number;
|
|
54
|
+
bytesDownloaded?: number;
|
|
55
|
+
bytesTotal?: number | null;
|
|
56
|
+
overallDownloaded?: number;
|
|
57
|
+
overallTotal?: number;
|
|
58
|
+
}
|
|
59
|
+
export declare function downloadAssets(options?: DownloadOptions): Promise<void>;
|
|
60
|
+
export declare function cleanAssets(assetDir?: string): Promise<void>;
|
|
61
|
+
/** Ask user yes/no in the terminal. Returns true for yes. */
|
|
62
|
+
export declare function promptYesNo(question: string): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Ensures assets are available. If missing, prompts the user to download them.
|
|
65
|
+
* Returns the resolved asset root path.
|
|
66
|
+
* Throws if assets are unavailable and user declines download.
|
|
67
|
+
*/
|
|
68
|
+
export declare function ensureAssets(packageRoot: string): Promise<string>;
|
|
69
|
+
export declare function downloadWithProgress(options?: DownloadOptions): Promise<void>;
|
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset manager — downloads, caches, and verifies LPC sprite assets
|
|
3
|
+
* for npm-installed CLI users who don't have the full repo checkout.
|
|
4
|
+
*/
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { mkdir, readFile, writeFile, rm, cp, } from 'node:fs/promises';
|
|
8
|
+
import { get as httpsGet } from 'node:https';
|
|
9
|
+
import { get as httpGet } from 'node:http';
|
|
10
|
+
import { homedir, platform, tmpdir } from 'node:os';
|
|
11
|
+
import { join, resolve } from 'node:path';
|
|
12
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
13
|
+
import { pipeline } from 'node:stream/promises';
|
|
14
|
+
import { createInterface } from 'node:readline';
|
|
15
|
+
import { execFile } from 'node:child_process';
|
|
16
|
+
import { promisify } from 'node:util';
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
18
|
+
// ──────────────────────────────────────────────
|
|
19
|
+
// Constants
|
|
20
|
+
// ──────────────────────────────────────────────
|
|
21
|
+
const GITHUB_REPO = 'LiberatedPixelCup/Universal-LPC-Spritesheet-Character-Generator';
|
|
22
|
+
const MANIFEST_FILENAME = 'assets-manifest.json';
|
|
23
|
+
const LOCAL_MANIFEST = '.lpc-forge-manifest.json';
|
|
24
|
+
// ──────────────────────────────────────────────
|
|
25
|
+
// Asset directory resolution
|
|
26
|
+
// ──────────────────────────────────────────────
|
|
27
|
+
/** Platform-aware asset cache directory */
|
|
28
|
+
export function getAssetDir() {
|
|
29
|
+
if (process.env.LPC_FORGE_ASSETS) {
|
|
30
|
+
return resolve(process.env.LPC_FORGE_ASSETS);
|
|
31
|
+
}
|
|
32
|
+
const p = platform();
|
|
33
|
+
if (p === 'darwin') {
|
|
34
|
+
return join(homedir(), 'Library', 'Application Support', 'lpc-forge', 'assets');
|
|
35
|
+
}
|
|
36
|
+
if (p === 'win32') {
|
|
37
|
+
return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'lpc-forge', 'assets');
|
|
38
|
+
}
|
|
39
|
+
// Linux / other — respect XDG
|
|
40
|
+
return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'lpc-forge', 'assets');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the root directory where `spritesheets/` and `sheet_definitions/` live.
|
|
44
|
+
*
|
|
45
|
+
* Priority:
|
|
46
|
+
* 1. LPC_FORGE_ASSETS env var
|
|
47
|
+
* 2. Local repo checkout (spritesheets/ next to package root)
|
|
48
|
+
* 3. Cached asset directory (~/.lpc-forge/assets or platform equivalent)
|
|
49
|
+
*/
|
|
50
|
+
export function resolveAssetRoot(packageRoot) {
|
|
51
|
+
if (process.env.LPC_FORGE_ASSETS) {
|
|
52
|
+
return resolve(process.env.LPC_FORGE_ASSETS);
|
|
53
|
+
}
|
|
54
|
+
// Check if running from a git clone / dev checkout
|
|
55
|
+
if (existsSync(join(packageRoot, 'spritesheets'))) {
|
|
56
|
+
return packageRoot;
|
|
57
|
+
}
|
|
58
|
+
return getAssetDir();
|
|
59
|
+
}
|
|
60
|
+
// ──────────────────────────────────────────────
|
|
61
|
+
// Status checks
|
|
62
|
+
// ──────────────────────────────────────────────
|
|
63
|
+
/** Check if assets are installed and match the expected version */
|
|
64
|
+
export async function isAssetsInstalled(version) {
|
|
65
|
+
const assetDir = getAssetDir();
|
|
66
|
+
const manifestPath = join(assetDir, LOCAL_MANIFEST);
|
|
67
|
+
if (!existsSync(manifestPath)) {
|
|
68
|
+
return { installed: false, path: assetDir };
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const raw = await readFile(manifestPath, 'utf-8');
|
|
72
|
+
const manifest = JSON.parse(raw);
|
|
73
|
+
// Check if critical directories actually exist
|
|
74
|
+
const hasSpritesheets = existsSync(join(assetDir, 'spritesheets'));
|
|
75
|
+
const hasDefinitions = existsSync(join(assetDir, 'sheet_definitions'));
|
|
76
|
+
if (!hasSpritesheets || !hasDefinitions) {
|
|
77
|
+
return { installed: false, path: assetDir };
|
|
78
|
+
}
|
|
79
|
+
// Version mismatch check
|
|
80
|
+
if (version && manifest.version !== version) {
|
|
81
|
+
return {
|
|
82
|
+
installed: false,
|
|
83
|
+
version: manifest.version,
|
|
84
|
+
chunks: manifest.chunks,
|
|
85
|
+
path: assetDir,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
installed: true,
|
|
90
|
+
version: manifest.version,
|
|
91
|
+
chunks: manifest.chunks,
|
|
92
|
+
path: assetDir,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return { installed: false, path: assetDir };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ──────────────────────────────────────────────
|
|
100
|
+
// Download helpers
|
|
101
|
+
// ──────────────────────────────────────────────
|
|
102
|
+
function followRedirects(url, maxRedirects = 5) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
if (maxRedirects <= 0) {
|
|
105
|
+
reject(new Error('Too many redirects'));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const getter = url.startsWith('https') ? httpsGet : httpGet;
|
|
109
|
+
const req = getter(url, {
|
|
110
|
+
headers: { 'User-Agent': 'lpc-forge-cli' },
|
|
111
|
+
}, (res) => {
|
|
112
|
+
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
113
|
+
res.resume(); // drain the response
|
|
114
|
+
followRedirects(res.headers.location, maxRedirects - 1).then(resolve, reject);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
118
|
+
res.resume();
|
|
119
|
+
reject(new Error(`HTTP ${res.statusCode} fetching ${url}`));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
resolve(res);
|
|
123
|
+
});
|
|
124
|
+
req.on('error', reject);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async function downloadToFile(url, destPath, onProgress) {
|
|
128
|
+
const res = await followRedirects(url);
|
|
129
|
+
const total = res.headers['content-length'] ? parseInt(res.headers['content-length'], 10) : null;
|
|
130
|
+
await mkdir(join(destPath, '..'), { recursive: true });
|
|
131
|
+
const tmpPath = destPath + '.tmp';
|
|
132
|
+
const ws = createWriteStream(tmpPath);
|
|
133
|
+
let downloaded = 0;
|
|
134
|
+
res.on('data', (chunk) => {
|
|
135
|
+
downloaded += chunk.length;
|
|
136
|
+
onProgress?.(downloaded, total);
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
await pipeline(res, ws);
|
|
140
|
+
// Atomic rename from tmp to final
|
|
141
|
+
const { rename } = await import('node:fs/promises');
|
|
142
|
+
await rename(tmpPath, destPath);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
// Clean up partial file
|
|
146
|
+
await rm(tmpPath, { force: true });
|
|
147
|
+
throw err;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function computeSha256(filePath) {
|
|
151
|
+
const hash = createHash('sha256');
|
|
152
|
+
const stream = createReadStream(filePath);
|
|
153
|
+
for await (const chunk of stream) {
|
|
154
|
+
hash.update(chunk);
|
|
155
|
+
}
|
|
156
|
+
return hash.digest('hex');
|
|
157
|
+
}
|
|
158
|
+
// ──────────────────────────────────────────────
|
|
159
|
+
// Manifest fetching
|
|
160
|
+
// ──────────────────────────────────────────────
|
|
161
|
+
async function fetchJson(url) {
|
|
162
|
+
const res = await followRedirects(url);
|
|
163
|
+
const chunks = [];
|
|
164
|
+
for await (const chunk of res) {
|
|
165
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
|
|
166
|
+
}
|
|
167
|
+
return JSON.parse(Buffer.concat(chunks).toString('utf-8'));
|
|
168
|
+
}
|
|
169
|
+
/** Fetch the remote asset manifest from the latest GitHub release */
|
|
170
|
+
export async function fetchRemoteManifest(version) {
|
|
171
|
+
const tag = version || 'latest';
|
|
172
|
+
// For 'latest', use the GitHub API to resolve the actual tag
|
|
173
|
+
if (tag === 'latest') {
|
|
174
|
+
const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
|
|
175
|
+
const release = await fetchJson(releaseUrl);
|
|
176
|
+
const manifestAsset = release.assets.find(a => a.name === MANIFEST_FILENAME);
|
|
177
|
+
if (!manifestAsset) {
|
|
178
|
+
throw new Error(`No ${MANIFEST_FILENAME} found in latest release (${release.tag_name}). ` +
|
|
179
|
+
`The release may not have been packaged correctly.`);
|
|
180
|
+
}
|
|
181
|
+
return fetchJson(manifestAsset.browser_download_url);
|
|
182
|
+
}
|
|
183
|
+
const url = `https://github.com/${GITHUB_REPO}/releases/download/${tag}/${MANIFEST_FILENAME}`;
|
|
184
|
+
return fetchJson(url);
|
|
185
|
+
}
|
|
186
|
+
// ──────────────────────────────────────────────
|
|
187
|
+
// Git clone fallback
|
|
188
|
+
// ──────────────────────────────────────────────
|
|
189
|
+
/** Check if git is available on the system */
|
|
190
|
+
async function isGitAvailable() {
|
|
191
|
+
try {
|
|
192
|
+
await execFileAsync('git', ['--version']);
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Fall back to git clone when GitHub Releases are unavailable.
|
|
201
|
+
* Clones the repo to a temp dir, copies needed directories to the asset cache.
|
|
202
|
+
*/
|
|
203
|
+
async function downloadAssetsViaGitClone(assetDir, options = {}) {
|
|
204
|
+
if (!(await isGitAvailable())) {
|
|
205
|
+
throw new Error('Git is required to download LPC assets. Install git and try again.\n' +
|
|
206
|
+
'Alternatively, manually clone:\n' +
|
|
207
|
+
` git clone --depth 1 https://github.com/${GITHUB_REPO}.git\n` +
|
|
208
|
+
' Then set LPC_FORGE_ASSETS=/path/to/cloned/repo');
|
|
209
|
+
}
|
|
210
|
+
const cloneDir = join(tmpdir(), `lpc-forge-clone-${Date.now()}`);
|
|
211
|
+
try {
|
|
212
|
+
await mkdir(assetDir, { recursive: true });
|
|
213
|
+
// Clone (shallow) into temp dir
|
|
214
|
+
await execFileAsync('git', [
|
|
215
|
+
'clone', '--depth', '1',
|
|
216
|
+
`https://github.com/${GITHUB_REPO}.git`,
|
|
217
|
+
cloneDir,
|
|
218
|
+
], { timeout: 600_000 }); // 10 minute timeout
|
|
219
|
+
// Copy needed directories
|
|
220
|
+
if (options.minimal) {
|
|
221
|
+
// Minimal: only sheet_definitions + spritesheets/body
|
|
222
|
+
await cp(join(cloneDir, 'sheet_definitions'), join(assetDir, 'sheet_definitions'), { recursive: true });
|
|
223
|
+
await mkdir(join(assetDir, 'spritesheets'), { recursive: true });
|
|
224
|
+
await cp(join(cloneDir, 'spritesheets', 'body'), join(assetDir, 'spritesheets', 'body'), { recursive: true });
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
await cp(join(cloneDir, 'spritesheets'), join(assetDir, 'spritesheets'), { recursive: true });
|
|
228
|
+
await cp(join(cloneDir, 'sheet_definitions'), join(assetDir, 'sheet_definitions'), { recursive: true });
|
|
229
|
+
}
|
|
230
|
+
// Write local manifest
|
|
231
|
+
const localManifest = {
|
|
232
|
+
version: 'git-clone',
|
|
233
|
+
installedAt: new Date().toISOString(),
|
|
234
|
+
chunks: ['git-clone'],
|
|
235
|
+
};
|
|
236
|
+
await writeFile(join(assetDir, LOCAL_MANIFEST), JSON.stringify(localManifest, null, 2));
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
// Clean up temp clone
|
|
240
|
+
await rm(cloneDir, { recursive: true, force: true });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export async function downloadAssets(options = {}) {
|
|
244
|
+
const assetDir = options.path ? resolve(options.path) : getAssetDir();
|
|
245
|
+
// Check available disk space (best-effort)
|
|
246
|
+
await checkDiskSpace(assetDir);
|
|
247
|
+
// 1. Fetch manifest
|
|
248
|
+
options.onProgress?.({ phase: 'fetching-manifest' });
|
|
249
|
+
let manifest;
|
|
250
|
+
try {
|
|
251
|
+
manifest = await fetchRemoteManifest();
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// GitHub Releases not available — fall back to git clone
|
|
255
|
+
await downloadAssetsViaGitClone(assetDir, options);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
// 2. Filter chunks
|
|
259
|
+
let chunks = manifest.chunks;
|
|
260
|
+
if (options.minimal) {
|
|
261
|
+
chunks = chunks.filter(c => c.required);
|
|
262
|
+
}
|
|
263
|
+
const totalSize = chunks.reduce((s, c) => s + c.size, 0);
|
|
264
|
+
let overallDownloaded = 0;
|
|
265
|
+
// 3. Download and extract each chunk
|
|
266
|
+
await mkdir(assetDir, { recursive: true });
|
|
267
|
+
const downloadedChunks = [];
|
|
268
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
269
|
+
const chunk = chunks[i];
|
|
270
|
+
const archivePath = join(assetDir, chunk.filename);
|
|
271
|
+
// Download
|
|
272
|
+
options.onProgress?.({
|
|
273
|
+
phase: 'downloading',
|
|
274
|
+
currentChunk: chunk.name,
|
|
275
|
+
chunkIndex: i,
|
|
276
|
+
totalChunks: chunks.length,
|
|
277
|
+
bytesDownloaded: 0,
|
|
278
|
+
bytesTotal: chunk.size,
|
|
279
|
+
overallDownloaded,
|
|
280
|
+
overallTotal: totalSize,
|
|
281
|
+
});
|
|
282
|
+
await downloadToFile(chunk.url, archivePath, (downloaded, total) => {
|
|
283
|
+
options.onProgress?.({
|
|
284
|
+
phase: 'downloading',
|
|
285
|
+
currentChunk: chunk.name,
|
|
286
|
+
chunkIndex: i,
|
|
287
|
+
totalChunks: chunks.length,
|
|
288
|
+
bytesDownloaded: downloaded,
|
|
289
|
+
bytesTotal: total ?? chunk.size,
|
|
290
|
+
overallDownloaded: overallDownloaded + downloaded,
|
|
291
|
+
overallTotal: totalSize,
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
overallDownloaded += chunk.size;
|
|
295
|
+
// Verify checksum
|
|
296
|
+
options.onProgress?.({
|
|
297
|
+
phase: 'verifying',
|
|
298
|
+
currentChunk: chunk.name,
|
|
299
|
+
chunkIndex: i,
|
|
300
|
+
totalChunks: chunks.length,
|
|
301
|
+
});
|
|
302
|
+
const actualHash = await computeSha256(archivePath);
|
|
303
|
+
if (actualHash !== chunk.sha256) {
|
|
304
|
+
await rm(archivePath, { force: true });
|
|
305
|
+
throw new Error(`Checksum mismatch for ${chunk.filename}. ` +
|
|
306
|
+
`Expected ${chunk.sha256}, got ${actualHash}. ` +
|
|
307
|
+
`The file may be corrupted — try again.`);
|
|
308
|
+
}
|
|
309
|
+
// Extract
|
|
310
|
+
options.onProgress?.({
|
|
311
|
+
phase: 'extracting',
|
|
312
|
+
currentChunk: chunk.name,
|
|
313
|
+
chunkIndex: i,
|
|
314
|
+
totalChunks: chunks.length,
|
|
315
|
+
});
|
|
316
|
+
await execFileAsync('tar', ['xzf', archivePath, '-C', assetDir]);
|
|
317
|
+
// Remove archive after extraction to save space
|
|
318
|
+
await rm(archivePath, { force: true });
|
|
319
|
+
downloadedChunks.push(chunk.name);
|
|
320
|
+
}
|
|
321
|
+
// 4. Write local manifest
|
|
322
|
+
const localManifest = {
|
|
323
|
+
version: manifest.version,
|
|
324
|
+
installedAt: new Date().toISOString(),
|
|
325
|
+
chunks: downloadedChunks,
|
|
326
|
+
};
|
|
327
|
+
await writeFile(join(assetDir, LOCAL_MANIFEST), JSON.stringify(localManifest, null, 2));
|
|
328
|
+
options.onProgress?.({ phase: 'done' });
|
|
329
|
+
}
|
|
330
|
+
// ──────────────────────────────────────────────
|
|
331
|
+
// Disk space check (best-effort)
|
|
332
|
+
// ──────────────────────────────────────────────
|
|
333
|
+
async function checkDiskSpace(dir) {
|
|
334
|
+
// Ensure parent exists for statvfs
|
|
335
|
+
await mkdir(dir, { recursive: true });
|
|
336
|
+
try {
|
|
337
|
+
// Use df on Unix-like systems
|
|
338
|
+
if (platform() !== 'win32') {
|
|
339
|
+
const { stdout } = await execFileAsync('df', ['-k', dir]);
|
|
340
|
+
const lines = stdout.trim().split('\n');
|
|
341
|
+
if (lines.length >= 2) {
|
|
342
|
+
const parts = lines[1].split(/\s+/);
|
|
343
|
+
const availKB = parseInt(parts[3], 10);
|
|
344
|
+
if (!isNaN(availKB)) {
|
|
345
|
+
const availMB = availKB / 1024;
|
|
346
|
+
if (availMB < 2000) { // Less than 2GB available
|
|
347
|
+
throw new Error(`Insufficient disk space: ${Math.round(availMB)} MB available, ` +
|
|
348
|
+
`but assets require ~1.3 GB. Free up space or use --path to specify a different location.`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
catch (err) {
|
|
355
|
+
// If it's our own insufficient space error, re-throw
|
|
356
|
+
if (err instanceof Error && err.message.includes('Insufficient disk space')) {
|
|
357
|
+
throw err;
|
|
358
|
+
}
|
|
359
|
+
// Otherwise ignore — best-effort check
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// ──────────────────────────────────────────────
|
|
363
|
+
// Clean up
|
|
364
|
+
// ──────────────────────────────────────────────
|
|
365
|
+
export async function cleanAssets(assetDir) {
|
|
366
|
+
const dir = assetDir || getAssetDir();
|
|
367
|
+
if (existsSync(dir)) {
|
|
368
|
+
await rm(dir, { recursive: true, force: true });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
// ──────────────────────────────────────────────
|
|
372
|
+
// Interactive prompt
|
|
373
|
+
// ──────────────────────────────────────────────
|
|
374
|
+
/** Ask user yes/no in the terminal. Returns true for yes. */
|
|
375
|
+
export async function promptYesNo(question) {
|
|
376
|
+
// Non-interactive / CI environments
|
|
377
|
+
if (process.env.LPC_FORGE_AUTO_DOWNLOAD === 'true') {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
if (!process.stdin.isTTY) {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
384
|
+
return new Promise((resolve) => {
|
|
385
|
+
rl.question(question, (answer) => {
|
|
386
|
+
rl.close();
|
|
387
|
+
const a = answer.trim().toLowerCase();
|
|
388
|
+
resolve(a === '' || a === 'y' || a === 'yes');
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
// ──────────────────────────────────────────────
|
|
393
|
+
// Ensure assets (called before sprite commands)
|
|
394
|
+
// ──────────────────────────────────────────────
|
|
395
|
+
/**
|
|
396
|
+
* Ensures assets are available. If missing, prompts the user to download them.
|
|
397
|
+
* Returns the resolved asset root path.
|
|
398
|
+
* Throws if assets are unavailable and user declines download.
|
|
399
|
+
*/
|
|
400
|
+
export async function ensureAssets(packageRoot) {
|
|
401
|
+
const assetRoot = resolveAssetRoot(packageRoot);
|
|
402
|
+
// If we found a local checkout with spritesheets, we're good
|
|
403
|
+
if (existsSync(join(assetRoot, 'spritesheets')) && existsSync(join(assetRoot, 'sheet_definitions'))) {
|
|
404
|
+
return assetRoot;
|
|
405
|
+
}
|
|
406
|
+
// Assets not found — need to download
|
|
407
|
+
const chalk = (await import('chalk')).default;
|
|
408
|
+
console.log('');
|
|
409
|
+
console.log(chalk.yellow('⚠️ LPC Forge assets not found.') + ' These are required for sprite generation.');
|
|
410
|
+
console.log('');
|
|
411
|
+
console.log(` Total download: ${chalk.bold('~1.3 GB')} (305,680 sprite files)`);
|
|
412
|
+
console.log(` Install location: ${chalk.gray(getAssetDir())}`);
|
|
413
|
+
console.log('');
|
|
414
|
+
const proceed = await promptYesNo(` Download now? (Y/n): `);
|
|
415
|
+
if (!proceed) {
|
|
416
|
+
console.log('');
|
|
417
|
+
console.log(chalk.gray(' Run ') + chalk.cyan('lpc-forge setup') + chalk.gray(' when ready to download.'));
|
|
418
|
+
console.log(chalk.gray(' Run ') + chalk.cyan('lpc-forge setup --help') + chalk.gray(' for more options.'));
|
|
419
|
+
console.log('');
|
|
420
|
+
process.exit(1);
|
|
421
|
+
}
|
|
422
|
+
// Download with progress display
|
|
423
|
+
await downloadWithProgress();
|
|
424
|
+
return getAssetDir();
|
|
425
|
+
}
|
|
426
|
+
// ──────────────────────────────────────────────
|
|
427
|
+
// Progress display
|
|
428
|
+
// ──────────────────────────────────────────────
|
|
429
|
+
function formatBytes(bytes) {
|
|
430
|
+
if (bytes < 1024)
|
|
431
|
+
return `${bytes} B`;
|
|
432
|
+
if (bytes < 1024 * 1024)
|
|
433
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
434
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
435
|
+
return `${(bytes / (1024 * 1024)).toFixed(0)} MB`;
|
|
436
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
437
|
+
}
|
|
438
|
+
function progressBar(fraction, width = 20) {
|
|
439
|
+
const filled = Math.round(fraction * width);
|
|
440
|
+
const empty = width - filled;
|
|
441
|
+
return '[' + '#'.repeat(filled) + '-'.repeat(empty) + ']';
|
|
442
|
+
}
|
|
443
|
+
export async function downloadWithProgress(options = {}) {
|
|
444
|
+
const chalk = (await import('chalk')).default;
|
|
445
|
+
const ora = (await import('ora')).default;
|
|
446
|
+
let manifest;
|
|
447
|
+
const manifestSpinner = ora('Fetching asset manifest...').start();
|
|
448
|
+
try {
|
|
449
|
+
manifest = await fetchRemoteManifest();
|
|
450
|
+
manifestSpinner.succeed('Asset manifest fetched');
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
manifestSpinner.text = 'GitHub Releases unavailable, falling back to git clone...';
|
|
454
|
+
try {
|
|
455
|
+
const assetDir = options.path ? resolve(options.path) : getAssetDir();
|
|
456
|
+
manifestSpinner.text = `Downloading assets via git clone (~1.3 GB)...`;
|
|
457
|
+
await downloadAssetsViaGitClone(assetDir, options);
|
|
458
|
+
manifestSpinner.succeed('Assets installed via git clone');
|
|
459
|
+
const finalDir = options.path ? resolve(options.path) : getAssetDir();
|
|
460
|
+
console.log('');
|
|
461
|
+
console.log(chalk.green(`✅ Assets installed → ${finalDir}`));
|
|
462
|
+
console.log('');
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
catch (cloneErr) {
|
|
466
|
+
manifestSpinner.fail('Failed to download assets');
|
|
467
|
+
throw cloneErr;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
let chunks = manifest.chunks;
|
|
471
|
+
if (options.minimal) {
|
|
472
|
+
chunks = chunks.filter(c => c.required);
|
|
473
|
+
}
|
|
474
|
+
const totalSize = chunks.reduce((s, c) => s + c.size, 0);
|
|
475
|
+
const assetDir = options.path ? resolve(options.path) : getAssetDir();
|
|
476
|
+
console.log('');
|
|
477
|
+
console.log(chalk.bold('📦 Downloading LPC Forge assets...'));
|
|
478
|
+
console.log('');
|
|
479
|
+
await mkdir(assetDir, { recursive: true });
|
|
480
|
+
await checkDiskSpace(assetDir);
|
|
481
|
+
const downloadedChunks = [];
|
|
482
|
+
let overallDownloaded = 0;
|
|
483
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
484
|
+
const chunk = chunks[i];
|
|
485
|
+
const archivePath = join(assetDir, chunk.filename);
|
|
486
|
+
// Show which chunk we're downloading
|
|
487
|
+
const spinner = ora({
|
|
488
|
+
text: `${chunk.name} (${formatBytes(chunk.size)})`,
|
|
489
|
+
prefixText: ' ',
|
|
490
|
+
}).start();
|
|
491
|
+
try {
|
|
492
|
+
// Download
|
|
493
|
+
await downloadToFile(chunk.url, archivePath, (downloaded, total) => {
|
|
494
|
+
const t = total ?? chunk.size;
|
|
495
|
+
const pct = Math.round((downloaded / t) * 100);
|
|
496
|
+
spinner.text = `${chunk.name} (${formatBytes(chunk.size)}) ${progressBar(downloaded / t)} ${pct}%`;
|
|
497
|
+
});
|
|
498
|
+
// Verify
|
|
499
|
+
spinner.text = `${chunk.name} — verifying checksum...`;
|
|
500
|
+
const actualHash = await computeSha256(archivePath);
|
|
501
|
+
if (actualHash !== chunk.sha256) {
|
|
502
|
+
await rm(archivePath, { force: true });
|
|
503
|
+
spinner.fail(`${chunk.name} — checksum mismatch`);
|
|
504
|
+
throw new Error(`Checksum mismatch for ${chunk.filename}. ` +
|
|
505
|
+
`Expected ${chunk.sha256}, got ${actualHash}.`);
|
|
506
|
+
}
|
|
507
|
+
// Extract
|
|
508
|
+
spinner.text = `${chunk.name} — extracting...`;
|
|
509
|
+
await execFileAsync('tar', ['xzf', archivePath, '-C', assetDir]);
|
|
510
|
+
await rm(archivePath, { force: true });
|
|
511
|
+
overallDownloaded += chunk.size;
|
|
512
|
+
spinner.succeed(`${chunk.name} (${formatBytes(chunk.size)})`);
|
|
513
|
+
downloadedChunks.push(chunk.name);
|
|
514
|
+
}
|
|
515
|
+
catch (err) {
|
|
516
|
+
spinner.fail(`${chunk.name} — failed`);
|
|
517
|
+
throw err;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// Write local manifest
|
|
521
|
+
const localManifest = {
|
|
522
|
+
version: manifest.version,
|
|
523
|
+
installedAt: new Date().toISOString(),
|
|
524
|
+
chunks: downloadedChunks,
|
|
525
|
+
};
|
|
526
|
+
await writeFile(join(assetDir, LOCAL_MANIFEST), JSON.stringify(localManifest, null, 2));
|
|
527
|
+
console.log('');
|
|
528
|
+
console.log(chalk.green(`✅ Assets installed (${formatBytes(overallDownloaded)}) → ${assetDir}`));
|
|
529
|
+
console.log('');
|
|
530
|
+
}
|
|
531
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/assets/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SFX_PRESETS } from './sfx-presets.js';
|
|
2
|
+
export { generateSfx, generateAllSfx, getPresetsByCategory, listSfxPresets } from './sfx-generator.js';
|
|
3
|
+
export { MUSIC_CATALOG, getMusicByContext, listMusicContexts } from './music-catalog.js';
|
|
4
|
+
export type { SfxPreset, SfxCategory, MusicTrack, SfxGenerationResult, AudioBundle } from './types.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SFX_PRESETS } from './sfx-presets.js';
|
|
2
|
+
export { generateSfx, generateAllSfx, getPresetsByCategory, listSfxPresets } from './sfx-generator.js';
|
|
3
|
+
export { MUSIC_CATALOG, getMusicByContext, listMusicContexts } from './music-catalog.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MusicTrack } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Curated music tracks for RPG games.
|
|
4
|
+
* All tracks are CC0 or CC-BY licensed from OpenGameArt.org.
|
|
5
|
+
* Source files are stored in assets/music/
|
|
6
|
+
*/
|
|
7
|
+
export declare const MUSIC_CATALOG: MusicTrack[];
|
|
8
|
+
/** Get tracks by context */
|
|
9
|
+
export declare function getMusicByContext(context: string): MusicTrack[];
|
|
10
|
+
/** List all music contexts */
|
|
11
|
+
export declare function listMusicContexts(): string[];
|