@codehawks/agent-battle-arena-mcp 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 (74) hide show
  1. package/README.md +112 -0
  2. package/dist/data/creatures.d.ts +6 -0
  3. package/dist/data/creatures.d.ts.map +1 -0
  4. package/dist/data/creatures.js +524 -0
  5. package/dist/data/creatures.js.map +1 -0
  6. package/dist/data/moves.d.ts +5 -0
  7. package/dist/data/moves.d.ts.map +1 -0
  8. package/dist/data/moves.js +1034 -0
  9. package/dist/data/moves.js.map +1 -0
  10. package/dist/data/sprites.d.ts +6 -0
  11. package/dist/data/sprites.d.ts.map +1 -0
  12. package/dist/data/sprites.js +5 -0
  13. package/dist/data/sprites.js.map +1 -0
  14. package/dist/data/types.d.ts +115 -0
  15. package/dist/data/types.d.ts.map +1 -0
  16. package/dist/data/types.js +29 -0
  17. package/dist/data/types.js.map +1 -0
  18. package/dist/engine/ai.d.ts +4 -0
  19. package/dist/engine/ai.d.ts.map +1 -0
  20. package/dist/engine/ai.js +138 -0
  21. package/dist/engine/ai.js.map +1 -0
  22. package/dist/engine/battle.d.ts +12 -0
  23. package/dist/engine/battle.d.ts.map +1 -0
  24. package/dist/engine/battle.js +313 -0
  25. package/dist/engine/battle.js.map +1 -0
  26. package/dist/engine/damage.d.ts +14 -0
  27. package/dist/engine/damage.d.ts.map +1 -0
  28. package/dist/engine/damage.js +51 -0
  29. package/dist/engine/damage.js.map +1 -0
  30. package/dist/engine/effects.d.ts +9 -0
  31. package/dist/engine/effects.d.ts.map +1 -0
  32. package/dist/engine/effects.js +99 -0
  33. package/dist/engine/effects.js.map +1 -0
  34. package/dist/engine/typeChart.d.ts +7 -0
  35. package/dist/engine/typeChart.d.ts.map +1 -0
  36. package/dist/engine/typeChart.js +73 -0
  37. package/dist/engine/typeChart.js.map +1 -0
  38. package/dist/index.d.ts +3 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +14 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/server.d.ts +3 -0
  43. package/dist/server.d.ts.map +1 -0
  44. package/dist/server.js +97 -0
  45. package/dist/server.js.map +1 -0
  46. package/dist/tools/getMoveInfo.d.ts +4 -0
  47. package/dist/tools/getMoveInfo.d.ts.map +1 -0
  48. package/dist/tools/getMoveInfo.js +33 -0
  49. package/dist/tools/getMoveInfo.js.map +1 -0
  50. package/dist/tools/getSprites.d.ts +2 -0
  51. package/dist/tools/getSprites.d.ts.map +1 -0
  52. package/dist/tools/getSprites.js +15 -0
  53. package/dist/tools/getSprites.js.map +1 -0
  54. package/dist/tools/getState.d.ts +2 -0
  55. package/dist/tools/getState.d.ts.map +1 -0
  56. package/dist/tools/getState.js +18 -0
  57. package/dist/tools/getState.js.map +1 -0
  58. package/dist/tools/listCreatures.d.ts +4 -0
  59. package/dist/tools/listCreatures.d.ts.map +1 -0
  60. package/dist/tools/listCreatures.js +36 -0
  61. package/dist/tools/listCreatures.js.map +1 -0
  62. package/dist/tools/makeMove.d.ts +4 -0
  63. package/dist/tools/makeMove.d.ts.map +1 -0
  64. package/dist/tools/makeMove.js +21 -0
  65. package/dist/tools/makeMove.js.map +1 -0
  66. package/dist/tools/startBattle.d.ts +6 -0
  67. package/dist/tools/startBattle.d.ts.map +1 -0
  68. package/dist/tools/startBattle.js +22 -0
  69. package/dist/tools/startBattle.js.map +1 -0
  70. package/dist/utils/rng.d.ts +11 -0
  71. package/dist/utils/rng.d.ts.map +1 -0
  72. package/dist/utils/rng.js +26 -0
  73. package/dist/utils/rng.js.map +1 -0
  74. package/package.json +45 -0
