pokemon-io-core 0.0.28 → 0.0.30

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 *
@@ -190,11 +189,18 @@ const applyDamageToFighter = (state, defender, amount, actorId, isCritical) => {
190
189
  // ------------------------------------------------------
191
190
  const applyStatusToFighter = (state, target, statusId) => {
192
191
  const def = state.runtime.statusesById[statusId];
192
+ dbg("APPLY_STATUS_FN", {
193
+ targetId: target.fighterId,
194
+ statusId,
195
+ hasDef: !!def,
196
+ currentStatuses: target.statuses,
197
+ });
193
198
  if (!def)
194
199
  return { updated: target, events: [] };
195
200
  const events = [];
196
201
  const existing = target.statuses.find((s) => s.statusId === statusId);
197
- const duration = Math.floor(randomInRange(def.minDurationTurns, def.maxDurationTurns + 1)) || def.minDurationTurns;
202
+ const duration = Math.floor(randomInRange(def.minDurationTurns, def.maxDurationTurns + 1)) ||
203
+ def.minDurationTurns;
198
204
  let newStatuses = [...target.statuses];
199
205
  if (!existing) {
200
206
  newStatuses.push({
@@ -227,7 +233,10 @@ const applyStatusToFighter = (state, target, statusId) => {
227
233
  events,
228
234
  };
229
235
  };
230
- const applyClearStatusToFighter = (state, target, effect) => {
236
+ // ------------------------------------------------------
237
+ // clear_status
238
+ // ------------------------------------------------------
239
+ const clearStatusFromFighter = (state, target, effect) => {
231
240
  const { statusIds, kinds, clearAll } = effect;
232
241
  const events = [];
233
242
  const before = target.statuses;
@@ -299,42 +308,129 @@ const applyHealToFighter = (state, target, amount, sourceId) => {
299
308
  return { updated, events };
300
309
  };
301
310
  // ------------------------------------------------------
311
+ // Target por defecto y resolución de target
312
+ // ------------------------------------------------------
313
+ const defaultTargetForKind = (kind) => {
314
+ switch (kind) {
315
+ case "damage":
316
+ case "apply_status":
317
+ return "enemy";
318
+ case "heal":
319
+ case "clear_status":
320
+ case "modify_stats":
321
+ case "modify_hit_chance":
322
+ case "modify_crit_chance":
323
+ case "modify_priority":
324
+ case "modify_effective_speed":
325
+ case "shield":
326
+ return "self";
327
+ default:
328
+ return "self";
329
+ }
330
+ };
331
+ const resolveEffectTarget = (eff, actor, target) => {
332
+ const t = eff.target ?? defaultTargetForKind(eff.kind);
333
+ const isSelf = t === "self";
334
+ return {
335
+ primary: isSelf ? actor : target,
336
+ isSelf,
337
+ };
338
+ };
339
+ // ------------------------------------------------------
302
340
  // Motor de efectos genérico (move + item)
303
341
  // ------------------------------------------------------
304
- const applyEffectsOnTarget = (state, actor, target, effects) => {
342
+ const applyEffectsOnTarget = (state, actor, target, moveTypeId, isCritical, effects) => {
343
+ dbg("applyEffectsOnTarget", {
344
+ actorId: actor.fighterId,
345
+ targetId: target.fighterId,
346
+ moveTypeId,
347
+ isCritical,
348
+ effects,
349
+ });
305
350
  let currentActor = actor;
306
351
  let currentTarget = target;
307
352
  const events = [];
353
+ dbg("APPLY_EFFECTS_START", {
354
+ actorId: actor.fighterId,
355
+ targetId: target.fighterId,
356
+ moveTypeId,
357
+ isCritical,
358
+ effectsCount: effects?.length ?? 0,
359
+ });
308
360
  for (const eff of effects) {
361
+ dbg("EFFECT_LOOP", eff);
309
362
  switch (eff.kind) {
310
363
  case "heal": {
311
- const res = applyHealToFighter(state, currentActor, eff.amount, actor.fighterId);
312
- currentActor = res.updated;
364
+ dbg("EFFECT_HEAL_START", {
365
+ amount: eff.amount,
366
+ targetDefault: eff.target,
367
+ });
368
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
369
+ const res = applyHealToFighter(state, primary, eff.amount, actor.fighterId);
370
+ if (isSelf)
371
+ currentActor = res.updated;
372
+ else
373
+ currentTarget = res.updated;
313
374
  events.push(...res.events);
314
375
  break;
315
376
  }
316
377
  case "apply_status": {
317
- const res = applyStatusToFighter(state, currentTarget, eff.statusId);
318
- currentTarget = res.updated;
378
+ dbg("EFFECT_APPLY_STATUS_START", {
379
+ statusId: eff.statusId,
380
+ targetDefault: eff.target,
381
+ });
382
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
383
+ const res = applyStatusToFighter(state, primary, eff.statusId);
384
+ if (isSelf)
385
+ currentActor = res.updated;
386
+ else
387
+ currentTarget = res.updated;
319
388
  events.push(...res.events);
320
389
  break;
321
390
  }
322
391
  case "clear_status": {
323
- const res = applyClearStatusToFighter(state, currentTarget, eff);
324
- currentTarget = res.updated;
392
+ dbg("debemos eliminar status");
393
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
394
+ const res = clearStatusFromFighter(state, primary, eff);
395
+ if (isSelf)
396
+ currentActor = res.updated;
397
+ else
398
+ currentTarget = res.updated;
325
399
  events.push(...res.events);
326
400
  break;
327
401
  }
328
402
  case "damage": {
329
- if (typeof eff.amount === "number") {
330
- const res = applyDamageToFighter(state, currentTarget, eff.amount, actor.fighterId, false);
331
- currentTarget = res.updatedDefender;
403
+ dbg("debemos hacer daño");
404
+ const { primary, isSelf } = resolveEffectTarget(eff, currentActor, currentTarget);
405
+ let totalDamage = 0;
406
+ // Daño de fórmula (stats + tipo + crit…)
407
+ if (eff.basePower && moveTypeId) {
408
+ const { damage } = computeDamage({
409
+ state,
410
+ attacker: currentActor,
411
+ defender: primary,
412
+ moveTypeId,
413
+ basePower: eff.basePower,
414
+ isCritical,
415
+ });
416
+ totalDamage += damage;
417
+ }
418
+ // Daño plano adicional
419
+ if (eff.flatAmount && eff.flatAmount > 0) {
420
+ totalDamage += eff.flatAmount;
421
+ }
422
+ if (totalDamage > 0) {
423
+ const res = applyDamageToFighter(state, primary, totalDamage, currentActor.fighterId, isCritical);
424
+ if (isSelf)
425
+ currentActor = res.updatedDefender;
426
+ else
427
+ currentTarget = res.updatedDefender;
332
428
  events.push(...res.events);
333
429
  }
334
430
  break;
335
431
  }
432
+ // TODO: conectar shield, modify_stats, etc.
336
433
  default:
337
- // otros efectos (modify_stats, etc.) se pueden añadir aquí
338
434
  break;
339
435
  }
340
436
  }
@@ -373,6 +469,7 @@ const resolveDamageMove = (state, playerKey, action) => {
373
469
  const { self, opponent } = getOpponentAndSelf(state, playerKey);
374
470
  const events = [];
375
471
  const moveSlot = self.moves[action.moveIndex];
472
+ dbg("use_move: slot", moveSlot);
376
473
  if (!moveSlot) {
377
474
  dbg("use_move: empty slot", { playerKey, moveIndex: action.moveIndex });
378
475
  return { state, events };
@@ -393,30 +490,6 @@ const resolveDamageMove = (state, playerKey, action) => {
393
490
  });
394
491
  return { state, events };
395
492
  }
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
493
  events.push({
421
494
  ...createBaseEvent(state.turnNumber, "action_declared", `${self.fighterId} usa ${move.name}`),
422
495
  actorId: self.fighterId,
@@ -448,19 +521,12 @@ const resolveDamageMove = (state, playerKey, action) => {
448
521
  }
449
522
  const critChance = computeCritChance(state.runtime.rules, updatedSelf.effectiveStats.crit);
450
523
  const isCritical = chance(critChance);
451
- const { damage, effectiveness } = computeDamage({
452
- state,
453
- attacker: updatedSelf,
454
- defender: updatedOpponent,
455
- move,
456
- isCritical,
457
- });
524
+ const effectiveness = getTypeEffectiveness(state, move.typeId, updatedOpponent.classId);
458
525
  dbg("HIT", {
459
526
  fighterId: self.fighterId,
460
527
  moveId: move.id,
461
528
  moveName: move.name,
462
529
  isCritical,
463
- damage,
464
530
  effectiveness,
465
531
  defenderBeforeHp: opponent.currentHp,
466
532
  });
@@ -472,21 +538,19 @@ const resolveDamageMove = (state, playerKey, action) => {
472
538
  isCritical,
473
539
  effectiveness,
474
540
  });
475
- const damageRes = applyDamageToFighter(state, updatedOpponent, damage, updatedSelf.fighterId, isCritical);
476
- dbg("AFTER_DAMAGE", {
477
- targetId: opponent.fighterId,
478
- newHp: damageRes.updatedDefender.currentHp,
541
+ dbg("MOVE_EFFECTS", {
542
+ moveId: move.id,
543
+ moveName: move.name,
544
+ effects: move.effects,
479
545
  });
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);
546
+ // Todos los efectos (daño, aplicar estado, curas, etc.)
547
+ const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, move.typeId, isCritical, move.effects);
484
548
  events.push(...extraEvents);
485
549
  const newState = updateFightersInState(state, playerKey, finalSelf, finalOpp);
486
550
  return { state: newState, events };
487
551
  };
488
552
  // ------------------------------------------------------
489
- // use_item (respeta item.target: "self" | "enemy")
553
+ // use_item (ahora el target real está en cada efecto)
490
554
  // ------------------------------------------------------
491
555
  const resolveItemUse = (state, playerKey, action) => {
492
556
  if (action.kind !== "use_item") {
@@ -519,23 +583,9 @@ const resolveItemUse = (state, playerKey, action) => {
519
583
  ...createBaseEvent(state.turnNumber, "action_declared", `${self.fighterId} usa objeto ${itemDef.name}`),
520
584
  actorId: self.fighterId,
521
585
  });
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
- }
586
+ const { actor: finalSelf, target: finalOpp, events: extraEvents, } = applyEffectsOnTarget(state, updatedSelf, updatedOpponent, null, // los items no usan fórmula de tipo por ahora
587
+ false, itemDef.effects);
588
+ events.push(...extraEvents);
539
589
  const newState = updateFightersInState(state, playerKey, finalSelf, finalOpp);
540
590
  return { state: newState, events };
541
591
  };
@@ -611,8 +661,12 @@ const applyEndOfTurnStatuses = (state) => {
611
661
  def.effectsPerStack.forEach((eff) => {
612
662
  if (eff.kind === "damage") {
613
663
  const stacksMultiplier = st.stacks === 2 ? 2 : 1;
614
- const basePower = typeof eff.amount === "number" ? eff.amount : 10;
615
- damageFromStatus += basePower * stacksMultiplier;
664
+ const base = typeof eff.flatAmount === "number"
665
+ ? eff.flatAmount
666
+ : typeof eff.basePower === "number"
667
+ ? eff.basePower
668
+ : 10; // fallback
669
+ damageFromStatus += base * stacksMultiplier;
616
670
  }
617
671
  });
618
672
  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.30",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",