pokemon-io-core 0.0.27 → 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,51 +4,58 @@ 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,
15
+ },
16
+ {
17
+ kind: "apply_status",
18
+ target: "enemy",
19
+ statusId: "poison",
17
20
  },
18
21
  ],
19
22
  },
20
23
  {
21
24
  id: "fire_fang",
22
25
  name: "Colmillo Ígneo",
23
- typeId: "fire",
24
- kind: "damage",
25
- basePower: 65,
26
+ typeId: POKEMON_TYPE_IDS.fire,
26
27
  accuracy: 95,
27
28
  maxPP: 15,
28
29
  priority: 0,
29
- target: "enemy",
30
30
  effects: [
31
- { kind: "damage", amount: 10 },
32
- { 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
+ },
33
41
  ],
34
42
  },
35
43
  {
36
44
  id: "ember",
37
45
  name: "Ascuas",
38
46
  typeId: POKEMON_TYPE_IDS.fire,
39
- kind: "damage",
40
- basePower: 20,
41
47
  accuracy: 100,
42
48
  maxPP: 25,
43
49
  priority: 0,
44
- target: "enemy",
45
50
  effects: [
46
51
  {
47
52
  kind: "damage",
48
- amount: 20,
53
+ target: "enemy",
54
+ basePower: 20,
49
55
  },
50
56
  {
51
57
  kind: "apply_status",
58
+ target: "enemy",
52
59
  statusId: "burn",
53
60
  },
54
61
  ],
@@ -57,16 +64,14 @@ export const POKEMON_MOVES = [
57
64
  id: "water_gun",
58
65
  name: "Pistola Agua",
59
66
  typeId: POKEMON_TYPE_IDS.water,
60
- kind: "damage",
61
- basePower: 40,
62
67
  accuracy: 100,
63
68
  maxPP: 25,
64
69
  priority: 0,
65
- target: "enemy",
66
70
  effects: [
67
71
  {
68
- kind: "damage",
69
- amount: 20,
72
+ kind: "apply_status",
73
+ target: "enemy",
74
+ statusId: "poison",
70
75
  },
71
76
  ],
72
77
  },
@@ -74,16 +79,14 @@ export const POKEMON_MOVES = [
74
79
  id: "water_gun2",
75
80
  name: "Hidropulso",
76
81
  typeId: POKEMON_TYPE_IDS.water,
77
- kind: "damage",
78
- basePower: 40,
79
82
  accuracy: 100,
80
83
  maxPP: 25,
81
84
  priority: 0,
82
- target: "enemy",
83
85
  effects: [
84
86
  {
85
87
  kind: "damage",
86
- amount: 20,
88
+ target: "enemy",
89
+ basePower: 40,
87
90
  },
88
91
  ],
89
92
  },
@@ -91,16 +94,14 @@ export const POKEMON_MOVES = [
91
94
  id: "water_gun3",
92
95
  name: "Llover",
93
96
  typeId: POKEMON_TYPE_IDS.water,
94
- kind: "damage",
95
- basePower: 40,
96
97
  accuracy: 100,
97
98
  maxPP: 25,
98
99
  priority: 0,
99
- target: "enemy",
100
100
  effects: [
101
101
  {
102
102
  kind: "damage",
103
- amount: 20,
103
+ target: "enemy",
104
+ basePower: 40,
104
105
  },
105
106
  ],
106
107
  },
@@ -108,16 +109,14 @@ export const POKEMON_MOVES = [
108
109
  id: "water_gun4",
109
110
  name: "Wet",
110
111
  typeId: POKEMON_TYPE_IDS.water,
111
- kind: "damage",
112
- basePower: 40,
113
112
  accuracy: 100,
114
113
  maxPP: 25,
115
114
  priority: 0,
116
- target: "enemy",
117
115
  effects: [
118
116
  {
119
117
  kind: "damage",
120
- amount: 20,
118
+ target: "enemy",
119
+ basePower: 40,
121
120
  },
122
121
  ],
123
122
  },
@@ -125,16 +124,14 @@ export const POKEMON_MOVES = [
125
124
  id: "vine_whip",
126
125
  name: "Látigo Cepa",
127
126
  typeId: POKEMON_TYPE_IDS.grass,
128
- kind: "damage",
129
- basePower: 45,
130
127
  accuracy: 100,
131
128
  maxPP: 25,
132
129
  priority: 0,
133
- target: "enemy",
134
130
  effects: [
135
131
  {
136
132
  kind: "damage",
137
- amount: 20,
133
+ target: "enemy",
134
+ basePower: 45,
138
135
  },
139
136
  ],
140
137
  },
@@ -142,16 +139,14 @@ export const POKEMON_MOVES = [
142
139
  id: "vine_whip2",
143
140
  name: "Hierbita",
144
141
  typeId: POKEMON_TYPE_IDS.grass,
145
- kind: "damage",
146
- basePower: 45,
147
142
  accuracy: 100,
148
143
  maxPP: 25,
149
144
  priority: 0,
150
- target: "enemy",
151
145
  effects: [
152
146
  {
153
147
  kind: "damage",
154
- amount: 20,
148
+ target: "enemy",
149
+ basePower: 45,
155
150
  },
156
151
  ],
157
152
  },
@@ -159,16 +154,14 @@ export const POKEMON_MOVES = [
159
154
  id: "vine_whip3",
160
155
  name: "Buena flor",
161
156
  typeId: POKEMON_TYPE_IDS.grass,
162
- kind: "damage",
163
- basePower: 45,
164
157
  accuracy: 100,
165
158
  maxPP: 25,
166
159
  priority: 0,
167
- target: "enemy",
168
160
  effects: [
169
161
  {
170
162
  kind: "damage",
171
- amount: 20,
163
+ target: "enemy",
164
+ basePower: 45,
172
165
  },
173
166
  ],
174
167
  },
@@ -176,16 +169,14 @@ export const POKEMON_MOVES = [
176
169
  id: "vine_whip4",
177
170
  name: "Recurrente",
178
171
  typeId: POKEMON_TYPE_IDS.grass,
179
- kind: "damage",
180
- basePower: 45,
181
172
  accuracy: 100,
182
173
  maxPP: 25,
183
174
  priority: 0,
184
- target: "enemy",
185
175
  effects: [
186
176
  {
187
177
  kind: "damage",
188
- amount: 20,
178
+ target: "enemy",
179
+ basePower: 45,
189
180
  },
190
181
  ],
191
182
  },
@@ -193,16 +184,14 @@ export const POKEMON_MOVES = [
193
184
  id: "thunder_shock",
194
185
  name: "Impactrueno",
195
186
  typeId: POKEMON_TYPE_IDS.electric,
196
- kind: "damage",
197
- basePower: 40,
198
187
  accuracy: 100,
199
188
  maxPP: 30,
200
189
  priority: 0,
201
- target: "enemy",
202
190
  effects: [
203
191
  {
204
192
  kind: "damage",
205
- amount: 20,
193
+ target: "enemy",
194
+ basePower: 40,
206
195
  },
207
196
  ],
208
197
  },
@@ -210,16 +199,14 @@ export const POKEMON_MOVES = [
210
199
  id: "thunder_shock2",
211
200
  name: "Rayo",
212
201
  typeId: POKEMON_TYPE_IDS.electric,
213
- kind: "damage",
214
- basePower: 40,
215
202
  accuracy: 100,
216
203
  maxPP: 30,
217
204
  priority: 0,
218
- target: "enemy",
219
205
  effects: [
220
206
  {
221
207
  kind: "damage",
222
- amount: 20,
208
+ target: "enemy",
209
+ basePower: 40,
223
210
  },
224
211
  ],
225
212
  },
@@ -227,16 +214,14 @@ export const POKEMON_MOVES = [
227
214
  id: "thunder_shock3",
228
215
  name: "Tormenta",
229
216
  typeId: POKEMON_TYPE_IDS.electric,
230
- kind: "damage",
231
- basePower: 40,
232
217
  accuracy: 100,
233
218
  maxPP: 30,
234
219
  priority: 0,
235
- target: "enemy",
236
220
  effects: [
237
221
  {
238
222
  kind: "damage",
239
- amount: 20,
223
+ target: "enemy",
224
+ basePower: 40,
240
225
  },
241
226
  ],
242
227
  },
@@ -244,16 +229,14 @@ export const POKEMON_MOVES = [
244
229
  id: "thunder_shock4",
245
230
  name: "Lluvia de rayos",
246
231
  typeId: POKEMON_TYPE_IDS.electric,
247
- kind: "damage",
248
- basePower: 40,
249
232
  accuracy: 100,
250
233
  maxPP: 30,
251
234
  priority: 0,
252
- target: "enemy",
253
235
  effects: [
254
236
  {
255
237
  kind: "damage",
256
- amount: 20,
238
+ target: "enemy",
239
+ basePower: 40,
257
240
  },
258
241
  ],
259
242
  },
@@ -261,16 +244,14 @@ export const POKEMON_MOVES = [
261
244
  id: "think",
262
245
  name: "Rayada mental",
263
246
  typeId: POKEMON_TYPE_IDS.psychic,
264
- kind: "damage",
265
- basePower: 40,
266
247
  accuracy: 100,
267
248
  maxPP: 30,
268
249
  priority: 0,
269
- target: "enemy",
270
250
  effects: [
271
251
  {
272
252
  kind: "damage",
273
- amount: 20,
253
+ target: "enemy",
254
+ basePower: 40,
274
255
  },
275
256
  ],
276
257
  },
@@ -278,16 +259,14 @@ export const POKEMON_MOVES = [
278
259
  id: "think2",
279
260
  name: "Psicoterapia",
280
261
  typeId: POKEMON_TYPE_IDS.psychic,
281
- kind: "damage",
282
- basePower: 40,
283
262
  accuracy: 100,
284
263
  maxPP: 30,
285
264
  priority: 0,
286
- target: "enemy",
287
265
  effects: [
288
266
  {
289
267
  kind: "damage",
290
- amount: 20,
268
+ target: "enemy",
269
+ basePower: 40,
291
270
  },
292
271
  ],
293
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.27",
3
+ "version": "0.0.29",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",