mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-23 23:56:24 -04:00
Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e88d971f7 | ||
|
|
bfc1c66097 | ||
|
|
13d9f84d8d | ||
|
|
148eb130d9 | ||
|
|
eb07b0e03f | ||
|
|
1b8d416962 | ||
|
|
3030b544b5 | ||
|
|
b890d662f6 | ||
|
|
2a9bbc1d68 | ||
|
|
c10c91d86a | ||
|
|
d5fd2e9a07 | ||
|
|
45cc0ba579 | ||
|
|
1880a0a24e | ||
|
|
5f3a0b96cc | ||
|
|
7ab1610700 | ||
|
|
daad9f6c00 | ||
|
|
2b234b740e | ||
|
|
39e3983020 | ||
|
|
9d58cdb21c | ||
|
|
f05e35e792 | ||
|
|
a333e68620 | ||
|
|
2c2791ec69 |
@@ -85,6 +85,16 @@
|
||||
- Bellossom
|
||||
|
||||
### Changes
|
||||
- Restructured Botany Pots integration folder structure
|
||||
- Decrease default pastured mon wander radius to 32.
|
||||
- Factor in the weight of pokemon when calculating pushing forces between hitboxes.
|
||||
- Remade the Starter Selection Screen with new assets
|
||||
- Refactored berry trees to be less impactful on TPS (more performant)
|
||||
- Trading has been overhauled to allow offering multiple Pokémon, up to the entire party, in a single trade
|
||||
- Selected Pokémon are now highlighted in both parties with new party slot assets
|
||||
- Hovering an offered Pokémon now shows its summary, and clicking the active Pokémon no longer exits the summary view
|
||||
- The trade animation now moves the offered Pokémon towards the Poké Ball
|
||||
- Parties are compacted after a trade so no empty slots are left between Pokémon
|
||||
- Terrain Seeds can now be planted
|
||||
- Terrain Seeds are now consumed during PvP and NPC battles
|
||||
- Glow Item Frames can be crafted using Bright Powder as an alternative to Glow Ink Sacs
|
||||
@@ -133,6 +143,11 @@
|
||||
- Fixed Safari Ball catch rate outside of battle
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
- Added `FishingSpawnerFactory` which allows influence registration on fishing encounters
|
||||
- Added `BattleFleeAttemptEvent` fired from `PokemonBattle.checkFleeAttempt`, allowing developers to intercept and control flee attempts
|
||||
- Trade network packets (`TradeUpdatedPacket`, `UpdateTradeOfferPacket`, and `TradeCompletedPacket`) now receive an array of Pokémon instead of a single Pokémon to execute trades
|
||||
- `TradeEvent.Pre` and `TradeEvent.Post` now expose every Pokémon each participant receives (`tradeParticipant1Pokemon` and `tradeParticipant2Pokemon` are now lists), and their Molang context includes `trade_participant_1_pokemon_list` and `trade_participant_2_pokemon_list`
|
||||
- Evolution requirements can now set `pokedexIcon` and `pokedexTooltip` directly in their JSON to control how they're shown on the Pokédex's evolution tree, for example:
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.trade.TradeParticipant
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
|
||||
/**
|
||||
@@ -31,9 +33,9 @@ interface TradeEvent {
|
||||
val tradeParticipant1: TradeParticipant
|
||||
|
||||
/**
|
||||
* The [Pokemon] being traded by the first participant.
|
||||
* All the [Pokemon] the first participant receives in the trade.
|
||||
*/
|
||||
val tradeParticipant1Pokemon: Pokemon
|
||||
val tradeParticipant1Pokemon: List<Pokemon>
|
||||
|
||||
/**
|
||||
* The second [TradeParticipant].
|
||||
@@ -41,9 +43,19 @@ interface TradeEvent {
|
||||
val tradeParticipant2: TradeParticipant
|
||||
|
||||
/**
|
||||
* The [Pokemon] being traded by the second participant.
|
||||
* All the [Pokemon] the second participant receives in the trade.
|
||||
*/
|
||||
val tradeParticipant2Pokemon: Pokemon
|
||||
val tradeParticipant2Pokemon: List<Pokemon>
|
||||
|
||||
fun createContext(): MutableMap<String, MoValue> = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
// Kept for backwards compatibility, this is the first Pokémon of each side.
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.first().struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.first().struct,
|
||||
"trade_participant_1_pokemon_list" to tradeParticipant1Pokemon.asArrayValue { it.struct },
|
||||
"trade_participant_2_pokemon_list" to tradeParticipant2Pokemon.asArrayValue { it.struct }
|
||||
)
|
||||
|
||||
/**
|
||||
* Event fired when a trade is about to happen. Cancelling this event prevents the trade from occurring.
|
||||
@@ -53,16 +65,11 @@ interface TradeEvent {
|
||||
*/
|
||||
data class Pre(
|
||||
override val tradeParticipant1: TradeParticipant,
|
||||
override val tradeParticipant1Pokemon: Pokemon,
|
||||
override val tradeParticipant1Pokemon: List<Pokemon>,
|
||||
override val tradeParticipant2: TradeParticipant,
|
||||
override val tradeParticipant2Pokemon: Pokemon
|
||||
override val tradeParticipant2Pokemon: List<Pokemon>
|
||||
) : TradeEvent, Cancelable() {
|
||||
val context = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.struct
|
||||
)
|
||||
val context = createContext()
|
||||
|
||||
val functions = moLangFunctionMap(
|
||||
cancelFunc
|
||||
@@ -77,15 +84,10 @@ interface TradeEvent {
|
||||
*/
|
||||
data class Post(
|
||||
override val tradeParticipant1: TradeParticipant,
|
||||
override val tradeParticipant1Pokemon: Pokemon,
|
||||
override val tradeParticipant1Pokemon: List<Pokemon>,
|
||||
override val tradeParticipant2: TradeParticipant,
|
||||
override val tradeParticipant2Pokemon: Pokemon
|
||||
override val tradeParticipant2Pokemon: List<Pokemon>
|
||||
) : TradeEvent {
|
||||
val context = mutableMapOf(
|
||||
"trade_participant_1" to (tradeParticipant1.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_2" to (tradeParticipant2.uuid.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"trade_participant_1_pokemon" to tradeParticipant1Pokemon.struct,
|
||||
"trade_participant_2_pokemon" to tradeParticipant2Pokemon.struct
|
||||
)
|
||||
val context = createContext()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.joml.Vector3f
|
||||
|
||||
open class PartySlot(
|
||||
x: Int, y: Int,
|
||||
private val pokemon: TradeStartedPacket.TradeablePokemon?,
|
||||
val pokemon: TradeStartedPacket.TradeablePokemon?,
|
||||
private val parent: TradeGUI,
|
||||
private val isOpposing: Boolean = false,
|
||||
val isOpposing: Boolean = false,
|
||||
onPress: OnPress
|
||||
) : Button(x, y, SIZE, SIZE, Component.literal("PartySlot"), onPress, DEFAULT_NARRATION), CobblemonRenderable {
|
||||
val state = FloatingState()
|
||||
@@ -42,6 +42,8 @@ open class PartySlot(
|
||||
private val genderIconFemale = cobblemonResource("textures/gui/pc/gender_icon_female.png")
|
||||
private val selectPointerResource = cobblemonResource("textures/gui/pc/pc_pointer.png")
|
||||
private val untradeableResource = cobblemonResource("textures/gui/trade/trade_slot_icon_locked.png")
|
||||
private val tradePartySlotSelectedResource = cobblemonResource("textures/gui/trade/trade_party_slot_selected.png")
|
||||
private val tradePartySlotSelectedOpposingResource = cobblemonResource("textures/gui/trade/trade_party_slot_selected_opposing.png")
|
||||
}
|
||||
|
||||
override fun playDownSound(soundManager: SoundManager) {
|
||||
@@ -60,6 +62,17 @@ open class PartySlot(
|
||||
)
|
||||
}
|
||||
|
||||
if (hasSelected()) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (isOpposing) tradePartySlotSelectedOpposingResource else tradePartySlotSelectedResource,
|
||||
x = x - 2,
|
||||
y = y - 2,
|
||||
width = 29,
|
||||
height = 29
|
||||
)
|
||||
}
|
||||
|
||||
if (pokemon != null) {
|
||||
// context.enableScissor(x - 2, y + 2, x + SIZE + 4, y + SIZE + 4)
|
||||
// Render Pokémon
|
||||
@@ -118,7 +131,16 @@ open class PartySlot(
|
||||
}
|
||||
|
||||
matrices.popPose()
|
||||
if (hasSelected()) {
|
||||
|
||||
val isViewed = if (isOpposing) {
|
||||
parent.opposingOfferedPokemon?.uuid == pokemon.pokemonId
|
||||
} else {
|
||||
parent.offeredPokemon?.uuid == pokemon.pokemonId
|
||||
}
|
||||
|
||||
if (isViewed && pokemon.tradeable) {
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 200.0)
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = selectPointerResource,
|
||||
@@ -128,6 +150,7 @@ open class PartySlot(
|
||||
height = 8,
|
||||
scale = TradeGUI.SCALE
|
||||
)
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
// Held Item
|
||||
@@ -145,8 +168,9 @@ open class PartySlot(
|
||||
}
|
||||
|
||||
open fun hasSelected(): Boolean {
|
||||
val offeredPokemon = if (isOpposing) parent.trade.oppositeOffer.get() else parent.trade.myOffer.get()
|
||||
return pokemon?.pokemonId == offeredPokemon?.uuid && pokemon != null
|
||||
if (pokemon == null) return false
|
||||
val offeredPokemons = if (isOpposing) parent.trade.oppositeOffer.get() else parent.trade.myOffer.get()
|
||||
return offeredPokemons.any { it.uuid == pokemon.pokemonId }
|
||||
}
|
||||
|
||||
fun isHovered(mouseX: Int, mouseY: Int) = pokemon?.tradeable != false && mouseX.toFloat() in (x.toFloat()..(x.toFloat() + SIZE)) && mouseY.toFloat() in (y.toFloat()..(y.toFloat() + SIZE))
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.common.reformatNature
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScaledTextJustifiedRight
|
||||
import com.cobblemon.mod.common.client.trade.ClientTrade
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket.TradeablePokemon
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.*
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
@@ -98,15 +99,23 @@ class TradeGUI(
|
||||
private val tradeAnimationArrowsResource = cobblemonResource("textures/gui/trade/trade_animation_arrows.png")
|
||||
}
|
||||
|
||||
private var offeredPokemonModel: ModelWidget? = null
|
||||
private var opposingOfferedPokemonModel: ModelWidget? = null
|
||||
private var offeredPokemonModels: MutableList<ModelWidget> = mutableListOf()
|
||||
private var opposingOfferedPokemonModels: MutableList<ModelWidget> = mutableListOf()
|
||||
|
||||
private lateinit var offeredPokemonMarkings: MarkingsWidget
|
||||
private lateinit var opposingOfferedPokemonMarkings: MarkingsWidget
|
||||
|
||||
var selectedPartyIndices = mutableListOf<Int>()
|
||||
var offeredPokemons: MutableList<Pokemon> = mutableListOf()
|
||||
var opposingPokemons: MutableList<Pokemon> = mutableListOf()
|
||||
|
||||
// For backwards compatibility where single is referenced in rendering text info
|
||||
var offeredPokemon: Pokemon? = null
|
||||
var opposingOfferedPokemon: Pokemon? = null
|
||||
|
||||
var myGridMode = true
|
||||
var opposingGridMode = true
|
||||
|
||||
var ticksElapsed = 0
|
||||
var protectiveTicks = 0
|
||||
var selectPointerOffsetY = 0
|
||||
@@ -125,30 +134,67 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
trade.completedEmitter.subscribe {
|
||||
val (pokemonId1, pokemonId2) = it
|
||||
val myTradedPokemon = party.find { it?.pokemonId == pokemonId1 }
|
||||
val theirTradedPokemon = traderParty.find { it?.pokemonId == pokemonId2 }
|
||||
if (myTradedPokemon == null || theirTradedPokemon == null) {
|
||||
val (pokemonIds1, pokemonIds2) = it
|
||||
val myTradedPokemons = pokemonIds1.mapNotNull { id -> party.find { it?.pokemonId == id } }
|
||||
val theirTradedPokemons = pokemonIds2.mapNotNull { id -> traderParty.find { it?.pokemonId == id } }
|
||||
if (myTradedPokemons.isEmpty() || theirTradedPokemons.isEmpty()) {
|
||||
CobblemonNetwork.sendToServer(CancelTradePacket())
|
||||
return@subscribe onClose()
|
||||
}
|
||||
val tradedSlot = party.indexOf(myTradedPokemon)
|
||||
val opposingTradedSlot = traderParty.indexOf(theirTradedPokemon)
|
||||
party[tradedSlot] = theirTradedPokemon
|
||||
traderParty[opposingTradedSlot] = myTradedPokemon
|
||||
|
||||
myTradedPokemons.forEach { pk ->
|
||||
val idx = party.indexOf(pk)
|
||||
if (idx != -1) party[idx] = null
|
||||
}
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val idx = traderParty.indexOf(pk)
|
||||
if (idx != -1) traderParty[idx] = null
|
||||
}
|
||||
|
||||
val newSelectedIndices = mutableListOf<Int>()
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val emptyIdx = party.indexOf(null)
|
||||
if (emptyIdx != -1) {
|
||||
party[emptyIdx] = pk
|
||||
}
|
||||
}
|
||||
myTradedPokemons.forEach { pk ->
|
||||
val emptyIdx = traderParty.indexOf(null)
|
||||
if (emptyIdx != -1) traderParty[emptyIdx] = pk
|
||||
}
|
||||
|
||||
val compactUI = { list: MutableList<TradeStartedPacket.TradeablePokemon?> ->
|
||||
val nonNulls = list.filterNotNull()
|
||||
list.clear()
|
||||
list.addAll(nonNulls)
|
||||
while (list.size < 6) list.add(null)
|
||||
}
|
||||
compactUI(party)
|
||||
compactUI(traderParty)
|
||||
|
||||
theirTradedPokemons.forEach { pk ->
|
||||
val idx = party.indexOf(pk)
|
||||
if (idx != -1) newSelectedIndices.add(idx)
|
||||
}
|
||||
|
||||
trade.oppositeAcceptedMyOffer.set(false)
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(Pair(theirTradedPokemon.pokemonId, PartyPosition(tradedSlot))))
|
||||
selectedPartyIndices.clear()
|
||||
selectedPartyIndices.addAll(newSelectedIndices)
|
||||
|
||||
val newOffers = selectedPartyIndices.mapNotNull { idx ->
|
||||
party[idx]?.let { it.pokemonId to PartyPosition(idx) }
|
||||
}
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(newOffers))
|
||||
|
||||
rebuildWidgets()
|
||||
}
|
||||
|
||||
trade.oppositeOffer.subscribe { newOffer: Pokemon? ->
|
||||
setOfferedPokemon(pokemon = newOffer, isOpposing = true)
|
||||
trade.oppositeOffer.subscribe { newOffer: List<Pokemon> ->
|
||||
setOfferedPokemon(pokemonList = newOffer, isOpposing = true)
|
||||
}
|
||||
|
||||
trade.myOffer.subscribe { myOffer: Pokemon? ->
|
||||
setOfferedPokemon(pokemon = myOffer)
|
||||
trade.myOffer.subscribe { myOffer: List<Pokemon> ->
|
||||
setOfferedPokemon(pokemonList = myOffer)
|
||||
}
|
||||
|
||||
trade.oppositeAcceptedMyOffer.subscribe {
|
||||
@@ -216,9 +262,16 @@ class TradeGUI(
|
||||
pokemon = pokemon,
|
||||
parent = this,
|
||||
onPress = {
|
||||
if (!trade.acceptedOppositeOffer && !tradeProcessing) {
|
||||
val pk = if (offeredPokemon?.uuid == pokemon?.pokemonId) null else pokemon
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(pk?.let { it.pokemonId to PartyPosition(partyIndex) }))
|
||||
if (!trade.acceptedOppositeOffer && !tradeProcessing && pokemon != null) {
|
||||
if (selectedPartyIndices.contains(partyIndex)) {
|
||||
selectedPartyIndices.remove(partyIndex)
|
||||
} else if (selectedPartyIndices.size < 6) {
|
||||
selectedPartyIndices.add(partyIndex)
|
||||
}
|
||||
val newOffers = selectedPartyIndices.mapNotNull { idx ->
|
||||
party[idx]?.let { it.pokemonId to PartyPosition(idx) }
|
||||
}
|
||||
CobblemonNetwork.sendToServer(UpdateTradeOfferPacket(newOffers))
|
||||
playSound(CobblemonSounds.GUI_CLICK)
|
||||
}
|
||||
}
|
||||
@@ -250,8 +303,8 @@ class TradeGUI(
|
||||
).also { widget -> addRenderableWidget(widget) }
|
||||
}
|
||||
|
||||
setOfferedPokemon(pokemon = offeredPokemon, isOpposing = false)
|
||||
setOfferedPokemon(pokemon = opposingOfferedPokemon, isOpposing = true)
|
||||
setOfferedPokemon(pokemonList = offeredPokemons.toList(), isOpposing = false)
|
||||
setOfferedPokemon(pokemonList = opposingPokemons.toList(), isOpposing = true)
|
||||
|
||||
offeredPokemonMarkings = MarkingsWidget(x + 74.5, y + 21, offeredPokemon, false)
|
||||
opposingOfferedPokemonMarkings = MarkingsWidget(x + 177.5, y + 21, opposingOfferedPokemon, false)
|
||||
@@ -284,7 +337,7 @@ class TradeGUI(
|
||||
if (tradeAnimationProgress > REVERSE_ANIMATION_TICK)
|
||||
(REVERSE_ANIMATION_TICK + TRADE_ANIMATION_FRAMES - tradeAnimationProgress)
|
||||
else (tradeAnimationProgress - MODEL_SCALE_BUFFER_FRAMES)
|
||||
) * TRADE_ANIMATION_HEIGHT
|
||||
) * TRADE_ANIMATION_HEIGHT
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = tradeAnimationResource,
|
||||
@@ -313,20 +366,56 @@ class TradeGUI(
|
||||
// Render Model Portraits
|
||||
var scale = PORTRAIT_SCALE
|
||||
var scaleOffsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
var isShrinking = false
|
||||
if (tradeProcessing) {
|
||||
val scaleInterval = if (tradeAnimationProgress > REVERSE_ANIMATION_TICK) (MAX_TRADE_PROGRESS - tradeAnimationProgress) else tradeAnimationProgress
|
||||
scale = (PORTRAIT_SCALE - (scaleInterval * PORTRAIT_SCALE_MULTIPLIER)).coerceIn(0F, PORTRAIT_SCALE)
|
||||
scaleOffsetY = (45.0 - (45.0 / PORTRAIT_SCALE) * scale) + PORTRAIT_MODEL_OFFSET_Y
|
||||
isShrinking = true
|
||||
}
|
||||
val shrinkPercentage = if (isShrinking) 1.0F - (scale / PORTRAIT_SCALE) else 0.0F
|
||||
val myCenterXDest = x + 70 + (PORTRAIT_SIZE / 2.0)
|
||||
val myCenterYDest = y + 30 + (PORTRAIT_SIZE / 2.0)
|
||||
val opCenterXDest = x + 145 + (PORTRAIT_SIZE / 2.0)
|
||||
val opCenterYDest = y + 30 + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
if (scale > 0F) {
|
||||
context.enableScissor(backgroundX, backgroundY, backgroundX + BASE_BACKGROUND_WIDTH, backgroundY + BASE_BACKGROUND_HEIGHT)
|
||||
offeredPokemonModel?.baseScale = scale
|
||||
offeredPokemonModel?.offsetY = scaleOffsetY
|
||||
offeredPokemonModel?.render(context, mouseX, mouseY, delta)
|
||||
|
||||
opposingOfferedPokemonModel?.baseScale = scale
|
||||
opposingOfferedPokemonModel?.offsetY = scaleOffsetY
|
||||
opposingOfferedPokemonModel?.render(context, mouseX, mouseY, delta)
|
||||
offeredPokemonModels.forEachIndexed { i, model ->
|
||||
val posAndScale = getModelPositionAndScale(i, offeredPokemons.size, x + 70, y + 30)
|
||||
val originalScale = posAndScale.second
|
||||
model.baseScale = if (isShrinking) (originalScale / PORTRAIT_SCALE) * scale else originalScale
|
||||
model.offsetY = if (isShrinking) scaleOffsetY else PORTRAIT_MODEL_OFFSET_Y
|
||||
|
||||
val startCenterX = posAndScale.first.first + (PORTRAIT_SIZE / 2.0)
|
||||
val startCenterY = posAndScale.first.second + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
context.pose().pushPose()
|
||||
context.pose().translate((myCenterXDest - startCenterX) * shrinkPercentage, (myCenterYDest - startCenterY) * shrinkPercentage, 0.0)
|
||||
|
||||
model.render(context, mouseX, mouseY, delta)
|
||||
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
opposingOfferedPokemonModels.forEachIndexed { i, model ->
|
||||
val posAndScale = getModelPositionAndScale(i, opposingPokemons.size, x + 145, y + 30)
|
||||
val originalScale = posAndScale.second
|
||||
model.baseScale = if (isShrinking) (originalScale / PORTRAIT_SCALE) * scale else originalScale
|
||||
model.offsetY = if (isShrinking) scaleOffsetY else PORTRAIT_MODEL_OFFSET_Y
|
||||
|
||||
val startCenterX = posAndScale.first.first + (PORTRAIT_SIZE / 2.0)
|
||||
val startCenterY = posAndScale.first.second + (PORTRAIT_SIZE / 2.0)
|
||||
|
||||
context.pose().pushPose()
|
||||
context.pose().translate((opCenterXDest - startCenterX) * shrinkPercentage, (opCenterYDest - startCenterY) * shrinkPercentage, 0.0)
|
||||
|
||||
model.render(context, mouseX, mouseY, delta)
|
||||
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
@@ -341,8 +430,46 @@ class TradeGUI(
|
||||
|
||||
renderInfoLabels(context, x, y)
|
||||
|
||||
renderPokemonInfo(offeredPokemon, false, context, x, y, mouseX, mouseY)
|
||||
renderPokemonInfo(opposingOfferedPokemon, true, context, x, y, mouseX, mouseY)
|
||||
children().filterIsInstance<PartySlot>().forEach { slot ->
|
||||
if (slot.isHovered(mouseX, mouseY)) {
|
||||
val hoveredId = slot.pokemon?.pokemonId
|
||||
if (slot.isOpposing && slot.hasSelected()) {
|
||||
opposingPokemons.find { it.uuid == hoveredId }?.let { opposingOfferedPokemon = it }
|
||||
} else if (!slot.isOpposing) {
|
||||
val matchingModel = offeredPokemons.find { it.uuid == hoveredId }
|
||||
if (matchingModel != null) {
|
||||
offeredPokemon = matchingModel
|
||||
} else {
|
||||
val realPokemon = com.cobblemon.mod.common.client.CobblemonClient.storage.party.find { it?.uuid == hoveredId }
|
||||
if (realPokemon != null) {
|
||||
offeredPokemon = realPokemon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val currentOffered = offeredPokemon
|
||||
if (currentOffered != null) {
|
||||
renderPokemonInfo(currentOffered, false, context, x, y, mouseX, mouseY)
|
||||
if (::offeredPokemonMarkings.isInitialized) {
|
||||
offeredPokemonMarkings.visible = true
|
||||
if (offeredPokemonMarkings.pokemon != currentOffered) offeredPokemonMarkings.setActivePokemon(currentOffered)
|
||||
}
|
||||
} else {
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.visible = false
|
||||
}
|
||||
|
||||
val currentOpposing = opposingOfferedPokemon
|
||||
if (currentOpposing != null) {
|
||||
renderPokemonInfo(currentOpposing, true, context, x, y, mouseX, mouseY)
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) {
|
||||
opposingOfferedPokemonMarkings.visible = true
|
||||
if (opposingOfferedPokemonMarkings.pokemon != currentOpposing) opposingOfferedPokemonMarkings.setActivePokemon(currentOpposing)
|
||||
}
|
||||
} else {
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.visible = false
|
||||
}
|
||||
|
||||
if (trade.acceptedOppositeOffer) {
|
||||
blitk(
|
||||
@@ -431,19 +558,25 @@ class TradeGUI(
|
||||
|
||||
super.render(context, mouseX, mouseY, delta)
|
||||
|
||||
// Item Tooltip
|
||||
if (offeredPokemon != null && !offeredPokemon!!.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 50
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, offeredPokemon!!.heldItemNoCopy(), mouseX, mouseY)
|
||||
val ttOffered = offeredPokemon
|
||||
if (ttOffered != null) {
|
||||
// Item Tooltip
|
||||
if (!ttOffered.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 50
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, ttOffered.heldItemNoCopy(), mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
|
||||
if (opposingOfferedPokemon != null && !opposingOfferedPokemon!!.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 227
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, opposingOfferedPokemon!!.heldItemNoCopy(), mouseX, mouseY)
|
||||
val ttOpposing = opposingOfferedPokemon
|
||||
if (ttOpposing != null) {
|
||||
if (!ttOpposing.heldItemNoCopy().isEmpty) {
|
||||
val itemX = x + 227
|
||||
val itemY = y + 125
|
||||
val itemHovered = mouseX.toFloat() in (itemX.toFloat()..(itemX.toFloat() + 16)) && mouseY.toFloat() in (itemY.toFloat()..(itemY.toFloat() + 16))
|
||||
if (itemHovered) context.renderTooltip(Minecraft.getInstance().font, ttOpposing.heldItemNoCopy(), mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,11 +613,13 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
if (tradeAnimationProgress == (MAX_TRADE_PROGRESS + CRY_BUFFER)) {
|
||||
if (offeredPokemonModel !== null && opposingOfferedPokemonModel !== null) {
|
||||
offeredPokemonModel!!.state.activeAnimations.clear()
|
||||
offeredPokemonModel!!.state.addFirstAnimation(setOf("cry"))
|
||||
opposingOfferedPokemonModel!!.state.activeAnimations.clear()
|
||||
opposingOfferedPokemonModel!!.state.addFirstAnimation(setOf("cry"))
|
||||
offeredPokemonModels.forEach {
|
||||
it.state.activeAnimations.clear()
|
||||
it.state.addFirstAnimation(setOf("cry"))
|
||||
}
|
||||
opposingOfferedPokemonModels.forEach {
|
||||
it.state.activeAnimations.clear()
|
||||
it.state.addFirstAnimation(setOf("cry"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,41 +650,140 @@ class TradeGUI(
|
||||
|
||||
override fun renderMenuBackground(context: GuiGraphics) {}
|
||||
|
||||
private fun setOfferedPokemon(pokemon: Pokemon?, isOpposing: Boolean = false) {
|
||||
private fun setOfferedPokemon(pokemonList: List<Pokemon>, isOpposing: Boolean = false) {
|
||||
protectiveTicks = 20
|
||||
if (isOpposing) {
|
||||
val wasEmpty = opposingPokemons.isEmpty()
|
||||
val currentViewedUuid = if (opposingGridMode) null else opposingOfferedPokemon?.uuid
|
||||
opposingPokemons.clear()
|
||||
opposingPokemons.addAll(pokemonList)
|
||||
|
||||
val matchingPokemon = opposingPokemons.find { it.uuid == currentViewedUuid }
|
||||
|
||||
if (matchingPokemon != null) {
|
||||
opposingOfferedPokemon = matchingPokemon
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
} else {
|
||||
opposingOfferedPokemon = opposingPokemons.lastOrNull()
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
if (wasEmpty && opposingOfferedPokemon != null) {
|
||||
opposingGridMode = false
|
||||
} else if (!opposingGridMode) {
|
||||
opposingGridMode = true
|
||||
}
|
||||
}
|
||||
trade.acceptedOppositeOffer = false
|
||||
} else {
|
||||
val wasEmpty = offeredPokemons.isEmpty()
|
||||
val currentViewedUuid = if (myGridMode) null else offeredPokemon?.uuid
|
||||
offeredPokemons.clear()
|
||||
offeredPokemons.addAll(pokemonList)
|
||||
|
||||
val matchingPokemon = offeredPokemons.find { it.uuid == currentViewedUuid }
|
||||
|
||||
if (matchingPokemon != null) {
|
||||
offeredPokemon = matchingPokemon
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
} else {
|
||||
offeredPokemon = offeredPokemons.lastOrNull()
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
if (wasEmpty && offeredPokemon != null) {
|
||||
myGridMode = false
|
||||
} else if (!myGridMode) {
|
||||
myGridMode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
rebuildSelectedModels(isOpposing)
|
||||
}
|
||||
|
||||
private fun rebuildSelectedModels(isOpposing: Boolean) {
|
||||
val x = (width - BASE_WIDTH) / 2
|
||||
val y = (height - BASE_HEIGHT) / 2
|
||||
|
||||
if (isOpposing) {
|
||||
opposingOfferedPokemon = pokemon
|
||||
opposingOfferedPokemonModel = if (pokemon != null) ModelWidget(
|
||||
pX = x + 145,
|
||||
pY = y + 30,
|
||||
pWidth = PORTRAIT_SIZE,
|
||||
pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pokemon.asRenderablePokemon(),
|
||||
baseScale = PORTRAIT_SCALE,
|
||||
rotationY = 35F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
) else null
|
||||
if (::opposingOfferedPokemonMarkings.isInitialized) opposingOfferedPokemonMarkings.setActivePokemon(opposingOfferedPokemon)
|
||||
trade.acceptedOppositeOffer = false
|
||||
opposingOfferedPokemonModels.clear()
|
||||
val total = opposingPokemons.size
|
||||
opposingPokemons.forEachIndexed { i, pk ->
|
||||
val (pos, currentScale) = getModelPositionAndScale(i, total, x + 145, y + 30)
|
||||
opposingOfferedPokemonModels.add(ModelWidget(
|
||||
pX = pos.first, pY = pos.second,
|
||||
pWidth = PORTRAIT_SIZE, pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pk.asRenderablePokemon(),
|
||||
baseScale = currentScale,
|
||||
rotationY = 35F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
))
|
||||
}
|
||||
} else {
|
||||
offeredPokemon = pokemon
|
||||
offeredPokemonModel = if (pokemon != null) ModelWidget(
|
||||
pX = x + 70,
|
||||
pY = y + 30,
|
||||
pWidth = PORTRAIT_SIZE,
|
||||
pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pokemon.asRenderablePokemon(),
|
||||
baseScale = PORTRAIT_SCALE,
|
||||
rotationY = 325F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
) else null
|
||||
if (::offeredPokemonMarkings.isInitialized) offeredPokemonMarkings.setActivePokemon(offeredPokemon)
|
||||
offeredPokemonModels.clear()
|
||||
val total = offeredPokemons.size
|
||||
offeredPokemons.forEachIndexed { i, pk ->
|
||||
val (pos, currentScale) = getModelPositionAndScale(i, total, x + 70, y + 30)
|
||||
offeredPokemonModels.add(ModelWidget(
|
||||
pX = pos.first, pY = pos.second,
|
||||
pWidth = PORTRAIT_SIZE, pHeight = PORTRAIT_SIZE,
|
||||
pokemon = pk.asRenderablePokemon(),
|
||||
baseScale = currentScale,
|
||||
rotationY = 325F,
|
||||
offsetY = PORTRAIT_MODEL_OFFSET_Y
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getModelPositionAndScale(index: Int, total: Int, baseX: Int, baseY: Int): Pair<Pair<Int, Int>, Float> {
|
||||
val scale = when (total) {
|
||||
1 -> PORTRAIT_SCALE
|
||||
2 -> PORTRAIT_SCALE * 0.75f
|
||||
3 -> PORTRAIT_SCALE * 0.65f
|
||||
4 -> PORTRAIT_SCALE * 0.55f
|
||||
else -> PORTRAIT_SCALE * 0.5f
|
||||
}
|
||||
|
||||
if (total <= 1) {
|
||||
return Pair(Pair(baseX, baseY), scale)
|
||||
}
|
||||
|
||||
val rowLength1 = when (total) {
|
||||
2, 3, 4 -> 2
|
||||
else -> 3
|
||||
}
|
||||
val rowLength2 = total - rowLength1
|
||||
|
||||
val isBottomRow = index >= rowLength1
|
||||
val row = if (isBottomRow) 1 else 0
|
||||
val col = if (isBottomRow) index - rowLength1 else index
|
||||
val currentRowLength = if (isBottomRow) rowLength2 else rowLength1
|
||||
|
||||
val colSpacing = when (total) {
|
||||
2 -> 35
|
||||
3 -> 30
|
||||
4 -> 25
|
||||
else -> 23
|
||||
}
|
||||
val rowSpacing = when (total) {
|
||||
2, 3 -> 30
|
||||
4 -> 28
|
||||
else -> 25
|
||||
}
|
||||
|
||||
val totalWidth = (currentRowLength - 1) * colSpacing
|
||||
val startX = baseX - (totalWidth / 2)
|
||||
|
||||
val totalHeight = if (rowLength2 > 0) rowSpacing else 0
|
||||
var startY = baseY + 12 - (totalHeight / 2)
|
||||
|
||||
if (total >= 4) {
|
||||
startY += 8
|
||||
}
|
||||
|
||||
val posX = startX + (col * colSpacing)
|
||||
val posY = startY + (row * rowSpacing)
|
||||
|
||||
return Pair(Pair(posX, posY), scale)
|
||||
}
|
||||
|
||||
private fun playSound(soundEvent: SoundEvent): SoundInstance {
|
||||
val soundInstance = SimpleSoundInstance.forUI(soundEvent, 1.0F)
|
||||
Minecraft.getInstance().soundManager.play(soundInstance)
|
||||
@@ -557,10 +791,10 @@ class TradeGUI(
|
||||
}
|
||||
|
||||
private fun cancelTradeSound() {
|
||||
if (tradeSoundInstance !== null) Minecraft.getInstance().soundManager.stop(tradeSoundInstance)
|
||||
if (tradeSoundInstance != null) Minecraft.getInstance().soundManager.stop(tradeSoundInstance!!)
|
||||
}
|
||||
|
||||
private fun renderPokemonInfo(pokemon: Pokemon?, isOpposing: Boolean, context: GuiGraphics, x: Int, y: Int, mouseX: Int, mouseY: Int) {
|
||||
public fun renderPokemonInfo(pokemon: Pokemon?, isOpposing: Boolean, context: GuiGraphics, x: Int, y: Int, mouseX: Int, mouseY: Int) {
|
||||
if (pokemon != null) {
|
||||
val matrices = context.pose()
|
||||
// Level
|
||||
@@ -1047,4 +1281,4 @@ class TradeGUI(
|
||||
scale = SCALE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,9 +15,9 @@ import net.minecraft.client.Minecraft
|
||||
|
||||
object TradeAcceptanceChangedHandler : ClientNetworkPacketHandler<TradeAcceptanceChangedPacket> {
|
||||
override fun handle(packet: TradeAcceptanceChangedPacket, client: Minecraft) {
|
||||
if (CobblemonClient.trade?.myOffer?.get()?.uuid == packet.pokemonId) {
|
||||
if (CobblemonClient.trade?.myOffer?.get()?.any { it.uuid == packet.pokemonId } == true) {
|
||||
CobblemonClient.trade!!.oppositeAcceptedMyOffer.set(packet.accepted)
|
||||
} else if (CobblemonClient.trade?.oppositeOffer?.get()?.uuid == packet.pokemonId) {
|
||||
} else if (CobblemonClient.trade?.oppositeOffer?.get()?.any { it.uuid == packet.pokemonId } == true) {
|
||||
CobblemonClient.trade!!.acceptedOppositeOffer = packet.accepted
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,6 +16,6 @@ import net.minecraft.client.Minecraft
|
||||
object TradeCompletedHandler : ClientNetworkPacketHandler<TradeCompletedPacket> {
|
||||
override fun handle(packet: TradeCompletedPacket, client: Minecraft) {
|
||||
val trade = CobblemonClient.trade ?: return
|
||||
trade.completedEmitter.emit(packet.pokemonId1 to packet.pokemonId2)
|
||||
trade.completedEmitter.emit(packet.pokemonIds1 to packet.pokemonIds2)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ import net.minecraft.client.Minecraft
|
||||
|
||||
object TradeStartedHandler : ClientNetworkPacketHandler<TradeStartedPacket> {
|
||||
override fun handle(packet: TradeStartedPacket, client: Minecraft) {
|
||||
Cobblemon.LOGGER.error("handle trade start from: " + packet.traderId)
|
||||
Cobblemon.LOGGER.info("Trade started with {}", packet.traderId)
|
||||
val trade = ClientTrade()
|
||||
CobblemonClient.trade = trade
|
||||
Minecraft.getInstance().setScreen(
|
||||
|
||||
+2
-2
@@ -18,9 +18,9 @@ object TradeUpdatedHandler : ClientNetworkPacketHandler<TradeUpdatedPacket> {
|
||||
val trade = CobblemonClient.trade ?: return
|
||||
|
||||
if (packet.playerId == Minecraft.getInstance().player?.uuid) {
|
||||
trade.myOffer.set(packet.pokemon)
|
||||
trade.myOffer.set(packet.pokemons)
|
||||
} else {
|
||||
trade.oppositeOffer.set(packet.pokemon)
|
||||
trade.oppositeOffer.set(packet.pokemons)
|
||||
}
|
||||
trade.oppositeAcceptedMyOffer.set(false)
|
||||
trade.acceptedOppositeOffer = false
|
||||
|
||||
@@ -14,12 +14,12 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import java.util.UUID
|
||||
|
||||
class ClientTrade {
|
||||
var myOffer = SettableObservable<Pokemon?>(null)
|
||||
var oppositeOffer = SettableObservable<Pokemon?>(null)
|
||||
var myOffer = SettableObservable<List<Pokemon>>(emptyList())
|
||||
var oppositeOffer = SettableObservable<List<Pokemon>>(emptyList())
|
||||
var tradeProcessing = SettableObservable(Pair(false, false))
|
||||
var oppositeAcceptedMyOffer = SettableObservable(false)
|
||||
var acceptedOppositeOffer = false
|
||||
|
||||
var completedEmitter = SimpleObservable<Pair<UUID, UUID>>()
|
||||
var completedEmitter = SimpleObservable<Pair<List<UUID>, List<UUID>>>()
|
||||
var cancelEmitter = SimpleObservable<Unit>()
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import net.minecraft.world.item.BlockItem
|
||||
import com.cobblemon.mod.common.platform.events.ServerPlayerEvent
|
||||
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreTypes
|
||||
import com.cobblemon.mod.common.item.GemItem
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||
import com.cobblemon.mod.common.util.effectiveName
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
@@ -164,26 +165,21 @@ object AdvancementHandler : EventHandler {
|
||||
}
|
||||
|
||||
fun onTradeCompleted(event : TradeEvent.Post) {
|
||||
val player1 = event.tradeParticipant1Pokemon.getOwnerPlayer()
|
||||
val player2 = event.tradeParticipant2Pokemon.getOwnerPlayer()
|
||||
if (player1 != null) {
|
||||
CobblemonCriteria.TRADE_POKEMON.trigger(player1, TradePokemonContext(event.tradeParticipant1Pokemon, event.tradeParticipant2Pokemon))
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player1)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
advancementData.updateAspectsCollected(player1, event.tradeParticipant2Pokemon)
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player1, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
}
|
||||
if (player2 != null) {
|
||||
CobblemonCriteria.TRADE_POKEMON.trigger(player2, TradePokemonContext(event.tradeParticipant2Pokemon, event.tradeParticipant1Pokemon))
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player2)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
advancementData.updateAspectsCollected(player2, event.tradeParticipant1Pokemon)
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player2, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
onTradeCompleted(event.tradeParticipant1Pokemon, event.tradeParticipant2Pokemon)
|
||||
onTradeCompleted(event.tradeParticipant2Pokemon, event.tradeParticipant1Pokemon)
|
||||
}
|
||||
|
||||
private fun onTradeCompleted(received: List<Pokemon>, traded: List<Pokemon>) {
|
||||
val player = received.firstOrNull()?.getOwnerPlayer() ?: return
|
||||
received.forEach { receivedPokemon ->
|
||||
traded.forEach { tradedPokemon -> CobblemonCriteria.TRADE_POKEMON.trigger(player, TradePokemonContext(tradedPokemon, receivedPokemon)) }
|
||||
}
|
||||
val playerData = Cobblemon.playerDataManager.getGenericData(player)
|
||||
val advancementData = playerData.advancementData
|
||||
advancementData.updateTotalTradedCount()
|
||||
received.forEach { advancementData.updateAspectsCollected(player, it) }
|
||||
CobblemonCriteria.COLLECT_ASPECT.trigger(player, advancementData.aspectsCollected)
|
||||
Cobblemon.playerDataManager.saveSingle(playerData, PlayerInstancedDataStoreTypes.GENERAL)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,8 +110,8 @@ object StatHandler : EventHandler {
|
||||
}
|
||||
|
||||
fun onTradeCompleted(event : TradeEvent.Post) {
|
||||
event.tradeParticipant1Pokemon.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant2Pokemon.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant1Pokemon.firstOrNull()?.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
event.tradeParticipant2Pokemon.firstOrNull()?.getOwnerPlayer()?.awardStat(getStat(Cobblemon.statistics.TRADED))
|
||||
}
|
||||
|
||||
fun onFossilRevived(event : FossilRevivedEvent) {
|
||||
|
||||
+7
-4
@@ -23,16 +23,19 @@ import java.util.UUID
|
||||
* @author Hiroku
|
||||
* @since March 5th, 2023
|
||||
*/
|
||||
class TradeCompletedPacket(val pokemonId1: UUID, val pokemonId2: UUID) : NetworkPacket<TradeCompletedPacket> {
|
||||
class TradeCompletedPacket(val pokemonIds1: List<UUID>, val pokemonIds2: List<UUID>) : NetworkPacket<TradeCompletedPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("trade_completed")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeCompletedPacket(buffer.readUUID(), buffer.readUUID())
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeCompletedPacket(
|
||||
buffer.readList { it.readUUID() },
|
||||
buffer.readList { it.readUUID() }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeUUID(pokemonId1)
|
||||
buffer.writeUUID(pokemonId2)
|
||||
buffer.writeCollection(pokemonIds1) { buf, id -> buf.writeUUID(id) }
|
||||
buffer.writeCollection(pokemonIds2) { buf, id -> buf.writeUUID(id) }
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -12,10 +12,6 @@ import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.net.UnsplittablePacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readNullable
|
||||
import com.cobblemon.mod.common.util.readUUID
|
||||
import com.cobblemon.mod.common.util.writeNullable
|
||||
import com.cobblemon.mod.common.util.writeUUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import java.util.UUID
|
||||
|
||||
@@ -27,15 +23,18 @@ import java.util.UUID
|
||||
* @author Hiroku
|
||||
* @since March 5th, 2023
|
||||
*/
|
||||
class TradeUpdatedPacket(val playerId: UUID, val pokemon: Pokemon?) : NetworkPacket<TradeUpdatedPacket>, UnsplittablePacket {
|
||||
class TradeUpdatedPacket(val playerId: UUID, val pokemons: List<Pokemon>) : NetworkPacket<TradeUpdatedPacket>, UnsplittablePacket {
|
||||
companion object {
|
||||
val ID = cobblemonResource("trade_updated")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeUpdatedPacket(buffer.readUUID(), buffer.readNullable { Pokemon.S2C_CODEC.decode(buffer) })
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = TradeUpdatedPacket(
|
||||
buffer.readUUID(),
|
||||
buffer.readList { Pokemon.S2C_CODEC.decode(it as RegistryFriendlyByteBuf) }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeUUID(playerId)
|
||||
buffer.writeNullable(pokemon) { _, pokemon -> Pokemon.S2C_CODEC.encode(buffer, pokemon) }
|
||||
buffer.writeCollection(pokemons) { buf, pokemon -> Pokemon.S2C_CODEC.encode(buf as RegistryFriendlyByteBuf, pokemon) }
|
||||
}
|
||||
}
|
||||
+9
-5
@@ -11,26 +11,30 @@ package com.cobblemon.mod.common.net.messages.server.trade
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readList
|
||||
import com.cobblemon.mod.common.util.readNullable
|
||||
import com.cobblemon.mod.common.util.readPartyPosition
|
||||
import com.cobblemon.mod.common.util.readUUID
|
||||
import com.cobblemon.mod.common.util.writeCollection
|
||||
import com.cobblemon.mod.common.util.writeNullable
|
||||
import com.cobblemon.mod.common.util.writePartyPosition
|
||||
import com.cobblemon.mod.common.util.writeUUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import java.util.UUID
|
||||
|
||||
class UpdateTradeOfferPacket(val newOffer: Pair<UUID, PartyPosition>?): NetworkPacket<UpdateTradeOfferPacket> {
|
||||
class UpdateTradeOfferPacket(val newOffers: List<Pair<UUID, PartyPosition>>): NetworkPacket<UpdateTradeOfferPacket> {
|
||||
companion object {
|
||||
val ID = cobblemonResource("update_trade_offer")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = UpdateTradeOfferPacket(buffer.readNullable { buffer.readUUID() to buffer.readPartyPosition() })
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = UpdateTradeOfferPacket(
|
||||
buffer.readList { it.readUUID() to it.readPartyPosition() }
|
||||
)
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeNullable(newOffer) { buffer, (pokemonId, partyPosition) ->
|
||||
buffer.writeUUID(pokemonId)
|
||||
buffer.writePartyPosition(partyPosition)
|
||||
buffer.writeCollection(newOffers) { buf, (pokemonId, partyPosition) ->
|
||||
buf.writeUUID(pokemonId)
|
||||
buf.writePartyPosition(partyPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ object ChangeTradeAcceptanceHandler : ServerNetworkPacketHandler<ChangeTradeAcce
|
||||
override fun handle(packet: ChangeTradeAcceptancePacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(TradeCancelledPacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon?.uuid == packet.pokemonOfferId) {
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon.any { it.uuid == packet.pokemonOfferId }) {
|
||||
trade.updateAcceptance(tradeParticipant, packet.newAcceptance)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ object PerformTradeHandler : ServerNetworkPacketHandler<PerformTradePacket> {
|
||||
override fun handle(packet: PerformTradePacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(TradeCancelledPacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon?.uuid == packet.pokemonOfferId) {
|
||||
if (trade.getOpposingOffer(tradeParticipant).pokemon.any { it.uuid == packet.pokemonOfferId }) {
|
||||
trade.performTrade(tradeParticipant)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-12
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.trade.TradeManager
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import net.minecraft.server.MinecraftServer
|
||||
@@ -21,20 +22,16 @@ object UpdateTradeOfferHandler : ServerNetworkPacketHandler<UpdateTradeOfferPack
|
||||
override fun handle(packet: UpdateTradeOfferPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val trade = TradeManager.getActiveTrade(player.uuid) ?: return player.sendPacket(CancelTradePacket())
|
||||
val tradeParticipant = trade.getTradeParticipant(player.uuid)
|
||||
val newOffer = packet.newOffer
|
||||
if (newOffer == null) {
|
||||
trade.updateOffer(tradeParticipant, null)
|
||||
} else {
|
||||
val (pokemonId, partyPosition) = newOffer
|
||||
val party = player.party()
|
||||
val newOffers = packet.newOffers
|
||||
|
||||
val validPokemons = mutableListOf<Pokemon>()
|
||||
val party = player.party()
|
||||
for ((pokemonId, partyPosition) in newOffers) {
|
||||
val pokemon = party[partyPosition]
|
||||
if (pokemon == null || pokemon.uuid != pokemonId) {
|
||||
return
|
||||
} else if (!pokemon.tradeable) {
|
||||
return
|
||||
} else {
|
||||
trade.updateOffer(tradeParticipant, pokemon)
|
||||
if (pokemon != null && pokemon.uuid == pokemonId && pokemon.tradeable) {
|
||||
validPokemons.add(pokemon)
|
||||
}
|
||||
}
|
||||
trade.updateOffer(tradeParticipant, validPokemons)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
fun getOffer(tradeParticipant: TradeParticipant) = if (tradeParticipant == player1) player1Offer else player2Offer
|
||||
fun getOpposingOffer(tradeParticipant: TradeParticipant) = if (tradeParticipant == player1) player2Offer else player1Offer
|
||||
|
||||
fun updateOffer(tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
fun updateOffer(tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
getOffer(tradeParticipant).updateOffer(pokemon)
|
||||
getOffer(getOppositePlayer(tradeParticipant)).accepted = false
|
||||
player1.updateOffer(this, tradeParticipant, pokemon)
|
||||
@@ -30,8 +30,9 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
val offer = getOpposingOffer(tradeParticipant)
|
||||
if (offer.accepted != acceptance) {
|
||||
offer.accepted = acceptance
|
||||
getOppositePlayer(tradeParticipant).changeTradeAcceptance(this, offer.pokemon!!.uuid, acceptance)
|
||||
tradeParticipant.changeTradeAcceptance(this, offer.pokemon!!.uuid, acceptance)
|
||||
val firstId = offer.pokemon.firstOrNull()?.uuid ?: java.util.UUID.randomUUID()
|
||||
getOppositePlayer(tradeParticipant).changeTradeAcceptance(this, firstId, acceptance)
|
||||
tradeParticipant.changeTradeAcceptance(this, firstId, acceptance)
|
||||
}
|
||||
|
||||
if (offer.accepted && getOffer(tradeParticipant).accepted) {
|
||||
@@ -51,8 +52,8 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
activeTrade = this,
|
||||
player1 = player1,
|
||||
player2 = player2,
|
||||
pokemon1 = player1Offer.pokemon!!,
|
||||
pokemon2 = player2Offer.pokemon!!
|
||||
pokemon1 = player1Offer.pokemon,
|
||||
pokemon2 = player2Offer.pokemon
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -64,12 +65,14 @@ class ActiveTrade(val player1: TradeParticipant, val player2: TradeParticipant)
|
||||
}
|
||||
|
||||
fun completeTrade() {
|
||||
player1.completeTrade(this, player1Offer.pokemon!!.uuid, player2Offer.pokemon!!.uuid)
|
||||
player2.completeTrade(this, player2Offer.pokemon!!.uuid, player1Offer.pokemon!!.uuid)
|
||||
val uuids1 = player1Offer.pokemon.map { it.uuid }
|
||||
val uuids2 = player2Offer.pokemon.map { it.uuid }
|
||||
player1.completeTrade(this, uuids1, uuids2)
|
||||
player2.completeTrade(this, uuids2, uuids1)
|
||||
|
||||
player1Offer.pokemon = null
|
||||
player1Offer.pokemon = emptyList()
|
||||
player1Offer.accepted = false
|
||||
player2Offer.pokemon = null
|
||||
player2Offer.pokemon = emptyList()
|
||||
player2Offer.accepted = false
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokemon.TradeEvent
|
||||
import com.cobblemon.mod.common.api.interaction.ServerPlayerActionRequest
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
import com.cobblemon.mod.common.api.text.aqua
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
|
||||
@@ -101,71 +102,98 @@ object TradeManager : RequestManager<TradeManager.TradeRequest>() {
|
||||
fun performTrade(
|
||||
activeTrade: ActiveTrade,
|
||||
player1: TradeParticipant,
|
||||
pokemon1: Pokemon,
|
||||
pokemon1: List<Pokemon>,
|
||||
player2: TradeParticipant,
|
||||
pokemon2: Pokemon
|
||||
pokemon2: List<Pokemon>
|
||||
) {
|
||||
val party1 = player1.party
|
||||
val party2 = player2.party
|
||||
|
||||
if (pokemon1 !in party1 || pokemon2 !in party2) {
|
||||
if (pokemon1.any { it !in party1 } || pokemon2.any { it !in party2 }) {
|
||||
Cobblemon.LOGGER.warn("Attempted to perform a trade with Pokémon that aren't in the party anymore. Could be attempted duping between ${player1.name} and ${player2.name}")
|
||||
activeTrade.cancelTrade()
|
||||
return
|
||||
}
|
||||
|
||||
CobblemonEvents.TRADE_EVENT_PRE.postThen(TradeEvent.Pre(player1, pokemon2, player2, pokemon1)) {
|
||||
val party1 = player1.party
|
||||
val party2 = player2.party
|
||||
if (pokemon1.isEmpty() || pokemon2.isEmpty()) {
|
||||
Cobblemon.LOGGER.warn("Attempted to perform a trade where one side offered no Pokémon between ${player1.name} and ${player2.name}. This should never happen.")
|
||||
activeTrade.cancelTrade()
|
||||
return
|
||||
}
|
||||
|
||||
val player1Removed = party1.remove(pokemon1)
|
||||
val player2Removed = party2.remove(pokemon2)
|
||||
CobblemonEvents.TRADE_EVENT_PRE.postThen(
|
||||
TradeEvent.Pre(player1, pokemon2, player2, pokemon1)
|
||||
) {
|
||||
val player1Removed = pokemon1.filter { party1.remove(it) }
|
||||
val player2Removed = pokemon2.filter { party2.remove(it) }
|
||||
|
||||
if (!player1Removed || !player2Removed) {
|
||||
if (!player1Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon1.species.resourceIdentifier} from ${player1.name.string}(${player1.uuid}). Aborting trade with ${player2.name.string}(${player2.uuid}), potential exploit abused.")
|
||||
if (player1Removed.size != pokemon1.size || player2Removed.size != pokemon2.size) {
|
||||
(pokemon1 - player1Removed.toSet()).forEach {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${it.species.resourceIdentifier} from ${player1.name.string}(${player1.uuid}). Aborting trade with ${player2.name.string}(${player2.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
if (!player2Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon2.species.resourceIdentifier} from ${player2.name.string}(${player2.uuid}). Aborting trade with ${player1.name.string}(${player1.uuid}), potential exploit abused.")
|
||||
(pokemon2 - player2Removed.toSet()).forEach {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${it.species.resourceIdentifier} from ${player2.name.string}(${player2.uuid}). Aborting trade with ${player1.name.string}(${player1.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
// Revert any changes if one of the removals failed
|
||||
if (player1Removed) party1.add(pokemon1)
|
||||
if (player2Removed) party2.add(pokemon2)
|
||||
player1Removed.forEach { party1.add(it) }
|
||||
player2Removed.forEach { party2.add(it) }
|
||||
return@postThen
|
||||
}
|
||||
|
||||
// If player1 is the OT, keep track of the friendship
|
||||
pokemon1.cacheFriendship(player1.uuid)
|
||||
pokemon1.forEach { it.cacheFriendship(player1.uuid) }
|
||||
// If player2 is the OT, keep track of the friendship
|
||||
pokemon2.cacheFriendship(player2.uuid)
|
||||
pokemon2.forEach { it.cacheFriendship(player2.uuid) }
|
||||
|
||||
// If pokemon2 was originally player1's, set the friendship back to what it was at point of trading
|
||||
if ( !pokemon2.restoreFriendship(player1.uuid) ) {
|
||||
// Otherwise, reset the friendship
|
||||
pokemon2.setFriendship(pokemon2.form.baseFriendship)
|
||||
// If a Pokémon received by player1 was originally theirs, set the friendship back to what it was at point of trading
|
||||
pokemon2.forEach {
|
||||
if (!it.restoreFriendship(player1.uuid)) {
|
||||
// Otherwise, reset the friendship
|
||||
it.setFriendship(it.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
// If pokemon1 was originally player2's, set the friendship back to what it was at point of trading
|
||||
if ( !pokemon1.restoreFriendship(player2.uuid) ) {
|
||||
// Otherwise, reset the friendship
|
||||
pokemon1.setFriendship(pokemon1.form.baseFriendship)
|
||||
// If a Pokémon received by player2 was originally theirs, set the friendship back to what it was at point of trading
|
||||
pokemon1.forEach {
|
||||
if (!it.restoreFriendship(player2.uuid)) {
|
||||
// Otherwise, reset the friendship
|
||||
it.setFriendship(it.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
|
||||
party2.add(pokemon1)
|
||||
party1.add(pokemon2)
|
||||
pokemon1.forEach { party2.add(it) }
|
||||
pokemon2.forEach { party1.add(it) }
|
||||
|
||||
pokemon1.lockedEvolutions.filterIsInstance<TradeEvolution>().firstOrNull {
|
||||
it.attemptEvolution(pokemon1, pokemon2)
|
||||
}
|
||||
// Each traded Pokémon may evolve if any of the Pokémon it was traded for satisfies its context.
|
||||
// Evolutions are resolved before any are applied so one evolving can't invalidate another's context.
|
||||
(pokemon1.map { it to pokemon2 } + pokemon2.map { it to pokemon1 })
|
||||
.mapNotNull { (pokemon, tradedFor) ->
|
||||
pokemon.lockedEvolutions.filterIsInstance<TradeEvolution>()
|
||||
.firstOrNull { evolution -> tradedFor.any { evolution.testContext(pokemon, it) } && evolution.test(pokemon) }
|
||||
?.let { pokemon to it }
|
||||
}
|
||||
.forEach { (pokemon, evolution) -> evolution.evolve(pokemon) }
|
||||
|
||||
pokemon2.lockedEvolutions.filterIsInstance<TradeEvolution>().firstOrNull {
|
||||
it.attemptEvolution(pokemon2, pokemon1)
|
||||
val compactParty = { party: PartyStore ->
|
||||
var writeIdx = 0
|
||||
for (readIdx in 0 until party.size()) {
|
||||
if (party.get(readIdx) != null) {
|
||||
if (readIdx != writeIdx) {
|
||||
party.swap(readIdx, writeIdx)
|
||||
}
|
||||
writeIdx++
|
||||
}
|
||||
}
|
||||
}
|
||||
compactParty(party1)
|
||||
compactParty(party2)
|
||||
|
||||
activeTrade.completeTrade()
|
||||
|
||||
CobblemonEvents.TRADE_EVENT_POST.post(TradeEvent.Post(player1, pokemon2, player2, pokemon1))
|
||||
CobblemonEvents.TRADE_EVENT_POST.post(
|
||||
TradeEvent.Post(player1, pokemon2, player2, pokemon1)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@ package com.cobblemon.mod.common.trade
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
class TradeOffer {
|
||||
var pokemon: Pokemon? = null
|
||||
var pokemon: List<Pokemon> = emptyList()
|
||||
var accepted = false
|
||||
|
||||
fun updateOffer(pokemon: Pokemon?) {
|
||||
fun updateOffer(pokemon: List<Pokemon>) {
|
||||
this.pokemon = pokemon
|
||||
accepted = false
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ interface TradeParticipant {
|
||||
*
|
||||
* If it's null, it means they're no longer offering a Pokémon (so they're redeciding).
|
||||
*/
|
||||
fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?)
|
||||
fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>)
|
||||
|
||||
/**
|
||||
* Notifies the participant that the acceptance state for trading with the opponent [Pokemon] with UUID [pokemonId]
|
||||
@@ -59,7 +59,7 @@ interface TradeParticipant {
|
||||
fun cancelTrade(trade: ActiveTrade)
|
||||
|
||||
/** Notifies the participant that the trade has been completed. The actual Pokémon have already been exchanged. */
|
||||
fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID)
|
||||
fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ class PlayerTradeParticipant(val player: ServerPlayer): TradeParticipant {
|
||||
override val uuid = player.uuid
|
||||
override val party = player.party()
|
||||
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
player.sendPacket(TradeUpdatedPacket(tradeParticipant.uuid, pokemon))
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ class PlayerTradeParticipant(val player: ServerPlayer): TradeParticipant {
|
||||
player.sendPacket(TradeCancelledPacket())
|
||||
}
|
||||
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID) {
|
||||
player.sendPacket(TradeCompletedPacket(pokemonId1, pokemonId2))
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>) {
|
||||
player.sendPacket(TradeCompletedPacket(pokemonIds1, pokemonIds2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class DummyTradeParticipant(val pokemonList: MutableList<Pokemon>) : TradePartic
|
||||
// Don't need to do any notifying.
|
||||
}
|
||||
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonId1: UUID, pokemonId2: UUID) {
|
||||
override fun completeTrade(trade: ActiveTrade, pokemonIds1: List<UUID>, pokemonIds2: List<UUID>) {
|
||||
// Don't need to do any notifying.
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class DummyTradeParticipant(val pokemonList: MutableList<Pokemon>) : TradePartic
|
||||
// React, maybe. Change code and hotswap.
|
||||
}
|
||||
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: Pokemon?) {
|
||||
override fun updateOffer(trade: ActiveTrade, tradeParticipant: TradeParticipant, pokemon: List<Pokemon>) {
|
||||
// React, maybe. Change code and hotswap.
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 237 B |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 228 B |
Reference in New Issue
Block a user