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.
- package/dist/core/engine.js +96 -78
- package/dist/core/moves.d.ts +28 -31
- package/dist/core/moves.js +1 -0
- package/dist/skins/pokemon/items.js +4 -4
- package/dist/skins/pokemon/moves.js +50 -71
- package/dist/skins/pokemon/statuses.js +30 -9
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -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,
|
|
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,
|
|
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 ===
|
|
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)) ||
|
|
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
|
-
|
|
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
|
|
312
|
-
|
|
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
|
|
318
|
-
|
|
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
|
|
324
|
-
|
|
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
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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
|
|
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
|
-
|
|
476
|
-
|
|
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 (
|
|
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
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
615
|
-
|
|
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) {
|
package/dist/core/moves.d.ts
CHANGED
|
@@ -1,76 +1,73 @@
|
|
|
1
1
|
import type { MoveId, StatusId, TypeId } from "./ids";
|
|
2
|
-
|
|
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
|
|
4
|
+
export type TargetKind = EffectTarget;
|
|
5
|
+
interface BaseEffect {
|
|
6
|
+
target?: EffectTarget;
|
|
7
|
+
}
|
|
8
|
+
export interface DamageEffect extends BaseEffect {
|
|
7
9
|
kind: "damage";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 |
|
|
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 {};
|
package/dist/core/moves.js
CHANGED
|
@@ -42,7 +42,7 @@ export const POKEMON_ITEMS = [
|
|
|
42
42
|
category: "damage",
|
|
43
43
|
maxUses: 2,
|
|
44
44
|
effects: [
|
|
45
|
-
{ kind: "damage",
|
|
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",
|
|
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",
|
|
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",
|
|
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
|
-
|
|
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:
|
|
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
|
-
{
|
|
32
|
-
|
|
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
|
-
|
|
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: "
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
10
|
-
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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: [
|
|
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
|
];
|