clibuddy 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/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/adventure/adventureUI.d.ts +24 -0
- package/dist/adventure/adventureUI.js +290 -0
- package/dist/adventure/adventures.d.ts +4 -0
- package/dist/adventure/adventures.js +206 -0
- package/dist/adventure/biomes.d.ts +30 -0
- package/dist/adventure/biomes.js +80 -0
- package/dist/adventure/combat/combat.d.ts +14 -0
- package/dist/adventure/combat/combat.js +638 -0
- package/dist/adventure/combat/combatUI.d.ts +5 -0
- package/dist/adventure/combat/combatUI.js +116 -0
- package/dist/adventure/combat/conditions.d.ts +20 -0
- package/dist/adventure/combat/conditions.js +111 -0
- package/dist/adventure/combat/enemies.d.ts +4 -0
- package/dist/adventure/combat/enemies.js +430 -0
- package/dist/adventure/combat/gear.d.ts +3 -0
- package/dist/adventure/combat/gear.js +199 -0
- package/dist/adventure/combat/skills.d.ts +6 -0
- package/dist/adventure/combat/skills.js +197 -0
- package/dist/adventure/combat.d.ts +31 -0
- package/dist/adventure/combat.js +732 -0
- package/dist/adventure/combatUI.d.ts +5 -0
- package/dist/adventure/combatUI.js +116 -0
- package/dist/adventure/endless.d.ts +18 -0
- package/dist/adventure/endless.js +154 -0
- package/dist/adventure/enemies.d.ts +4 -0
- package/dist/adventure/enemies.js +320 -0
- package/dist/adventure/engine.d.ts +20 -0
- package/dist/adventure/engine.js +137 -0
- package/dist/adventure/gear.d.ts +3 -0
- package/dist/adventure/gear.js +149 -0
- package/dist/adventure/generation/biomes.d.ts +30 -0
- package/dist/adventure/generation/biomes.js +102 -0
- package/dist/adventure/generation/endless.d.ts +18 -0
- package/dist/adventure/generation/endless.js +154 -0
- package/dist/adventure/generation/generator.d.ts +9 -0
- package/dist/adventure/generation/generator.js +245 -0
- package/dist/adventure/generation/templates.d.ts +25 -0
- package/dist/adventure/generation/templates.js +228 -0
- package/dist/adventure/generator.d.ts +9 -0
- package/dist/adventure/generator.js +245 -0
- package/dist/adventure/skills.d.ts +6 -0
- package/dist/adventure/skills.js +197 -0
- package/dist/adventure/templates.d.ts +25 -0
- package/dist/adventure/templates.js +228 -0
- package/dist/adventure/types.d.ts +236 -0
- package/dist/adventure/types.js +97 -0
- package/dist/app/state.d.ts +49 -0
- package/dist/app/state.js +51 -0
- package/dist/buddy/activities.d.ts +16 -0
- package/dist/buddy/activities.js +90 -0
- package/dist/buddy/decay.d.ts +3 -0
- package/dist/buddy/decay.js +45 -0
- package/dist/buddy/leveling.d.ts +11 -0
- package/dist/buddy/leveling.js +25 -0
- package/dist/buddy/roll.d.ts +4 -0
- package/dist/buddy/roll.js +61 -0
- package/dist/buddy/species.d.ts +4 -0
- package/dist/buddy/species.js +592 -0
- package/dist/buddy/titles.d.ts +17 -0
- package/dist/buddy/titles.js +89 -0
- package/dist/buddy/types.d.ts +92 -0
- package/dist/buddy/types.js +21 -0
- package/dist/commands/actions.d.ts +2 -0
- package/dist/commands/actions.js +141 -0
- package/dist/commands/admin.d.ts +2 -0
- package/dist/commands/admin.js +202 -0
- package/dist/commands/registry.d.ts +25 -0
- package/dist/commands/registry.js +31 -0
- package/dist/commands/social.d.ts +2 -0
- package/dist/commands/social.js +92 -0
- package/dist/dialogue/engine.d.ts +7 -0
- package/dist/dialogue/engine.js +68 -0
- package/dist/dialogue/lines.d.ts +26 -0
- package/dist/dialogue/lines.js +294 -0
- package/dist/events/engine.d.ts +20 -0
- package/dist/events/engine.js +51 -0
- package/dist/events/events.d.ts +13 -0
- package/dist/events/events.js +149 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1665 -0
- package/dist/inventory/finding.d.ts +11 -0
- package/dist/inventory/finding.js +99 -0
- package/dist/inventory/items.d.ts +31 -0
- package/dist/inventory/items.js +63 -0
- package/dist/minigames/copycat.d.ts +2 -0
- package/dist/minigames/copycat.js +153 -0
- package/dist/minigames/fetch.d.ts +2 -0
- package/dist/minigames/fetch.js +179 -0
- package/dist/minigames/moodmatch.d.ts +2 -0
- package/dist/minigames/moodmatch.js +144 -0
- package/dist/minigames/quickpaws.d.ts +2 -0
- package/dist/minigames/quickpaws.js +142 -0
- package/dist/minigames/registry.d.ts +5 -0
- package/dist/minigames/registry.js +16 -0
- package/dist/minigames/rpsplus.d.ts +2 -0
- package/dist/minigames/rpsplus.js +168 -0
- package/dist/minigames/treasurehunt.d.ts +2 -0
- package/dist/minigames/treasurehunt.js +146 -0
- package/dist/minigames/types.d.ts +30 -0
- package/dist/minigames/types.js +69 -0
- package/dist/rendering/commandPalette.d.ts +16 -0
- package/dist/rendering/commandPalette.js +77 -0
- package/dist/rendering/display.d.ts +9 -0
- package/dist/rendering/display.js +231 -0
- package/dist/rendering/inventoryUI.d.ts +14 -0
- package/dist/rendering/inventoryUI.js +99 -0
- package/dist/rendering/items.d.ts +7 -0
- package/dist/rendering/items.js +34 -0
- package/dist/rendering/listUtils.d.ts +3 -0
- package/dist/rendering/listUtils.js +24 -0
- package/dist/rendering/minigameUI.d.ts +11 -0
- package/dist/rendering/minigameUI.js +37 -0
- package/dist/rendering/overlayUI.d.ts +24 -0
- package/dist/rendering/overlayUI.js +184 -0
- package/dist/rendering/scene.d.ts +8 -0
- package/dist/rendering/scene.js +87 -0
- package/dist/rendering/screen.d.ts +43 -0
- package/dist/rendering/screen.js +97 -0
- package/dist/sound/sound.d.ts +11 -0
- package/dist/sound/sound.js +55 -0
- package/dist/state/save.d.ts +5 -0
- package/dist/state/save.js +100 -0
- package/dist/state/settings.d.ts +7 -0
- package/dist/state/settings.js +81 -0
- package/dist/story/mainStory.d.ts +4 -0
- package/dist/story/mainStory.js +3111 -0
- package/dist/story/npcs.d.ts +17 -0
- package/dist/story/npcs.js +137 -0
- package/dist/story/progress.d.ts +26 -0
- package/dist/story/progress.js +168 -0
- package/dist/story/seasonal.d.ts +6 -0
- package/dist/story/seasonal.js +96 -0
- package/dist/story/shop.d.ts +7 -0
- package/dist/story/shop.js +26 -0
- package/dist/story/sideQuests.d.ts +4 -0
- package/dist/story/sideQuests.js +151 -0
- package/dist/story/types.d.ts +61 -0
- package/dist/story/types.js +36 -0
- package/dist/updates.d.ts +23 -0
- package/dist/updates.js +142 -0
- package/package.json +53 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateExpedition = generateExpedition;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const biomes_1 = require("./biomes");
|
|
6
|
+
const enemies_1 = require("./enemies");
|
|
7
|
+
const templates_1 = require("./templates");
|
|
8
|
+
function pick(arr) {
|
|
9
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
10
|
+
}
|
|
11
|
+
let idCounter = 0;
|
|
12
|
+
function nextId(prefix) {
|
|
13
|
+
return `${prefix}_${++idCounter}`;
|
|
14
|
+
}
|
|
15
|
+
// ─── Difficulty Scaling ──────────────────────────────────────
|
|
16
|
+
function getRoomCount(difficulty) {
|
|
17
|
+
if (difficulty <= 2)
|
|
18
|
+
return 3 + Math.floor(Math.random() * 2); // 3-4
|
|
19
|
+
if (difficulty <= 4)
|
|
20
|
+
return 4 + Math.floor(Math.random() * 2); // 4-5
|
|
21
|
+
if (difficulty <= 6)
|
|
22
|
+
return 5 + Math.floor(Math.random() * 2); // 5-6
|
|
23
|
+
if (difficulty <= 8)
|
|
24
|
+
return 6 + Math.floor(Math.random() * 2); // 6-7
|
|
25
|
+
return 7 + Math.floor(Math.random() * 2); // 7-8
|
|
26
|
+
}
|
|
27
|
+
function getEnemyTier(difficulty) {
|
|
28
|
+
if (difficulty <= 2)
|
|
29
|
+
return "easy";
|
|
30
|
+
if (difficulty <= 5)
|
|
31
|
+
return "medium";
|
|
32
|
+
return "hard";
|
|
33
|
+
}
|
|
34
|
+
function hasBoss(difficulty) {
|
|
35
|
+
return difficulty >= 5;
|
|
36
|
+
}
|
|
37
|
+
function getStatMultiplier(difficulty) {
|
|
38
|
+
return 1 + difficulty * 0.15;
|
|
39
|
+
}
|
|
40
|
+
function getLootTier(difficulty) {
|
|
41
|
+
if (difficulty <= 2)
|
|
42
|
+
return pick(["common", "uncommon"]);
|
|
43
|
+
if (difficulty <= 5)
|
|
44
|
+
return pick(["uncommon", "rare"]);
|
|
45
|
+
if (difficulty <= 8)
|
|
46
|
+
return pick(["rare", "epic"]);
|
|
47
|
+
return "epic";
|
|
48
|
+
}
|
|
49
|
+
function getEnergyCost(difficulty) {
|
|
50
|
+
return 10 + difficulty * 3;
|
|
51
|
+
}
|
|
52
|
+
function getHungerCost(difficulty) {
|
|
53
|
+
return 5 + difficulty * 2;
|
|
54
|
+
}
|
|
55
|
+
function getLevelRequired(difficulty) {
|
|
56
|
+
return Math.max(1, (difficulty - 1) * 2);
|
|
57
|
+
}
|
|
58
|
+
// ─── Scaled Enemy Creation ───────────────────────────────────
|
|
59
|
+
function pickScaledEnemy(biome, difficulty) {
|
|
60
|
+
const tier = getEnemyTier(difficulty);
|
|
61
|
+
const pool = biome.enemies[tier];
|
|
62
|
+
if (pool.length === 0)
|
|
63
|
+
return biome.enemies.easy[0]; // fallback
|
|
64
|
+
return pick(pool);
|
|
65
|
+
}
|
|
66
|
+
function pickBoss(biome) {
|
|
67
|
+
return pick(biome.enemies.boss);
|
|
68
|
+
}
|
|
69
|
+
// ─── Room Type Distribution ──────────────────────────────────
|
|
70
|
+
function pickRoomTypes(count, hasBossRoom) {
|
|
71
|
+
// First room is always narrative, last is boss (if applicable) or combat
|
|
72
|
+
const types = ["narrative"];
|
|
73
|
+
const middleCount = count - (hasBossRoom ? 2 : 1); // subtract entry + boss
|
|
74
|
+
const pool = [];
|
|
75
|
+
// Ensure at least one combat
|
|
76
|
+
pool.push("combat");
|
|
77
|
+
// Fill rest with weighted random
|
|
78
|
+
for (let i = 1; i < middleCount; i++) {
|
|
79
|
+
const roll = Math.random();
|
|
80
|
+
if (roll < 0.35)
|
|
81
|
+
pool.push("combat");
|
|
82
|
+
else if (roll < 0.55)
|
|
83
|
+
pool.push("narrative");
|
|
84
|
+
else if (roll < 0.70)
|
|
85
|
+
pool.push("treasure");
|
|
86
|
+
else if (roll < 0.85)
|
|
87
|
+
pool.push("event");
|
|
88
|
+
else
|
|
89
|
+
pool.push("rest");
|
|
90
|
+
}
|
|
91
|
+
// Shuffle middle rooms
|
|
92
|
+
for (let i = pool.length - 1; i > 0; i--) {
|
|
93
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
94
|
+
[pool[i], pool[j]] = [pool[j], pool[i]];
|
|
95
|
+
}
|
|
96
|
+
types.push(...pool);
|
|
97
|
+
if (hasBossRoom) {
|
|
98
|
+
types.push("boss");
|
|
99
|
+
}
|
|
100
|
+
return types;
|
|
101
|
+
}
|
|
102
|
+
// ─── Main Generator ──────────────────────────────────────────
|
|
103
|
+
function generateExpedition(config) {
|
|
104
|
+
idCounter = 0;
|
|
105
|
+
const biome = (0, biomes_1.getBiome)(config.biomeId);
|
|
106
|
+
const { difficulty, buddyState } = config;
|
|
107
|
+
const roomCount = getRoomCount(difficulty);
|
|
108
|
+
const bossRoom = hasBoss(difficulty);
|
|
109
|
+
const roomTypes = pickRoomTypes(roomCount, bossRoom);
|
|
110
|
+
const rooms = [];
|
|
111
|
+
// Build rooms
|
|
112
|
+
for (let i = 0; i < roomTypes.length; i++) {
|
|
113
|
+
const type = roomTypes[i];
|
|
114
|
+
const roomId = nextId(type);
|
|
115
|
+
const isLast = i === roomTypes.length - 1;
|
|
116
|
+
// Next room ID (linear chain for now, narrative rooms get branching)
|
|
117
|
+
const nextRoomId = isLast ? undefined : undefined; // will be wired below
|
|
118
|
+
const room = buildRoom(type, roomId, biome, difficulty, buddyState);
|
|
119
|
+
rooms.push(room);
|
|
120
|
+
}
|
|
121
|
+
// Wire linear next-room chain
|
|
122
|
+
for (let i = 0; i < rooms.length - 1; i++) {
|
|
123
|
+
if (rooms[i].type === "narrative" && !rooms[i].choices) {
|
|
124
|
+
rooms[i].nextRoomId = rooms[i + 1].id;
|
|
125
|
+
}
|
|
126
|
+
else if (rooms[i].type !== "narrative") {
|
|
127
|
+
rooms[i].nextRoomId = rooms[i + 1].id;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// First room (narrative) gets branching choices
|
|
131
|
+
if (rooms.length >= 3 && rooms[0].type === "narrative") {
|
|
132
|
+
// Entry branches to rooms[1] and rooms[2], both converge later
|
|
133
|
+
const entryRoom = rooms[0];
|
|
134
|
+
const pathA = rooms[1];
|
|
135
|
+
const pathB = rooms.length > 2 ? rooms[2] : rooms[1];
|
|
136
|
+
const labels = (0, templates_1.generateChoiceLabels)(biome);
|
|
137
|
+
entryRoom.choices = [
|
|
138
|
+
{ label: labels[0], nextRoomId: pathA.id },
|
|
139
|
+
{ label: labels[1], nextRoomId: pathB.id },
|
|
140
|
+
];
|
|
141
|
+
entryRoom.nextRoomId = undefined; // choices handle navigation
|
|
142
|
+
// Both paths converge at room[3] (or the next available room after the two paths)
|
|
143
|
+
if (rooms.length > 3) {
|
|
144
|
+
pathA.nextRoomId = rooms[3].id;
|
|
145
|
+
pathB.nextRoomId = rooms[3].id;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Optionally add hidden room for matching species
|
|
149
|
+
if (Math.random() < 0.4 && biome.comfortSpecies.includes(buddyState.speciesId)) {
|
|
150
|
+
const hiddenId = nextId("hidden");
|
|
151
|
+
const convergeTo = rooms.length > 3 ? rooms[rooms.length - 2].id : rooms[rooms.length - 1].id;
|
|
152
|
+
const hiddenRoom = {
|
|
153
|
+
id: hiddenId,
|
|
154
|
+
type: "treasure",
|
|
155
|
+
title: "Secret Chamber",
|
|
156
|
+
text: (0, templates_1.generateHiddenRoomText)(biome, buddyState.speciesId),
|
|
157
|
+
buddyLine: "I knew I sensed something special here!",
|
|
158
|
+
nextRoomId: convergeTo,
|
|
159
|
+
lootPool: biome.loot.rare.concat(biome.loot.epic),
|
|
160
|
+
condition: { type: "species", value: buddyState.speciesId },
|
|
161
|
+
};
|
|
162
|
+
rooms.push(hiddenRoom);
|
|
163
|
+
// Add hidden room as a third choice on entry
|
|
164
|
+
if (rooms[0].choices) {
|
|
165
|
+
const speciesName = buddyState.speciesId.charAt(0).toUpperCase() + buddyState.speciesId.slice(1);
|
|
166
|
+
rooms[0].choices.push({
|
|
167
|
+
label: `[${speciesName}] Sniff out a hidden path`,
|
|
168
|
+
nextRoomId: hiddenId,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const completionXp = Math.round(15 * difficulty * roomCount * 0.3);
|
|
173
|
+
return {
|
|
174
|
+
id: `expedition_${Date.now()}`,
|
|
175
|
+
name: `${biome.name} Expedition`,
|
|
176
|
+
description: `Difficulty ${difficulty} — ${roomCount} rooms`,
|
|
177
|
+
difficulty,
|
|
178
|
+
levelRequired: getLevelRequired(difficulty),
|
|
179
|
+
energyCost: getEnergyCost(difficulty),
|
|
180
|
+
hungerCost: getHungerCost(difficulty),
|
|
181
|
+
rooms,
|
|
182
|
+
roomMap: (0, types_1.buildRoomMap)(rooms),
|
|
183
|
+
startRoomId: rooms[0].id,
|
|
184
|
+
completionXp,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// ─── Room Builder ────────────────────────────────────────────
|
|
188
|
+
function buildRoom(type, id, biome, difficulty, buddyState) {
|
|
189
|
+
const buddyLine = (0, templates_1.generateBuddyLine)(buddyState.speciesId, biome);
|
|
190
|
+
switch (type) {
|
|
191
|
+
case "narrative":
|
|
192
|
+
return {
|
|
193
|
+
id, type, title: (0, templates_1.generateNarrativeTitle)(biome),
|
|
194
|
+
text: (0, templates_1.generateNarrativeText)(biome), buddyLine,
|
|
195
|
+
// choices wired later
|
|
196
|
+
};
|
|
197
|
+
case "combat": {
|
|
198
|
+
const enemyId = pickScaledEnemy(biome, difficulty);
|
|
199
|
+
const enemy = enemies_1.ENEMIES[enemyId];
|
|
200
|
+
return {
|
|
201
|
+
id, type, title: (0, templates_1.generateCombatTitle)(biome),
|
|
202
|
+
text: (0, templates_1.generateCombatText)(biome, enemy?.name ?? "creature"), buddyLine,
|
|
203
|
+
enemyId,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
case "boss": {
|
|
207
|
+
const bossId = pickBoss(biome);
|
|
208
|
+
const boss = enemies_1.ENEMIES[bossId];
|
|
209
|
+
return {
|
|
210
|
+
id, type, title: `${boss?.name ?? "Boss"}'s Lair`,
|
|
211
|
+
text: (0, templates_1.generateBossText)(biome, boss?.name ?? "The Boss"), buddyLine: "Here it comes... STAY STRONG!",
|
|
212
|
+
enemyId: bossId,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
case "treasure": {
|
|
216
|
+
const tier = getLootTier(difficulty);
|
|
217
|
+
return {
|
|
218
|
+
id, type, title: "Hidden Stash",
|
|
219
|
+
text: (0, templates_1.generateTreasureText)(biome), buddyLine,
|
|
220
|
+
lootPool: biome.loot[tier],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
case "rest":
|
|
224
|
+
return {
|
|
225
|
+
id, type, title: "Safe Haven",
|
|
226
|
+
text: (0, templates_1.generateRestText)(biome), buddyLine: "Can we rest here? Just for a moment?",
|
|
227
|
+
healAmount: 15 + difficulty * 2,
|
|
228
|
+
};
|
|
229
|
+
case "event": {
|
|
230
|
+
const event = (0, templates_1.generateEvent)(biome);
|
|
231
|
+
return {
|
|
232
|
+
id, type, title: "Unexpected Encounter",
|
|
233
|
+
text: event.text, buddyLine,
|
|
234
|
+
eventChoices: event.choices.map((c) => ({
|
|
235
|
+
label: c.label,
|
|
236
|
+
outcome: c.outcome,
|
|
237
|
+
effect: c.effect ? { itemGain: c.effect.itemGain, hp: c.effect.hp, happiness: c.effect.happiness } : undefined,
|
|
238
|
+
})),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
default:
|
|
242
|
+
return { id, type: "narrative", title: "???", text: ["Something went wrong."], buddyLine: "Uh oh." };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SkillDef } from "./types";
|
|
2
|
+
export declare const SKILLS: SkillDef[];
|
|
3
|
+
/** Get skills available to a species at a given level */
|
|
4
|
+
export declare function getAvailableSkills(speciesId: string, level: number): SkillDef[];
|
|
5
|
+
export declare function getSkill(id: string): SkillDef | undefined;
|
|
6
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKILLS = void 0;
|
|
4
|
+
exports.getAvailableSkills = getAvailableSkills;
|
|
5
|
+
exports.getSkill = getSkill;
|
|
6
|
+
exports.SKILLS = [
|
|
7
|
+
// ─── Universal ─────────────────────────────────────────────
|
|
8
|
+
{
|
|
9
|
+
id: "focus", name: "Focus", description: "+50% ATK next turn",
|
|
10
|
+
speciesId: "all", levelRequired: 1, energyCost: 1,
|
|
11
|
+
effect: { type: "buff", stat: "atk", amount: 0.5, turns: 1 },
|
|
12
|
+
useLine: "concentrates deeply...",
|
|
13
|
+
},
|
|
14
|
+
// ─── Rabbit ────────────────────────────────────────────────
|
|
15
|
+
{
|
|
16
|
+
id: "quick_hop", name: "Quick Hop", description: "+30% dodge for 2 turns",
|
|
17
|
+
speciesId: "rabbit", levelRequired: 3, energyCost: 1,
|
|
18
|
+
effect: { type: "buff", stat: "dodge", amount: 0.3, turns: 2 },
|
|
19
|
+
useLine: "hops around frantically!",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "burrow", name: "Burrow", description: "Enemy skips next turn",
|
|
23
|
+
speciesId: "rabbit", levelRequired: 6, energyCost: 2,
|
|
24
|
+
effect: { type: "skip_enemy_turn" },
|
|
25
|
+
useLine: "digs underground and vanishes!",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "natures_blessing", name: "Nature's Blessing", description: "Regen 5 HP/turn for 3 turns",
|
|
29
|
+
speciesId: "rabbit", levelRequired: 10, energyCost: 2, element: "nature",
|
|
30
|
+
effect: { type: "buff", stat: "def", amount: 0, turns: 3 }, // handled specially by ID in combat.ts
|
|
31
|
+
useLine: "channels the power of nature!",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "earthquake", name: "Earthquake", description: "1.5x Nature dmg + stun",
|
|
35
|
+
speciesId: "rabbit", levelRequired: 15, energyCost: 3, element: "nature",
|
|
36
|
+
effect: { type: "damage", multiplier: 1.5 },
|
|
37
|
+
useLine: "stomps the ground with tremendous force!",
|
|
38
|
+
},
|
|
39
|
+
// ─── Cat ───────────────────────────────────────────────────
|
|
40
|
+
{
|
|
41
|
+
id: "pounce", name: "Pounce", description: "1.5x damage",
|
|
42
|
+
speciesId: "cat", levelRequired: 3, energyCost: 1,
|
|
43
|
+
effect: { type: "damage", multiplier: 1.5 },
|
|
44
|
+
useLine: "leaps through the air!",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "shadow_step", name: "Shadow Step", description: "+40% dodge 3 turns + next crit",
|
|
48
|
+
speciesId: "cat", levelRequired: 6, energyCost: 2, element: "shadow",
|
|
49
|
+
effect: { type: "buff", stat: "dodge", amount: 0.4, turns: 3 },
|
|
50
|
+
useLine: "melts into the shadows!",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "nine_lives", name: "Nine Lives", description: "Survive one KO with 1 HP",
|
|
54
|
+
speciesId: "cat", levelRequired: 10, energyCost: 3,
|
|
55
|
+
effect: { type: "revive", hpPercent: 0.01 },
|
|
56
|
+
useLine: "'s eyes flash — not done yet!",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "shadow_strike", name: "Shadow Strike", description: "2x Shadow dmg + charm 1t",
|
|
60
|
+
speciesId: "cat", levelRequired: 15, energyCost: 3, element: "shadow",
|
|
61
|
+
effect: { type: "damage", multiplier: 2.0 },
|
|
62
|
+
useLine: "strikes from the darkness!",
|
|
63
|
+
},
|
|
64
|
+
// ─── Frog ──────────────────────────────────────────────────
|
|
65
|
+
{
|
|
66
|
+
id: "tongue_lash", name: "Tongue Lash", description: "1.3x, ignores DEF",
|
|
67
|
+
speciesId: "frog", levelRequired: 3, energyCost: 1,
|
|
68
|
+
effect: { type: "damage", multiplier: 1.3, ignoreDefense: true },
|
|
69
|
+
useLine: "'s tongue snaps out!",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "toxic_splash", name: "Toxic Splash", description: "Poison: 4 dmg/turn for 3 turns",
|
|
73
|
+
speciesId: "frog", levelRequired: 6, energyCost: 2, element: "nature",
|
|
74
|
+
effect: { type: "poison", damagePerTurn: 4, turns: 3 },
|
|
75
|
+
useLine: "sprays a toxic mist!",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "aqua_shield", name: "Aqua Shield", description: "Shield absorbs 20 damage",
|
|
79
|
+
speciesId: "frog", levelRequired: 10, energyCost: 2, element: "water",
|
|
80
|
+
effect: { type: "buff", stat: "def", amount: 0, turns: 1 }, // handled specially
|
|
81
|
+
useLine: "conjures a water barrier!",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "tidal_wave", name: "Tidal Wave", description: "2x Water dmg + freeze 1t",
|
|
85
|
+
speciesId: "frog", levelRequired: 15, energyCost: 3, element: "water",
|
|
86
|
+
effect: { type: "damage", multiplier: 2.0 },
|
|
87
|
+
useLine: "summons a massive wave!",
|
|
88
|
+
},
|
|
89
|
+
// ─── Owl ───────────────────────────────────────────────────
|
|
90
|
+
{
|
|
91
|
+
id: "keen_eye", name: "Keen Eye", description: "+25% crit for 3 turns",
|
|
92
|
+
speciesId: "owl", levelRequired: 3, energyCost: 1,
|
|
93
|
+
effect: { type: "buff", stat: "crit", amount: 0.25, turns: 3 },
|
|
94
|
+
useLine: "'s eyes narrow with focus...",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: "screech", name: "Screech", description: "-30% enemy ATK for 3 turns",
|
|
98
|
+
speciesId: "owl", levelRequired: 6, energyCost: 2,
|
|
99
|
+
effect: { type: "debuff", stat: "atk", amount: 0.3, turns: 3 },
|
|
100
|
+
useLine: "lets out a piercing screech!",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "illuminate", name: "Illuminate", description: "Blind enemy for 2 turns",
|
|
104
|
+
speciesId: "owl", levelRequired: 10, energyCost: 2, element: "light",
|
|
105
|
+
effect: { type: "stun", turns: 0 }, // handled specially — applies blind condition
|
|
106
|
+
useLine: "emits a blinding flash!",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "piercing_gaze", name: "Piercing Gaze", description: "2.5x Light dmg + -50% DEF 2t",
|
|
110
|
+
speciesId: "owl", levelRequired: 15, energyCost: 4, element: "light",
|
|
111
|
+
effect: { type: "damage", multiplier: 2.5 },
|
|
112
|
+
useLine: "focuses an intense beam of light!",
|
|
113
|
+
},
|
|
114
|
+
// ─── Fox ───────────────────────────────────────────────────
|
|
115
|
+
{
|
|
116
|
+
id: "trick", name: "Trick", description: "Stun enemy 1 turn",
|
|
117
|
+
speciesId: "fox", levelRequired: 3, energyCost: 1,
|
|
118
|
+
effect: { type: "stun", turns: 1 },
|
|
119
|
+
useLine: "pulls a clever feint!",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "cunning_strike", name: "Cunning Strike", description: "2x dmg if HP > 50%",
|
|
123
|
+
speciesId: "fox", levelRequired: 6, energyCost: 2,
|
|
124
|
+
effect: { type: "damage", multiplier: 2.0 },
|
|
125
|
+
useLine: "strikes with cunning precision!",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "shadow_cloak", name: "Shadow Cloak", description: "+50% dodge 2t, stealth",
|
|
129
|
+
speciesId: "fox", levelRequired: 10, energyCost: 2, element: "shadow",
|
|
130
|
+
effect: { type: "buff", stat: "dodge", amount: 0.5, turns: 2 },
|
|
131
|
+
useLine: "vanishes into thin air!",
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: "outfox", name: "Outfox", description: "2x Nature dmg + charm 1t",
|
|
135
|
+
speciesId: "fox", levelRequired: 15, energyCost: 3, element: "nature",
|
|
136
|
+
effect: { type: "damage", multiplier: 2.0 },
|
|
137
|
+
useLine: "outwits the enemy completely!",
|
|
138
|
+
},
|
|
139
|
+
// ─── Phoenix ───────────────────────────────────────────────
|
|
140
|
+
{
|
|
141
|
+
id: "flame_burst", name: "Flame Burst", description: "1.6x Fire damage",
|
|
142
|
+
speciesId: "phoenix", levelRequired: 3, energyCost: 1, element: "fire",
|
|
143
|
+
effect: { type: "damage", multiplier: 1.6 },
|
|
144
|
+
useLine: "erupts in flames!",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: "inferno", name: "Inferno", description: "1.4x Fire + burn 5/t 3t",
|
|
148
|
+
speciesId: "phoenix", levelRequired: 6, energyCost: 2, element: "fire",
|
|
149
|
+
effect: { type: "damage", multiplier: 1.4 },
|
|
150
|
+
useLine: "unleashes a raging inferno!",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "rebirth", name: "Rebirth", description: "Revive with 30% HP once",
|
|
154
|
+
speciesId: "phoenix", levelRequired: 10, energyCost: 3,
|
|
155
|
+
effect: { type: "revive", hpPercent: 0.3 },
|
|
156
|
+
useLine: "bursts into ashes... and rises reborn!",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "supernova", name: "Supernova", description: "2.5x Fire + burn all",
|
|
160
|
+
speciesId: "phoenix", levelRequired: 15, energyCost: 4, element: "fire",
|
|
161
|
+
effect: { type: "damage", multiplier: 2.5 },
|
|
162
|
+
useLine: "explodes in a blinding supernova!",
|
|
163
|
+
},
|
|
164
|
+
// ─── Dragon ────────────────────────────────────────────────
|
|
165
|
+
{
|
|
166
|
+
id: "fire_breath", name: "Fire Breath", description: "1.8x Fire damage",
|
|
167
|
+
speciesId: "dragon", levelRequired: 3, energyCost: 1, element: "fire",
|
|
168
|
+
effect: { type: "damage", multiplier: 1.8 },
|
|
169
|
+
useLine: "unleashes a stream of fire!",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "scale_shield", name: "Scale Shield", description: "+50% DEF for 3 turns",
|
|
173
|
+
speciesId: "dragon", levelRequired: 6, energyCost: 2,
|
|
174
|
+
effect: { type: "buff", stat: "def", amount: 0.5, turns: 3 },
|
|
175
|
+
useLine: "'s scales harden and gleam!",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "dragons_roar", name: "Dragon's Roar", description: "-40% enemy ATK 2 turns",
|
|
179
|
+
speciesId: "dragon", levelRequired: 10, energyCost: 2,
|
|
180
|
+
effect: { type: "debuff", stat: "atk", amount: 0.4, turns: 2 },
|
|
181
|
+
useLine: "lets out an earth-shaking roar!",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "apocalypse", name: "Apocalypse", description: "3x Fire dmg (devastating)",
|
|
185
|
+
speciesId: "dragon", levelRequired: 15, energyCost: 4, element: "fire",
|
|
186
|
+
effect: { type: "damage", multiplier: 3.0 },
|
|
187
|
+
useLine: "rains fire from above!",
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
/** Get skills available to a species at a given level */
|
|
191
|
+
function getAvailableSkills(speciesId, level) {
|
|
192
|
+
return exports.SKILLS.filter((s) => (s.speciesId === speciesId || s.speciesId === "all") && level >= s.levelRequired);
|
|
193
|
+
}
|
|
194
|
+
function getSkill(id) {
|
|
195
|
+
return exports.SKILLS.find((s) => s.id === id);
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Biome } from "./biomes";
|
|
2
|
+
export declare function generateNarrativeText(biome: Biome): string[];
|
|
3
|
+
export declare function generateNarrativeTitle(biome: Biome): string;
|
|
4
|
+
export declare function generateChoiceLabels(biome: Biome): string[];
|
|
5
|
+
export declare function generateCombatText(biome: Biome, enemyName: string): string[];
|
|
6
|
+
export declare function generateCombatTitle(biome: Biome): string;
|
|
7
|
+
export declare function generateTreasureText(biome: Biome): string[];
|
|
8
|
+
export declare function generateRestText(biome: Biome): string[];
|
|
9
|
+
export interface EventTemplate {
|
|
10
|
+
text: string[];
|
|
11
|
+
choices: {
|
|
12
|
+
label: string;
|
|
13
|
+
outcome: string;
|
|
14
|
+
effect?: {
|
|
15
|
+
itemGain?: string;
|
|
16
|
+
hp?: number;
|
|
17
|
+
happiness?: number;
|
|
18
|
+
};
|
|
19
|
+
}[];
|
|
20
|
+
}
|
|
21
|
+
export declare function generateEvent(biome: Biome): EventTemplate;
|
|
22
|
+
export declare function generateBuddyLine(speciesId: string, biome: Biome): string;
|
|
23
|
+
export declare function generateBossText(biome: Biome, bossName: string): string[];
|
|
24
|
+
export declare function generateHiddenRoomText(biome: Biome, speciesId: string): string[];
|
|
25
|
+
//# sourceMappingURL=templates.d.ts.map
|