Skip to content

Commit

Permalink
1.0.27 (Public Test)
Browse files Browse the repository at this point in the history
DO A WORLD BACKUP OR TEST ON NEW WORLDS!

This version implements a better method of registering Mons, the old one has been completely removed! (meaning that you lost all your data)

Added Collection search bar
Added Collection entry tooltip
Added Highlight effect when hovering an entry
  • Loading branch information
Rafacasari committed Jun 26, 2024
1 parent 2ce6ac0 commit 8febb0c
Show file tree
Hide file tree
Showing 21 changed files with 524 additions and 123 deletions.
55 changes: 25 additions & 30 deletions common/src/main/kotlin/com/rafacasari/mod/cobbledex/Cobbledex.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import com.cobblemon.mod.common.api.text.onHover
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.platform.events.ServerPlayerEvent
import com.cobblemon.mod.common.pokemon.FormData
import com.rafacasari.mod.cobbledex.api.CobbledexDiscovery
import com.rafacasari.mod.cobbledex.api.classes.DiscoveryRegister
import com.rafacasari.mod.cobbledex.client.gui.CobbledexCollectionGUI
import com.rafacasari.mod.cobbledex.client.gui.CobbledexGUI
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.util.ActionResult
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import com.rafacasari.mod.cobbledex.cobblemon.extensions.PlayerDiscovery
import com.rafacasari.mod.cobbledex.network.client.packets.OpenCobbledexPacket
import com.rafacasari.mod.cobbledex.network.client.packets.AddToCollectionPacket
import com.rafacasari.mod.cobbledex.network.client.packets.ReceiveCollectionDataPacket
Expand Down Expand Up @@ -51,24 +51,25 @@ object Cobbledex {
// TODO: Make our own event so we don't need to depend on Cobblemon PlatformEvents
PlatformEvents.SERVER_STARTED.subscribe { _ ->
LOGGER.info("Cobbledex: Server initialized...")
PlayerDataExtensionRegistry.register(PlayerDiscovery.NAME_KEY, PlayerDiscovery::class.java)
//PlayerDataExtensionRegistry.register(PlayerDiscovery.NAME_KEY, PlayerDiscovery::class.java)
PlayerDataExtensionRegistry.register(CobbledexDiscovery.NAME_KEY, CobbledexDiscovery::class.java)

if (!eventsCreated) {
CobblemonEvents.STARTER_CHOSEN.subscribe(Priority.LOW) {
registerPlayerDiscovery(it.player, it.pokemon.form)
registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT)

val itemStack = ItemStack(CobbledexConstants.Cobbledex_Item, 1)
it.player.giveItemStack(itemStack)
}

CobblemonEvents.POKEMON_CAPTURED.subscribe(Priority.LOW) {
registerPlayerDiscovery(it.player, it.pokemon.form)
registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT)
}

CobblemonEvents.EVOLUTION_COMPLETE.subscribe(Priority.LOW) {
val player = it.pokemon.getOwnerPlayer()
if (player != null) {
registerPlayerDiscovery(player, it.pokemon.form)
registerPlayerDiscovery(player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT)
}
}

Expand All @@ -79,7 +80,7 @@ object Cobbledex {
}

PlatformEvents.CLIENT_PLAYER_LOGOUT.subscribe {
CobbledexCollectionGUI.discoveredList = null
CobbledexCollectionGUI.discoveredList.clear()
}

PlatformEvents.CLIENT_PLAYER_LOGIN.subscribe {
Expand All @@ -89,14 +90,20 @@ object Cobbledex {

PlatformEvents.SERVER_PLAYER_LOGIN.subscribe { login: ServerPlayerEvent.Login ->

// val playerData = CobblemonPlayerData.get(login.player)
// val cobbledexData = playerData.extraData[PlayerDiscovery.NAME_KEY] as PlayerDiscovery?
// var totalPokemonDiscovered = 0
// if (cobbledexData != null)
// totalPokemonDiscovered = cobbledexData.caughtSpecies.size
//
// AddToCollectionPacket(totalPokemonDiscovered).sendToPlayer(login.player)
// ReceiveCollectionDataPacket(cobbledexData?.caughtSpecies?.toList() ?: listOf()).sendToPlayer(login.player)

val playerData = CobblemonPlayerData.get(login.player)
val cobbledexData = playerData.extraData[PlayerDiscovery.NAME_KEY] as PlayerDiscovery?
var totalPokemonDiscovered = 0
if (cobbledexData != null)
totalPokemonDiscovered = cobbledexData.caughtSpecies.size
val cobbledexData = playerData.extraData[CobbledexDiscovery.NAME_KEY] as? CobbledexDiscovery?

AddToCollectionPacket(totalPokemonDiscovered).sendToPlayer(login.player)
ReceiveCollectionDataPacket(cobbledexData?.caughtSpecies?.toList() ?: listOf()).sendToPlayer(login.player)
val registers = cobbledexData?.registers ?: mutableMapOf()
ReceiveCollectionDataPacket(registers).sendToPlayer(login.player)
}
}

Expand All @@ -108,33 +115,21 @@ object Cobbledex {
return implementation.environment() == Environment.SERVER
}

fun registerPlayerDiscovery(player: PlayerEntity?, formData: FormData?): ActionResult
fun registerPlayerDiscovery(player: ServerPlayerEntity, formData: FormData?, isShiny: Boolean, type: DiscoveryRegister.RegisterType): ActionResult
{
if (player == null || formData == null)
if (formData == null)
return ActionResult.PASS

val playerData = CobblemonPlayerData.get(player)
val cobbledexData = playerData.extraData.getOrPut(PlayerDiscovery.NAME_KEY) {
// TODO: Maybe add the player PC/party pokemon in the first discover?
PlayerDiscovery()
} as PlayerDiscovery


if (!cobbledexData.caughtSpecies.contains(formData.species.nationalPokedexNumber)) {
cobbledexData.caughtSpecies.add(formData.species.nationalPokedexNumber)

if(CobbledexDiscovery.addOrUpdatePlayer(player, formData, isShiny, type) { newEntry ->
AddToCollectionPacket(formData, newEntry).sendToPlayer(player)
}) {
val translation = cobbledexTextTranslation("new_pokemon_discovered", formData.species.translatedName.bold().formatted(Formatting.GREEN).onClick {
OpenCobbledexPacket(formData).sendToPlayer(it)
}.onHover(cobbledexTextTranslation("click_to_open_cobbledex")))

player.sendMessage(translation)

if (player is ServerPlayerEntity)
AddToCollectionPacket(formData.species.nationalPokedexNumber).sendToPlayer(player)
}

CobblemonPlayerData.saveSingle(playerData)

return ActionResult.SUCCESS
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import kotlin.reflect.KClass

//import net.minecraft.world.biome.Biome

interface CobbledexImplementation {
val modAPI: ModAPI
val networkManager: INetworkManager
fun server(): MinecraftServer?
fun environment(): Environment
fun registerItems()
// fun getAllRegisteredBiomes() : List<Biome>
}

enum class ModAPI {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.rafacasari.mod.cobbledex.api

import com.cobblemon.mod.common.Cobblemon.playerData
import com.cobblemon.mod.common.api.storage.player.PlayerDataExtension
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.pc
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.rafacasari.mod.cobbledex.Cobbledex
import com.rafacasari.mod.cobbledex.api.classes.DiscoveryRegister
import com.rafacasari.mod.cobbledex.network.client.packets.ReceiveCollectionDataPacket
import com.rafacasari.mod.cobbledex.utils.logInfo
import net.minecraft.server.network.ServerPlayerEntity

class CobbledexDiscovery(val registers: MutableMap<String, MutableMap<String, DiscoveryRegister>> = mutableMapOf()): PlayerDataExtension {

companion object {
const val NAME_KEY = "${Cobbledex.MOD_ID}_discovery"

private val GSON = GsonBuilder()
.disableHtmlEscaping()
.create()

fun addOrUpdatePlayer(player: ServerPlayerEntity, form: FormData, isShiny: Boolean, status: DiscoveryRegister.RegisterType, update: (DiscoveryRegister) -> (Unit)): Boolean {
val data = playerData.get(player)

val cobbledexData = data.extraData.getOrPut(NAME_KEY) {
val discovery = CobbledexDiscovery()

val pc = player.pc()
pc.forEach { pokemon ->
discovery.addOrUpdate(pokemon.species.showdownId(), pokemon.form.formOnlyShowdownId(), pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT, null)
}

val party = player.party()
party.forEach { pokemon ->
discovery.addOrUpdate(pokemon.species.showdownId(), pokemon.form.formOnlyShowdownId(), pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT, null)
}

ReceiveCollectionDataPacket(discovery.registers).sendToPlayer(player)
logInfo("Added ${discovery.registers.size} entries in ${player.entityName}'s Cobbledex")
return@getOrPut discovery
} as CobbledexDiscovery

val isNewRegister = cobbledexData.addOrUpdate(form.species.showdownId(), form.formOnlyShowdownId(), isShiny, status, update)

playerData.saveSingle(data)
return isNewRegister
}
}

private fun getRegister(showdownId: String): MutableMap<String, DiscoveryRegister>? {
return registers[showdownId]
}

fun addOrUpdate(species: String, form: String, isShiny: Boolean, status: DiscoveryRegister.RegisterType, update: ((DiscoveryRegister) -> Unit)?): Boolean {
val currentRegister = getRegister(species)

val discoverTimestamp = System.currentTimeMillis()
val caughtTimestamp = if(status == DiscoveryRegister.RegisterType.CAUGHT) discoverTimestamp else null

if (currentRegister != null) {
val formRegister = currentRegister[form]
if (formRegister != null) {
// Update only if needed
if (!formRegister.isShiny && isShiny)
formRegister.isShiny = true

// Update only if needed
if (formRegister.status == DiscoveryRegister.RegisterType.SEEN && status == DiscoveryRegister.RegisterType.CAUGHT) {
formRegister.status = DiscoveryRegister.RegisterType.CAUGHT
formRegister.caughtTimestamp = caughtTimestamp
}

update?.invoke(formRegister)
return false
} else {
// New form
val newRegister = DiscoveryRegister(isShiny, status, discoverTimestamp, caughtTimestamp)
currentRegister[form] = newRegister
update?.invoke(newRegister)
return true
}
} else {
// New pokemon
val newRegister = DiscoveryRegister(isShiny, status, discoverTimestamp, caughtTimestamp)
registers[species] = mutableMapOf(form to newRegister)
update?.invoke(newRegister)
return true
}
}

override fun name(): String {
return NAME_KEY
}

override fun serialize(): JsonObject {
val jsonObject = GSON.toJsonTree(this).asJsonObject
jsonObject.addProperty(PlayerDataExtension.NAME_KEY, this.name())
return jsonObject
}

override fun deserialize(json: JsonObject): PlayerDataExtension {
return GSON.fromJson(json, CobbledexDiscovery::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.rafacasari.mod.cobbledex.api.adapters
//
//import com.google.gson.*
//import com.rafacasari.mod.cobbledex.api.classes.DiscoveryRegister
//import com.rafacasari.mod.cobbledex.utils.logInfo
//import java.lang.reflect.Type
//import java.util.AbstractMap.SimpleEntry
//
//class DiscoveryRegisterAdapter : JsonSerializer<Map.Entry<String, DiscoveryRegister>>, JsonDeserializer<Map.Entry<String, DiscoveryRegister>> {
// override fun serialize(src: Map.Entry<String, DiscoveryRegister>, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
// logInfo("Serializing")
//
// val jsonObject = JsonObject()
// jsonObject.addProperty("speciesWithForm", src.key)
// jsonObject.addProperty("isShiny", src.value.isShiny)
// jsonObject.addProperty("status", src.value.status.name)
// return jsonObject
// }
//
// override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Map.Entry<String, DiscoveryRegister> {
// logInfo("De-serializing")
//
// val jsonObject = json.asJsonObject
// val speciesWithForm = jsonObject.get("speciesWithForm").asString
// val isShiny = jsonObject.get("isShiny").asBoolean
// val status = DiscoveryRegister.RegisterType.valueOf(jsonObject.get("status").asString)
//
// return SimpleEntry(speciesWithForm, DiscoveryRegister(isShiny, status))
// }
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.rafacasari.mod.cobbledex.api.classes

import com.rafacasari.mod.cobbledex.network.IEncodable
import com.rafacasari.mod.cobbledex.utils.PacketUtils.readNullableLong
import com.rafacasari.mod.cobbledex.utils.PacketUtils.writeNullableLong
import net.minecraft.network.PacketByteBuf
import net.minecraft.text.Text
import net.minecraft.util.Formatting
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle

class DiscoveryRegister(var isShiny: Boolean, var status: RegisterType, var discoveredTimestamp: Long?, var caughtTimestamp: Long?) : IEncodable {
enum class RegisterType {
SEEN, CAUGHT
}

fun getDiscoveredTimestamp(): Text? {
if (discoveredTimestamp == null) return null

val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(discoveredTimestamp!!), ZoneId.systemDefault())
return Text.literal(localDateTime.format(TIME_FORMAT)).formatted(Formatting.ITALIC, Formatting.GRAY)
}

fun getCaughtTimestamp(): Text? {
if (caughtTimestamp == null) return null

val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(caughtTimestamp!!), ZoneId.systemDefault())
return Text.literal(localDateTime.format(TIME_FORMAT)).formatted(Formatting.ITALIC, Formatting.GRAY)
}

override fun encode(buffer: PacketByteBuf) {
buffer.writeBoolean(isShiny)
buffer.writeString(status.name)
buffer.writeNullableLong(discoveredTimestamp)
buffer.writeNullableLong(caughtTimestamp)
}

companion object {
private val TIME_FORMAT = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)

fun decode(reader: PacketByteBuf) : DiscoveryRegister {
val isShiny = reader.readBoolean()
val status = RegisterType.valueOf(reader.readString())
val discoveredTimestamp = reader.readNullableLong()
val caughtTimestamp = reader.readNullableLong()

return DiscoveryRegister(isShiny, status, discoveredTimestamp, caughtTimestamp)
}
}
}
Loading

0 comments on commit 8febb0c

Please sign in to comment.