forked from mirrors/cobblemon
Merge branch 'trade_friendship' into 'main'
Caching trade friendships to player data Closes #1898 See merge request cable-mc/cobblemon!2119
This commit is contained in:
@@ -209,6 +209,7 @@
|
||||
- Resolved the niche issue where Structures would spawn in an incorrect location, creating very funky world gen.
|
||||
- Fixed Galarian Ponyta missing its cry.
|
||||
- Fixed various log warnings caused by redundant files and sound events.
|
||||
- Traded Pokémon will now retain the original friendship level when traded back to its OT
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
|
||||
@@ -109,9 +109,11 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.codec.internal.ClientPokemonP1
|
||||
import com.cobblemon.mod.common.util.codec.internal.ClientPokemonP2
|
||||
import com.cobblemon.mod.common.util.codec.internal.ClientPokemonP3
|
||||
import com.cobblemon.mod.common.util.codec.internal.ClientPokemonP4
|
||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP1
|
||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP2
|
||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP3
|
||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP4
|
||||
import com.cobblemon.mod.common.util.nextBetween
|
||||
import com.cobblemon.mod.common.util.playSoundServer
|
||||
import com.cobblemon.mod.common.util.server
|
||||
@@ -543,6 +545,12 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
onChange(OriginalTrainerUpdatePacket({ this }, value))
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache friendship on trade for OT
|
||||
*/
|
||||
var originalTrainerFriendship: Int? = null
|
||||
internal set
|
||||
|
||||
/**
|
||||
* All moves that the Pokémon has, at some point, known. This is to allow players to
|
||||
* swap in moves they've used before at any time, while holding onto the remaining PP
|
||||
@@ -2263,6 +2271,19 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
onChange(packet)
|
||||
}
|
||||
|
||||
fun cacheFriendship(playerID: UUID) {
|
||||
if ((OriginalTrainerType.PLAYER == originalTrainerType) && (UUID.fromString(originalTrainer) == playerID)) originalTrainerFriendship = friendship
|
||||
}
|
||||
|
||||
fun restoreFriendship(playerID: UUID) : Boolean {
|
||||
if ((OriginalTrainerType.PLAYER == originalTrainerType) && (UUID.fromString(originalTrainer) == playerID)) {
|
||||
originalTrainerFriendship?.let { friendship = it }
|
||||
originalTrainerFriendship = null
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to run when a save-able change has been made to the Pokémon. This takes a packet to send to watching
|
||||
* players just for convenience, but the main thing is that this will notify the store that this Pokémon is in
|
||||
@@ -2356,13 +2377,15 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
instance.group(
|
||||
PokemonP1.CODEC.forGetter(PokemonP1::from),
|
||||
PokemonP2.CODEC.forGetter(PokemonP2::from),
|
||||
PokemonP3.CODEC.forGetter(PokemonP3::from)
|
||||
).apply(instance) { p1, p2, p3->
|
||||
PokemonP3.CODEC.forGetter(PokemonP3::from),
|
||||
PokemonP4.CODEC.forGetter(PokemonP4::from)
|
||||
).apply(instance) { p1, p2, p3, p4 ->
|
||||
val pokemon = Pokemon()
|
||||
pokemon.isClient = false
|
||||
p1.into(pokemon)
|
||||
p2.into(pokemon)
|
||||
p3.into(pokemon)
|
||||
p4.into(pokemon)
|
||||
pokemon.initialize()
|
||||
}
|
||||
}
|
||||
@@ -2381,13 +2404,15 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
instance.group(
|
||||
ClientPokemonP1.CODEC.forGetter(ClientPokemonP1::from),
|
||||
ClientPokemonP2.CODEC.forGetter(ClientPokemonP2::from),
|
||||
ClientPokemonP3.CODEC.forGetter(ClientPokemonP3::from)
|
||||
).apply(instance) { p1, p2, p3->
|
||||
ClientPokemonP3.CODEC.forGetter(ClientPokemonP3::from),
|
||||
ClientPokemonP4.CODEC.forGetter(ClientPokemonP4::from)
|
||||
).apply(instance) { p1, p2, p3, p4 ->
|
||||
val pokemon = Pokemon()
|
||||
pokemon.isClient = true
|
||||
p1.into(pokemon)
|
||||
p2.into(pokemon)
|
||||
p3.into(pokemon)
|
||||
p4.into(pokemon)
|
||||
pokemon.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,21 @@ object TradeManager : RequestManager<TradeManager.TradeRequest>() {
|
||||
party1.remove(pokemon1)
|
||||
party2.remove(pokemon2)
|
||||
|
||||
pokemon1.setFriendship(pokemon1.form.baseFriendship)
|
||||
pokemon2.setFriendship(pokemon2.form.baseFriendship)
|
||||
// If player1 is the OT, keep track of the friendship
|
||||
pokemon1.cacheFriendship(player1.uuid)
|
||||
// If player2 is the OT, keep track of the friendship
|
||||
pokemon2.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 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)
|
||||
}
|
||||
|
||||
party2.add(pokemon1)
|
||||
party1.add(pokemon2)
|
||||
|
||||
@@ -85,6 +85,7 @@ object DataKeys {
|
||||
const val POKEMON_ORIGINAL_TRAINER = "PokemonOriginalTrainer"
|
||||
const val POKEMON_ORIGINAL_TRAINER_NAME = "PokemonOriginalTrainerName"
|
||||
const val POKEMON_ORIGINAL_TRAINER_TYPE = "PokemonOriginalTrainerType"
|
||||
const val POKEMON_ORIGINAL_TRAINER_FRIENDSHIP = "PokemonOriginalTrainerFriendship"
|
||||
|
||||
const val POKEMON_PROPERTIES_MOVES = "Moves"
|
||||
const val POKEMON_PROPERTIES_HELDITEM = "HeldItem"
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.util.codec.internal
|
||||
|
||||
import com.cobblemon.mod.common.api.mark.Marks
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.client.settings.ServerSettings
|
||||
import com.cobblemon.mod.common.pokemon.OriginalTrainerType
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import java.util.*
|
||||
|
||||
internal data class ClientPokemonP4(
|
||||
val originalTrainerFriendship: Optional<Int>
|
||||
) : Partial<Pokemon> {
|
||||
|
||||
override fun into(other: Pokemon): Pokemon {
|
||||
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
|
||||
return other
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* do not use cobblemon.config in here, as this is used by the client whose config is different to server, always use [ServerSettings]
|
||||
*/
|
||||
internal val CODEC: MapCodec<ClientPokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(ClientPokemonP4::originalTrainerFriendship)
|
||||
).apply(instance, ::ClientPokemonP4)
|
||||
}
|
||||
|
||||
internal fun from(pokemon: Pokemon): ClientPokemonP4 = ClientPokemonP4(
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.util.codec.internal
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import java.util.*
|
||||
|
||||
internal data class PokemonP4(
|
||||
val originalTrainerFriendship: Optional<Int>
|
||||
) : Partial<Pokemon> {
|
||||
|
||||
override fun into(other: Pokemon): Pokemon {
|
||||
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
|
||||
other.refreshOriginalTrainer()
|
||||
return other
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val CODEC: MapCodec<PokemonP4> = RecordCodecBuilder.mapCodec { instance ->
|
||||
instance.group(
|
||||
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship)
|
||||
).apply(instance) {
|
||||
originalTrainerFriendship -> PokemonP4(
|
||||
originalTrainerFriendship
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun from(pokemon: Pokemon): PokemonP4 = PokemonP4(
|
||||
Optional.ofNullable(pokemon.originalTrainerFriendship)
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user