pokemon-io-core 0.0.70 → 0.0.71
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.d.ts
CHANGED
|
@@ -16,15 +16,44 @@ export interface BattleRuntime {
|
|
|
16
16
|
statusesById: Record<StatusId, StatusDefinition>;
|
|
17
17
|
typeEffectiveness: TypeEffectivenessMatrix;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Slot de equipo: UN luchador con sus stats base y movimientos.
|
|
21
|
+
* OJO: aquí NO van los items; los items son por jugador.
|
|
22
|
+
*/
|
|
19
23
|
export interface PlayerFighterConfig {
|
|
20
24
|
fighter: FighterDefinition;
|
|
21
25
|
maxHp: number;
|
|
22
26
|
moves: MoveDefinition[];
|
|
23
|
-
|
|
27
|
+
amulet: AmuletDefinition | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuración de un jugador para el combate.
|
|
31
|
+
*
|
|
32
|
+
* - Forma nueva (multi-team): usar `team`.
|
|
33
|
+
* - Forma legacy (1 vs 1): usar fighter/maxHp/moves/items/amulet como hasta ahora.
|
|
34
|
+
* Si `team` no viene o está vacío, el engine construye un equipo de 1 con esos datos.
|
|
35
|
+
*/
|
|
36
|
+
export interface FighterSlotConfig {
|
|
37
|
+
fighter: FighterDefinition;
|
|
38
|
+
maxHp: number;
|
|
39
|
+
moves: MoveDefinition[];
|
|
24
40
|
amulet: AmuletDefinition | null;
|
|
25
41
|
}
|
|
26
42
|
export interface PlayerBattleConfig {
|
|
27
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Nueva forma: equipo completo. Si existe y tiene elementos,
|
|
45
|
+
* el engine usará esto como fuente de verdad.
|
|
46
|
+
*/
|
|
47
|
+
team?: FighterSlotConfig[];
|
|
48
|
+
/**
|
|
49
|
+
* Forma legacy (1 vs 1). Se mantiene para compatibilidad
|
|
50
|
+
* con skins y backends actuales.
|
|
51
|
+
*/
|
|
52
|
+
fighter: FighterDefinition;
|
|
53
|
+
maxHp: number;
|
|
54
|
+
moves: MoveDefinition[];
|
|
55
|
+
items: ItemDefinition[];
|
|
56
|
+
amulet: AmuletDefinition | null;
|
|
28
57
|
}
|
|
29
58
|
export interface BattleConfig {
|
|
30
59
|
types: TypeDefinition[];
|
package/dist/core/engine.js
CHANGED
|
@@ -30,29 +30,26 @@ const cloneStats = (stats) => ({
|
|
|
30
30
|
// ------------------------------------------------------
|
|
31
31
|
// Creación de estado inicial
|
|
32
32
|
// ------------------------------------------------------
|
|
33
|
-
const createBattleFighter = (
|
|
34
|
-
if (cfg.moves.length !== 4) {
|
|
35
|
-
throw new Error("Each fighter must have exactly 4 moves in MVP");
|
|
36
|
-
}
|
|
37
|
-
if (cfg.items.length > 4) {
|
|
38
|
-
throw new Error("A fighter cannot have more than 4 items");
|
|
39
|
-
}
|
|
33
|
+
const createBattleFighter = (slot, playerItems) => {
|
|
40
34
|
return {
|
|
41
|
-
fighterId:
|
|
42
|
-
classId:
|
|
43
|
-
maxHp:
|
|
44
|
-
currentHp:
|
|
45
|
-
baseStats:
|
|
46
|
-
effectiveStats:
|
|
47
|
-
moves:
|
|
48
|
-
moveId:
|
|
49
|
-
currentPP:
|
|
35
|
+
fighterId: slot.fighter.id,
|
|
36
|
+
classId: slot.fighter.classId,
|
|
37
|
+
maxHp: slot.maxHp,
|
|
38
|
+
currentHp: slot.maxHp,
|
|
39
|
+
baseStats: slot.fighter.baseStats,
|
|
40
|
+
effectiveStats: slot.fighter.baseStats,
|
|
41
|
+
moves: slot.moves.map((m) => ({
|
|
42
|
+
moveId: m.id,
|
|
43
|
+
currentPP: m.maxPP,
|
|
50
44
|
})),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
// ⚠️ De momento mantenemos el comportamiento actual:
|
|
46
|
+
// cada luchador tiene su copia de items.
|
|
47
|
+
// Más adelante, si quieres, los movemos a nivel jugador.
|
|
48
|
+
items: playerItems.map((it) => ({
|
|
49
|
+
itemId: it.id,
|
|
50
|
+
usesRemaining: it.maxUses ?? 1,
|
|
54
51
|
})),
|
|
55
|
-
amuletId:
|
|
52
|
+
amuletId: slot.amulet?.id ?? null,
|
|
56
53
|
statuses: [],
|
|
57
54
|
isAlive: true,
|
|
58
55
|
};
|
|
@@ -89,11 +86,37 @@ const recomputeEffectiveStatsForFighter = (state, fighter) => {
|
|
|
89
86
|
effectiveStats: eff,
|
|
90
87
|
};
|
|
91
88
|
};
|
|
89
|
+
const normalizeTeamFromConfig = (cfg) => {
|
|
90
|
+
// Si ya viene en forma de equipo, úsalo tal cual
|
|
91
|
+
if (cfg.team && cfg.team.length > 0) {
|
|
92
|
+
return cfg.team;
|
|
93
|
+
}
|
|
94
|
+
// Forma legacy: un solo fighter → lo envolvemos en un array
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
fighter: cfg.fighter,
|
|
98
|
+
maxHp: cfg.maxHp,
|
|
99
|
+
moves: cfg.moves,
|
|
100
|
+
amulet: cfg.amulet,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
};
|
|
92
104
|
const createPlayerBattleState = (cfg) => {
|
|
93
|
-
|
|
105
|
+
// Si viene team, lo usamos; si no, construimos equipo de 1 (modo legacy)
|
|
106
|
+
const teamSlots = cfg.team && cfg.team.length > 0
|
|
107
|
+
? cfg.team
|
|
108
|
+
: [
|
|
109
|
+
{
|
|
110
|
+
fighter: cfg.fighter,
|
|
111
|
+
maxHp: cfg.maxHp,
|
|
112
|
+
moves: cfg.moves,
|
|
113
|
+
amulet: cfg.amulet,
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
const fighterTeam = teamSlots.map((slot) => createBattleFighter(slot, cfg.items));
|
|
94
117
|
return {
|
|
95
118
|
fighterTeam,
|
|
96
|
-
activeIndex: 0,
|
|
119
|
+
activeIndex: 0,
|
|
97
120
|
};
|
|
98
121
|
};
|
|
99
122
|
export const createInitialBattleState = (config) => {
|
|
@@ -2,9 +2,24 @@ import type { TypeDefinition, TypeEffectivenessMatrix, MoveDefinition, ItemDefin
|
|
|
2
2
|
import type { PlayerBattleConfig } from "../core/engine.js";
|
|
3
3
|
export interface FighterLoadout {
|
|
4
4
|
fighterId: string | null;
|
|
5
|
+
moveIds: string[];
|
|
5
6
|
itemIds: string[];
|
|
6
7
|
amuletId: string | null;
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Lista de luchadores del equipo (máx. 6).
|
|
10
|
+
* Si solo hay uno, puede contener un único id.
|
|
11
|
+
*/
|
|
12
|
+
fighterIds?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Movimientos por luchador. Si falta para alguno, se usan
|
|
15
|
+
* `moveIds` como fallback.
|
|
16
|
+
*/
|
|
17
|
+
movesByFighterId?: Record<string, string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* (Opcional) Futuro: cuál es el activo actual.
|
|
20
|
+
* Si no se define, se asume fighterIds[0].
|
|
21
|
+
*/
|
|
22
|
+
activeFighterId?: string | null;
|
|
8
23
|
}
|
|
9
24
|
export interface CombatSkin {
|
|
10
25
|
readonly id: string;
|
|
@@ -71,22 +71,31 @@ export class TribeSkin {
|
|
|
71
71
|
if (!loadout.fighterId) {
|
|
72
72
|
throw new Error("fighterId is required in FighterLoadout");
|
|
73
73
|
}
|
|
74
|
+
console.log("buildPlayerConfig", loadout.fighterId);
|
|
74
75
|
const fighter = findTribeFighterById(loadout.fighterId);
|
|
75
76
|
if (!fighter) {
|
|
76
|
-
throw new Error(`Unknown fighterId for
|
|
77
|
+
throw new Error(`Unknown fighterId for Pokemon skin: ${loadout.fighterId}`);
|
|
77
78
|
}
|
|
78
79
|
const moves = buildMovesFromLoadout(fighter, loadout);
|
|
79
80
|
const items = buildItemsFromLoadout(loadout);
|
|
81
|
+
const maxHp = fighter.baseStats.defense + fighter.baseStats.offense;
|
|
80
82
|
return {
|
|
83
|
+
// ✅ NUEVO: modelo multi-equipo
|
|
81
84
|
team: [
|
|
82
85
|
{
|
|
83
86
|
fighter,
|
|
84
|
-
maxHp
|
|
87
|
+
maxHp,
|
|
85
88
|
moves,
|
|
86
|
-
items,
|
|
87
89
|
amulet: null,
|
|
88
90
|
},
|
|
89
91
|
],
|
|
92
|
+
// ✅ LEGACY: seguimos rellenando los campos antiguos
|
|
93
|
+
// por si algún sitio sigue leyéndolos.
|
|
94
|
+
fighter,
|
|
95
|
+
maxHp,
|
|
96
|
+
moves,
|
|
97
|
+
items,
|
|
98
|
+
amulet: null,
|
|
90
99
|
};
|
|
91
100
|
}
|
|
92
101
|
}
|
|
@@ -70,22 +70,31 @@ export class PokemonSkin {
|
|
|
70
70
|
if (!loadout.fighterId) {
|
|
71
71
|
throw new Error("fighterId is required in FighterLoadout");
|
|
72
72
|
}
|
|
73
|
+
console.log("buildPlayerConfig", loadout.fighterId);
|
|
73
74
|
const fighter = findPokemonById(loadout.fighterId);
|
|
74
75
|
if (!fighter) {
|
|
75
76
|
throw new Error(`Unknown fighterId for Pokemon skin: ${loadout.fighterId}`);
|
|
76
77
|
}
|
|
77
78
|
const moves = buildMovesFromLoadout(fighter, loadout);
|
|
78
79
|
const items = buildItemsFromLoadout(loadout);
|
|
80
|
+
const maxHp = fighter.baseStats.defense + fighter.baseStats.offense;
|
|
79
81
|
return {
|
|
82
|
+
// ✅ NUEVO: modelo multi-equipo
|
|
80
83
|
team: [
|
|
81
84
|
{
|
|
82
85
|
fighter,
|
|
83
|
-
maxHp
|
|
86
|
+
maxHp,
|
|
84
87
|
moves,
|
|
85
|
-
items,
|
|
86
88
|
amulet: null,
|
|
87
89
|
},
|
|
88
90
|
],
|
|
91
|
+
// ✅ LEGACY: seguimos rellenando los campos antiguos
|
|
92
|
+
// por si algún sitio sigue leyéndolos.
|
|
93
|
+
fighter,
|
|
94
|
+
maxHp,
|
|
95
|
+
moves,
|
|
96
|
+
items,
|
|
97
|
+
amulet: null,
|
|
89
98
|
};
|
|
90
99
|
}
|
|
91
100
|
}
|