mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-21 22:56:23 -04:00
Added ability to spectate pokemon battles
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
+29
-10
@@ -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"))
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -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
|
||||
|
||||
+21
@@ -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))
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -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
|
||||
|
||||
|
||||
+54
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
+8
-2
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
+40
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -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())
|
||||
}
|
||||
}
|
||||
+26
@@ -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())
|
||||
}
|
||||
}
|
||||
+40
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
+40
@@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 398 B |
Reference in New Issue
Block a user