Saltar al contenido principal

BattleManager

El MonoBehaviour que dirige un combate de monstruos. BattleManager es un coordinador fino: el trabajo real se reparte entre 15+ modulos hermanos (cada uno su propio MonoBehaviour en el mismo GameObject) y el flujo de turnos lo gobierna BattleStateMachine. Este es el mapa a nivel Source de esa arquitectura.

Namespace: OpenMon.MCE.Battle

Superficie SDK vs. Source

Para la mayoria de las integraciones no hablas con BattleManager directamente: observas los combates a traves de la interfaz de solo lectura del SDK IBattleSystem (eventos, estado actual). Los miembros de abajo son internal (accesores de modulos) o la API concreta de BattleManager usada dentro del ensamblado del motor (OpenMon.MCE.Runtime), es decir, el nivel Source. Usalos cuando extiendas la logica de combate, no para leer estado desde tu codigo.

Forma de la clase​

[RequireComponent(typeof(BattleStateMachine))]
[RequireComponent(typeof(BattleManagerBattlersModule))]
// ...un RequireComponent por modulo...
public class BattleManager : OpenMonBehaviour<BattleManager>, IBattleManager, IPlayerDataReceiver
{
// Accesores de modulos (internal — resueltos desde componentes hermanos):
internal BattleManagerBattlersModule Battlers { get; }
internal BattleManagerHealthModule BattlerHealth { get; }
internal BattleManagerMovesModule Moves { get; }
internal BattleManagerCaptureModule Capture { get; }
internal BattleManagerAIModule AI { get; }
// ...BattlerStats, BattlerSwitch, Rosters, Scenario, Statuses,
// Characters, Animation, Audio, Megas...

// Estado de combate publico:
public BattleType BattleType;
public EnemyType EnemyType;
public bool IsBattleOver;
public int TurnCounter { get; }
public byte BattleSpeed { get; }
public bool CanPlayerRun { get; }

public void SubscribeToBattleInitialized(Action callback);
public void SubscribeToBattleFinished(Action<BattleResultParameters> callback);
public void TickTurn();
public void FinishBattle();
public BattleMonsterSprite GetMonsterSprite(BattlerType type, int index);
}

Cada modulo deriva de la clase base compartida BattleManagerModule<T>, que expone el mismo conjunto de accesores a modulos hermanos para que los modulos se llamen entre si:

public abstract class BattleManagerModule<T> : OpenMonBehaviour<T>
where T : BattleManagerModule<T>
{
protected BattleManager BattleManager { get; }
protected BattleManagerBattlersModule Battlers { get; }
protected BattleManagerHealthModule BattlerHealth { get; }
// ...mismos accesores que BattleManager...
}

Indice de modulos​

Cada comportamiento de combate es un MonoBehaviour junto a BattleManager, requerido via [RequireComponent]. Los cinco de abajo son los que tocas al extender combates; el resto maneja presentacion y contabilidad.

ModuloAccesorResponsabilidad
BattleManagerBattlersModuleBattlersBusqueda de battlers, sprites, formas, huir
BattleManagerHealthModuleBattlerHealthCambios de HP, deteccion y proceso de debilitados
BattleManagerMovesModuleMovesEjecucion de movimientos, precision
BattleManagerCaptureModuleCaptureIntentos de captura
BattleManagerAIModuleAIIA por roster
BattleManagerBattlerStatsModuleBattlerStatsEtapas de stats, amistad al inicio
BattleManagerBattlerSwitchModuleBattleManagerBattlerSwitchEnviar battlers dentro/fuera
BattleManagerRostersModuleRostersPreparacion de rosters, chequeo de debilitados
BattleManagerScenariosModuleScenarioClima, terreno, escenario
BattleManagerStatusesModuleStatusesCondiciones de estado
BattleManagerCharactersModuleCharactersPersonajes entrenadores
BattleManagerAnimationModuleAnimationAnimacion de intro/flujo de combate
BattleManagerAudioModuleAudioAudio de combate
BattleManagerMegaModuleMegasCambios de forma mega / giga

