Added ability to spectate pokemon battles

This commit is contained in:
Apion
2023-11-10 05:28:50 +00:00
committed by Hiroku
parent 8af1225c90
commit 132a43c5c7
20 changed files with 380 additions and 32 deletions
+1
View File
@@ -9,6 +9,7 @@
- The Healing Machine now has a more difficult recipe, placing it later game.
### Additions
- Added battle spectating, can disable in config
- Cobblemon now has compatibility with [Adorn](https://modrinth.com/mod/adorn) allowing you to craft Apricorn wood furniture.
- Berries can now be used in recipes from [Farmer's Delight](https://modrinth.com/mod/farmers-delight) and [Farmer's Delight (Fabric)](https://modrinth.com/mod/farmers-delight-fabric), as well as any other mods using the same berry tags.
- The nature of cobblemon will now be displayed italicized when a mint has been applied. Hovering over the nature will display the mint that was applied. This is the intended behaviour, because the original nature and taste of the Cobblemon does not change when a mint is applied.
@@ -11,8 +11,27 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
import com.cobblemon.mod.common.client.net.battle.*
import com.cobblemon.mod.common.client.net.battle.BattleApplyPassResponseHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureShakeHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureStartHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeExpiredHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeNotificationHandler
import com.cobblemon.mod.common.client.net.battle.BattleEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleFaintHandler
import com.cobblemon.mod.common.client.net.battle.BattleHealthChangeHandler
import com.cobblemon.mod.common.client.net.battle.BattleInitializeHandler
import com.cobblemon.mod.common.client.net.battle.BattleMadeInvalidChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMakeChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMessageHandler
import com.cobblemon.mod.common.client.net.battle.BattleMusicHandler
import com.cobblemon.mod.common.client.net.battle.BattlePersistentStatusHandler
import com.cobblemon.mod.common.client.net.battle.BattleQueueRequestHandler
import com.cobblemon.mod.common.client.net.battle.BattleSetTeamPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleSwitchPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleUpdateTeamPokemonHandler
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
@@ -51,6 +70,7 @@ import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.client.battle.*
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
@@ -99,12 +119,10 @@ import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.net.messages.server.*
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectedPacket
import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonSelectedPacket
@@ -134,7 +152,10 @@ import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptanceP
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectedHandler
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSelectedHandler
@@ -168,12 +189,12 @@ import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHa
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.util.server
import kotlin.reflect.KClass
import net.minecraft.network.PacketByteBuf
import net.minecraft.network.listener.ClientPlayPacketListener
import net.minecraft.network.packet.Packet
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import kotlin.reflect.KClass
/**
* Registers Cobblemon network packets.
@@ -238,6 +259,7 @@ object CobblemonNetwork : NetworkManager {
// UI Packets
this.createClientBound(SummaryUIPacket.ID, SummaryUIPacket::decode, SummaryUIPacketHandler)
this.createClientBound(InteractPokemonUIPacket.ID, InteractPokemonUIPacket::decode, InteractPokemonUIPacketHandler)
this.createClientBound(PlayerInteractOptionsPacket.ID, PlayerInteractOptionsPacket::decode, PlayerInteractOptionsHandler)
// Starter packets
this.createClientBound(OpenStarterUIPacket.ID, OpenStarterUIPacket::decode, StarterUIPacketHandler)
@@ -323,6 +345,7 @@ object CobblemonNetwork : NetworkManager {
// Interaction Packets
this.createServerBound(InteractPokemonPacket.ID, InteractPokemonPacket::decode, InteractPokemonHandler)
this.createServerBound(RequestPlayerInteractionsPacket.ID, RequestPlayerInteractionsPacket::decode, RequestInteractionsHandler)
// Storage Packets
this.createServerBound(SendOutPokemonPacket.ID, SendOutPokemonPacket::decode, SendOutPokemonHandler)
@@ -350,6 +373,8 @@ object CobblemonNetwork : NetworkManager {
// Battle packets
this.createServerBound(BattleSelectActionsPacket.ID, BattleSelectActionsPacket::decode, BattleSelectActionsHandler)
this.createServerBound(SpectateBattlePacket.ID, SpectateBattlePacket::decode, SpectateBattleHandler)
this.createServerBound(RemoveSpectatorPacket.ID, RemoveSpectatorPacket::decode, RemoveSpectatorHandler)
// Trade
this.createServerBound(AcceptTradeRequestPacket.ID, AcceptTradeRequestPacket::decode, AcceptTradeRequestHandler)
@@ -86,12 +86,13 @@ open class PokemonBattle(
val playerUUIDs: Iterable<UUID>
get() = actors.flatMap { it.getPlayerUUIDs() }
val players = playerUUIDs.mapNotNull { it.getPlayer() }
val spectators = mutableListOf<UUID>()
val spectators = mutableSetOf<UUID>()
val battleId = UUID.randomUUID()
val showdownMessages = mutableListOf<String>()
val battleLog = mutableListOf<String>()
val chatLog = mutableListOf<Text>()
var started = false
var ended = false
// TEMP battle showcase stuff
@@ -179,11 +180,8 @@ open class PokemonBattle(
}
fun broadcastChatMessage(component: Text) {
spectators.forEach { spectatorId ->
spectatorId.getPlayer()?.let {
CobblemonNetwork.sendPacketToPlayer(it, BattleMessagePacket(component))
}
}
chatLog.add(component)
sendSpectatorUpdate(BattleMessagePacket(component))
return actors.forEach { it.sendMessage(component) }
}
@@ -221,6 +221,10 @@ object BattleRegistry {
return battleMap.values.find { it.getActor(serverPlayerEntity) != null }
}
fun getBattleByParticipatingPlayerId(playerId: UUID): PokemonBattle? {
return battleMap.values.find { playerId in it.playerUUIDs }
}
fun tick() {
battleMap.forEachValue(Long.MAX_VALUE) { it.tick() }
}
@@ -1448,7 +1448,9 @@ object ShowdownInterpreter {
GO
}
}
privateMessage.pnxAndUuid(0)?.let { (pnx, _) -> battle.sendSidedUpdate(actor, BattleHealthChangePacket(pnx, remainingHealth.toFloat()), BattleHealthChangePacket(pnx, newHealthRatio)) }
privateMessage.pnxAndUuid(0)?.let { (pnx, _) -> {
battle.sendSidedUpdate(actor, BattleHealthChangePacket(pnx, remainingHealth.toFloat()), BattleHealthChangePacket(pnx, newHealthRatio))
}}
battle.minorBattleActions[battlePokemon.uuid] = privateMessage
WaitDispatch(1F)
@@ -13,12 +13,14 @@ import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.battle.ClientBattleActor
import com.cobblemon.mod.common.client.battle.SingleActionRequest
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleActionSelection
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleBackButton
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleGeneralActionSelection
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleSwitchPokemonSelection
import com.cobblemon.mod.common.client.gui.battle.widgets.BattleMessagePane
import com.cobblemon.mod.common.client.keybind.boundKey
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.MinecraftClient
@@ -41,6 +43,7 @@ class BattleGUI : Screen(battleLang("gui.title")) {
private lateinit var messagePane: BattleMessagePane
var opacity = 0F
val actor = CobblemonClient.battle?.side1?.actors?.find { it.uuid == MinecraftClient.getInstance().player?.uuid }
val specBackButton = BattleBackButton(12f, MinecraftClient.getInstance().window.scaledHeight - 32f)
var queuedActions = mutableListOf<() -> Unit>()
@@ -106,6 +109,10 @@ class BattleGUI : Screen(battleLang("gui.title")) {
}
}
if (battle.spectating) {
specBackButton.render(context.matrices, mouseX, mouseY, delta)
}
val currentSelection = getCurrentActionSelection()
if (currentSelection == null || currentSelection is BattleGeneralActionSelection ) {
drawScaledText(
@@ -153,4 +160,13 @@ class BattleGUI : Screen(battleLang("gui.title")) {
}
return super.charTyped(chr, modifiers)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val battle = CobblemonClient.battle
if (battle?.spectating == true && specBackButton.isHovered(mouseX, mouseY)) {
RemoveSpectatorPacket(battle.battleId).sendToServer()
CobblemonClient.endBattle()
}
return super.mouseClicked(mouseX, mouseY, button)
}
}
@@ -10,7 +10,9 @@ package com.cobblemon.mod.common.client.gui.interact.wheel
import com.cobblemon.mod.common.CobblemonNetwork
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
@@ -48,14 +50,14 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean): Intera
return InteractWheelGUI(options, Text.translatable("cobblemon.ui.interact.pokemon"))
}
fun createPlayerInteractGui(targetPlayer: PlayerEntity, pokemon: Pokemon): InteractWheelGUI {
fun createPlayerInteractGui(optionsPacket: PlayerInteractOptionsPacket): InteractWheelGUI {
val trade = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_trade.png"),
colour = { if (CobblemonClient.requests.tradeOffers.any { it.traderId == targetPlayer.uuid }) Vector3f(0F, 0.6F, 0F) else null },
colour = { if (CobblemonClient.requests.tradeOffers.any { it.traderId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
val tradeOffer = CobblemonClient.requests.tradeOffers.find { it.traderId == targetPlayer.uuid }
val tradeOffer = CobblemonClient.requests.tradeOffers.find { it.traderId == optionsPacket.targetId }
if (tradeOffer == null) {
CobblemonNetwork.sendToServer(OfferTradePacket(targetPlayer.uuid))
CobblemonNetwork.sendToServer(OfferTradePacket(optionsPacket.targetId))
} else {
CobblemonClient.requests.tradeOffers -= tradeOffer
CobblemonNetwork.sendToServer(AcceptTradeRequestPacket(tradeOffer.tradeOfferId))
@@ -65,18 +67,35 @@ fun createPlayerInteractGui(targetPlayer: PlayerEntity, pokemon: Pokemon): Inter
)
val battle = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_battle.png"),
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == targetPlayer.uuid }) Vector3f(0F, 0.6F, 0F) else null },
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
val battleRequest = CobblemonClient.requests.battleChallenges.find { it.challengerId == targetPlayer.uuid }
val battleRequest = CobblemonClient.requests.battleChallenges.find { it.challengerId == optionsPacket.targetId }
// This can be improved in future with more detailed battle challenge data.
BattleChallengePacket(targetPlayer.id, pokemon.uuid).sendToServer()
BattleChallengePacket(optionsPacket.numericTargetId, optionsPacket.selectedPokemonId).sendToServer()
closeGUI()
}
)
val options = mutableMapOf(
Orientation.TOP_LEFT to trade,
Orientation.TOP_RIGHT to battle
val spectate = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_spectate_battle.png"),
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
SpectateBattlePacket(optionsPacket.targetId).sendToServer()
closeGUI()
}
)
val options = mutableMapOf<Orientation, InteractWheelOption>()
//The way things are positioned should probably be more thought out if more options are added
optionsPacket.options.map {
if (it.equals(PlayerInteractOptionsPacket.Options.TRADE)) {
options[Orientation.TOP_LEFT] = trade
}
if (it.equals(PlayerInteractOptionsPacket.Options.BATTLE)) {
options[Orientation.TOP_RIGHT] = battle
}
if (it.equals(PlayerInteractOptionsPacket.Options.SPECTATE_BATTLE)) {
options[Orientation.TOP_RIGHT] = spectate
}
}
return InteractWheelGUI(options, Text.translatable("cobblemon.ui.interact.player"))
}
@@ -11,15 +11,14 @@ package com.cobblemon.mod.common.client.keybind.keybinds
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToServer
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
import com.cobblemon.mod.common.client.gui.interact.wheel.createPlayerInteractGui
import com.cobblemon.mod.common.client.keybind.CobblemonBlockingKeyBinding
import com.cobblemon.mod.common.client.keybind.KeybindCategories
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.traceFirstEntityCollision
import javax.swing.plaf.basic.BasicSliderUI.ScrollListener
import net.minecraft.client.MinecraftClient
import net.minecraft.client.network.ClientPlayerEntity
import net.minecraft.client.util.InputUtil
@@ -90,7 +89,9 @@ object PartySendBinding : CobblemonBlockingKeyBinding(
private fun processEntityTarget(player: ClientPlayerEntity, pokemon: Pokemon, entity: LivingEntity) {
when (entity) {
is PlayerEntity -> {
MinecraftClient.getInstance().setScreen(createPlayerInteractGui(entity, pokemon))
//This sends a packet to the server with the id of the player
//The server sends a packet back that opens the player interaction menu with the proper options
sendPacketToServer(RequestPlayerInteractionsPacket(entity.uuid, entity.id, pokemon.uuid))
}
is PokemonEntity -> {
if (!entity.canBattle(player)) return
@@ -0,0 +1,21 @@
/*
* 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.client.net
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.client.gui.interact.wheel.createPlayerInteractGui
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import net.minecraft.client.MinecraftClient
object PlayerInteractOptionsHandler : ClientNetworkPacketHandler<PlayerInteractOptionsPacket> {
override fun handle(packet: PlayerInteractOptionsPacket, client: MinecraftClient) {
MinecraftClient.getInstance().setScreen(createPlayerInteractGui(packet))
}
}
@@ -32,10 +32,10 @@ object BattleInitializeHandler : ClientNetworkPacketHandler<BattleInitializePack
}
val otherSide = if (mySide == packet.side1) packet.side2 else packet.side1
side1.actors.addAll(mySide.actors.map{ actorFromDTO(it, true) })
val sides = listOf(packet.side1, packet.side2)
spectating = !sides.any { it.actors.any { it.uuid == MinecraftClient.getInstance().player?.uuid } }
side1.actors.addAll(mySide.actors.map{ actorFromDTO(it, !spectating) })
side2.actors.addAll(otherSide.actors.map{ actorFromDTO(it, false) })
spectating = sides.any { it.actors.any { it.uuid == MinecraftClient.getInstance().player?.uuid } }
for (side in listOf(side1, side2)) {
side.battle = this
for (actor in side.actors) {
@@ -131,6 +131,9 @@ class CobblemonConfig {
@NodeCategory(category = Category.Battles)
var luckyEggMultiplier = 1.5
@NodeCategory(category = Category.Battles)
var allowSpectating = true
@NodeCategory(category = Category.Pokemon)
var experienceMultiplier = 2F
@@ -0,0 +1,54 @@
/*
* 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.net.messages.client
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
import java.util.EnumSet
/**
* Used to populate the player interaction menu
*
*
* @author Apion
* @since November 5th, 2023
*/
class PlayerInteractOptionsPacket(
val options: EnumSet<Options>,
val targetId: UUID,
val numericTargetId: Int,
val selectedPokemonId: UUID
) : NetworkPacket<PlayerInteractOptionsPacket> {
companion object {
val ID = cobblemonResource("player_interactions")
fun decode(buffer: PacketByteBuf) = PlayerInteractOptionsPacket(
buffer.readEnumSet(Options::class.java),
buffer.readUuid(),
buffer.readInt(),
buffer.readUuid()
)
}
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeEnumSet(options, Options::class.java)
buffer.writeUuid(targetId)
buffer.writeInt(numericTargetId)
buffer.writeUuid(selectedPokemonId)
}
enum class Options {
BATTLE,
SPECTATE_BATTLE,
TRADE
}
}
@@ -49,7 +49,11 @@ class BattleInitializePacket() : NetworkPacket<BattleInitializePacket> {
lateinit var side1: BattleSideDTO
lateinit var side2: BattleSideDTO
constructor(battle: PokemonBattle, allySide: BattleSide): this() {
/**
* @param battle The battle to initialize on the client
* @param allySide The [BattleSide] the client is on, null if the client is a spectator
*/
constructor(battle: PokemonBattle, allySide: BattleSide?): this() {
battleId = battle.battleId
battleFormat = battle.format
val sides = arrayOf(battle.side1, battle.side2).map { side ->
@@ -59,7 +63,9 @@ class BattleInitializePacket() : NetworkPacket<BattleInitializePacket> {
uuid = actor.uuid,
showdownId = actor.showdownId,
displayName = actor.getName(),
activePokemon = actor.activePokemon.map { it.battlePokemon?.let { pkm -> ActiveBattlePokemonDTO.fromPokemon(pkm, allySide == side) } },
activePokemon = actor.activePokemon.map { it.battlePokemon?.let {
pkm -> ActiveBattlePokemonDTO.fromPokemon(pkm, allySide == side)
} },
type = actor.type
)
}
@@ -0,0 +1,40 @@
/*
* 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.net.messages.server
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
/**
* Sent from client to request a [com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket]
*
* @author Apion
* @since November 5th, 2023
*/
class RequestPlayerInteractionsPacket(
val targetId: UUID,
val targetNumericId: Int,
val pokemonId: UUID
) : NetworkPacket<RequestPlayerInteractionsPacket> {
companion object {
val ID = cobblemonResource("request_interactions")
fun decode(buffer: PacketByteBuf) = RequestPlayerInteractionsPacket(buffer.readUuid(), buffer.readInt(), buffer.readUuid())
}
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(targetId)
buffer.writeInt(targetNumericId)
buffer.writeUuid(pokemonId)
}
}
@@ -0,0 +1,26 @@
/*
* 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.net.messages.server.battle
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
class RemoveSpectatorPacket(val battleId: UUID) : NetworkPacket<RemoveSpectatorPacket> {
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(battleId)
}
companion object {
val ID = cobblemonResource("remove_spectator")
fun decode(buffer: PacketByteBuf) = RemoveSpectatorPacket(buffer.readUuid())
}
}
@@ -0,0 +1,26 @@
/*
* 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.net.messages.server.battle
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
class SpectateBattlePacket(val targetedEntityId: UUID) : NetworkPacket<SpectateBattlePacket> {
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(targetedEntityId)
}
companion object {
val ID = cobblemonResource("battle_spectate")
fun decode(buffer: PacketByteBuf) = SpectateBattlePacket(buffer.readUuid())
}
}
@@ -0,0 +1,40 @@
/*
* 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.net.serverhandling
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import java.util.EnumSet
object RequestInteractionsHandler : ServerNetworkPacketHandler<RequestPlayerInteractionsPacket> {
override fun handle(
packet: RequestPlayerInteractionsPacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
//We could potentially check if the targeted player has pokemon here
val options = EnumSet.of(PlayerInteractOptionsPacket.Options.TRADE)
val isTargetBattling = BattleRegistry.getBattleByParticipatingPlayerId(packet.targetId) != null
if (isTargetBattling and Cobblemon.config.allowSpectating) {
options.add(PlayerInteractOptionsPacket.Options.SPECTATE_BATTLE)
}
else {
options.add(PlayerInteractOptionsPacket.Options.BATTLE)
}
PlayerInteractOptionsPacket(options, packet.targetId, packet.targetNumericId, packet.pokemonId).sendToPlayer(player)
}
}
@@ -0,0 +1,26 @@
/*
* 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.net.serverhandling.battle
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
object RemoveSpectatorHandler : ServerNetworkPacketHandler<RemoveSpectatorPacket> {
override fun handle(
packet: RemoveSpectatorPacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
BattleRegistry.getBattle(packet.battleId)?.spectators?.remove(player.uuid)
}
}
@@ -0,0 +1,40 @@
/*
* 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.net.serverhandling.battle
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.client.battle.BattleInitializePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import org.apache.logging.log4j.LogManager
object SpectateBattleHandler : ServerNetworkPacketHandler<SpectateBattlePacket> {
val LOGGER = LogManager.getLogger()
override fun handle(
packet: SpectateBattlePacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
val battle = BattleRegistry.getBattleByParticipatingPlayerId(packet.targetedEntityId)
if ((battle != null) and Cobblemon.config.allowSpectating) {
battle!!.spectators.add(player.uuid)
player.sendPacket(BattleInitializePacket(battle, null))
player.sendPacket(BattleMessagePacket(battle.chatLog))
}
else {
LOGGER.error("Battle of player id ${packet.targetedEntityId} not found (${player.uuid} tried spectating)")
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B