pokemon-io-core 0.0.81 → 0.0.82

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.
@@ -12,7 +12,14 @@ export interface BattlePlayerView {
12
12
  activeFighterId: string | null;
13
13
  activeIndex: number;
14
14
  }
15
- export type BattleStatus = "ongoing" | "finished";
15
+ export type BattleStatus = "ongoing" | "awaiting_forced_switch" | "finished";
16
+ export type ForcedSwitchReason = "roar";
17
+ export interface ForcedSwitchView {
18
+ targetPlayerId: string;
19
+ sourcePlayerId: string;
20
+ reason: ForcedSwitchReason;
21
+ turnNumber: number;
22
+ }
16
23
  export interface BattleView {
17
24
  roomId: string;
18
25
  status: BattleStatus;
@@ -30,4 +37,5 @@ export interface BattleView {
30
37
  player1: boolean;
31
38
  player2: boolean;
32
39
  };
40
+ forcedSwitch: ForcedSwitchView | null;
33
41
  }
@@ -49,6 +49,10 @@ export interface ClientToServerEvents {
49
49
  roomId: string;
50
50
  newIndex: number;
51
51
  }) => void;
52
+ "battle:chooseForcedSwitch": (payload: {
53
+ roomId: string;
54
+ newIndex: number;
55
+ }) => void;
52
56
  "battle:rematchSameLoadout": (payload: {
53
57
  roomId: string;
54
58
  }) => void;
@@ -31,9 +31,18 @@ export interface PlayerBattleState {
31
31
  activeIndex: number;
32
32
  inventory: EquippedItem[];
33
33
  }
34
+ export type ForcedSwitchState = null | {
35
+ targetPlayer: "player1" | "player2";
36
+ reason: {
37
+ kind: "move";
38
+ moveId: string;
39
+ actorFighterId: string;
40
+ };
41
+ };
34
42
  export interface BattleState {
35
43
  turnNumber: number;
36
44
  player1: PlayerBattleState;
37
45
  player2: PlayerBattleState;
38
46
  runtime: BattleRuntime;
47
+ forcedSwitch: ForcedSwitchState;
39
48
  }
@@ -42,6 +42,10 @@ export interface RuntimeBattleState extends BattleState {
42
42
  runtime: BattleRuntime;
43
43
  }
44
44
  export declare const createInitialBattleState: (config: BattleConfig) => BattleState;
45
+ export declare const applyForcedSwitchChoice: (state: BattleState, targetPlayer: "player1" | "player2", newIndex: number) => {
46
+ state: BattleState;
47
+ events: BattleEvent[];
48
+ };
45
49
  export declare const resolveTurn: (state: BattleState, actions: BattleActions) => {
46
50
  newState: BattleState;
47
51
  events: BattleEvent[];
@@ -115,6 +115,7 @@ export const createInitialBattleState = (config) => {
115
115
  player1,
116
116
  player2,
117
117
  runtime,
118
+ forcedSwitch: null,
118
119
  };
119
120
  return state;
120
121
  };
@@ -201,6 +202,44 @@ const computeDamage = (input) => {
201
202
  effectiveness: typeEffectiveness,
202
203
  };
203
204
  };
