forked from mirrors/cobblemon
Merge branch 'battle-lockup-fix' into 'main'
Battle lockup fix See merge request cable-mc/cobblemon!2199
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
- Fixed a Server warning when recalling Pokemon
|
||||
- Fixed sliding particles incorrectly handling block collision
|
||||
- Fixed Full Heal not curing status conditions in battle
|
||||
- Fixed a rare issue with battles locking up when you are forced to switch, with the switch menu appearing instantly.
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
|
||||
@@ -137,7 +137,6 @@ open class PokemonBattle(
|
||||
|
||||
var dispatchResult = GO
|
||||
val dispatches = ConcurrentLinkedDeque<BattleDispatch>()
|
||||
val afterDispatches = mutableListOf<() -> Unit>()
|
||||
|
||||
val captureActions = mutableListOf<BattleCaptureAction>()
|
||||
|
||||
@@ -400,12 +399,10 @@ open class PokemonBattle(
|
||||
|
||||
fun dispatch(dispatcher: () -> DispatchResult) {
|
||||
dispatches.add(BattleDispatch { dispatcher() })
|
||||
|
||||
}
|
||||
|
||||
fun dispatchToFront(dispatcher: () -> DispatchResult) {
|
||||
dispatches.addFirst(BattleDispatch { dispatcher() })
|
||||
|
||||
}
|
||||
|
||||
fun dispatchWaitingToFront(delaySeconds: Float = 1F, dispatcher: () -> Unit) {
|
||||
@@ -456,21 +453,12 @@ open class PokemonBattle(
|
||||
dispatches.addFirst(dispatcher)
|
||||
}
|
||||
|
||||
fun doWhenClear(action: () -> Unit) {
|
||||
afterDispatches.add(action)
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
try {
|
||||
while (dispatchResult.canProceed()) {
|
||||
val dispatch = dispatches.poll() ?: break
|
||||
dispatchResult = dispatch(this)
|
||||
}
|
||||
|
||||
if (dispatches.isEmpty()) {
|
||||
afterDispatches.toList().forEach { it() }
|
||||
afterDispatches.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LOGGER.error("Exception while ticking a battle. Saving battle log.", e)
|
||||
val message = battleLang("crash").red()
|
||||
|
||||
+2
-4
@@ -8,8 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.battles.model.actor
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
@@ -76,7 +74,7 @@ abstract class BattleActor(
|
||||
fun turn() {
|
||||
val request = request ?: return
|
||||
responses.clear()
|
||||
if(activePokemon.any { it.isAlive() }) {
|
||||
if (activePokemon.any { it.isAlive() }) {
|
||||
mustChoose = true
|
||||
sendUpdate(BattleMakeChoicePacket())
|
||||
}
|
||||
@@ -90,7 +88,7 @@ abstract class BattleActor(
|
||||
}
|
||||
}
|
||||
|
||||
fun upkeep() {
|
||||
fun postUpdate() {
|
||||
val request = request ?: return
|
||||
val forceSwitchPokemon = request.forceSwitch.mapIndexedNotNull { index, b -> if (b) activePokemon[index] else null }
|
||||
if (forceSwitchPokemon.isEmpty()) {
|
||||
|
||||
@@ -9,10 +9,14 @@
|
||||
package com.cobblemon.mod.common.battles
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.*
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BasicContext
|
||||
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.interpreter.Effect
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.InvalidInstructionException
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.MissingContext
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.api.text.yellow
|
||||
import com.cobblemon.mod.common.battles.dispatch.InstructionSet
|
||||
@@ -22,21 +26,7 @@ import com.cobblemon.mod.common.battles.interpreter.instructions.*
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import com.cobblemon.mod.common.util.runOnServer
|
||||
import net.minecraft.world.level.ClipContext
|
||||
import net.minecraft.world.phys.HitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import java.util.UUID
|
||||
import kotlin.collections.Iterator
|
||||
import kotlin.collections.filter
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.listOf
|
||||
import kotlin.collections.map
|
||||
import kotlin.collections.mutableListOf
|
||||
import kotlin.collections.mutableMapOf
|
||||
import kotlin.collections.set
|
||||
import kotlin.collections.toMutableList
|
||||
import kotlin.collections.toTypedArray
|
||||
import kotlin.time.measureTime
|
||||
|
||||
@Suppress("KotlinPlaceholderCountMatchesArgumentCount", "UNUSED_PARAMETER")
|
||||
object ShowdownInterpreter {
|
||||
@@ -141,7 +131,6 @@ object ShowdownInterpreter {
|
||||
// Note '-cureteam' is a legacy thing that is only used in generation 2 and 4 mods for heal bell and aromatherapy respectively as such we can just ignore that
|
||||
}
|
||||
|
||||
|
||||
fun interpretMessage(battleId: UUID, message: String) {
|
||||
// Check key map and use function if matching
|
||||
if (message.startsWith("{\"winner\":\"")) {
|
||||
@@ -170,7 +159,6 @@ object ShowdownInterpreter {
|
||||
val instructionSet = InstructionSet()
|
||||
val battleMessages = mutableListOf<BattleMessage>()
|
||||
|
||||
|
||||
try {
|
||||
val lines = rawMessage.split("\n").toMutableList()
|
||||
if (lines[0] == "update") {
|
||||
@@ -184,6 +172,7 @@ object ShowdownInterpreter {
|
||||
val instruction = updateInstructionParser[id]?.invoke(battle, instructionSet, message, iterator) ?: UnknownInstruction(message)
|
||||
instructionSet.instructions.add(instruction)
|
||||
}
|
||||
instructionSet.instructions.add(PostUpdateInstruction)
|
||||
}
|
||||
else if (lines[0] == "sideupdate") {
|
||||
val showdownId = lines[1]
|
||||
@@ -330,5 +319,4 @@ object ShowdownInterpreter {
|
||||
fun registerSideInstructionParser(id: String, callback: (PokemonBattle, BattleActor, InstructionSet, BattleMessage) -> InterpreterInstruction) {
|
||||
sideInstructionParser[id] = callback
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@ import com.cobblemon.mod.common.api.battles.interpreter.BattleContext
|
||||
* @since April 10th, 2023
|
||||
*/
|
||||
@Deprecated(message =
|
||||
"This was designed before Doubles and Multi battle formats were introduce and has not been maintained since." +
|
||||
"This was designed before Doubles and Multi battle formats were introduced and has not been maintained since.\n" +
|
||||
"Accurate context for formats other than Singles is not guaranteed. This will be replaced in the near future.")
|
||||
class ContextManager {
|
||||
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.battles.interpreter.instructions
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
|
||||
/**
|
||||
* Tails every `update` output from Showdown. Used for picking up any forced switches that need to be done.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since April 13th, 2026
|
||||
*/
|
||||
object PostUpdateInstruction : InterpreterInstruction {
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
battle.dispatchGo { battle.actors.forEach { it.postUpdate() } }
|
||||
}
|
||||
}
|
||||
+2
-10
@@ -14,13 +14,12 @@ import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.battles.ShowdownActionRequest
|
||||
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
|
||||
|
||||
/**
|
||||
* Format: |request|REQUEST
|
||||
*
|
||||
* It's time for the actor to make a decision.
|
||||
* The actor needs to know its options for when it next has to make a decision.
|
||||
* @author Deltric
|
||||
* @since January 22nd, 2022
|
||||
*/
|
||||
@@ -35,17 +34,10 @@ class RequestInstruction(val battleActor: BattleActor, val message: BattleMessag
|
||||
val request = BattleRegistry.gson.fromJson(message.rawMessage.split("|request|")[1], ShowdownActionRequest::class.java)
|
||||
request.sanitize(battle, battleActor)
|
||||
battle.dispatchGo {
|
||||
// This request won't be acted on until the start of next turn
|
||||
// This request won't be acted on until the start of next turn or post-`update` if there's a force switch
|
||||
battleActor.sendUpdate(BattleQueueRequestPacket(request))
|
||||
battleActor.request = request
|
||||
battleActor.responses.clear()
|
||||
// We need to send this out because 'upkeep' isn't received until the request is handled since the turn won't swap
|
||||
if (request.forceSwitch.contains(true)) {
|
||||
battle.doWhenClear {
|
||||
battleActor.mustChoose = true
|
||||
battleActor.sendUpdate(BattleMakeChoicePacket())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.battles.interpreter.instructions
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.dispatch.GO
|
||||
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
|
||||
/**
|
||||
@@ -21,9 +20,6 @@ import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
*/
|
||||
class UpkeepInstruction : InterpreterInstruction {
|
||||
override fun invoke(battle: PokemonBattle) {
|
||||
battle.dispatch {
|
||||
battle.actors.forEach { it.upkeep() }
|
||||
GO
|
||||
}
|
||||
// We could do some updates here like checking field condition state for client side shenanigans
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user