Estado publico y callbacks​

BattleType​

El tipo de combate en curso (individual, doble, etc.).

Tipo: BattleType

EnemyType​

Si el combate es contra monstruos Wild (salvajes) o un Trainer (entrenador).

Tipo: EnemyType

IsBattleOver​

true una vez que el combate se ha resuelto.

Tipo: bool

TurnCounter​

Numero de turnos transcurridos en este combate.

Tipo: int (solo lectura)

BattleSpeed​

El factor de aceleracion de animacion de este combate, tomado de la configuracion.

Tipo: byte (solo lectura)

CanPlayerRun​

true cuando el enemigo es Wild y ningun battler enemigo en combate es un alpha.

Tipo: bool (solo lectura)

SubscribeToBattleInitialized(Action callback)​

Registra un callback que se dispara cuando el combate termina de inicializar.

SubscribeToBattleFinished(Action<BattleResultParameters> callback)​

Registra un callback que se dispara al terminar el combate, recibiendo un BattleResultParameters (tipo de combate, quien gano, monstruo capturado, flag de respawn).

TickTurn()​

Avanza el contador de turnos y limpia LastSuccessfulMoveThisTurn. Lo llama la maquina de estados al inicio de cada turno.

FinishBattle()​

Construye el BattleResultParameters y lanza el callback de combate finalizado.

GetMonsterSprite(BattlerType type, int index)​

Obtiene el BattleMonsterSprite en pantalla para una posicion de battler. Hay sobrecargas que aceptan un Battler o una tupla (BattlerType, int).

Devuelve: BattleMonsterSprite.

Modulo Battlers​

BattleManagerBattlersModule — resolver battlers a/desde indices y sus sprites.

GetBattlerFromBattleIndex(BattlerType type, int battleIndex)​

Obtiene el Battler en un indice de combate para un bando.

Devuelve: Battler.

GetTypeAndIndexOfBattler(Battler battler)​

Busqueda inversa: el (BattlerType Type, int Index) de un battler.

Devuelve: (BattlerType Type, int Index).

GetBattlersFighting(BattlerType type)​

Todos los battlers que estan combatiendo en un bando. Una sobrecarga sin parametros devuelve ambos bandos.

Devuelve: List<Battler>.

IsBattlerFighting(BattlerType type, int battlerIndex)​

Si la posicion dada tiene un battler combatiendo activamente.

Devuelve: bool.

ChangeForm(BattlerType battlerType, int index, ...)​

Corrutina que cambia la forma de un battler en pleno combate (regional/mega/transform). Existen varias sobrecargas para los distintos disparadores de cambio de forma.

Devuelve: IEnumerator.

RunAway(BattlerType type, int index, bool playAnimation, bool bypassAllyChances = false)​

Corrutina que intenta huir del combate.

Devuelve: IEnumerator.

Modulo Health​

BattleManagerHealthModule — mutacion de HP y manejo de debilitados.

ChangeLife(Battler battler, Battler user, int amount, Move userMove = null, bool playAudio = true, bool forceSurvive = false, bool isSecondaryDamage = false, bool ignoreAbilities = false, Action<int, bool> finished = null)​

La forma canonica de aplicar dano o curacion a un battler en combate. Ejecuta la animacion y el audio de impacto, dispara habilidades e informa (cantidadAplicada, debilitado) a traves de finished. Hay sobrecargas que aceptan indices de battler en lugar de referencias Battler.

Devuelve: IEnumerator.

CheckFaintedBattlers()​

Corrutina que detecta battlers cuyo HP llego a cero en este paso.

Devuelve: IEnumerator.

ProcessFaintedBattlers()​

Corrutina que reproduce animaciones de debilitamiento y resuelve los battlers debilitados.

Devuelve: IEnumerator.

GetNumberOfFainted(BattlerType battlerType, int battlerIndex)​

Cantidad de monstruos debilitados en un roster.

Devuelve: int.

Modulo Moves​

BattleManagerMovesModule — ejecutar movimientos.

