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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/adventure/adventureUI.d.ts +24 -0
  4. package/dist/adventure/adventureUI.js +290 -0
  5. package/dist/adventure/adventures.d.ts +4 -0
  6. package/dist/adventure/adventures.js +206 -0
  7. package/dist/adventure/biomes.d.ts +30 -0
  8. package/dist/adventure/biomes.js +80 -0
  9. package/dist/adventure/combat/combat.d.ts +14 -0
  10. package/dist/adventure/combat/combat.js +638 -0
  11. package/dist/adventure/combat/combatUI.d.ts +5 -0
  12. package/dist/adventure/combat/combatUI.js +116 -0
  13. package/dist/adventure/combat/conditions.d.ts +20 -0
  14. package/dist/adventure/combat/conditions.js +111 -0
  15. package/dist/adventure/combat/enemies.d.ts +4 -0
  16. package/dist/adventure/combat/enemies.js +430 -0
  17. package/dist/adventure/combat/gear.d.ts +3 -0
  18. package/dist/adventure/combat/gear.js +199 -0
  19. package/dist/adventure/combat/skills.d.ts +6 -0
  20. package/dist/adventure/combat/skills.js +197 -0
  21. package/dist/adventure/combat.d.ts +31 -0
  22. package/dist/adventure/combat.js +732 -0
  23. package/dist/adventure/combatUI.d.ts +5 -0
  24. package/dist/adventure/combatUI.js +116 -0
  25. package/dist/adventure/endless.d.ts +18 -0
  26. package/dist/adventure/endless.js +154 -0
  27. package/dist/adventure/enemies.d.ts +4 -0
  28. package/dist/adventure/enemies.js +320 -0
  29. package/dist/adventure/engine.d.ts +20 -0
  30. package/dist/adventure/engine.js +137 -0
  31. package/dist/adventure/gear.d.ts +3 -0
  32. package/dist/adventure/gear.js +149 -0
  33. package/dist/adventure/generation/biomes.d.ts +30 -0
  34. package/dist/adventure/generation/biomes.js +102 -0
  35. package/dist/adventure/generation/endless.d.ts +18 -0
  36. package/dist/adventure/generation/endless.js +154 -0
  37. package/dist/adventure/generation/generator.d.ts +9 -0
  38. package/dist/adventure/generation/generator.js +245 -0
  39. package/dist/adventure/generation/templates.d.ts +25 -0
  40. package/dist/adventure/generation/templates.js +228 -0
  41. package/dist/adventure/generator.d.ts +9 -0
  42. package/dist/adventure/generator.js +245 -0
  43. package/dist/adventure/skills.d.ts +6 -0
  44. package/dist/adventure/skills.js +197 -0
  45. package/dist/adventure/templates.d.ts +25 -0
  46. package/dist/adventure/templates.js +228 -0
  47. package/dist/adventure/types.d.ts +236 -0
  48. package/dist/adventure/types.js +97 -0
  49. package/dist/app/state.d.ts +49 -0
  50. package/dist/app/state.js +51 -0
  51. package/dist/buddy/activities.d.ts +16 -0
  52. package/dist/buddy/activities.js +90 -0
  53. package/dist/buddy/decay.d.ts +3 -0
  54. package/dist/buddy/decay.js +45 -0
  55. package/dist/buddy/leveling.d.ts +11 -0
  56. package/dist/buddy/leveling.js +25 -0
  57. package/dist/buddy/roll.d.ts +4 -0
  58. package/dist/buddy/roll.js +61 -0
  59. package/dist/buddy/species.d.ts +4 -0
  60. package/dist/buddy/species.js +592 -0
  61. package/dist/buddy/titles.d.ts +17 -0
  62. package/dist/buddy/titles.js +89 -0
  63. package/dist/buddy/types.d.ts +92 -0
  64. package/dist/buddy/types.js +21 -0
  65. package/dist/commands/actions.d.ts +2 -0
  66. package/dist/commands/actions.js +141 -0
  67. package/dist/commands/admin.d.ts +2 -0
  68. package/dist/commands/admin.js +202 -0
  69. package/dist/commands/registry.d.ts +25 -0
  70. package/dist/commands/registry.js +31 -0
  71. package/dist/commands/social.d.ts +2 -0
  72. package/dist/commands/social.js +92 -0
  73. package/dist/dialogue/engine.d.ts +7 -0
  74. package/dist/dialogue/engine.js +68 -0
  75. package/dist/dialogue/lines.d.ts +26 -0
  76. package/dist/dialogue/lines.js +294 -0
  77. package/dist/events/engine.d.ts +20 -0
  78. package/dist/events/engine.js +51 -0
  79. package/dist/events/events.d.ts +13 -0
  80. package/dist/events/events.js +149 -0
  81. package/dist/index.d.ts +10 -0
  82. package/dist/index.js +1665 -0
  83. package/dist/inventory/finding.d.ts +11 -0
  84. package/dist/inventory/finding.js +99 -0
  85. package/dist/inventory/items.d.ts +31 -0
  86. package/dist/inventory/items.js +63 -0
  87. package/dist/minigames/copycat.d.ts +2 -0
  88. package/dist/minigames/copycat.js +153 -0
  89. package/dist/minigames/fetch.d.ts +2 -0
  90. package/dist/minigames/fetch.js +179 -0
  91. package/dist/minigames/moodmatch.d.ts +2 -0
  92. package/dist/minigames/moodmatch.js +144 -0
  93. package/dist/minigames/quickpaws.d.ts +2 -0
  94. package/dist/minigames/quickpaws.js +142 -0
  95. package/dist/minigames/registry.d.ts +5 -0
  96. package/dist/minigames/registry.js +16 -0
  97. package/dist/minigames/rpsplus.d.ts +2 -0
  98. package/dist/minigames/rpsplus.js +168 -0
  99. package/dist/minigames/treasurehunt.d.ts +2 -0
  100. package/dist/minigames/treasurehunt.js +146 -0
  101. package/dist/minigames/types.d.ts +30 -0
  102. package/dist/minigames/types.js +69 -0
  103. package/dist/rendering/commandPalette.d.ts +16 -0
  104. package/dist/rendering/commandPalette.js +77 -0
  105. package/dist/rendering/display.d.ts +9 -0
  106. package/dist/rendering/display.js +231 -0
  107. package/dist/rendering/inventoryUI.d.ts +14 -0
  108. package/dist/rendering/inventoryUI.js +99 -0
  109. package/dist/rendering/items.d.ts +7 -0
  110. package/dist/rendering/items.js +34 -0
  111. package/dist/rendering/listUtils.d.ts +3 -0
  112. package/dist/rendering/listUtils.js +24 -0
  113. package/dist/rendering/minigameUI.d.ts +11 -0
  114. package/dist/rendering/minigameUI.js +37 -0
  115. package/dist/rendering/overlayUI.d.ts +24 -0
  116. package/dist/rendering/overlayUI.js +184 -0
  117. package/dist/rendering/scene.d.ts +8 -0
  118. package/dist/rendering/scene.js +87 -0
  119. package/dist/rendering/screen.d.ts +43 -0
  120. package/dist/rendering/screen.js +97 -0
  121. package/dist/sound/sound.d.ts +11 -0
  122. package/dist/sound/sound.js +55 -0
  123. package/dist/state/save.d.ts +5 -0
  124. package/dist/state/save.js +100 -0
  125. package/dist/state/settings.d.ts +7 -0
  126. package/dist/state/settings.js +81 -0
  127. package/dist/story/mainStory.d.ts +4 -0
  128. package/dist/story/mainStory.js +3111 -0
  129. package/dist/story/npcs.d.ts +17 -0
  130. package/dist/story/npcs.js +137 -0
  131. package/dist/story/progress.d.ts +26 -0
  132. package/dist/story/progress.js +168 -0
  133. package/dist/story/seasonal.d.ts +6 -0
  134. package/dist/story/seasonal.js +96 -0
  135. package/dist/story/shop.d.ts +7 -0
  136. package/dist/story/shop.js +26 -0
  137. package/dist/story/sideQuests.d.ts +4 -0
  138. package/dist/story/sideQuests.js +151 -0
  139. package/dist/story/types.d.ts +61 -0
  140. package/dist/story/types.js +36 -0
  141. package/dist/updates.d.ts +23 -0
  142. package/dist/updates.js +142 -0
  143. package/package.json +53 -0
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderCombat = renderCombat;
4
+ exports.renderSkillMenu = renderSkillMenu;
5
+ const types_1 = require("../../buddy/types");
6
+ const species_1 = require("../../buddy/species");
7
+ const types_2 = require("../types");
8
+ const lines_1 = require("../../dialogue/lines");
9
+ const skills_1 = require("./skills");
10
+ const screen_1 = require("../../rendering/screen");
11
+ const CONDITION_ICONS = {
12
+ burn: "🔥", poison: "☠", freeze: "❄", stun: "⚡", charm: "💕",
13
+ blind: "👁", regen: "💚", shield: "🛡", buff: "↑", debuff: "↓",
14
+ };
15
+ function formatConditions(conditions) {
16
+ if (conditions.length === 0)
17
+ return "";
18
+ const icons = conditions.map((c) => CONDITION_ICONS[c.type] ?? c.type).join(" ");
19
+ return ` ${icons}`;
20
+ }
21
+ function hpBar(current, max, width = 15) {
22
+ const filled = Math.max(0, Math.round((current / max) * width));
23
+ const empty = width - filled;
24
+ const pct = Math.round((current / max) * 100);
25
+ let color;
26
+ if (pct > 60)
27
+ color = screen_1.ansi.colors.green;
28
+ else if (pct > 30)
29
+ color = screen_1.ansi.colors.yellow;
30
+ else
31
+ color = screen_1.ansi.colors.red;
32
+ return `${color}${"█".repeat(filled)}${screen_1.ansi.dim}${"░".repeat(empty)}${screen_1.ansi.reset} ${color}${current}/${max}${screen_1.ansi.reset}`;
33
+ }
34
+ function renderCombat(combat, state, adventureName) {
35
+ const species = (0, species_1.getSpecies)(state.speciesId);
36
+ const lines = [];
37
+ lines.push("");
38
+ lines.push(` ${screen_1.ansi.bold}${adventureName}${screen_1.ansi.reset} ${screen_1.ansi.dim}Combat${screen_1.ansi.reset}`);
39
+ lines.push(` ${screen_1.ansi.dim}${"─".repeat(44)}${screen_1.ansi.reset}`);
40
+ lines.push("");
41
+ // Enemy
42
+ const enemyElemIcon = types_2.ELEMENT_ICONS[combat.enemyElement] ?? "";
43
+ lines.push(` ${screen_1.ansi.colors.red}${screen_1.ansi.bold}${combat.enemy.name}${screen_1.ansi.reset} ${enemyElemIcon}`);
44
+ lines.push(` HP: ${hpBar(combat.enemyStats.hp, combat.enemyStats.maxHp)} ${screen_1.ansi.dim}ATK:${combat.enemyStats.atk} DEF:${combat.enemyStats.def}${screen_1.ansi.reset}${formatConditions(combat.enemyConditions)}`);
45
+ for (const artLine of combat.enemy.art) {
46
+ lines.push(` ${screen_1.ansi.colors.red}${artLine}${screen_1.ansi.reset}`);
47
+ }
48
+ lines.push("");
49
+ lines.push(` ${screen_1.ansi.dim} vs${screen_1.ansi.reset}`);
50
+ lines.push("");
51
+ // Player buddy
52
+ const speciesColor = species ? types_1.RARITY_COLORS[species.rarity] : "";
53
+ const playerElemIcon = types_2.ELEMENT_ICONS[combat.playerElement] ?? "";
54
+ lines.push(` ${speciesColor}${screen_1.ansi.bold}${state.name}${screen_1.ansi.reset} ${playerElemIcon}`);
55
+ lines.push(` HP: ${hpBar(combat.playerStats.hp, combat.playerStats.maxHp)} ${screen_1.ansi.dim}ATK:${combat.playerStats.atk} DEF:${combat.playerStats.def}${screen_1.ansi.reset}${formatConditions(combat.playerConditions)}`);
56
+ if (species) {
57
+ const frame = species.animations.idle[0].split("\n");
58
+ for (const artLine of frame) {
59
+ lines.push(` ${speciesColor}${artLine}${screen_1.ansi.reset}`);
60
+ }
61
+ }
62
+ lines.push("");
63
+ // Combat log (last 2 messages)
64
+ const recentLog = combat.log.slice(-2);
65
+ for (const msg of recentLog) {
66
+ lines.push(` ${screen_1.ansi.dim}${msg}${screen_1.ansi.reset}`);
67
+ }
68
+ lines.push("");
69
+ // Action menu (only during player turn)
70
+ if (combat.phase === "player_turn") {
71
+ lines.push(` ${screen_1.ansi.dim}${"─".repeat(44)}${screen_1.ansi.reset}`);
72
+ lines.push(` [1] Attack [2] Skill [3] Item`);
73
+ lines.push(` [4] Defend [5] Flee`);
74
+ lines.push(` ${screen_1.ansi.dim}Energy: ${"◆".repeat(combat.combatEnergy)}${"◇".repeat(combat.maxCombatEnergy - combat.combatEnergy)}${screen_1.ansi.reset}`);
75
+ }
76
+ else if (combat.phase === "victory") {
77
+ const victoryLines = lines_1.COMBAT_VICTORY_LINES[state.speciesId];
78
+ const victoryLine = victoryLines ? victoryLines[Math.floor(Math.random() * victoryLines.length)] : "We did it!";
79
+ lines.push(` ${screen_1.ansi.colors.green}${screen_1.ansi.bold}Victory!${screen_1.ansi.reset} ${screen_1.ansi.dim}+${combat.enemy.xpReward} XP${screen_1.ansi.reset}`);
80
+ lines.push(` ${state.name}: "${victoryLine}"`);
81
+ lines.push(` ${screen_1.ansi.dim}Press Enter to continue...${screen_1.ansi.reset}`);
82
+ }
83
+ else if (combat.phase === "defeat") {
84
+ const defeatLines = lines_1.COMBAT_DEFEAT_LINES[state.speciesId];
85
+ const defeatLine = defeatLines ? defeatLines[Math.floor(Math.random() * defeatLines.length)] : "We'll get them next time...";
86
+ lines.push(` ${screen_1.ansi.colors.red}${screen_1.ansi.bold}Defeated!${screen_1.ansi.reset}`);
87
+ lines.push(` ${state.name}: "${defeatLine}"`);
88
+ lines.push(` ${screen_1.ansi.dim}Press Enter to retreat...${screen_1.ansi.reset}`);
89
+ }
90
+ else if (combat.phase === "fled") {
91
+ lines.push(` ${screen_1.ansi.colors.yellow}Escaped!${screen_1.ansi.reset}`);
92
+ lines.push(` ${screen_1.ansi.dim}Press Enter to continue...${screen_1.ansi.reset}`);
93
+ }
94
+ else {
95
+ // Animating
96
+ lines.push(` ${screen_1.ansi.dim}...${screen_1.ansi.reset}`);
97
+ }
98
+ lines.push("");
99
+ return lines.join("\n");
100
+ }
101
+ function renderSkillMenu(combat, state) {
102
+ const skills = (0, skills_1.getAvailableSkills)(state.speciesId, state.level);
103
+ const lines = [];
104
+ lines.push(` ${screen_1.ansi.dim}${"─".repeat(44)}${screen_1.ansi.reset}`);
105
+ lines.push(` ${screen_1.ansi.bold}Skills${screen_1.ansi.reset} ${screen_1.ansi.dim}Energy: ${"◆".repeat(combat.combatEnergy)}${"◇".repeat(combat.maxCombatEnergy - combat.combatEnergy)}${screen_1.ansi.reset}`);
106
+ for (let i = 0; i < skills.length; i++) {
107
+ const s = skills[i];
108
+ const canUse = combat.combatEnergy >= s.energyCost;
109
+ const color = canUse ? "" : screen_1.ansi.dim;
110
+ lines.push(` ${color}[${i + 1}] ${s.name} (${s.energyCost}◆) — ${s.description}${screen_1.ansi.reset}`);
111
+ }
112
+ lines.push(` ${screen_1.ansi.dim}[0] Back${screen_1.ansi.reset}`);
113
+ lines.push(` ${screen_1.ansi.dim}${"─".repeat(44)}${screen_1.ansi.reset}`);
114
+ return lines.join("\n");
115
+ }
116
+ //# sourceMappingURL=combatUI.js.map
@@ -0,0 +1,20 @@
1
+ import { StatusCondition, StatType, Element } from "../types";
2
+ /** Apply start-of-turn conditions to a combatant. Returns updated HP, conditions, and log messages. */
3
+ export declare function processConditions(hp: number, maxHp: number, conditions: StatusCondition[], log: string[], targetName: string): {
4
+ hp: number;
5
+ conditions: StatusCondition[];
6
+ log: string[];
7
+ skipTurn: boolean;
8
+ };
9
+ /** Apply shield absorption */
10
+ export declare function applyShield(damage: number, conditions: StatusCondition[]): {
11
+ damage: number;
12
+ conditions: StatusCondition[];
13
+ };
14
+ /** Check if target has a specific condition */
15
+ export declare function hasCondition(conditions: StatusCondition[], type: string): boolean;
16
+ /** Add a condition, respecting immunities */
17
+ export declare function addCondition(conditions: StatusCondition[], cond: StatusCondition, targetElement: Element): StatusCondition[];
18
+ /** Get effective stat modifier from conditions (buff/debuff) */
19
+ export declare function getConditionStatMod(conditions: StatusCondition[], stat: StatType): number;
20
+ //# sourceMappingURL=conditions.d.ts.map
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processConditions = processConditions;
4
+ exports.applyShield = applyShield;
5
+ exports.hasCondition = hasCondition;
6
+ exports.addCondition = addCondition;
7
+ exports.getConditionStatMod = getConditionStatMod;
8
+ const types_1 = require("../types");
9
+ /** Apply start-of-turn conditions to a combatant. Returns updated HP, conditions, and log messages. */
10
+ function processConditions(hp, maxHp, conditions, log, targetName) {
11
+ let skipTurn = false;
12
+ const newLog = [...log];
13
+ let newConditions = [];
14
+ for (const cond of conditions) {
15
+ switch (cond.type) {
16
+ case "burn":
17
+ hp = Math.max(0, hp - cond.damagePerTurn);
18
+ newLog.push(`${targetName} takes ${cond.damagePerTurn} burn damage!`);
19
+ if (cond.turnsLeft > 1)
20
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
21
+ break;
22
+ case "poison":
23
+ hp = Math.max(0, hp - cond.damagePerTurn);
24
+ newLog.push(`${targetName} takes ${cond.damagePerTurn} poison damage!`);
25
+ if (cond.turnsLeft > 1)
26
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
27
+ break;
28
+ case "freeze":
29
+ skipTurn = true;
30
+ newLog.push(`${targetName} is frozen solid!`);
31
+ if (cond.turnsLeft > 1)
32
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
33
+ break;
34
+ case "stun":
35
+ skipTurn = true;
36
+ newLog.push(`${targetName} is stunned!`);
37
+ if (cond.turnsLeft > 1)
38
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
39
+ break;
40
+ case "charm":
41
+ skipTurn = true;
42
+ newLog.push(`${targetName} is charmed and confused!`);
43
+ if (cond.turnsLeft > 1)
44
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
45
+ break;
46
+ case "blind":
47
+ if (cond.turnsLeft > 1)
48
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
49
+ break;
50
+ case "regen":
51
+ const heal = Math.min(cond.healPerTurn, maxHp - hp);
52
+ if (heal > 0) {
53
+ hp = hp + heal;
54
+ newLog.push(`${targetName} regenerates ${heal} HP!`);
55
+ }
56
+ if (cond.turnsLeft > 1)
57
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
58
+ break;
59
+ case "shield":
60
+ newConditions.push(cond);
61
+ break;
62
+ case "buff":
63
+ case "debuff":
64
+ if (cond.turnsLeft > 1)
65
+ newConditions.push({ ...cond, turnsLeft: cond.turnsLeft - 1 });
66
+ break;
67
+ }
68
+ }
69
+ return { hp, conditions: newConditions, log: newLog, skipTurn };
70
+ }
71
+ /** Apply shield absorption */
72
+ function applyShield(damage, conditions) {
73
+ const newConds = [];
74
+ let remaining = damage;
75
+ for (const cond of conditions) {
76
+ if (cond.type === "shield" && remaining > 0) {
77
+ if (cond.amount > remaining) {
78
+ newConds.push({ ...cond, amount: cond.amount - remaining });
79
+ remaining = 0;
80
+ }
81
+ else {
82
+ remaining -= cond.amount;
83
+ }
84
+ }
85
+ else {
86
+ newConds.push(cond);
87
+ }
88
+ }
89
+ return { damage: remaining, conditions: newConds };
90
+ }
91
+ /** Check if target has a specific condition */
92
+ function hasCondition(conditions, type) {
93
+ return conditions.some((c) => c.type === type);
94
+ }
95
+ /** Add a condition, respecting immunities */
96
+ function addCondition(conditions, cond, targetElement) {
97
+ if ((0, types_1.isImmune)(cond.type, targetElement))
98
+ return conditions;
99
+ return [...conditions, cond];
100
+ }
101
+ /** Get effective stat modifier from conditions (buff/debuff) */
102
+ function getConditionStatMod(conditions, stat) {
103
+ let mod = 0;
104
+ for (const c of conditions) {
105
+ if ((c.type === "buff" || c.type === "debuff") && c.stat === stat) {
106
+ mod += c.type === "buff" ? c.amount : -c.amount;
107
+ }
108
+ }
109
+ return mod;
110
+ }
111
+ //# sourceMappingURL=conditions.js.map
@@ -0,0 +1,4 @@
1
+ import { EnemyDef } from "../types";
2
+ export declare const ENEMIES: Record<string, EnemyDef>;
3
+ export declare function getEnemy(id: string): EnemyDef | undefined;
4
+ //# sourceMappingURL=enemies.d.ts.map