205
+ export const applyForcedSwitchChoice = (state, targetPlayer, newIndex) => {
206
+ const forced = state.forcedSwitch;
207
+ if (!forced)
208
+ return { state, events: [] };
209
+ if (forced.targetPlayer !== targetPlayer)
210
+ return { state, events: [] };
211
+ const self = targetPlayer === "player1" ? state.player1 : state.player2;
212
+ if (newIndex < 0 || newIndex >= self.fighterTeam.length) {
213
+ return { state, events: [] };
214
+ }
215
+ const fromIndex = self.activeIndex;
216
+ if (newIndex === fromIndex)
217
+ return { state, events: [] };
218
+ const toFighter = self.fighterTeam[newIndex];
219
+ if (!toFighter || !toFighter.isAlive || toFighter.currentHp <= 0) {
220
+ return { state, events: [] };
221
+ }
222
+ const fromFighter = self.fighterTeam[fromIndex];
223
+ const events = [
224
+ {
225
+ ...createBaseEvent(state.turnNumber, "fighter_switched", `El entrenador cambia a ${toFighter.fighterId}`),
226
+ fromFighterId: fromFighter.fighterId,
227
+ toFighterId: toFighter.fighterId,
228
+ },
229
+ ];
230
+ const nextState = targetPlayer === "player1"
231
+ ? {
232
+ ...state,
233
+ forcedSwitch: null,
234
+ player1: { ...state.player1, activeIndex: newIndex },
235
+ }
236
+ : {
237
+ ...state,
238
+ forcedSwitch: null,
239
+ player2: { ...state.player2, activeIndex: newIndex },
240
+ };
241
+ return { state: nextState, events };
242
+ };
204
243
  let eventCounter = 0;
205
244
  const nextEventId = () => {
206
245
  eventCounter += 1;
@@ -1,6 +1,6 @@
1
1
  import type { MoveId, StatusId, TypeId } from "./ids.js";
2
2
  export type EffectTarget = "self" | "enemy";
3
- export type EffectKind = "damage" | "heal" | "shield" | "modify_stats" | "apply_status" | "clear_status" | "modify_hit_chance" | "modify_crit_chance" | "modify_priority" | "modify_effective_speed";
3
+ export type EffectKind = "damage" | "heal" | "shield" | "modify_stats" | "apply_status" | "clear_status" | "modify_hit_chance" | "modify_crit_chance" | "modify_priority" | "modify_effective_speed" | "force_switch";
4
4
  export type TargetKind = EffectTarget;
5
5
  interface BaseEffect {
6
6
  target?: EffectTarget;
@@ -56,11 +56,19 @@ export interface ModifyPriorityEffect extends BaseEffect {
56
56
  kind: "modify_priority";
57
57
  delta: number;
58
58
  }
59
+ export interface ForceSwitchEffect extends BaseEffect {
60
+ kind: "force_switch";
61
+ /**
62
+ * Mensaje/razón opcional para debug/narración interna.
63
+ * Si no lo usas, lo puedes ignorar en el engine.
64
+ */
65
+ reason?: string;
66
+ }
59
67
  export interface ModifyEffectiveSpeedEffect extends BaseEffect {
60
68
  kind: "modify_effective_speed";
61
69
  multiplier: number;
62
70
  }
63
- export type EffectDefinition = DamageEffect | HealEffect | ShieldEffect | ModifyStatsEffect | ApplyStatusEffect | ClearStatusEffect | ModifyHitChanceEffect | ModifyCritChanceEffect | ModifyPriorityEffect | ModifyEffectiveSpeedEffect;
71
+ export type EffectDefinition = DamageEffect | HealEffect | ShieldEffect | ModifyStatsEffect | ApplyStatusEffect | ClearStatusEffect | ModifyHitChanceEffect | ModifyCritChanceEffect | ModifyPriorityEffect | ModifyEffectiveSpeedEffect | ForceSwitchEffect;
64
72
  export interface MoveDefinition {
65
73
  id: MoveId;
66
74
  name: string;
@@ -1,4 +1,18 @@
1
1
  export const POKEMON_MOVES = [
2
+ {
3
+ "id": "roar",
4
+ "name": "Rugido",
5
+ "typeId": "fire",
6
+ "accuracy": 100,
7
+ "maxPP": 3,
8
+ "priority": 0,
9
+ "effects": [
10
+ {
11
+ "kind": "force_switch",
12
+ "reason": "Roar"
13
+ },
14
+ ]
15
+ },
2
16
  {
3
17
  "id": "overheat",
4
18
  "name": "Sofoco Ígneo",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pokemon-io-core",
3
- "version": "0.0.81",
3
+ "version": "0.0.82",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",