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 de la edición 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, las ediciones Source y Studio. 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);
}
}
}