Definir un Desafío de Batalla
El sistema de Battle Challenge (Desafío de Batalla) en Pokémon Essentials permite crear instalaciones de combate estilo Battle Frontier. Estas instalaciones ofrecen combates consecutivos contra entrenadores generados dinámicamente, con reglas especiales, progresión por rondas y recompensas al alcanzar ciertas rachas de victorias. En esta página se explica cómo configurar y personalizar un desafío de batalla completo.
Tipos de instalaciones de batalla
Essentials incluye soporte para varios tipos de instalaciones, inspiradas en las de los juegos oficiales:
- Battle Tower (Torre Batalla): combates simples o dobles con tu propio equipo. El formato clásico de 7 combates por ronda.
- Battle Factory (Fábrica Batalla): el jugador elige Pokémon de alquiler en lugar de usar los propios. Después de cada combate, puede intercambiar un Pokémon.
- Battle Palace (Palacio Batalla): los Pokémon luchan de forma autónoma según su naturaleza. El jugador no elige los movimientos.
- Battle Arena (Dojo Batalla): los combates duran máximo 3 turnos. Si ningún Pokémon cae, un jurado decide al ganador.
- Battle Pike (Tubo Batalla): el jugador avanza por pasillos eligiendo entre tres puertas, cada una con un evento aleatorio.
- Battle Dome (Cúpula Batalla): un torneo de eliminación donde el jugador puede ver los equipos rivales de antemano.
- Battle Pyramid (Pirámide Batalla): el jugador explora pisos de un calabozo con visibilidad limitada y Pokémon salvajes.
La Base de Sky incluye la implementación de la Battle Tower y la Battle Factory como instalaciones principales. Las demás pueden implementarse como extensiones personalizadas.
Clase BattleChallenge
La clase central del sistema es BattleChallenge. Esta clase gestiona el estado del desafío, las rondas, las rachas de victorias y la generación de entrenadores. Se accede a ella a través de la variable global $PokemonGlobal.challenge.
# Estructura interna principal de BattleChallenge
class BattleChallenge
attr_accessor :currentChallenge # Tipo de desafío actual
attr_accessor :battleRules # Reglas de batalla activas
attr_accessor :wins # Victorias en la racha actual
attr_accessor :swaps # Intercambios realizados (Battle Factory)
attr_accessor :pokemon # Equipo del jugador en el desafío
attr_accessor :trainers # Lista de entrenadores disponibles
end
Iniciar un desafío
Para iniciar un desafío de batalla desde un evento, usa la siguiente secuencia de comandos:
# Ejemplo: Iniciar una Battle Tower en formato individual
pbBattleChallenge.set("pokemon_challenge", # ID interno del desafío
7, # Número de combates por ronda
Pokemon::MAX_LEVEL, # Nivel máximo permitido
Pokemon::MAX_PARTY_SIZE # Tamaño máximo del equipo
)
pbBattleTowerChallenge
El primer argumento es el identificador interno del desafío, que debe coincidir con los datos guardados de rachas de victorias. Los argumentos configuran las reglas básicas del desafío.
Evento NPC de recepción
El NPC de recepción en la instalación de batalla debe seguir este flujo:
# Evento del NPC de recepción
pbMessage(_I("¡Bienvenido a la Torre Batalla!"))
pbMessage(_I("Aquí podrás poner a prueba tu fuerza en combates consecutivos."))
# Preguntar el tipo de desafío
choices = [_I("Combate Individual"), _I("Combate Doble"), _I("Cancelar")]
choice = pbMessage(_I("¿Qué tipo de desafío deseas?"), choices, 3)
case choice
when 0 # Individual
pbMessage(_I("Elige 3 Pokémon de tu equipo para participar."))
if pbBattleChallenge.set("pokemon_challenge_single", 7, 50, 3)
pbBattleTowerChallenge
end
when 1 # Doble
pbMessage(_I("Elige 4 Pokémon de tu equipo para participar."))
if pbBattleChallenge.set("pokemon_challenge_double", 7, 50, 4)
pbBattleTowerChallenge
end
when 2 # Cancelar
pbMessage(_I("¡Vuelve cuando estés listo!"))
end
Reglas de batalla
Las reglas de batalla determinan las restricciones y formato de los combates dentro del desafío. Se configuran mediante el objeto BattleRules:
# Configurar reglas de batalla
rules = PokemonChallengeRules.new
# Nivel máximo
rules.setLevelAdjustment(OpenLevelAdjustment.new(50))
# Número de Pokémon por equipo
rules.addPokemonRule(MaximumNumberRestriction.new(3))
# Prohibir Pokémon legendarios
rules.addPokemonRule(BannedSpeciesRestriction.new(
:MEWTWO, :MEW, :LUGIA, :HOOH, :CELEBI,
:KYOGRE, :GROUDON, :RAYQUAZA, :JIRACHI, :DEOXYS,
:DIALGA, :PALKIA, :GIRATINA, :ARCEUS
))
# Prohibir objetos duplicados
rules.addTeamRule(UniqueItemRestriction.new)
# Prohibir Pokémon duplicados
rules.addTeamRule(SpeciesClause.new)
Tipos de restricciones disponibles
| Restricción | Descripción |
|---|---|
MaximumNumberRestriction | Limita el número máximo de Pokémon en el equipo. |
BannedSpeciesRestriction | Prohíbe especies específicas de Pokémon. |
UniqueItemRestriction | No permite objetos duplicados en el equipo. |
SpeciesClause | No permite especies duplicadas en el equipo. |
LevelRestriction | Limita el nivel máximo de los Pokémon. |
BannedItemRestriction | Prohíbe objetos específicos. |
BannedMoveRestriction | Prohíbe movimientos específicos. |
Pool de entrenadores
Los entrenadores del desafío se generan a partir de un pool definido en el archivo PBS battle_tower_trainers.txt (o el archivo correspondiente a la instalación). Cada entrada define un entrenador con su equipo:
# Formato de battle_tower_trainers.txt
# Cada entrenador tiene un tipo, nombre y equipo de Pokémon
[POKEMONTRAINER_Aria,Aria,0]
Pokemon = GARDEVOIR,50
Item = CHOICE_SPECS
Moves = PSYCHIC,MOONBLAST,THUNDERBOLT,SHADOW_BALL
Nature = MODEST
EVs = 0,0,0,252,4,252
Pokemon = LUCARIO,50
Item = LIFE_ORB
Moves = AURA_SPHERE,FLASH_CANNON,DARK_PULSE,NASTY_PLOT
Nature = TIMID
EVs = 0,0,0,252,4,252
Pokemon = TOGEKISS,50
Item = LEFTOVERS
Moves = AIR_SLASH,DAZZLING_GLEAM,ROOST,THUNDER_WAVE
Nature = CALM
EVs = 252,0,0,0,200,56
Se recomienda crear al menos 50–100 entrenadores en el pool para garantizar variedad. El sistema selecciona entrenadores aleatoriamente con dificultad escalada según la racha actual del jugador.
Progresión por rondas
Un desafío estándar de Battle Tower sigue esta progresión:
- Ronda 1–6: Entrenadores normales del pool, dificultad baja-media.
- Ronda 7: Entrenador "jefe" (Tycoon/Brain) de la instalación. Si se vence, se completa una racha.
- Ronda 14: El Brain aparece de nuevo con un equipo más fuerte.
- Ronda 21+: Dificultad máxima. Los entrenadores del pool son los más fuertes.
Puedes personalizar la aparición del Brain configurando el evento correspondiente:
# En el script del desafío, definir cuándo aparece el Brain
if pbBattleChallenge.wins == 6 # Victoria 7 (índice 6)
# Mostrar diálogo especial del Brain
pbMessage(_I("¡Has llegado al combate final de la ronda!"))
pbMessage(_I("El As de la Torre te está esperando."))
# Combate contra el Brain
pbTrainerBattle(:POKEMON_TRAINER_Brain, "Arturo", 0)
end
Rachas de victorias (Win Streaks)
El sistema registra automáticamente la racha de victorias más alta del jugador. Esta se almacena y se puede consultar:
# Obtener la racha actual
current_wins = pbBattleChallenge.wins
# Obtener la racha récord
record = pbBattleChallenge.pokemon_challenge_record
pbMessage(_I("Tu racha récord es de #{record} victorias."))
Las rachas se usan para desbloquear recompensas especiales y para mostrar en la Tarjeta de Entrenador.
Recompensas
Después de completar cada ronda (7 victorias consecutivas), el jugador recibe recompensas. Puedes configurar Battle Points (BP) u objetos:
# Dar Battle Points como recompensa
# Los BP se almacenan como una variable del jugador
$player.battle_points += 3
pbMessage(_I("¡Has ganado 3 Puntos de Batalla!"))
# Recompensas escalonadas según la racha
case pbBattleChallenge.wins
when 7
$player.battle_points += 3
pbMessage(_I("¡Racha de 7! Has ganado 3 PB."))
when 14
$player.battle_points += 5
pbMessage(_I("¡Racha de 14! Has ganado 5 PB."))
when 21
$player.battle_points += 7
pbReceiveItem(:ABILITYCAPSULE)
pbMessage(_I("¡Racha de 21! Has ganado 7 PB y una Cápsula de Habilidad."))
when 49
$player.battle_points += 10
pbReceiveItem(:STARRIBBON)
pbMessage(_I("¡Racha de 49! Has ganado 10 PB y la Cinta Estrella."))
end
Tienda de intercambio de BP
Puedes crear una tienda donde los jugadores canjeen sus Puntos de Batalla por objetos:
# Tienda de BP (evento NPC)
pbMessage(_I("¡Bienvenido a la Tienda de Batalla!"))
pbMessage(_I("Tus PB actuales: #{$player.battle_points}"))
items = [
[:RARECANDY, 1], # 1 BP
[:PPUP, 3], # 3 BP
[:CHOICEBAND, 10], # 10 BP
[:CHOICESPECS, 10],
[:CHOICESCARF, 10],
[:LIFEORB, 15],
[:FOCUSSASH, 10],
[:ABILITYCAPSULE, 25]
]
# Mostrar opciones
choices = items.map { |item, cost|
name = GameData::Item.get(item).name
_I("#{name} - #{cost} PB")
}
choices.push(_I("Cancelar"))
loop do
choice = pbMessage(_I("¿Qué deseas comprar?"), choices, choices.length)
break if choice == choices.length - 1
item, cost = items[choice]
if $player.battle_points >= cost
$player.battle_points -= cost
pbReceiveItem(item)
else
pbMessage(_I("No tienes suficientes Puntos de Batalla."))
end
end
Battle Factory: Pokémon de alquiler
La Battle Factory tiene una mecánica especial donde el jugador no usa sus propios Pokémon. En su lugar, elige de un grupo de Pokémon generados aleatoriamente:
# Iniciar Battle Factory
pbBattleChallenge.set("pokemon_factory", 7, 50, 3)
pbBattleFactoryChallenge
El sistema genera automáticamente un grupo de 6 Pokémon aleatorios del pool. El jugador elige 3. Después de cada combate victorioso, el jugador puede intercambiar uno de sus Pokémon por uno del equipo rival derrotado.
Configurar la instalación completa
Para montar una instalación de batalla completa necesitas:
- Mapa de la instalación: lobby con NPCs de recepción, reglas y tienda de BP.
- Mapa de combate: un mapa simple donde ocurren los combates consecutivos.
- NPC de recepción: explica las reglas y permite iniciar el desafío.
- NPC de reglas: muestra las restricciones del desafío actual.
- NPC de récords: muestra las rachas de victorias del jugador.
- Tienda BP: NPC donde canjear puntos por objetos.
- Pool de entrenadores: el archivo PBS con todos los entrenadores del desafío.
- Brain/Tycoon: el entrenador jefe de la instalación con diálogos especiales.
Guardar progreso del desafío
Los desafíos de batalla guardan automáticamente el progreso entre rondas. Si el jugador pierde o se retira, la racha actual se reinicia pero el récord se mantiene. El jugador puede guardar la partida entre combates en algunas instalaciones, dependiendo de la configuración.
# Forzar guardado entre rondas (opcional)
if pbBattleChallenge.wins % 7 == 0 && pbBattleChallenge.wins > 0
pbMessage(_I("¿Deseas guardar la partida antes de continuar?"))
if pbConfirmMessage(_I("¿Guardar?"))
pbSave
pbMessage(_I("Partida guardada."))
end
end
Errores comunes
- Pool de entrenadores vacío: asegúrate de que el archivo PBS de entrenadores exista y tenga formato correcto.
- Pokémon del jugador por encima del nivel: configura correctamente el ajuste de nivel para que los Pokémon se escalen al nivel máximo permitido.
- Racha no se guarda: verifica que el ID del desafío sea consistente entre llamadas.
- Brain no aparece: comprueba que el check de victorias coincida con la ronda correcta (índice base 0 vs base 1).