Merge branch 'sigma-pokemon' into 'sigma-pokemon'

Alpha boost implementation

See merge request cable-mc/cobblemon!2114
This commit is contained in:
Polymeta
2026-03-02 23:38:04 +00:00
5 changed files with 87 additions and 12 deletions
@@ -282,9 +282,13 @@ object BattleBuilder {
}
playerActor.battleTheme = pokemonEntity.getBattleTheme()
val finalFormat = if (pokemonEntity.pokemon.isAlpha && BattleRules.WILD_ALPHA !in battleFormat.ruleSet) {
BattleFormat.setBattleRules(battleFormat, battleFormat.ruleSet + BattleRules.WILD_ALPHA)
} else battleFormat
return if (errors.isEmpty) {
BattleRegistry.startBattle(
battleFormat = battleFormat,
battleFormat = finalFormat,
side1 = BattleSide(playerActor),
side2 = BattleSide(wildActor)
).ifSuccessful {
@@ -18,4 +18,5 @@ object BattleRules {
const val CANCEL_MOD = "Cancel Mod"
const val SLEEP_CLAUSE = "Sleep Clause"
const val HP_PERCENTAGE_MOD = "HP Percentage Mod"
const val WILD_ALPHA = "Wild Alpha"
}
@@ -8,16 +8,23 @@
package com.cobblemon.mod.common.battles.interpreter.instructions
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.battles.interpreter.BattleContext
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
import com.cobblemon.mod.common.api.text.yellow
import com.cobblemon.mod.common.battles.ShowdownInterpreter
import com.cobblemon.mod.common.battles.dispatch.ActionEffectInstruction
import com.cobblemon.mod.common.battles.dispatch.GO
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.chat.Component
import java.util.concurrent.CompletableFuture
/**
* Format: |-start|POKEMON|EFFECT
@@ -26,25 +33,59 @@ import net.minecraft.network.chat.Component
* @author Deltric
* @since January 21st, 2022
*/
class StartInstruction(val message: BattleMessage): InterpreterInstruction {
class StartInstruction(val message: BattleMessage): ActionEffectInstruction, InterpreterInstruction {
override var future: CompletableFuture<*> = CompletableFuture.completedFuture(Unit)
override var holds = mutableSetOf<String>()
override val id = cobblemonResource("start")
override fun invoke(battle: PokemonBattle) {
override fun preActionEffect(battle: PokemonBattle)
{
val pokemon = message.battlePokemon(0, battle) ?: return
val effectID = message.effectAt(1)?.id ?: return
// skip adding contexts for every time the perish counter decrements
if (!effectID.contains("perish")) {
// don't need to add unique: showdown won't send -start instruction if volatile status is already present
pokemon.contextManager.add(ShowdownInterpreter.getContextFromAction(message, BattleContext.Type.VOLATILE, battle))
}
battle.dispatch{
battle.minorBattleActions[pokemon.uuid] = message
GO
}
}
override fun runActionEffect(battle: PokemonBattle, runtime: MoLangRuntime) {
battle.dispatch {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
val effectID = message.effectAt(1)?.id ?: return@dispatch GO
val actionEffect = ActionEffects.actionEffects[cobblemonResource("start_${effectID}")] ?: return@dispatch GO
val providers = mutableListOf<Any>(battle)
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
val context = ActionEffectContext(
actionEffect = actionEffect,
runtime = runtime,
providers = providers,
level = battle.players.firstOrNull()?.level()
)
this.future = actionEffect.run(context)
holds = context.holds // Reference so future things can check on this action effect's holds
future.thenApply { holds.clear() }
return@dispatch GO
}
}
override fun postActionEffect(battle: PokemonBattle) {
battle.dispatch {
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
val effectID = message.effectAt(1)?.id ?: return@dispatch GO
val optionalEffect = message.effect()
val optionalPokemon = message.battlePokemonFromOptional(battle)
val optionalPokemonName = optionalPokemon?.getName()
val extraEffect = message.effectAt(2)?.typelessData ?: Component.literal("UNKOWN")
// skip adding contexts for every time the perish counter decrements
if (!effectID.contains("perish")) {
// don't need to add unique: showdown won't send -start instruction if volatile status is already present
pokemon.contextManager.add(ShowdownInterpreter.getContextFromAction(message, BattleContext.Type.VOLATILE, battle))
}
battle.minorBattleActions[pokemon.uuid] = message
if (!message.hasOptionalArgument("silent")) {
val lang = if (optionalEffect?.id == "reflecttype" && optionalPokemonName != null)
battleLang("start.reflecttype", pokemon.getName(), optionalPokemonName)
@@ -59,7 +100,8 @@ class StartInstruction(val message: BattleMessage): InterpreterInstruction {
}
battle.broadcastChatMessage(lang)
}
WaitDispatch(1F)
//We check holds here so the chat msg + particle effect happen more concurrently, instead of sequentially
UntilDispatch { "effects" !in holds}
}
}
}
@@ -2928,6 +2928,8 @@
"cobblemon.battle.start.typechange": "%1$s transformed into the %2$s type!",
"cobblemon.battle.start.uproar": "%1$s caused an uproar!",
"cobblemon.battle.start.yawn": "%1$s grew drowsy!",
"cobblemon.battle.start.alphaboost": "The alpha %1$s is filled with wild might! Its power was boosted!",
"cobblemon.battle.activate.afteryou": "%1$s took the kind offer!",
"cobblemon.battle.activate.allyswitch": "%1$s and %2$s switched places!",
@@ -0,0 +1,26 @@
{
"timeline": [
{
"type": "add_holds",
"holds": ["effects"]
},
{
"type": "entity_particles",
"effect": "cobblemon:statup_actor",
"delay": 0.1,
"locators": ["root"]
},
{
"type": "pause",
"pause": 1.0
},
{
"type": "remove_holds",
"holds": ["effects"]
},
{
"type": "pause",
"pause": 2.0
}
]
}