lpc-forge 1.0.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/CREDITS.csv +22985 -0
- package/LICENSE +674 -0
- package/README.md +281 -0
- package/assets/music/.gitkeep +0 -0
- package/dist/character/batch.d.ts +17 -0
- package/dist/character/batch.js +48 -0
- package/dist/character/batch.js.map +1 -0
- package/dist/character/composer.d.ts +3 -0
- package/dist/character/composer.js +164 -0
- package/dist/character/composer.js.map +1 -0
- package/dist/character/definitions.d.ts +16 -0
- package/dist/character/definitions.js +116 -0
- package/dist/character/definitions.js.map +1 -0
- package/dist/character/presets.d.ts +6 -0
- package/dist/character/presets.js +246 -0
- package/dist/character/presets.js.map +1 -0
- package/dist/character/slicer.d.ts +8 -0
- package/dist/character/slicer.js +66 -0
- package/dist/character/slicer.js.map +1 -0
- package/dist/character/types.d.ts +48 -0
- package/dist/character/types.js +32 -0
- package/dist/character/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +938 -0
- package/dist/export/frames.d.ts +5 -0
- package/dist/export/frames.js +15 -0
- package/dist/export/frames.js.map +1 -0
- package/dist/export/godot.d.ts +17 -0
- package/dist/export/godot.js +464 -0
- package/dist/export/godot.js.map +1 -0
- package/dist/export/types.d.ts +11 -0
- package/dist/export/types.js +2 -0
- package/dist/export/types.js.map +1 -0
- package/dist/license.d.ts +49 -0
- package/dist/license.js +271 -0
- package/dist/map/cellular.d.ts +3 -0
- package/dist/map/cellular.js +191 -0
- package/dist/map/cellular.js.map +1 -0
- package/dist/map/dungeon.d.ts +3 -0
- package/dist/map/dungeon.js +238 -0
- package/dist/map/dungeon.js.map +1 -0
- package/dist/map/multifloor.d.ts +20 -0
- package/dist/map/multifloor.js +57 -0
- package/dist/map/multifloor.js.map +1 -0
- package/dist/map/overworld.d.ts +3 -0
- package/dist/map/overworld.js +205 -0
- package/dist/map/overworld.js.map +1 -0
- package/dist/map/town.d.ts +7 -0
- package/dist/map/town.js +181 -0
- package/dist/map/town.js.map +1 -0
- package/dist/map/types.d.ts +65 -0
- package/dist/map/types.js +16 -0
- package/dist/map/types.js.map +1 -0
- package/dist/map/wfc.d.ts +18 -0
- package/dist/map/wfc.js +192 -0
- package/dist/map/wfc.js.map +1 -0
- package/dist/tileset/atlas.d.ts +15 -0
- package/dist/tileset/atlas.js +55 -0
- package/dist/tileset/atlas.js.map +1 -0
- package/dist/tileset/registry.d.ts +12 -0
- package/dist/tileset/registry.js +71 -0
- package/dist/tileset/registry.js.map +1 -0
- package/dist/tileset/terrain.d.ts +3 -0
- package/dist/tileset/terrain.js +110 -0
- package/dist/tileset/terrain.js.map +1 -0
- package/dist/utils/credits.d.ts +11 -0
- package/dist/utils/credits.js +74 -0
- package/dist/utils/credits.js.map +1 -0
- package/dist/utils/image.d.ts +17 -0
- package/dist/utils/image.js +94 -0
- package/dist/utils/image.js.map +1 -0
- package/dist/utils/rng.d.ts +18 -0
- package/dist/utils/rng.js +48 -0
- package/dist/utils/rng.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { sliceCharacter } from '../character/slicer.js';
|
|
4
|
+
/** Export a spritesheet as individual frame PNGs */
|
|
5
|
+
export async function exportFrames(sheetBuffer, outputDir, options) {
|
|
6
|
+
await mkdir(outputDir, { recursive: true });
|
|
7
|
+
// Save the full spritesheet
|
|
8
|
+
await writeFile(join(outputDir, 'spritesheet.png'), sheetBuffer);
|
|
9
|
+
// Slice into individual frames
|
|
10
|
+
await sliceCharacter(sheetBuffer, outputDir, {
|
|
11
|
+
format: options?.format ?? 'png',
|
|
12
|
+
animations: options?.animations,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=frames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/export/frames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,SAAiB,EACjB,OAA4D;IAE5D,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,4BAA4B;IAC5B,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,WAAW,CAAC,CAAC;IAEjE,+BAA+B;IAC/B,MAAM,cAAc,CAAC,WAAW,EAAE,SAAS,EAAE;QAC3C,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;QAChC,UAAU,EAAE,OAAO,EAAE,UAAU;KAChC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GeneratedMap } from '../map/types.js';
|
|
2
|
+
export interface CharacterExportOptions {
|
|
3
|
+
animationSpeed?: number;
|
|
4
|
+
resPath?: string;
|
|
5
|
+
isPlayer?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Export a character spritesheet as Godot 4.6 resources */
|
|
8
|
+
export declare function exportCharacterToGodot(sheetBuffer: Buffer, outputDir: string, characterName: string, options?: CharacterExportOptions): Promise<void>;
|
|
9
|
+
/** Export a generated map as Godot 4.6 TileMapLayer scene */
|
|
10
|
+
export declare function exportMapToGodot(map: GeneratedMap, outputDir: string, mapName: string, options?: {
|
|
11
|
+
tileSize?: number;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
/** Scaffold a complete Godot 4.6 project */
|
|
14
|
+
export declare function scaffoldGodotProject(outputDir: string, projectName: string, options?: {
|
|
15
|
+
characterName?: string;
|
|
16
|
+
mapName?: string;
|
|
17
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { sliceCharacter } from '../character/slicer.js';
|
|
4
|
+
import { ANIMATIONS, DIRECTIONS, FRAME_SIZE } from '../character/types.js';
|
|
5
|
+
/** Export a character spritesheet as Godot 4.6 resources */
|
|
6
|
+
export async function exportCharacterToGodot(sheetBuffer, outputDir, characterName, options) {
|
|
7
|
+
const speed = options?.animationSpeed ?? 10;
|
|
8
|
+
const resBase = options?.resPath ?? `res://sprites/${characterName}`;
|
|
9
|
+
const isPlayer = options?.isPlayer ?? true;
|
|
10
|
+
const spritesDir = join(outputDir, 'sprites', characterName);
|
|
11
|
+
await mkdir(spritesDir, { recursive: true });
|
|
12
|
+
// Slice into individual frames
|
|
13
|
+
await sliceCharacter(sheetBuffer, spritesDir);
|
|
14
|
+
// Save the full spritesheet too
|
|
15
|
+
await writeFile(join(spritesDir, 'spritesheet.png'), sheetBuffer);
|
|
16
|
+
// Generate .tres SpriteFrames resource
|
|
17
|
+
const tresContent = generateSpriteFramesTres(characterName, resBase, speed);
|
|
18
|
+
await writeFile(join(spritesDir, `${characterName}.tres`), tresContent);
|
|
19
|
+
// Generate .tscn scene with hitbox/hurtbox/timers
|
|
20
|
+
const tscnContent = generateCharacterTscn(characterName, resBase, isPlayer);
|
|
21
|
+
await writeFile(join(outputDir, `${characterName}.tscn`), tscnContent);
|
|
22
|
+
}
|
|
23
|
+
function generateSpriteFramesTres(name, resBase, speed) {
|
|
24
|
+
const lines = [];
|
|
25
|
+
const extResources = [];
|
|
26
|
+
let extId = 1;
|
|
27
|
+
const extIdMap = {};
|
|
28
|
+
// Collect all frame paths and assign ext_resource IDs
|
|
29
|
+
for (const [animName, animInfo] of Object.entries(ANIMATIONS)) {
|
|
30
|
+
const directions = animInfo.rows === 1 ? ['down'] : [...DIRECTIONS];
|
|
31
|
+
for (const dir of directions) {
|
|
32
|
+
for (let f = 0; f < animInfo.frames; f++) {
|
|
33
|
+
const path = `${resBase}/${animName}/${dir}_${f}.png`;
|
|
34
|
+
extIdMap[path] = extId;
|
|
35
|
+
extResources.push(`[ext_resource type="Texture2D" path="${path}" id="${extId}"]`);
|
|
36
|
+
extId++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
lines.push(`[gd_resource type="SpriteFrames" load_steps=${extId} format=3]`);
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push(...extResources);
|
|
43
|
+
lines.push('');
|
|
44
|
+
lines.push('[resource]');
|
|
45
|
+
// Build animations array
|
|
46
|
+
const anims = [];
|
|
47
|
+
for (const [animName, animInfo] of Object.entries(ANIMATIONS)) {
|
|
48
|
+
const directions = animInfo.rows === 1 ? ['down'] : [...DIRECTIONS];
|
|
49
|
+
for (const dir of directions) {
|
|
50
|
+
const gdAnimName = `${animName}_${dir}`;
|
|
51
|
+
const frames = [];
|
|
52
|
+
for (let f = 0; f < animInfo.frames; f++) {
|
|
53
|
+
const path = `${resBase}/${animName}/${dir}_${f}.png`;
|
|
54
|
+
const id = extIdMap[path];
|
|
55
|
+
frames.push(`{
|
|
56
|
+
"duration": 1.0,
|
|
57
|
+
"texture": ExtResource("${id}")
|
|
58
|
+
}`);
|
|
59
|
+
}
|
|
60
|
+
const loop = animName === 'walk' || animName === 'idle' || animName === 'run' || animName === 'combat_idle';
|
|
61
|
+
anims.push(`{
|
|
62
|
+
"frames": [${frames.join(', ')}],
|
|
63
|
+
"loop": ${loop},
|
|
64
|
+
"name": &"${gdAnimName}",
|
|
65
|
+
"speed": ${speed}.0
|
|
66
|
+
}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
lines.push(`animations = [${anims.join(', ')}]`);
|
|
70
|
+
return lines.join('\n');
|
|
71
|
+
}
|
|
72
|
+
function generateCharacterTscn(name, resBase, isPlayer) {
|
|
73
|
+
const loadSteps = isPlayer ? 6 : 4;
|
|
74
|
+
const lines = [];
|
|
75
|
+
lines.push(`[gd_scene load_steps=${loadSteps} format=3]`);
|
|
76
|
+
lines.push('');
|
|
77
|
+
lines.push(`[ext_resource type="SpriteFrames" path="${resBase}/${name}.tres" id="1"]`);
|
|
78
|
+
if (isPlayer) {
|
|
79
|
+
lines.push(`[ext_resource type="Script" path="res://scripts/player.gd" id="2"]`);
|
|
80
|
+
}
|
|
81
|
+
lines.push('');
|
|
82
|
+
// CollisionShape2D for body
|
|
83
|
+
lines.push(`[sub_resource type="RectangleShape2D" id="1"]`);
|
|
84
|
+
lines.push(`size = Vector2(${FRAME_SIZE / 2}, ${FRAME_SIZE / 2})`);
|
|
85
|
+
lines.push('');
|
|
86
|
+
// Hitbox shape
|
|
87
|
+
lines.push(`[sub_resource type="RectangleShape2D" id="2"]`);
|
|
88
|
+
lines.push(`size = Vector2(${FRAME_SIZE / 2}, ${FRAME_SIZE / 2})`);
|
|
89
|
+
lines.push('');
|
|
90
|
+
// Hurtbox shape
|
|
91
|
+
lines.push(`[sub_resource type="RectangleShape2D" id="3"]`);
|
|
92
|
+
lines.push(`size = Vector2(24, 32)`);
|
|
93
|
+
lines.push('');
|
|
94
|
+
// Root node
|
|
95
|
+
lines.push(`[node name="${capitalize(name)}" type="CharacterBody2D"]`);
|
|
96
|
+
if (isPlayer) {
|
|
97
|
+
lines.push(`script = ExtResource("2")`);
|
|
98
|
+
}
|
|
99
|
+
lines.push('');
|
|
100
|
+
// Sprite
|
|
101
|
+
lines.push(`[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]`);
|
|
102
|
+
lines.push(`sprite_frames = ExtResource("1")`);
|
|
103
|
+
lines.push(`animation = &"idle_down"`);
|
|
104
|
+
lines.push(`autoplay = "idle_down"`);
|
|
105
|
+
lines.push(`offset = Vector2(0, -16)`);
|
|
106
|
+
lines.push('');
|
|
107
|
+
// Body collision
|
|
108
|
+
lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="."]`);
|
|
109
|
+
lines.push(`shape = SubResource("1")`);
|
|
110
|
+
lines.push(`position = Vector2(0, 8)`);
|
|
111
|
+
lines.push('');
|
|
112
|
+
// Hitbox Area2D
|
|
113
|
+
lines.push(`[node name="Hitbox" type="Area2D" parent="."]`);
|
|
114
|
+
lines.push(`collision_layer = 2`);
|
|
115
|
+
lines.push(`collision_mask = 0`);
|
|
116
|
+
lines.push(`monitorable = true`);
|
|
117
|
+
lines.push(`monitoring = false`);
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]`);
|
|
120
|
+
lines.push(`shape = SubResource("2")`);
|
|
121
|
+
lines.push(`position = Vector2(16, 0)`);
|
|
122
|
+
lines.push(`disabled = true`);
|
|
123
|
+
lines.push('');
|
|
124
|
+
// Hurtbox Area2D
|
|
125
|
+
lines.push(`[node name="Hurtbox" type="Area2D" parent="."]`);
|
|
126
|
+
lines.push(`collision_layer = 0`);
|
|
127
|
+
lines.push(`collision_mask = 2`);
|
|
128
|
+
lines.push(`monitorable = false`);
|
|
129
|
+
lines.push(`monitoring = true`);
|
|
130
|
+
lines.push('');
|
|
131
|
+
lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"]`);
|
|
132
|
+
lines.push(`shape = SubResource("3")`);
|
|
133
|
+
lines.push('');
|
|
134
|
+
// Timers
|
|
135
|
+
lines.push(`[node name="AttackTimer" type="Timer" parent="."]`);
|
|
136
|
+
lines.push(`wait_time = 0.4`);
|
|
137
|
+
lines.push(`one_shot = true`);
|
|
138
|
+
lines.push('');
|
|
139
|
+
lines.push(`[node name="HurtTimer" type="Timer" parent="."]`);
|
|
140
|
+
lines.push(`wait_time = 0.5`);
|
|
141
|
+
lines.push(`one_shot = true`);
|
|
142
|
+
lines.push('');
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
/** Export a generated map as Godot 4.6 TileMapLayer scene */
|
|
146
|
+
export async function exportMapToGodot(map, outputDir, mapName, options) {
|
|
147
|
+
const tileSize = options?.tileSize ?? 32;
|
|
148
|
+
await mkdir(outputDir, { recursive: true });
|
|
149
|
+
// Generate tileset .tres
|
|
150
|
+
const tilesetContent = generateTilesetTres(tileSize);
|
|
151
|
+
await writeFile(join(outputDir, `${mapName}_tileset.tres`), tilesetContent);
|
|
152
|
+
// Generate map .tscn
|
|
153
|
+
const tscnContent = generateMapTscn(map, mapName, tileSize);
|
|
154
|
+
await writeFile(join(outputDir, `${mapName}.tscn`), tscnContent);
|
|
155
|
+
}
|
|
156
|
+
function generateTilesetTres(tileSize) {
|
|
157
|
+
const lines = [`[gd_resource type="TileSet" format=3]`, '', `[resource]`];
|
|
158
|
+
lines.push(`tile_size = Vector2i(${tileSize}, ${tileSize})`);
|
|
159
|
+
return lines.join('\n');
|
|
160
|
+
}
|
|
161
|
+
function generateMapTscn(map, mapName, tileSize) {
|
|
162
|
+
const lines = [];
|
|
163
|
+
// Count sub resources needed: 1 for tileset ref + 1 collision shape per wall group
|
|
164
|
+
lines.push(`[gd_scene load_steps=2 format=3]`);
|
|
165
|
+
lines.push('');
|
|
166
|
+
lines.push(`[ext_resource type="TileSet" path="res://${mapName}_tileset.tres" id="1"]`);
|
|
167
|
+
lines.push('');
|
|
168
|
+
// Collision shape for walls
|
|
169
|
+
lines.push(`[sub_resource type="RectangleShape2D" id="1"]`);
|
|
170
|
+
lines.push(`size = Vector2(${tileSize}, ${tileSize})`);
|
|
171
|
+
lines.push('');
|
|
172
|
+
lines.push(`[node name="${capitalize(mapName)}" type="Node2D"]`);
|
|
173
|
+
lines.push('');
|
|
174
|
+
// Ground TileMapLayer
|
|
175
|
+
lines.push(`[node name="Ground" type="TileMapLayer" parent="."]`);
|
|
176
|
+
lines.push(`tile_set = ExtResource("1")`);
|
|
177
|
+
lines.push('');
|
|
178
|
+
// Wall collision StaticBody2D with individual CollisionShape2Ds
|
|
179
|
+
lines.push(`[node name="Walls" type="StaticBody2D" parent="."]`);
|
|
180
|
+
lines.push(`collision_layer = 1`);
|
|
181
|
+
lines.push(`collision_mask = 0`);
|
|
182
|
+
lines.push('');
|
|
183
|
+
let wallIdx = 0;
|
|
184
|
+
for (let y = 0; y < map.height; y++) {
|
|
185
|
+
for (let x = 0; x < map.width; x++) {
|
|
186
|
+
const t = map.tiles[y][x];
|
|
187
|
+
// TileType.WALL = 2, TileType.TREE = 7
|
|
188
|
+
if (t === 2 || t === 7) {
|
|
189
|
+
lines.push(`[node name="Wall${wallIdx}" type="CollisionShape2D" parent="Walls"]`);
|
|
190
|
+
lines.push(`position = Vector2(${x * tileSize + tileSize / 2}, ${y * tileSize + tileSize / 2})`);
|
|
191
|
+
lines.push(`shape = SubResource("1")`);
|
|
192
|
+
lines.push('');
|
|
193
|
+
wallIdx++;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Spawn and exit markers
|
|
198
|
+
if (map.spawnPoint) {
|
|
199
|
+
lines.push(`[node name="SpawnPoint" type="Marker2D" parent="."]`);
|
|
200
|
+
lines.push(`position = Vector2(${map.spawnPoint.x * tileSize + tileSize / 2}, ${map.spawnPoint.y * tileSize + tileSize / 2})`);
|
|
201
|
+
lines.push('');
|
|
202
|
+
}
|
|
203
|
+
if (map.exitPoint) {
|
|
204
|
+
lines.push(`[node name="ExitPoint" type="Marker2D" parent="."]`);
|
|
205
|
+
lines.push(`position = Vector2(${map.exitPoint.x * tileSize + tileSize / 2}, ${map.exitPoint.y * tileSize + tileSize / 2})`);
|
|
206
|
+
lines.push('');
|
|
207
|
+
}
|
|
208
|
+
// POI markers
|
|
209
|
+
if (map.pois) {
|
|
210
|
+
for (let i = 0; i < map.pois.length; i++) {
|
|
211
|
+
const poi = map.pois[i];
|
|
212
|
+
const nodeName = `POI_${poi.type}_${i}`;
|
|
213
|
+
lines.push(`[node name="${nodeName}" type="Marker2D" parent="."]`);
|
|
214
|
+
lines.push(`position = Vector2(${poi.x * tileSize + tileSize / 2}, ${poi.y * tileSize + tileSize / 2})`);
|
|
215
|
+
const meta = { poi_type: poi.type };
|
|
216
|
+
if (poi.label)
|
|
217
|
+
meta['poi_label'] = poi.label;
|
|
218
|
+
lines.push(`metadata/poi_type = "${poi.type}"`);
|
|
219
|
+
if (poi.label)
|
|
220
|
+
lines.push(`metadata/poi_label = "${poi.label}"`);
|
|
221
|
+
lines.push('');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return lines.join('\n');
|
|
225
|
+
}
|
|
226
|
+
/** Scaffold a complete Godot 4.6 project */
|
|
227
|
+
export async function scaffoldGodotProject(outputDir, projectName, options) {
|
|
228
|
+
const charName = options?.characterName ?? 'player';
|
|
229
|
+
const mapName = options?.mapName ?? 'dungeon';
|
|
230
|
+
await mkdir(outputDir, { recursive: true });
|
|
231
|
+
// project.godot
|
|
232
|
+
const projectGodot = `; Engine configuration file.
|
|
233
|
+
; It's best edited using the editor UI and not directly,
|
|
234
|
+
; but it can also be edited because it's a plain text file.
|
|
235
|
+
|
|
236
|
+
config_version=5
|
|
237
|
+
|
|
238
|
+
[application]
|
|
239
|
+
|
|
240
|
+
config/name="${projectName}"
|
|
241
|
+
config/features=PackedStringArray("4.6")
|
|
242
|
+
run/main_scene="res://main.tscn"
|
|
243
|
+
config/icon="res://icon.svg"
|
|
244
|
+
|
|
245
|
+
[display]
|
|
246
|
+
|
|
247
|
+
window/size/viewport_width=1280
|
|
248
|
+
window/size/viewport_height=720
|
|
249
|
+
window/stretch/mode="canvas_items"
|
|
250
|
+
|
|
251
|
+
[input]
|
|
252
|
+
|
|
253
|
+
move_up={
|
|
254
|
+
"deadzone": 0.5,
|
|
255
|
+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
|
|
256
|
+
}
|
|
257
|
+
move_down={
|
|
258
|
+
"deadzone": 0.5,
|
|
259
|
+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
|
|
260
|
+
}
|
|
261
|
+
move_left={
|
|
262
|
+
"deadzone": 0.5,
|
|
263
|
+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
|
|
264
|
+
}
|
|
265
|
+
move_right={
|
|
266
|
+
"deadzone": 0.5,
|
|
267
|
+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
|
|
268
|
+
}
|
|
269
|
+
attack={
|
|
270
|
+
"deadzone": 0.5,
|
|
271
|
+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
[rendering]
|
|
275
|
+
|
|
276
|
+
textures/canvas_textures/default_texture_filter=0
|
|
277
|
+
`;
|
|
278
|
+
await writeFile(join(outputDir, 'project.godot'), projectGodot);
|
|
279
|
+
// Main scene — instances map + player at spawn, adds Camera2D and HUD
|
|
280
|
+
const mainTscn = `[gd_scene load_steps=4 format=3]
|
|
281
|
+
|
|
282
|
+
[ext_resource type="PackedScene" path="res://${charName}.tscn" id="1"]
|
|
283
|
+
[ext_resource type="PackedScene" path="res://${mapName}.tscn" id="2"]
|
|
284
|
+
[ext_resource type="Script" path="res://scripts/hud.gd" id="3"]
|
|
285
|
+
|
|
286
|
+
[node name="Main" type="Node2D"]
|
|
287
|
+
|
|
288
|
+
[node name="Map" parent="." instance=ExtResource("2")]
|
|
289
|
+
|
|
290
|
+
[node name="Player" parent="." instance=ExtResource("1")]
|
|
291
|
+
position = Vector2(400, 400)
|
|
292
|
+
|
|
293
|
+
[node name="Camera2D" type="Camera2D" parent="Player"]
|
|
294
|
+
zoom = Vector2(2, 2)
|
|
295
|
+
|
|
296
|
+
[node name="HUD" type="CanvasLayer" parent="."]
|
|
297
|
+
|
|
298
|
+
[node name="HUDControl" type="Control" parent="HUD"]
|
|
299
|
+
layout_mode = 3
|
|
300
|
+
anchors_preset = 15
|
|
301
|
+
anchor_right = 1.0
|
|
302
|
+
anchor_bottom = 1.0
|
|
303
|
+
script = ExtResource("3")
|
|
304
|
+
|
|
305
|
+
[node name="HealthBar" type="ProgressBar" parent="HUD/HUDControl"]
|
|
306
|
+
layout_mode = 1
|
|
307
|
+
offset_left = 16.0
|
|
308
|
+
offset_top = 16.0
|
|
309
|
+
offset_right = 216.0
|
|
310
|
+
offset_bottom = 32.0
|
|
311
|
+
value = 100.0
|
|
312
|
+
show_percentage = false
|
|
313
|
+
`;
|
|
314
|
+
await writeFile(join(outputDir, 'main.tscn'), mainTscn);
|
|
315
|
+
// Scripts directory
|
|
316
|
+
const scriptsDir = join(outputDir, 'scripts');
|
|
317
|
+
await mkdir(scriptsDir, { recursive: true });
|
|
318
|
+
// State machine player script
|
|
319
|
+
const playerGd = `extends CharacterBody2D
|
|
320
|
+
|
|
321
|
+
signal health_changed(new_health: int, max_health: int)
|
|
322
|
+
signal died
|
|
323
|
+
|
|
324
|
+
enum State { IDLE, WALK, ATTACK, HURT, DEATH }
|
|
325
|
+
|
|
326
|
+
const SPEED := 200.0
|
|
327
|
+
const MAX_HEALTH := 100
|
|
328
|
+
|
|
329
|
+
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
|
|
330
|
+
@onready var attack_timer: Timer = $AttackTimer
|
|
331
|
+
@onready var hurt_timer: Timer = $HurtTimer
|
|
332
|
+
@onready var hitbox: Area2D = $Hitbox
|
|
333
|
+
|
|
334
|
+
var state: State = State.IDLE
|
|
335
|
+
var direction := "down"
|
|
336
|
+
var health: int = MAX_HEALTH
|
|
337
|
+
|
|
338
|
+
func _ready() -> void:
|
|
339
|
+
\tattack_timer.timeout.connect(_on_attack_finished)
|
|
340
|
+
\thurt_timer.timeout.connect(_on_hurt_finished)
|
|
341
|
+
\thealth_changed.emit(health, MAX_HEALTH)
|
|
342
|
+
|
|
343
|
+
func _physics_process(_delta: float) -> void:
|
|
344
|
+
\tmatch state:
|
|
345
|
+
\t\tState.IDLE:
|
|
346
|
+
\t\t\t_process_idle()
|
|
347
|
+
\t\tState.WALK:
|
|
348
|
+
\t\t\t_process_walk()
|
|
349
|
+
\t\tState.ATTACK:
|
|
350
|
+
\t\t\tpass
|
|
351
|
+
\t\tState.HURT:
|
|
352
|
+
\t\t\tpass
|
|
353
|
+
\t\tState.DEATH:
|
|
354
|
+
\t\t\tpass
|
|
355
|
+
|
|
356
|
+
func _process_idle() -> void:
|
|
357
|
+
\tvar input_dir := _get_input()
|
|
358
|
+
\tif input_dir != Vector2.ZERO:
|
|
359
|
+
\t\t_set_direction(input_dir)
|
|
360
|
+
\t\t_change_state(State.WALK)
|
|
361
|
+
\t\treturn
|
|
362
|
+
\tif Input.is_action_just_pressed("attack"):
|
|
363
|
+
\t\t_change_state(State.ATTACK)
|
|
364
|
+
\t\treturn
|
|
365
|
+
\tsprite.play("idle_" + direction)
|
|
366
|
+
|
|
367
|
+
func _process_walk() -> void:
|
|
368
|
+
\tvar input_dir := _get_input()
|
|
369
|
+
\tif input_dir == Vector2.ZERO:
|
|
370
|
+
\t\t_change_state(State.IDLE)
|
|
371
|
+
\t\treturn
|
|
372
|
+
\tif Input.is_action_just_pressed("attack"):
|
|
373
|
+
\t\t_change_state(State.ATTACK)
|
|
374
|
+
\t\treturn
|
|
375
|
+
\t_set_direction(input_dir)
|
|
376
|
+
\tvelocity = input_dir * SPEED
|
|
377
|
+
\tsprite.play("walk_" + direction)
|
|
378
|
+
\tmove_and_slide()
|
|
379
|
+
|
|
380
|
+
func _change_state(new_state: State) -> void:
|
|
381
|
+
\tstate = new_state
|
|
382
|
+
\tmatch new_state:
|
|
383
|
+
\t\tState.ATTACK:
|
|
384
|
+
\t\t\tvelocity = Vector2.ZERO
|
|
385
|
+
\t\t\tvar anim := "slash_" + direction
|
|
386
|
+
\t\t\tif sprite.sprite_frames.has_animation(anim):
|
|
387
|
+
\t\t\t\tsprite.play(anim)
|
|
388
|
+
\t\t\thitbox.get_child(0).disabled = false
|
|
389
|
+
\t\t\tattack_timer.start()
|
|
390
|
+
\t\tState.HURT:
|
|
391
|
+
\t\t\tvelocity = Vector2.ZERO
|
|
392
|
+
\t\t\tvar anim := "hurt"
|
|
393
|
+
\t\t\tif sprite.sprite_frames.has_animation("hurt_down"):
|
|
394
|
+
\t\t\t\tanim = "hurt_down"
|
|
395
|
+
\t\t\tsprite.play(anim)
|
|
396
|
+
\t\t\thurt_timer.start()
|
|
397
|
+
\t\tState.DEATH:
|
|
398
|
+
\t\t\tvelocity = Vector2.ZERO
|
|
399
|
+
\t\t\tset_physics_process(false)
|
|
400
|
+
\t\t\tdied.emit()
|
|
401
|
+
\t\t_:
|
|
402
|
+
\t\t\tpass
|
|
403
|
+
|
|
404
|
+
func take_damage(amount: int) -> void:
|
|
405
|
+
\tif state == State.DEATH or state == State.HURT:
|
|
406
|
+
\t\treturn
|
|
407
|
+
\thealth = max(0, health - amount)
|
|
408
|
+
\thealth_changed.emit(health, MAX_HEALTH)
|
|
409
|
+
\tif health <= 0:
|
|
410
|
+
\t\t_change_state(State.DEATH)
|
|
411
|
+
\telse:
|
|
412
|
+
\t\t_change_state(State.HURT)
|
|
413
|
+
|
|
414
|
+
func _on_attack_finished() -> void:
|
|
415
|
+
\thitbox.get_child(0).disabled = true
|
|
416
|
+
\t_change_state(State.IDLE)
|
|
417
|
+
|
|
418
|
+
func _on_hurt_finished() -> void:
|
|
419
|
+
\t_change_state(State.IDLE)
|
|
420
|
+
|
|
421
|
+
func _get_input() -> Vector2:
|
|
422
|
+
\treturn Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
|
|
423
|
+
|
|
424
|
+
func _set_direction(input_dir: Vector2) -> void:
|
|
425
|
+
\tif abs(input_dir.x) > abs(input_dir.y):
|
|
426
|
+
\t\tdirection = "right" if input_dir.x > 0 else "left"
|
|
427
|
+
\telse:
|
|
428
|
+
\t\tdirection = "down" if input_dir.y > 0 else "up"
|
|
429
|
+
`;
|
|
430
|
+
await writeFile(join(scriptsDir, 'player.gd'), playerGd);
|
|
431
|
+
// HUD script
|
|
432
|
+
const hudGd = `extends Control
|
|
433
|
+
|
|
434
|
+
@onready var health_bar: ProgressBar = $HealthBar
|
|
435
|
+
|
|
436
|
+
func _ready() -> void:
|
|
437
|
+
\tvar player := _find_player()
|
|
438
|
+
\tif player:
|
|
439
|
+
\t\tplayer.health_changed.connect(_on_health_changed)
|
|
440
|
+
|
|
441
|
+
func _on_health_changed(new_health: int, max_health: int) -> void:
|
|
442
|
+
\thealth_bar.max_value = max_health
|
|
443
|
+
\thealth_bar.value = new_health
|
|
444
|
+
|
|
445
|
+
func _find_player() -> CharacterBody2D:
|
|
446
|
+
\tvar parent := get_tree().current_scene
|
|
447
|
+
\tif parent:
|
|
448
|
+
\t\tvar player := parent.find_child("Player", true, false)
|
|
449
|
+
\t\tif player is CharacterBody2D:
|
|
450
|
+
\t\t\treturn player as CharacterBody2D
|
|
451
|
+
\treturn null
|
|
452
|
+
`;
|
|
453
|
+
await writeFile(join(scriptsDir, 'hud.gd'), hudGd);
|
|
454
|
+
// Simple SVG icon
|
|
455
|
+
const iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">
|
|
456
|
+
<rect width="128" height="128" rx="16" fill="#478cbf"/>
|
|
457
|
+
<text x="64" y="80" text-anchor="middle" font-size="48" fill="white" font-family="sans-serif">LPC</text>
|
|
458
|
+
</svg>`;
|
|
459
|
+
await writeFile(join(outputDir, 'icon.svg'), iconSvg);
|
|
460
|
+
}
|
|
461
|
+
function capitalize(s) {
|
|
462
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=godot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"godot.js","sourceRoot":"","sources":["../../src/export/godot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/export/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface LicenseInfo {
|
|
2
|
+
/** The license key from Gumroad */
|
|
3
|
+
key: string;
|
|
4
|
+
/** Email from purchase */
|
|
5
|
+
email: string;
|
|
6
|
+
/** Product identifier */
|
|
7
|
+
product: string;
|
|
8
|
+
/** ISO timestamp of activation */
|
|
9
|
+
activatedAt: string;
|
|
10
|
+
/** ISO timestamp of last successful verification */
|
|
11
|
+
lastVerifiedAt: string;
|
|
12
|
+
/** Machine fingerprint at activation time */
|
|
13
|
+
machineId: string;
|
|
14
|
+
/** HMAC signature of the license data */
|
|
15
|
+
signature: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if a valid premium license exists.
|
|
19
|
+
*
|
|
20
|
+
* Validates:
|
|
21
|
+
* 1. File exists and parses
|
|
22
|
+
* 2. HMAC signature is correct (not tampered)
|
|
23
|
+
* 3. Machine fingerprint matches (not copied from another machine)
|
|
24
|
+
* 4. Key format is valid
|
|
25
|
+
* 5. Activation is not absurdly far in the future
|
|
26
|
+
*
|
|
27
|
+
* Periodic re-validation:
|
|
28
|
+
* - If last online verification was > 30 days ago, attempts re-verify
|
|
29
|
+
* - If re-verify fails due to network, still valid (grace period)
|
|
30
|
+
* - If re-verify fails due to invalid key, invalidates
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasValidLicense(): Promise<boolean>;
|
|
33
|
+
/** Require a valid license or exit with purchase instructions */
|
|
34
|
+
export declare function requireLicense(commandName: string): Promise<void>;
|
|
35
|
+
/** Get stored license info (for display only) */
|
|
36
|
+
export declare function getLicenseInfo(): Promise<{
|
|
37
|
+
key: string;
|
|
38
|
+
email: string;
|
|
39
|
+
activatedAt: string;
|
|
40
|
+
lastVerifiedAt: string;
|
|
41
|
+
valid: boolean;
|
|
42
|
+
} | null>;
|
|
43
|
+
/** Activate a license key */
|
|
44
|
+
export declare function activateLicense(licenseKey: string): Promise<{
|
|
45
|
+
success: boolean;
|
|
46
|
+
message: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** Deactivate the stored license */
|
|
49
|
+
export declare function deactivateLicense(): Promise<void>;
|