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.
- 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 +44 -69
- 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,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
|
-
|
|
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:
|
|
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
|
-
{
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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
|
];
|