PerformMove(BattlerType type, int index, List<(BattlerType Type, int Index)> targets, int moveIndex)​

Ejecuta el movimiento en la ranura moveIndex (0-3 para las cuatro ranuras, 4 para Forcejeo) contra los objetivos dados, corriendo el pipeline completo de efectos.

Devuelve: IEnumerator.

ForcePerformMove(BattlerType type, int index, ...)​

Fuerza la ejecucion de un movimiento especifico (usado por efectos que invocan otros movimientos).

Devuelve: IEnumerator.

LastSuccessfullyPerformedMove​

El ultimo movimiento que se resolvio con exito.

Tipo: Move

Modulo Capture​

BattleManagerCaptureModule — capturar monstruos salvajes.

TryCaptureMonster(int index, Ball ball)​

Corrutina que ejecuta un intento de captura contra el battler enemigo en index con la Ball dada. No hace nada (y registra un error) contra entrenadores o cuando hay mas de un enemigo combatiendo.

Devuelve: IEnumerator.

Modulo AI​

BattleManagerAIModule — la IA por roster, conectable.

PlayerControlsFirstRoster​

Si el jugador humano controla el primer roster aliado.

Tipo: bool

AllyAIs / EnemyAIs​

La estrategia BattleAI asignada a cada roster de cada bando.

Tipo: List<BattleAI>

GetAI(BattlerType type, int index)​

Obtiene la BattleAI que controla un roster dado.

Devuelve: BattleAI.

BattleAI (base de estrategia)​

Las estrategias de IA heredan del ScriptableObject abstracto BattleAI (OpenMon.MCE.Battle.AI). Las estrategias integradas incluyen RandomBattleAI, PerformEffectiveMove, PerformRandomMove y MLBattleAI (dirigida por ML-Agents).

public abstract class BattleAI : MonsterDatabaseScriptable<BattleAI>
{
public abstract IEnumerator RequestPerformAction(MCESettings settings,
BattleManager battleManager, BattlerType type, int inBattleIndex,
Action<BattleAction> callback);

public abstract int RequestNewMonster(MCESettings settings,
BattleManager battleManager, BattlerType type, int inBattleIndex,
List<Battler> forbiddenBattlers);

public virtual void OnBattlerFainted(BattleManager battleManager,
BattlerType ownType, int ownIndex, BattlerType faintedType, int faintedIndex);

public virtual void OnBattleEnded(BattlerType ownType, int ownIndex,
BattlerType winners, BattleManager battleManager);
}

Para agregar una IA propia, hereda de BattleAI, implementa RequestPerformAction (elegir la accion del turno) y RequestNewMonster (elegir el reemplazo tras un debilitamiento), y luego asigna el asset a una plantilla de combate.

BattleStateMachine​

BattleStateMachine (un hermano [RequireComponent]) dirige el bucle de turnos. BattleManager.Construct inicia la inicializacion del combate; cuando esta listo llama:

GetCachedComponent<BattleStateMachine>().StartBattleLoop();

StartBattleLoop()​

Inicia la corrutina que ejecuta el bucle ordenado de turnos (recolectar acciones → ordenar por prioridad → resolver → chequear debilitados → siguiente turno) hasta que IsBattleOver.

Extender un combate​

using System.Collections;
using OpenMon.MCE.Battle;
using OpenMon.Foundation.Behaviours;

namespace MyGame.Battle
{
// Un modulo propio vive en el mismo GameObject que BattleManager y alcanza los
// otros modulos a traves de la clase base compartida.
public class MyBattleHookModule : BattleManagerModule<MyBattleHookModule>
{
public IEnumerator HalveEnemyLead()
{
Battler lead = Battlers.GetBattlerFromBattleIndex(BattlerType.Enemy, 0);
int damage = (int)(lead.CurrentHP / 2);

// Enruta el HP por el modulo de salud para que animaciones/habilidades sigan corriendo.
yield return BattlerHealth.ChangeLife(lead, lead, -damage);
}
}
}