pokemon-io-core 0.0.28 → 0.0.29

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.
@@ -123,19 +123,18 @@ const computeCritChance = (rules, critStat) => {
123
123
  return Math.max(0, Math.min(1, raw));
124
124
  };
125
125
  const computeDamage = (input) => {
126
- const { state, attacker, defender, move, isCritical } = input;
126
+ const { state, attacker, defender, moveTypeId, basePower, isCritical } = input;
127
127
  const rules = state.runtime.rules;
128
- const basePower = move.basePower ?? 0;
129
128
  const attackerOff = attacker.effectiveStats.offense;
130
129
  const defenderDef = defender.effectiveStats.defense;
131
- const typeEffectiveness = getTypeEffectiveness(state, move.typeId, defender.classId);
130
+ const typeEffectiveness = getTypeEffectiveness(state, moveTypeId, defender.classId);
132
131
  if (typeEffectiveness === 0) {
133
132
  return {
134
133
  damage: 0,
135
134
  effectiveness: 0,
136
135
  };
137
136
  }
138
- const stabMultiplier = attacker.classId === move.typeId ? rules.stabMultiplier : 1;
137
+ const stabMultiplier = attacker.classId === moveTypeId ? rules.stabMultiplier : 1;
139
138
  const critMultiplier = isCritical ? rules.critMultiplier : 1;
140
139
  const randomFactor = randomInRange(rules.randomMinDamageFactor, rules.randomMaxDamageFactor);
141
140
  const rawDamage = basePower *
@@ -194,7 +193,8 @@ const applyStatusToFighter = (state, target, statusId) => {
194
193
  return { updated: target, events: [] };
195
194
  const events = [];
196
195
  const existing = target.statuses.find((s) => s.statusId === statusId);
197
- const duration = Math.floor(randomInRange(def.minDurationTurns, def.maxDurationTurns + 1)) || def.minDurationTurns;
196
+ const duration = Math.floor(randomInRange(def.minDurationTurns, def.maxDurationTurns + 1)) ||
197
+ def.minDurationTurns;
198
198
  let newStatuses = [...target.statuses];
199
199
  if (!existing) {
200
200
  newStatuses.push({
@@ -227,7 +227,10 @@ const applyStatusToFighter = (state, target, statusId) => {
227
227
  events,
228
228
  };
229
229
  };
230
- const applyClearStatusToFighter = (state, target, effect) => {
230
+ // ------------------------------------------------------
231
+ // clear_status
232
+ // ------------------------------------------------------
233
+ const clearStatusFromFighter = (state, target, effect) => {
231
234
  const { statusIds, kinds, clearAll } = effect;
232
235
  const events = [];
233
236
  const before = target.statuses;
@@ -299,42 +302,104 @@ const applyHealToFighter = (state, target, amount, sourceId) => {
299
302
  return { updated, events };
300
303
  };
301
304
  // ------------------------------------------------------
305
+ // Target por defecto y resolución de target
306
+ // ------------------------------------------------------
307
+ const defaultTargetForKind = (kind) => {
308
+ switch (kind) {
309
+ case "damage":
310
+ case "apply_status":
311
+ return "enemy";
312
+ case "heal":
313
+ case "clear_status":
314
+ case "modify_stats":
315
+ case "modify_hit_chance":
316
+ case "modify_crit_chance":
317
+ case "modify_priority":
318
+ case "modify_effective_speed":
319
+ case "shield":
320
+ return "self";
321
+ default:
322
+ return "self";
323
+ }
324
+ };
325
+ const resolveEffectTarget = (eff, actor, target) => {
326
+ const t = eff.target ?? defaultTargetForKind(eff.kind);
327
+ const isSelf = t === "self";
328
+ return {
329
+ primary: isSelf ? actor : target,
330
+ isSelf,
331
+ };
332
+ };
333
+ // ------------------------------------------------------
302
334
  // Motor de efectos genérico (move + item)
303
335
  // ------------------------------------------------------
304
- const applyEffectsOnTarget = (state, actor, target, effects) => {
336
+ const applyEffectsOnTarget = (state, actor, target, moveTypeId, isCritical, effects) => {
305
337
  let currentActor = actor;
306
338
  let currentTarget = target;
307
339
  const events = [];
308
340
  for (const eff of effects) {
309
341
  switch (eff.kind) {
310
342
  case "heal": {
311
- const res = applyHealToFighter(state, currentActor, eff.amount, actor.fighterId);
312
- currentActor = res.updated;
343
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
344
+ const res = applyHealToFighter(state, primary, eff.amount, actor.fighterId);
345
+ if (isSelf)
346
+ currentActor = res.updated;
347
+ else
348
+ currentTarget = res.updated;
313
349
  events.push(...res.events);
314
350
  break;
315
351
  }
316
352
  case "apply_status": {
317
- const res = applyStatusToFighter(state, currentTarget, eff.statusId);
318
- currentTarget = res.updated;
353
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
354
+ const res = applyStatusToFighter(state, primary, eff.statusId);
355
+ if (isSelf)
356
+ currentActor = res.updated;
357
+ else
358
+ currentTarget = res.updated;
319
359
  events.push(...res.events);
320
360
  break;
321
361
  }
322
362
  case "clear_status": {
323
- const res = applyClearStatusToFighter(state, currentTarget, eff);
324
- currentTarget = res.updated;
363
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
364
+ const res = clearStatusFromFighter(state, primary, eff);
365
+ if (isSelf)
366
+ currentActor = res.updated;
367
+ else
368
+ currentTarget = res.updated;
325
369
  events.push(...res.events);
326
370
  break;
327
371
  }
328
372
  case "damage": {
329
- if (typeof eff.amount === "number") {
330
- const res = applyDamageToFighter(state, currentTarget, eff.amount, actor.fighterId, false);
331
- currentTarget = res.updatedDefender;
373
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
374
+ let totalDamage = 0;
375
+ // Daño de fórmula (stats + tipo + crit…)
376
+ if (eff.basePower && moveTypeId) {
377
+ const { damage } = computeDamage({
378
+ state,
379
+ attacker: currentActor,
380
+ defender: primary,
381
+ moveTypeId,
382
+ basePower: eff.basePower,
383
+ isCritical,
384
+ });
385
+ totalDamage += damage;
386
+ }
387
+ // Daño plano adicional
388
+ if (eff.flatAmount && eff.flatAmount > 0) {
389
+ totalDamage += eff.flatAmount;
390
+ }
391
+ if (totalDamage > 0) {
392
+ const res = applyDamageToFighter(state, primary, totalDamage, currentActor.fighterId, isCritical);
393
+ if (isSelf)
394
+ currentActor = res.updatedDefender;
395
+ else
396
+ currentTarget = res.updatedDefender;
332
397
  events.push(...res.events);
333
398
  }
334
399
  break;
335
400
  }
401
+ // TODO: conectar shield, modify_stats, etc.
336
402
  default:
337
- // otros efectos (modify_stats, etc.) se pueden añadir aquí
338
403
  break;
339
404
  }
340
405
  }
@@ -373,6 +438,7 @@ const resolveDamageMove = (state, playerKey, action) => {
373
438
  const { self, opponent } = getOpponentAndSelf(state, playerKey);
374
439
  const events = [];
375
440
  const moveSlot = self.moves[action.moveIndex];
441
+ dbg("use_move: slot", moveSlot);
376
442
  if (!moveSlot) {
377
443
  dbg("use_move: empty slot", { playerKey, moveIndex: action.moveIndex });
378
444
  return { state, events };
@@ -393,30 +459,6 @@ const resolveDamageMove = (state, playerKey, action) => {
393
459
  });
394
460
  return { state, events };
395
461
  }
396
- // Movimiento solo de curación → no calculamos daño base
397
- if (move.kind === "heal") {
398
- events.push({
399
- ...createBaseEvent(state.turnNumber, "action_declared", `${self.fighterId} usa ${move.name}`),
400
- actorId: self.fighterId,
401
- });
402
- const updatedMoves = self.moves.map((m, idx) => idx === action.moveIndex
403
- ? { ...m, currentPP: Math.max(0, m.currentPP - 1) }
404
- : m);
405
- let updatedSelf = { ...self, moves: updatedMoves };
406
- let updatedOpponent = { ...opponent };
407
- const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, move.effects);
408
- events.push(...extraEvents);
409
- const newState = updateFightersInState(state, playerKey, finalSelf, finalOpp);
410
- return { state: newState, events };
411
- }
412
- dbg("ACTION", {
413
- playerKey,
414
- fighterId: self.fighterId,
415
- moveId: move.id,
416
- moveName: move.name,
417
- targetId: opponent.fighterId,
418
- currentPP: moveSlot.currentPP,
419
- });
420
462
  events.push({
421
463
  ...createBaseEvent(state.turnNumber, "action_declared", `${self.fighterId} usa ${move.name}`),
422
464
  actorId: self.fighterId,
@@ -448,19 +490,12 @@ const resolveDamageMove = (state, playerKey, action) => {
448
490
  }
449
491
  const critChance = computeCritChance(state.runtime.rules, updatedSelf.effectiveStats.crit);
450
492
  const isCritical = chance(critChance);
451
- const { damage, effectiveness } = computeDamage({
452
- state,
453
- attacker: updatedSelf,
454
- defender: updatedOpponent,
455
- move,
456
- isCritical,
457
- });
493
+ const effectiveness = getTypeEffectiveness(state, move.typeId, updatedOpponent.classId);
458
494
  dbg("HIT", {
459
495
  fighterId: self.fighterId,
460
496
  moveId: move.id,
461
497
  moveName: move.name,
462
498
  isCritical,
463
- damage,
464
499
  effectiveness,
465
500
  defenderBeforeHp: opponent.currentHp,
466
501
  });
@@ -472,21 +507,14 @@ const resolveDamageMove = (state, playerKey, action) => {
472
507
  isCritical,
473
508
  effectiveness,
474
509
  });
475
- const damageRes = applyDamageToFighter(state, updatedOpponent, damage, updatedSelf.fighterId, isCritical);
476
- dbg("AFTER_DAMAGE", {
477
- targetId: opponent.fighterId,
478
- newHp: damageRes.updatedDefender.currentHp,
479
- });
480
- updatedOpponent = damageRes.updatedDefender;
481
- events.push(...damageRes.events);
482
- // Efectos secundarios del movimiento (quemado, buffs, daño fijo, etc.)
483
- const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, move.effects);
510
+ // Todos los efectos (daño, aplicar estado, curas, etc.)
511
+ const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, move.typeId, isCritical, move.effects);
484
512
  events.push(...extraEvents);
485
513
  const newState = updateFightersInState(state, playerKey, finalSelf, finalOpp);
486
514
  return { state: newState, events };
487
515
  };
488
516
  // ------------------------------------------------------
489
- // use_item (respeta item.target: "self" | "enemy")
517
+ // use_item (ahora el target real está en cada efecto)
490
518
  // ------------------------------------------------------
491
519
  const resolveItemUse = (state, playerKey, action) => {
492
520
  if (action.kind !== "use_item") {
@@ -519,23 +547,9 @@ const resolveItemUse = (state, playerKey, action) => {
519
547
  ...createBaseEvent(state.turnNumber, "action_declared", `${self.fighterId} usa objeto ${itemDef.name}`),
520
548
  actorId: self.fighterId,
521
549
  });
522
- let finalSelf = updatedSelf;
523
- let finalOpp = updatedOpponent;
524
- // interpretamos itemDef.target:
525
- // - "self" → efectos aplican sobre el propio usuario
526
- // - "enemy" → efectos sobre el rival
527
- if (itemDef.target === "self") {
528
- const res = applyEffectsOnTarget(state, updatedSelf, updatedSelf, itemDef.effects);
529
- finalSelf = res.actor; // o res.target, son el mismo
530
- // el oponente no cambia
531
- events.push(...res.events);
532
- }
533
- else {
534
- const res = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, itemDef.effects);
535
- finalSelf = res.actor;
536
- finalOpp = res.target;
537
- events.push(...res.events);
538
- }
550
+ const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, null, // los items no usan fórmula de tipo por ahora
551
+ false, itemDef.effects);
552
+ events.push(...extraEvents);
539
553
  const newState = updateFightersInState(state, playerKey, finalSelf, finalOpp);
540
554
  return { state: newState, events };
541
555
  };
@@ -611,8 +625,12 @@ const applyEndOfTurnStatuses = (state) => {
611
625
  def.effectsPerStack.forEach((eff) => {
612
626
  if (eff.kind === "damage") {
613
627
  const stacksMultiplier = st.stacks === 2 ? 2 : 1;
614
- const basePower = typeof eff.amount === "number" ? eff.amount : 10;
615
- damageFromStatus += basePower * stacksMultiplier;
628
+ const base = typeof eff.flatAmount === "number"
629
+ ? eff.flatAmount
630
+ : typeof eff.basePower === "number"
631
+ ? eff.basePower
632
+ : 10; // fallback
633
+ damageFromStatus += base * stacksMultiplier;
616
634
  }
617
635
  });
618
636
  if (damageFromStatus > 0 && updated.isAlive) {
@@ -1,76 +1,73 @@
1
1
  import type { MoveId, StatusId, TypeId } from "./ids";
2
- import { StatusKind } from "./status";
3
- export type MoveKind = "damage" | "heal" | "status" | "hybrid";
4
- export type TargetKind = "self" | "enemy";
2
+ export type EffectTarget = "self" | "enemy";
5
3
  export type EffectKind = "damage" | "heal" | "shield" | "modify_stats" | "apply_status" | "clear_status" | "modify_hit_chance" | "modify_crit_chance" | "modify_priority" | "modify_effective_speed";
6
- export interface DamageEffect {
4
+ export type TargetKind = EffectTarget;
5
+ interface BaseEffect {
6
+ target?: EffectTarget;
7
+ }
8
+ export interface DamageEffect extends BaseEffect {
7
9
  kind: "damage";
8
- amount: number;
9
- powerMultiplier?: number;
10
- flatBonus?: number;
10
+ /**
11
+ * Daño “de fórmula” (stats + tipo + crit…).
12
+ * Si no se define, NO se llama a computeDamage.
13
+ */
14
+ basePower?: number;
15
+ /**
16
+ * Daño plano adicional.
17
+ * Se suma al daño de fórmula o se usa solo si no hay basePower.
18
+ */
19
+ flatAmount?: number;
11
20
  }
12
- export interface HealEffect {
21
+ export interface HealEffect extends BaseEffect {
13
22
  kind: "heal";
14
23
  amount: number;
15
24
  }
16
- export interface ShieldEffect {
25
+ export interface ShieldEffect extends BaseEffect {
17
26
  kind: "shield";
18
27
  amount: number;
19
28
  durationTurns: number;
20
29
  }
21
- export interface ModifyStatsEffect {
30
+ export interface ModifyStatsEffect extends BaseEffect {
22
31
  kind: "modify_stats";
23
32
  offenseDelta?: number;
24
33
  defenseDelta?: number;
25
34
  speedDelta?: number;
26
35
  critDelta?: number;
27
36
  }
28
- export interface ApplyStatusEffect {
37
+ export interface ApplyStatusEffect extends BaseEffect {
29
38
  kind: "apply_status";
30
39
  statusId: StatusId;
31
40
  }
32
- export interface ClearStatusEffect {
41
+ export interface ClearStatusEffect extends BaseEffect {
33
42
  kind: "clear_status";
34
43
  statusIds?: StatusId[];
35
- /**
36
- * Filtros opcionales por tipo de estado (hard_cc / soft).
37
- * Ejemplo: una berry que limpia solo debuffs “soft”.
38
- */
39
- kinds?: StatusKind[];
40
- /**
41
- * Si quieres que limpie TODO sin importar id ni tipo:
42
- * - statusIds === undefined
43
- * - kinds === undefined
44
- * - clearAll === true
45
- */
44
+ kinds?: ("hard_cc" | "soft")[];
46
45
  clearAll?: boolean;
47
46
  }
48
- export interface ModifyHitChanceEffect {
47
+ export interface ModifyHitChanceEffect extends BaseEffect {
49
48
  kind: "modify_hit_chance";
50
49
  delta: number;
51
50
  }
52
- export interface ModifyCritChanceEffect {
51
+ export interface ModifyCritChanceEffect extends BaseEffect {
53
52
  kind: "modify_crit_chance";
54
53
  delta: number;
55
54
  }
56
- export interface ModifyPriorityEffect {
55
+ export interface ModifyPriorityEffect extends BaseEffect {
57
56
  kind: "modify_priority";
58
57
  delta: number;
59
58
  }
60
- export interface ModifyEffectiveSpeedEffect {
59
+ export interface ModifyEffectiveSpeedEffect extends BaseEffect {
61
60
  kind: "modify_effective_speed";
62
61
  multiplier: number;
63
62
  }
64
- export type EffectDefinition = DamageEffect | HealEffect | ShieldEffect | ClearStatusEffect | ModifyStatsEffect | ApplyStatusEffect | ModifyHitChanceEffect | ModifyCritChanceEffect | ModifyPriorityEffect | ModifyEffectiveSpeedEffect;
63
+ export type EffectDefinition = DamageEffect | HealEffect | ShieldEffect | ModifyStatsEffect | ApplyStatusEffect | ClearStatusEffect | ModifyHitChanceEffect | ModifyCritChanceEffect | ModifyPriorityEffect | ModifyEffectiveSpeedEffect;
65
64
  export interface MoveDefinition {
66
65
  id: MoveId;
67
66
  name: string;
68
67
  typeId: TypeId;
69
- kind: MoveKind;
70
- basePower?: number;
71
68
  accuracy?: number;
72
69
  maxPP: number;
73
70
  priority?: number;
74
- target: TargetKind;
75
71
  effects: EffectDefinition[];
76
72
  }
73
+ export {};
@@ -1 +1,2 @@
1
+ // core/moves.ts
1
2
  export {};
@@ -42,7 +42,7 @@ export const POKEMON_ITEMS = [
42
42
  category: "damage",
43
43
  maxUses: 2,
44
44
  effects: [
45
- { kind: "damage", amount: 15 },
45
+ { kind: "damage", flatAmount: 15 },
46
46
  { kind: "apply_status", statusId: "burn" },
47
47
  ],
48
48
  image: "shotgun",
@@ -54,7 +54,7 @@ export const POKEMON_ITEMS = [
54
54
  target: "enemy",
55
55
  maxUses: 4,
56
56
  effects: [
57
- { kind: "damage", amount: 8 },
57
+ { kind: "damage", flatAmount: 8 },
58
58
  { kind: "apply_status", statusId: "burn" },
59
59
  ],
60
60
  image: "pistol",
@@ -66,7 +66,7 @@ export const POKEMON_ITEMS = [
66
66
  category: "damage",
67
67
  maxUses: 3,
68
68
  effects: [
69
- { kind: "damage", amount: 10 },
69
+ { kind: "damage", flatAmount: 10 },
70
70
  { kind: "apply_status", statusId: "burn" },
71
71
  ],
72
72
  image: "riffle",
@@ -78,7 +78,7 @@ export const POKEMON_ITEMS = [
78
78
  category: "damage",
79
79
  maxUses: 1,
80
80
  effects: [
81
- { kind: "damage", amount: 30 },
81
+ { kind: "damage", flatAmount: 30 },
82
82
  { kind: "apply_status", statusId: "burn" },
83
83
  ],
84
84
  image: "sniper",
@@ -4,19 +4,18 @@ export const POKEMON_MOVES = [
4
4
  id: "tackle",
5
5
  name: "Placaje",
6
6
  typeId: POKEMON_TYPE_IDS.fire,
7
- kind: "damage",
8
- basePower: 40,
9
7
  accuracy: 100,
10
8
  maxPP: 35,
11
9
  priority: 0,
12
- target: "enemy",
13
10
  effects: [
14
11
  {
15
12
  kind: "damage",
16
- amount: 20,
13
+ target: "enemy",
14
+ basePower: 40,
17
15
  },
18
16
  {
19
17
  kind: "apply_status",
18
+ target: "enemy",
20
19
  statusId: "poison",
21
20
  },
22
21
  ],
@@ -24,35 +23,39 @@ export const POKEMON_MOVES = [
24
23
  {
25
24
  id: "fire_fang",
26
25
  name: "Colmillo Ígneo",
27
- typeId: "fire",
28
- kind: "damage",
29
- basePower: 65,
26
+ typeId: POKEMON_TYPE_IDS.fire,
30
27
  accuracy: 95,
31
28
  maxPP: 15,
32
29
  priority: 0,
33
- target: "enemy",
34
30
  effects: [
35
- { kind: "damage", amount: 10 },
36
- { kind: "apply_status", statusId: "burn" },
31
+ {
32
+ kind: "damage",
33
+ target: "enemy",
34
+ basePower: 65,
35
+ },
36
+ {
37
+ kind: "apply_status",
38
+ target: "enemy",
39
+ statusId: "burn",
40
+ },
37
41
  ],
38
42
  },
39
43
  {
40
44
  id: "ember",
41
45
  name: "Ascuas",
42
46
  typeId: POKEMON_TYPE_IDS.fire,
43
- kind: "damage",
44
- basePower: 20,
45
47
  accuracy: 100,
46
48
  maxPP: 25,
47
49
  priority: 0,
48
- target: "enemy",
49
50
  effects: [
50
51
  {
51
52
  kind: "damage",
52
- amount: 20,
53
+ target: "enemy",
54
+ basePower: 20,
53
55
  },
54
56
  {
55
57
  kind: "apply_status",
58
+ target: "enemy",
56
59
  statusId: "burn",
57
60
  },
58
61
  ],
@@ -61,15 +64,13 @@ export const POKEMON_MOVES = [
61
64
  id: "water_gun",
62
65
  name: "Pistola Agua",
63
66
  typeId: POKEMON_TYPE_IDS.water,
64
- kind: "damage",
65
- basePower: 40,
66
67
  accuracy: 100,
67
68
  maxPP: 25,
68
69
  priority: 0,
69
- target: "enemy",
70
70
  effects: [
71
71
  {
72
72
  kind: "apply_status",
73
+ target: "enemy",
73
74
  statusId: "poison",
74
75
  },
75
76
  ],
@@ -78,16 +79,14 @@ export const POKEMON_MOVES = [
78
79
  id: "water_gun2",
79
80
  name: "Hidropulso",
80
81
  typeId: POKEMON_TYPE_IDS.water,
81
- kind: "damage",
82
- basePower: 40,
83
82
  accuracy: 100,
84
83
  maxPP: 25,
85
84
  priority: 0,
86
- target: "enemy",
87
85
  effects: [
88
86
  {
89
87
  kind: "damage",
90
- amount: 20,
88
+ target: "enemy",
89
+ basePower: 40,
91
90
  },
92
91
  ],
93
92
  },
@@ -95,16 +94,14 @@ export const POKEMON_MOVES = [
95
94
  id: "water_gun3",
96
95
  name: "Llover",
97
96
  typeId: POKEMON_TYPE_IDS.water,
98
- kind: "damage",
99
- basePower: 40,
100
97
  accuracy: 100,
101
98
  maxPP: 25,
102
99
  priority: 0,
103
- target: "enemy",
104
100
  effects: [
105
101
  {
106
102
  kind: "damage",
107
- amount: 20,
103
+ target: "enemy",
104
+ basePower: 40,
108
105
  },
109
106
  ],
110
107
  },
@@ -112,16 +109,14 @@ export const POKEMON_MOVES = [
112
109
  id: "water_gun4",
113
110
  name: "Wet",
114
111
  typeId: POKEMON_TYPE_IDS.water,
115
- kind: "damage",
116
- basePower: 40,
117
112
  accuracy: 100,
118
113
  maxPP: 25,
119
114
  priority: 0,
120
- target: "enemy",
121
115
  effects: [
122
116
  {
123
117
  kind: "damage",
124
- amount: 20,
118
+ target: "enemy",
119
+ basePower: 40,
125
120
  },
126
121
  ],
127
122
  },
@@ -129,16 +124,14 @@ export const POKEMON_MOVES = [
129
124
  id: "vine_whip",
130
125
  name: "Látigo Cepa",
131
126
  typeId: POKEMON_TYPE_IDS.grass,
132
- kind: "damage",
133
- basePower: 45,
134
127
  accuracy: 100,
135
128
  maxPP: 25,
136
129
  priority: 0,
137
- target: "enemy",
138
130
  effects: [
139
131
  {
140
132
  kind: "damage",
141
- amount: 20,
133
+ target: "enemy",
134
+ basePower: 45,
142
135
  },
143
136
  ],
144
137
  },
@@ -146,16 +139,14 @@ export const POKEMON_MOVES = [
146
139
  id: "vine_whip2",
147
140
  name: "Hierbita",
148
141
  typeId: POKEMON_TYPE_IDS.grass,
149
- kind: "damage",
150
- basePower: 45,
151
142
  accuracy: 100,
152
143
  maxPP: 25,
153
144
  priority: 0,
154
- target: "enemy",
155
145
  effects: [
156
146
  {
157
147
  kind: "damage",
158
- amount: 20,
148
+ target: "enemy",
149
+ basePower: 45,
159
150
  },
160
151
  ],
161
152
  },
@@ -163,16 +154,14 @@ export const POKEMON_MOVES = [
163
154
  id: "vine_whip3",
164
155
  name: "Buena flor",
165
156
  typeId: POKEMON_TYPE_IDS.grass,
166
- kind: "damage",
167
- basePower: 45,
168
157
  accuracy: 100,
169
158
  maxPP: 25,
170
159
  priority: 0,
171
- target: "enemy",
172
160
  effects: [
173
161
  {
174
162
  kind: "damage",
175
- amount: 20,
163
+ target: "enemy",
164
+ basePower: 45,
176
165
  },
177
166
  ],
178
167
  },
@@ -180,16 +169,14 @@ export const POKEMON_MOVES = [
180
169
  id: "vine_whip4",
181
170
  name: "Recurrente",
182
171
  typeId: POKEMON_TYPE_IDS.grass,
183
- kind: "damage",
184
- basePower: 45,
185
172
  accuracy: 100,
186
173
  maxPP: 25,
187
174
  priority: 0,
188
- target: "enemy",
189
175
  effects: [
190
176
  {
191
177
  kind: "damage",
192
- amount: 20,
178
+ target: "enemy",
179
+ basePower: 45,
193
180
  },
194
181
  ],
195
182
  },
@@ -197,16 +184,14 @@ export const POKEMON_MOVES = [
197
184
  id: "thunder_shock",
198
185
  name: "Impactrueno",
199
186
  typeId: POKEMON_TYPE_IDS.electric,
200
- kind: "damage",
201
- basePower: 40,
202
187
  accuracy: 100,
203
188
  maxPP: 30,
204
189
  priority: 0,
205
- target: "enemy",
206
190
  effects: [
207
191
  {
208
192
  kind: "damage",
209
- amount: 20,
193
+ target: "enemy",
194
+ basePower: 40,
210
195
  },
211
196
  ],
212
197
  },
@@ -214,16 +199,14 @@ export const POKEMON_MOVES = [
214
199
  id: "thunder_shock2",
215
200
  name: "Rayo",
216
201
  typeId: POKEMON_TYPE_IDS.electric,
217
- kind: "damage",
218
- basePower: 40,
219
202
  accuracy: 100,
220
203
  maxPP: 30,
221
204
  priority: 0,
222
- target: "enemy",
223
205
  effects: [
224
206
  {
225
207
  kind: "damage",
226
- amount: 20,
208
+ target: "enemy",
209
+ basePower: 40,
227
210
  },
228
211
  ],
229
212
  },
@@ -231,16 +214,14 @@ export const POKEMON_MOVES = [
231
214
  id: "thunder_shock3",
232
215
  name: "Tormenta",
233
216
  typeId: POKEMON_TYPE_IDS.electric,
234
- kind: "damage",
235
- basePower: 40,
236
217
  accuracy: 100,
237
218
  maxPP: 30,
238
219
  priority: 0,
239
- target: "enemy",
240
220
  effects: [
241
221
  {
242
222
  kind: "damage",
243
- amount: 20,
223
+ target: "enemy",
224
+ basePower: 40,
244
225
  },
245
226
  ],
246
227
  },
@@ -248,16 +229,14 @@ export const POKEMON_MOVES = [
248
229
  id: "thunder_shock4",
249
230
  name: "Lluvia de rayos",
250
231
  typeId: POKEMON_TYPE_IDS.electric,
251
- kind: "damage",
252
- basePower: 40,
253
232
  accuracy: 100,
254
233
  maxPP: 30,
255
234
  priority: 0,
256
- target: "enemy",
257
235
  effects: [
258
236
  {
259
237
  kind: "damage",
260
- amount: 20,
238
+ target: "enemy",
239
+ basePower: 40,
261
240
  },
262
241
  ],
263
242
  },
@@ -265,16 +244,14 @@ export const POKEMON_MOVES = [
265
244
  id: "think",
266
245
  name: "Rayada mental",
267
246
  typeId: POKEMON_TYPE_IDS.psychic,
268
- kind: "damage",
269
- basePower: 40,
270
247
  accuracy: 100,
271
248
  maxPP: 30,
272
249
  priority: 0,
273
- target: "enemy",
274
250
  effects: [
275
251
  {
276
252
  kind: "damage",
277
- amount: 20,
253
+ target: "enemy",
254
+ basePower: 40,
278
255
  },
279
256
  ],
280
257
  },
@@ -282,16 +259,14 @@ export const POKEMON_MOVES = [
282
259
  id: "think2",
283
260
  name: "Psicoterapia",
284
261
  typeId: POKEMON_TYPE_IDS.psychic,
285
- kind: "damage",
286
- basePower: 40,
287
262
  accuracy: 100,
288
263
  maxPP: 30,
289
264
  priority: 0,
290
- target: "enemy",
291
265
  effects: [
292
266
  {
293
267
  kind: "damage",
294
- amount: 20,
268
+ target: "enemy",
269
+ basePower: 40,
295
270
  },
296
271
  ],
297
272
  },
@@ -6,9 +6,19 @@ export const POKEMON_STATUSES = [
6
6
  minDurationTurns: 3,
7
7
  maxDurationTurns: 5,
8
8
  effectsPerStack: [
9
- { kind: "damage", amount: 6 }, // DoT
10
- { kind: "modify_stats", offenseDelta: -10 } // pega menos
11
- ]
9
+ {
10
+ // Daño plano por turno
11
+ kind: "damage",
12
+ target: "self",
13
+ flatAmount: 6,
14
+ },
15
+ {
16
+ // Baja el ataque mientras dure el estado
17
+ kind: "modify_stats",
18
+ target: "self",
19
+ offenseDelta: -10,
20
+ },
21
+ ],
12
22
  },
13
23
  {
14
24
  id: "poison",
@@ -17,8 +27,12 @@ export const POKEMON_STATUSES = [
17
27
  minDurationTurns: 3,
18
28
  maxDurationTurns: 5,
19
29
  effectsPerStack: [
20
- { kind: "damage", amount: 8 }
21
- ]
30
+ {
31
+ kind: "damage",
32
+ target: "self",
33
+ flatAmount: 8,
34
+ },
35
+ ],
22
36
  },
23
37
  {
24
38
  id: "paralysis",
@@ -27,8 +41,12 @@ export const POKEMON_STATUSES = [
27
41
  minDurationTurns: 2,
28
42
  maxDurationTurns: 4,
29
43
  effectsPerStack: [
30
- { kind: "modify_effective_speed", multiplier: 0.5 }
31
- ]
44
+ {
45
+ kind: "modify_effective_speed",
46
+ target: "self",
47
+ multiplier: 0.5,
48
+ },
49
+ ],
32
50
  },
33
51
  {
34
52
  id: "sleep",
@@ -36,6 +54,9 @@ export const POKEMON_STATUSES = [
36
54
  kind: "hard_cc",
37
55
  minDurationTurns: 1,
38
56
  maxDurationTurns: 3,
39
- effectsPerStack: [] // el hard_cc lo interpreta el motor
40
- }
57
+ effectsPerStack: [
58
+ // El motor interpreta hard_cc y bloquea la acción;
59
+ // no necesitas más efectos aquí de momento.
60
+ ],
61
+ },
41
62
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pokemon-io-core",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",