@@ -0,0 +1,313 @@
1
+ import { ALL_CREATURES } from '../data/creatures.js';
2
+ import { ALL_MOVES, getMove } from '../data/moves.js';
3
+ import { getMatchupChart } from './typeChart.js';
4
+ import { calculateDamage, applyDamage, getEffectiveSpeed } from './damage.js';
5
+ import { applyMoveEffect, processStatusEffects, consumePP } from './effects.js';
6
+ import { chooseOpponentMove } from './ai.js';
7
+ import { SeededRNG } from '../utils/rng.js';
8
+ let battleCounter = 0;
9
+ function generateBattleId() {
10
+ battleCounter++;
11
+ return `b_${Date.now().toString(36)}_${battleCounter}`;
12
+ }
13
+ function createBattleCreature(name) {
14
+ const def = ALL_CREATURES[name];
15
+ if (!def)
16
+ throw new Error(`Unknown creature: ${name}`);
17
+ const moves = def.moves.map(moveName => {
18
+ const moveDef = ALL_MOVES[moveName];
19
+ if (!moveDef)
20
+ throw new Error(`Unknown move: ${moveName}`);
21
+ return {
22
+ name: moveDef.name,
23
+ type: moveDef.type,
24
+ power: moveDef.power,
25
+ accuracy: moveDef.accuracy,
26
+ pp: moveDef.pp,
27
+ ppLeft: moveDef.pp,
28
+ effect: moveDef.effect
29
+ ? formatEffectDescription(moveDef)
30
+ : null,
31
+ };
32
+ });
33
+ return {
34
+ name: def.name,
35
+ type: def.type,
36
+ hp: def.hp,
37
+ maxHp: def.hp,
38
+ attack: def.attack,
39
+ defense: def.defense,
40
+ speed: def.speed,
41
+ moves,
42
+ statusEffects: [],
43
+ statModifiers: { attack: 0, defense: 0, speed: 0 },
44
+ };
45
+ }
46
+ function formatEffectDescription(moveDef) {
47
+ const e = moveDef.effect;
48
+ if (!e)
49
+ return '';
50
+ switch (e.type) {
51
+ case 'stat_boost': return `Raises ${e.target === 'self' ? 'user' : 'target'}'s ${e.stat} by ${e.stages ?? 1} stage(s)`;
52
+ case 'stat_lower': return `Lowers ${e.target === 'self' ? 'user' : 'target'}'s ${e.stat} by ${e.stages ?? 1} stage(s)`;
53
+ case 'heal': return `Heals ${e.healPercent}% of max HP`;
54
+ case 'recoil': return `Recoil: ${e.recoilPercent}% of damage dealt`;
55
+ case 'status': return `${e.chance === 100 ? '' : `${e.chance}% chance to `}${e.status === 'burned' ? 'burn' : e.status === 'frozen' ? 'freeze' : e.status === 'poisoned' ? 'poison' : 'paralyze'} the target`;
56
+ case 'high_crit': return `High critical hit chance (+${e.critBonus}%)`;
57
+ }
58
+ }
59
+ export class BattleManager {
60
+ battles = new Map();
61
+ startBattle(playerCreature, difficulty = 'normal', mode = 'single') {
62
+ const rng = new SeededRNG();
63
+ const creatureNames = Object.keys(ALL_CREATURES);
64
+ const playerName = playerCreature && ALL_CREATURES[playerCreature]
65
+ ? playerCreature
66
+ : rng.pick(creatureNames);
67
+ let opponentName = rng.pick(creatureNames);
68
+ while (opponentName === playerName) {
69
+ opponentName = rng.pick(creatureNames);
70
+ }
71
+ const player = createBattleCreature(playerName);
72
+ const opponent = createBattleCreature(opponentName);
73
+ const battleId = generateBattleId();
74
+ const session = {
75
+ gameState: {
76
+ battleId,
77
+ status: 'active',
78
+ turn: 0,
79
+ difficulty,
80
+ mode,
81
+ player: { creature: player },
82
+ opponent: { creature: opponent },
83
+ lastRound: null,
84
+ battleLog: [],
85
+ typeChart: getMatchupChart(player.type, opponent.type),
86
+ ...(mode === 'best_of_3' ? { seriesScore: { player: 0, opponent: 0, round: 1 } } : {}),
87
+ },
88
+ rng,
89
+ playerMoveHistory: [],
90
+ };
91
+ this.battles.set(battleId, session);
92
+ return session.gameState;
93
+ }
94
+ getState(battleId) {
95
+ if (battleId) {
96
+ return this.battles.get(battleId)?.gameState ?? null;
97
+ }
98
+ // Return most recent battle
99
+ const entries = Array.from(this.battles.entries());
100
+ if (entries.length === 0)
101
+ return null;
102
+ return entries[entries.length - 1][1].gameState;
103
+ }
104
+ makeMove(moveName, battleId) {
105
+ const session = battleId
106
+ ? this.battles.get(battleId)
107
+ : Array.from(this.battles.values()).pop();
108
+ if (!session)
109
+ throw new Error('No active battle. Use start_battle first.');
110
+ const { gameState, rng } = session;
111
+ if (gameState.status !== 'active') {
112
+ throw new Error(`Battle is over. Status: ${gameState.status}. Start a new battle.`);
113
+ }
114
+ const playerCreature = gameState.player.creature;
115
+ const opponentCreature = gameState.opponent.creature;
116
+ // Validate move
117
+ const playerMove = playerCreature.moves.find(m => m.name.toLowerCase() === moveName.toLowerCase());
118
+ if (!playerMove) {
119
+ const available = playerCreature.moves.map(m => m.name).join(', ');
120
+ throw new Error(`Unknown move: "${moveName}". Available: ${available}`);
121
+ }
122
+ if (playerMove.ppLeft <= 0) {
123
+ throw new Error(`${playerMove.name} has no PP left! Choose a different move.`);
124
+ }
125
+ gameState.turn++;
126
+ // Opponent chooses move
127
+ const opponentMoveName = chooseOpponentMove(opponentCreature, playerCreature, gameState.difficulty, session.playerMoveHistory, rng);
128
+ session.playerMoveHistory.push(moveName);
129
+ // Determine turn order by speed
130
+ const playerSpeed = getEffectiveSpeed(playerCreature);
131
+ const opponentSpeed = getEffectiveSpeed(opponentCreature);
132
+ const playerFirst = playerSpeed >= opponentSpeed;
133
+ const [first, second, firstName, secondName, firstMoveName, secondMoveName] = playerFirst
134
+ ? [playerCreature, opponentCreature, 'player', 'opponent', moveName, opponentMoveName]
135
+ : [opponentCreature, playerCreature, 'opponent', 'player', opponentMoveName, moveName];
136
+ const narrativeParts = [];
137
+ // === First attacker's turn ===
138
+ const firstAction = this.executeTurn(first, second, firstMoveName, rng, narrativeParts);
139
+ // === Check if second attacker fainted ===
140
+ let secondAction;
141
+ if (second.hp <= 0) {
142
+ secondAction = { move: secondMoveName, damage: 0, effectiveness: 'neutral', critical: false, missed: false };
143
+ narrativeParts.push(`${second.name} fainted!`);
144
+ }
145
+ else {
146
+ // === Second attacker's turn ===
147
+ secondAction = this.executeTurn(second, first, secondMoveName, rng, narrativeParts);
148
+ if (first.hp <= 0) {
149
+ narrativeParts.push(`${first.name} fainted!`);
150
+ }
151
+ }
152
+ // Assign results to player/opponent
153
+ const [playerAction, opponentAction] = playerFirst
154
+ ? [firstAction, secondAction]
155
+ : [secondAction, firstAction];
156
+ const round = {
157
+ playerAction,
158
+ opponentAction,
159
+ turnOrder: playerFirst ? 'player_first' : 'opponent_first',
160
+ narrative: narrativeParts.join(' '),
161
+ };
162
+ gameState.lastRound = round;
163
+ // Build log entry
164
+ const logParts = [];
165
+ if (playerAction.missed) {
166
+ logParts.push(`${playerCreature.name}'s ${playerAction.move} missed!`);
167
+ }
168
+ else if (playerAction.damage > 0) {
169
+ const seTag = playerAction.effectiveness === 'super_effective' ? ' SE!' : playerAction.effectiveness === 'not_very_effective' ? ' NVE' : '';
170
+ const critTag = playerAction.critical ? ' CRIT!' : '';
171
+ logParts.push(`${playerCreature.name}: ${playerAction.move} (${playerAction.damage} dmg${seTag}${critTag})`);
172
+ }
173
+ else {
174
+ logParts.push(`${playerCreature.name}: ${playerAction.move}${playerAction.effectApplied ? ` - ${playerAction.effectApplied}` : ''}`);
175
+ }
176
+ if (opponentAction.missed) {
177
+ logParts.push(`${opponentCreature.name}'s ${opponentAction.move} missed!`);
178
+ }
179
+ else if (opponentAction.damage > 0) {
180
+ const seTag = opponentAction.effectiveness === 'super_effective' ? ' SE!' : opponentAction.effectiveness === 'not_very_effective' ? ' NVE' : '';
181
+ const critTag = opponentAction.critical ? ' CRIT!' : '';
182
+ logParts.push(`${opponentCreature.name}: ${opponentAction.move} (${opponentAction.damage} dmg${seTag}${critTag})`);
183
+ }
184
+ else {
185
+ logParts.push(`${opponentCreature.name}: ${opponentAction.move}${opponentAction.effectApplied ? ` - ${opponentAction.effectApplied}` : ''}`);
186
+ }
187
+ gameState.battleLog.push({
188
+ turn: gameState.turn,
189
+ summary: logParts.join(' / '),
190
+ });
191
+ // Check win condition
192
+ if (playerCreature.hp <= 0) {
193
+ gameState.status = 'opponent_won';
194
+ if (gameState.seriesScore) {
195
+ gameState.seriesScore.opponent++;
196
+ this.maybeAdvanceSeries(session);
197
+ }
198
+ }
199
+ else if (opponentCreature.hp <= 0) {
200
+ gameState.status = 'player_won';
201
+ if (gameState.seriesScore) {
202
+ gameState.seriesScore.player++;
203
+ this.maybeAdvanceSeries(session);
204
+ }
205
+ }
206
+ return gameState;
207
+ }
208
+ executeTurn(attacker, defender, moveName, rng, narrative) {
209
+ // Process status effects first
210
+ const statusResult = processStatusEffects(attacker, rng);
211
+ narrative.push(...statusResult.messages);
212
+ if (statusResult.skipTurn) {
213
+ return {
214
+ move: moveName,
215
+ damage: 0,
216
+ effectiveness: 'neutral',
217
+ critical: false,
218
+ missed: false,
219
+ effectApplied: 'Skipped turn',
220
+ };
221
+ }
222
+ // Check if attacker fainted from status damage
223
+ if (attacker.hp <= 0) {
224
+ return {
225
+ move: moveName,
226
+ damage: 0,
227
+ effectiveness: 'neutral',
228
+ critical: false,
229
+ missed: false,
230
+ effectApplied: `${attacker.name} fainted from status damage`,
231
+ };
232
+ }
233
+ const moveDef = getMove(moveName);
234
+ if (!moveDef) {
235
+ return {
236
+ move: moveName,
237
+ damage: 0,
238
+ effectiveness: 'neutral',
239
+ critical: false,
240
+ missed: true,
241
+ };
242
+ }
243
+ // Consume PP
244
+ consumePP(attacker, moveName);
245
+ // Calculate and apply damage
246
+ const damageResult = calculateDamage(attacker, defender, moveDef, rng);
247
+ if (damageResult.missed) {
248
+ narrative.push(`${attacker.name} used ${moveName}, but it missed!`);
249
+ return {
250
+ move: moveName,
251
+ damage: 0,
252
+ effectiveness: damageResult.effectiveness,
253
+ critical: false,
254
+ missed: true,
255
+ };
256
+ }
257
+ if (damageResult.damage > 0) {
258
+ applyDamage(defender, damageResult.damage);
259
+ let desc = `${attacker.name} used ${moveName}`;
260
+ if (damageResult.effectiveness === 'super_effective') {
261
+ desc += ` — it's super effective! ${damageResult.damage} damage!`;
262
+ }
263
+ else if (damageResult.effectiveness === 'not_very_effective') {
264
+ desc += ` — not very effective. ${damageResult.damage} damage.`;
265
+ }
266
+ else {
267
+ desc += ` for ${damageResult.damage} damage.`;
268
+ }
269
+ if (damageResult.critical) {
270
+ desc += ' Critical hit!';
271
+ }
272
+ narrative.push(desc);
273
+ }
274
+ else {
275
+ narrative.push(`${attacker.name} used ${moveName}!`);
276
+ }
277
+ // Apply move effect
278
+ const effectMessage = applyMoveEffect(moveDef, attacker, defender, damageResult.damage, rng);
279
+ if (effectMessage) {
280
+ narrative.push(effectMessage);
281
+ }
282
+ return {
283
+ move: moveName,
284
+ damage: damageResult.damage,
285
+ effectiveness: damageResult.effectiveness,
286
+ critical: damageResult.critical,
287
+ missed: false,
288
+ effectApplied: effectMessage,
289
+ };
290
+ }
291
+ maybeAdvanceSeries(session) {
292
+ const score = session.gameState.seriesScore;
293
+ if (!score)
294
+ return;
295
+ // Best of 3: need 2 wins
296
+ if (score.player >= 2 || score.opponent >= 2) {
297
+ // Series is over, status already set from last round
298
+ return;
299
+ }
300
+ // If both haven't reached 2, series continues
301
+ // The next start_battle_round call will create the next round
302
+ // For now, just track it
303
+ score.round++;
304
+ }
305
+ getActiveBattleIds() {
306
+ return Array.from(this.battles.entries())
307
+ .filter(([_, s]) => s.gameState.status === 'active')
308
+ .map(([id]) => id);
309
+ }
310
+ }
311
+ // Singleton
312
+ export const battleManager = new BattleManager();
313
+ //# sourceMappingURL=battle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"battle.js","sourceRoot":"","sources":["../../src/engine/battle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { BattleCreature, MoveDefinition, Effectiveness } from '../data/types.js';
2
+ import { SeededRNG } from '../utils/rng.js';
3
+ export declare function getEffectiveAttack(creature: BattleCreature): number;
4
+ export declare function getEffectiveDefense(creature: BattleCreature): number;
5
+ export declare function getEffectiveSpeed(creature: BattleCreature): number;
6
+ export interface DamageResult {
7
+ damage: number;
8
+ effectiveness: Effectiveness;
9
+ critical: boolean;
10
+ missed: boolean;
11
+ }
12
+ export declare function calculateDamage(attacker: BattleCreature, defender: BattleCreature, move: MoveDefinition, rng: SeededRNG): DamageResult;
13
+ export declare function applyDamage(creature: BattleCreature, damage: number): void;
14
+ //# sourceMappingURL=damage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"damage.d.ts","sourceRoot":"","sources":["../../src/engine/damage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAgB,MAAM,kBAAkB,CAAC;AAE/F,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM5C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAOnE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAMlE;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,SAAS,GACb,YAAY,CAiCd;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE1E"}
@@ -0,0 +1,51 @@
1
+ import { getEffectiveness, getTypeMultiplier } from './typeChart.js';
2
+ function getStatMultiplier(stage) {
3
+ return 1 + stage * 0.25;
4
+ }
5
+ export function getEffectiveAttack(creature) {
6
+ const base = creature.attack;
7
+ let mult = getStatMultiplier(creature.statModifiers.attack);
8
+ if (creature.statusEffects.includes('burned')) {
9
+ mult *= 0.75;
10
+ }
11
+ return Math.round(base * mult);
12
+ }
13
+ export function getEffectiveDefense(creature) {
14
+ return Math.round(creature.defense * getStatMultiplier(creature.statModifiers.defense));
15
+ }
16
+ export function getEffectiveSpeed(creature) {
17
+ let mult = getStatMultiplier(creature.statModifiers.speed);
18
+ if (creature.statusEffects.includes('frozen') || creature.statusEffects.includes('paralyzed')) {
19
+ mult *= 0.5;
20
+ }
21
+ return Math.round(creature.speed * mult);
22
+ }
23
+ export function calculateDamage(attacker, defender, move, rng) {
24
+ // Status moves deal no damage
25
+ if (move.power === 0) {
26
+ return { damage: 0, effectiveness: 'neutral', critical: false, missed: false };
27
+ }
28
+ // Accuracy check
29
+ const accuracyRoll = rng.next() * 100;
30
+ if (accuracyRoll >= move.accuracy) {
31
+ return { damage: 0, effectiveness: 'neutral', critical: false, missed: true };
32
+ }
33
+ const effectiveness = getEffectiveness(move.type, defender.type);
34
+ const typeMultiplier = getTypeMultiplier(effectiveness);
35
+ // Crit check
36
+ let critChance = 10;
37
+ if (move.effect?.type === 'high_crit' && move.effect.critBonus) {
38
+ critChance += move.effect.critBonus;
39
+ }
40
+ const critical = rng.chance(critChance);
41
+ const critMultiplier = critical ? 1.5 : 1.0;
42
+ const atk = getEffectiveAttack(attacker);
43
+ const def = getEffectiveDefense(defender);
44
+ const baseDamage = ((2 * move.power * (atk / Math.max(def, 1))) / 10 + 2);
45
+ const finalDamage = Math.max(1, Math.round(baseDamage * typeMultiplier * critMultiplier * rng.variance()));
46
+ return { damage: finalDamage, effectiveness, critical, missed: false };
47
+ }
48
+ export function applyDamage(creature, damage) {
49
+ creature.hp = Math.max(0, creature.hp - damage);
50
+ }
51
+ //# sourceMappingURL=damage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"damage.js","sourceRoot":"","sources":["../../src/engine/damage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { BattleCreature, MoveDefinition } from '../data/types.js';
2
+ import { SeededRNG } from '../utils/rng.js';
3
+ export declare function applyMoveEffect(move: MoveDefinition, user: BattleCreature, target: BattleCreature, damageDone: number, rng: SeededRNG): string | undefined;
4
+ export declare function processStatusEffects(creature: BattleCreature, rng: SeededRNG): {
5
+ skipTurn: boolean;
6
+ messages: string[];
7
+ };
8
+ export declare function consumePP(creature: BattleCreature, moveName: string): boolean;
9
+ //# sourceMappingURL=effects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effects.d.ts","sourceRoot":"","sources":["../../src/engine/effects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,wBAAgB,eAAe,CAC7B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,SAAS,GACb,MAAM,GAAG,SAAS,CAuDpB;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG;IAC9E,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CA2CA;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAK7E"}
@@ -0,0 +1,99 @@
1
+ export function applyMoveEffect(move, user, target, damageDone, rng) {
2
+ const effect = move.effect;
3
+ if (!effect)
4
+ return undefined;
5
+ const effectTarget = effect.target === 'self' ? user : target;
6
+ switch (effect.type) {
7
+ case 'stat_boost': {
8
+ const stat = effect.stat;
9
+ const stages = effect.stages ?? 1;
10
+ const oldVal = effectTarget.statModifiers[stat];
11
+ effectTarget.statModifiers[stat] = Math.min(4, oldVal + stages);
12
+ const word = stages > 1 ? 'sharply rose' : 'rose';
13
+ return `${effectTarget.name}'s ${stat} ${word}!`;
14
+ }
15
+ case 'stat_lower': {
16
+ const stat = effect.stat;
17
+ const stages = effect.stages ?? 1;
18
+ const oldVal = effectTarget.statModifiers[stat];
19
+ effectTarget.statModifiers[stat] = Math.max(-4, oldVal - stages);
20
+ const word = stages > 1 ? 'sharply fell' : 'fell';
21
+ return `${effectTarget.name}'s ${stat} ${word}!`;
22
+ }
23
+ case 'heal': {
24
+ const healAmount = Math.round(user.maxHp * (effect.healPercent / 100));
25
+ user.hp = Math.min(user.maxHp, user.hp + healAmount);
26
+ return `${user.name} restored ${healAmount} HP!`;
27
+ }
28
+ case 'recoil': {
29
+ const recoilDamage = Math.max(1, Math.round(damageDone * (effect.recoilPercent / 100)));
30
+ user.hp = Math.max(0, user.hp - recoilDamage);
31
+ return `${user.name} took ${recoilDamage} recoil damage!`;
32
+ }
33
+ case 'status': {
34
+ const chance = effect.chance ?? 100;
35
+ if (!rng.chance(chance))
36
+ return undefined;
37
+ const status = effect.status;
38
+ if (effectTarget.statusEffects.includes(status)) {
39
+ return `${effectTarget.name} is already ${status}!`;
40
+ }
41
+ effectTarget.statusEffects.push(status);
42
+ return `${effectTarget.name} was ${status}!`;
43
+ }
44
+ case 'high_crit': {
45
+ // Handled in damage calculation, no additional effect
46
+ return undefined;
47
+ }
48
+ }
49
+ return undefined;
50
+ }
51
+ export function processStatusEffects(creature, rng) {
52
+ const messages = [];
53
+ let skipTurn = false;
54
+ for (const status of creature.statusEffects) {
55
+ switch (status) {
56
+ case 'burned':
57
+ {
58
+ const burnDamage = Math.max(1, Math.round(creature.maxHp * 0.1));
59
+ creature.hp = Math.max(0, creature.hp - burnDamage);
60
+ messages.push(`${creature.name} is hurt by its burn! (-${burnDamage} HP)`);
61
+ }
62
+ break;
63
+ case 'poisoned':
64
+ {
65
+ const poisonDamage = Math.max(1, Math.round(creature.maxHp * 0.08));
66
+ creature.hp = Math.max(0, creature.hp - poisonDamage);
67
+ messages.push(`${creature.name} is hurt by poison! (-${poisonDamage} HP)`);
68
+ }
69
+ break;
70
+ case 'frozen':
71
+ if (rng.chance(25)) {
72
+ skipTurn = true;
73
+ messages.push(`${creature.name} is frozen solid and can't move!`);
74
+ }
75
+ else {
76
+ messages.push(`${creature.name} struggles against the ice!`);
77
+ }
78
+ break;
79
+ case 'paralyzed':
80
+ if (rng.chance(25)) {
81
+ skipTurn = true;
82
+ messages.push(`${creature.name} is paralyzed and can't move!`);
83
+ }
84
+ else {
85
+ messages.push(`${creature.name} fought through the paralysis!`);
86
+ }
87
+ break;
88
+ }
89
+ }
90
+ return { skipTurn, messages };
91
+ }
92
+ export function consumePP(creature, moveName) {
93
+ const move = creature.moves.find(m => m.name === moveName);
94
+ if (!move || move.ppLeft <= 0)
95
+ return false;
96
+ move.ppLeft -= 1;
97
+ return true;
98
+ }
99
+ //# sourceMappingURL=effects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effects.js","sourceRoot":"","sources":["../../src/engine/effects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { CreatureType, MoveType, Effectiveness, TypeInfo } from '../data/types.js';
2
+ export declare function getEffectiveness(moveType: MoveType, defenderType: CreatureType): Effectiveness;
3
+ export declare function getTypeMultiplier(effectiveness: Effectiveness): number;
4
+ export declare function getTypeInfo(type: CreatureType): TypeInfo;
5
+ export declare function getMatchupChart(playerType: CreatureType, opponentType: CreatureType): Record<string, TypeInfo>;
6
+ export declare function getAllTypes(): CreatureType[];
7
+ //# sourceMappingURL=typeChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeChart.d.ts","sourceRoot":"","sources":["../../src/engine/typeChart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAgCnF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,GAAG,aAAa,CAU9F;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAMtE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAoBxD;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAK9G;AAED,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAE5C"}
@@ -0,0 +1,73 @@
1
+ const SUPER_EFFECTIVE = {
2
+ electric: ['water', 'air'],
3
+ earth: ['electric', 'fire', 'metal'],
4
+ water: ['fire', 'earth'],
5
+ fire: ['plant', 'ice', 'metal'],
6
+ air: ['plant', 'poison'],
7
+ plant: ['water', 'earth'],
8
+ light: ['shadow', 'poison'],
9
+ shadow: ['light', 'plasma'],
10
+ metal: ['ice', 'air'],
11
+ ice: ['plant', 'air', 'plasma'],
12
+ poison: ['plant', 'light'],
13
+ plasma: ['metal', 'water'],
14
+ };
15
+ const NOT_VERY_EFFECTIVE = {
16
+ electric: ['earth', 'plant', 'electric'],
17
+ earth: ['air', 'plant'],
18
+ water: ['water', 'plant'],
19
+ fire: ['fire', 'water', 'plasma'],
20
+ air: ['metal', 'electric'],
21
+ plant: ['fire', 'poison', 'metal'],
22
+ light: ['light', 'metal'],
23
+ shadow: ['shadow'],
24
+ metal: ['fire', 'metal', 'earth'],
25
+ ice: ['fire', 'water', 'ice', 'metal'],
26
+ poison: ['metal', 'poison', 'earth'],
27
+ plasma: ['plasma', 'shadow'],
28
+ };
29
+ export function getEffectiveness(moveType, defenderType) {
30
+ if (moveType === 'normal')
31
+ return 'neutral';
32
+ const seList = SUPER_EFFECTIVE[moveType];
33
+ if (seList && seList.includes(defenderType))
34
+ return 'super_effective';
35
+ const nveList = NOT_VERY_EFFECTIVE[moveType];
36
+ if (nveList && nveList.includes(defenderType))
37
+ return 'not_very_effective';
38
+ return 'neutral';
39
+ }
40
+ export function getTypeMultiplier(effectiveness) {
41
+ switch (effectiveness) {
42
+ case 'super_effective': return 1.5;
43
+ case 'not_very_effective': return 0.67;
44
+ case 'neutral': return 1.0;
45
+ }
46
+ }
47
+ export function getTypeInfo(type) {
48
+ const strong_against = SUPER_EFFECTIVE[type] || [];
49
+ const weak_against = NOT_VERY_EFFECTIVE[type] || [];
50
+ const weak_to = [];
51
+ const resists = [];
52
+ for (const [attackType, targets] of Object.entries(SUPER_EFFECTIVE)) {
53
+ if (targets.includes(type)) {
54
+ weak_to.push(attackType);
55
+ }
56
+ }
57
+ for (const [attackType, targets] of Object.entries(NOT_VERY_EFFECTIVE)) {
58
+ if (targets.includes(type)) {
59
+ resists.push(attackType);
60
+ }
61
+ }
62
+ return { strong_against, weak_against, resists, weak_to };
63
+ }
64
+ export function getMatchupChart(playerType, opponentType) {
65
+ return {
66
+ [playerType]: getTypeInfo(playerType),
67
+ [opponentType]: getTypeInfo(opponentType),
68
+ };
69
+ }
70
+ export function getAllTypes() {
71
+ return Object.keys(SUPER_EFFECTIVE);
72
+ }
73
+ //# sourceMappingURL=typeChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeChart.js","sourceRoot":"","sources":["../../src/engine/typeChart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}