From 1fe431710fa792cdcaa70ad793f6b65949452f46 Mon Sep 17 00:00:00 2001 From: Rafa <32463720+Rafacasari@users.noreply.github.com> Date: Sat, 6 Jul 2024 05:48:10 -0300 Subject: [PATCH] 1.0.36 Added Caught Rewards! Added item into Tools tab, now JEI should work properly Added credits into /cobbledex command, when used without parameters Added French translation (thanks @dafthunk) Code cleanup --- .../com/rafacasari/mod/cobbledex/Cobbledex.kt | 91 ++++--- .../mod/cobbledex/CobbledexConfig.kt | 2 + .../cobbledex/api/CobbledexCoopDiscovery.kt | 29 +-- .../mod/cobbledex/api/CobbledexDiscovery.kt | 35 ++- .../mod/cobbledex/api/CobbledexEvents.kt | 18 ++ .../mod/cobbledex/api/PokedexRewardHistory.kt | 90 +++++++ .../mod/cobbledex/api/PokedexRewards.kt | 111 +++++++++ .../cobbledex/api/events/DiscoveryEvent.kt | 21 ++ .../client/gui/CobbledexCollectionGUI.kt | 24 +- .../client/widget/DiscoveryRewardWidget.kt | 113 +++++++++ .../commands/server/CobbledexCommand.kt | 46 +++- .../packets/SyncServerSettingsPacket.kt | 4 - .../handlers/ClaimRewardPacketHandler.kt | 71 ++++++ .../server/packets/ClaimRewardPacket.kt | 23 ++ .../mod/cobbledex/utils/BiomeUtils.kt | 1 - .../mod/cobbledex/utils/CobblemonUtils.kt | 16 +- .../mod/cobbledex/utils/MiscUtils.kt | 3 + .../assets/cobbledex/lang/en_us.json | 3 + .../assets/cobbledex/lang/fr_fr.json | 230 ++++++++++++++++++ .../gui/collection/collection_base.png | Bin 3049 -> 3048 bytes .../textures/gui/collection/item_reward.png | Bin 0 -> 245 bytes .../mod/cobbledex/fabric/CobbledexFabric.kt | 19 +- .../mod/cobbledex/forge/CobbledexForge.kt | 8 + gradle.properties | 2 +- 24 files changed, 863 insertions(+), 97 deletions(-) create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/CobbledexEvents.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewardHistory.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewards.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/events/DiscoveryEvent.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/widget/DiscoveryRewardWidget.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/handlers/ClaimRewardPacketHandler.kt create mode 100644 common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/packets/ClaimRewardPacket.kt create mode 100644 common/src/main/resources/assets/cobbledex/lang/fr_fr.json create mode 100644 common/src/main/resources/assets/cobbledex/textures/gui/collection/item_reward.png diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/Cobbledex.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/Cobbledex.kt index 4c9dd5d..93b5e17 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/Cobbledex.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/Cobbledex.kt @@ -9,9 +9,9 @@ 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.cobblemon.mod.common.util.giveOrDropItemStack import com.cobblemon.mod.common.util.server -import com.rafacasari.mod.cobbledex.api.CobbledexCoopDiscovery -import com.rafacasari.mod.cobbledex.api.CobbledexDiscovery +import com.rafacasari.mod.cobbledex.api.* import com.rafacasari.mod.cobbledex.api.classes.DiscoveryRegister import com.rafacasari.mod.cobbledex.client.gui.CobbledexCollectionGUI import com.rafacasari.mod.cobbledex.client.gui.CobbledexGUI @@ -35,7 +35,10 @@ import java.nio.file.Paths object Cobbledex { private lateinit var config: CobbledexConfig + private lateinit var rewardManager: PokedexRewards + fun getConfig() : CobbledexConfig = config + fun getRewardManager(): PokedexRewards = rewardManager const val MOD_ID : String = "cobbledex" @@ -45,59 +48,81 @@ object Cobbledex { val LOGGER: Logger = LoggerFactory.getLogger("Cobbledex") lateinit var implementation: CobbledexImplementation - private var eventsCreated: Boolean = false fun preInitialize(implementation: CobbledexImplementation) { logInfo("Initializing Cobbledex $VERSION...") Cobbledex.implementation = implementation implementation.registerItems() + rewardManager = PokedexRewards.getInstance() + loadConfig() + // Register our custom extension data + PlayerDataExtensionRegistry.register(CobbledexDiscovery.NAME_KEY, CobbledexDiscovery::class.java) + PlayerDataExtensionRegistry.register(PokedexRewardHistory.NAME_KEY, PokedexRewardHistory::class.java) + PlatformEvents.SERVER_STARTED.subscribe { serverEvent -> logInfo("Server initialized...") - PlayerDataExtensionRegistry.register(CobbledexDiscovery.NAME_KEY, CobbledexDiscovery::class.java) + // Initialize CO-OP Discovery. Save inside world-root path to work on LAN servers without overlaps val serverPath = serverEvent.server.getSavePath(WorldSavePath.ROOT).toAbsolutePath() CobbledexCoopDiscovery.load(Paths.get(serverPath.toString(), "cobbledex-coop.json").toString()) + } - if (!eventsCreated) { - CobblemonEvents.STARTER_CHOSEN.subscribe(Priority.LOW) { - registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + CobblemonEvents.STARTER_CHOSEN.subscribe(Priority.LOW) { + registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) - if (getConfig().GiveCobbledexItemOnStarterChosen) { - val itemStack = ItemStack(CobbledexConstants.COBBLEDEX_ITEM, 1) - it.player.giveItemStack(itemStack) - } - } + if (getConfig().GiveCobbledexItemOnStarterChosen) { + val itemStack = ItemStack(CobbledexConstants.COBBLEDEX_ITEM, 1) + it.player.giveOrDropItemStack(itemStack) + } + } - CobblemonEvents.POKEMON_CAPTURED.subscribe(Priority.LOWEST) { - registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) - } + CobblemonEvents.POKEMON_CAPTURED.subscribe(Priority.LOWEST) { + registerPlayerDiscovery(it.player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + } - CobblemonEvents.EVOLUTION_COMPLETE.subscribe(Priority.LOW) { - val player = it.pokemon.getOwnerPlayer() + CobblemonEvents.EVOLUTION_COMPLETE.subscribe(Priority.LOW) { + val player = it.pokemon.getOwnerPlayer() - if (player != null) - registerPlayerDiscovery(player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) - } + if (player != null) + registerPlayerDiscovery(player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + } - CobblemonEvents.TRADE_COMPLETED.subscribe(Priority.LOW) { - serverEvent.server.playerManager.getPlayer(it.tradeParticipant1.uuid)?.let { player -> - val pokemon = it.tradeParticipant1Pokemon - registerPlayerDiscovery(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) - } + CobblemonEvents.TRADE_COMPLETED.subscribe(Priority.LOW) { + it.tradeParticipant1Pokemon.getOwnerPlayer()?.let { player -> + val pokemon = it.tradeParticipant1Pokemon + registerPlayerDiscovery(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + } - serverEvent.server.playerManager.getPlayer(it.tradeParticipant2.uuid)?.let { player -> - val pokemon = it.tradeParticipant2Pokemon - registerPlayerDiscovery(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) - } - } + it.tradeParticipant2Pokemon.getOwnerPlayer()?.let { player -> + val pokemon = it.tradeParticipant2Pokemon + registerPlayerDiscovery(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + } + } - // This should prevent events from being added more than once - eventsCreated = true + CobblemonEvents.FOSSIL_REVIVED.subscribe(Priority.LOW) { + it.player?.let { player -> + registerPlayerDiscovery(player, it.pokemon.form, it.pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) } } +// CobblemonEvents.BATTLE_STARTED_PRE.subscribe(Priority.LOW) { event -> +// val pokemonList = event.battle.activePokemon +// +// event.battle.players.forEach { player -> +// pokemonList.forEach { +// val pokemon = it.battlePokemon?.entity?.pokemon +// if (pokemon != null) +// registerPlayerDiscovery(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.SEEN) +// } +// } +// } + + CobbledexEvents.NEW_FORM_CAUGHT.subscribe { + PokedexRewardHistory.checkRewards(it.player) + } + PlatformEvents.CLIENT_PLAYER_LOGOUT.subscribe { CobbledexConstants.Client.discoveredList.clear() } @@ -121,6 +146,8 @@ object Cobbledex { } getConfig().syncPlayer(login.player) + + PokedexRewardHistory.checkRewards(login.player) } } diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/CobbledexConfig.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/CobbledexConfig.kt index a850b09..3f0f89b 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/CobbledexConfig.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/CobbledexConfig.kt @@ -28,6 +28,8 @@ class CobbledexConfig : IEncodable { var Collection_NeedCatch = false var Collection_DisableBlackSilhouette = false + var CaughtRewards = true + companion object { val GSON: Gson = GsonBuilder() diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/CobbledexCoopDiscovery.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/CobbledexCoopDiscovery.kt index b8bc17b..c0fc44c 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/CobbledexCoopDiscovery.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/CobbledexCoopDiscovery.kt @@ -18,27 +18,23 @@ class CobbledexCoopDiscovery(val registers: MutableMap - discovery.addOrUpdate(pokemon.species.showdownId(), pokemon.form.formOnlyShowdownId(), pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT, null) + discovery.addOrUpdate(player, pokemon.form, 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) + discovery.addOrUpdate(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT, null) } ReceiveCollectionDataPacket(discovery.registers).sendToPlayer(player) @@ -51,7 +52,7 @@ class CobbledexDiscovery(val registers: MutableMap Unit)? = null): Boolean { + fun getTotalDiscovered(): Int { + return registers.values.flatMap { it.values }.count() + } + + fun getTotalCaught(): Int { + return registers.values.flatMap { it.values }.count { it.status == DiscoveryRegister.RegisterType.CAUGHT } + } + + fun addOrUpdate(player: ServerPlayerEntity, formData: FormData, isShiny: Boolean, status: DiscoveryRegister.RegisterType, update: ((DiscoveryRegister) -> Unit)? = null): Boolean { + val species = formData.species.showdownId() + val form = formData.formOnlyShowdownId() + val currentRegister = getRegister(species) val discoverTimestamp = System.currentTimeMillis() @@ -79,6 +91,8 @@ class CobbledexDiscovery(val registers: MutableMap() + + @JvmField + val NEW_FORM_DISCOVERED = EventObservable() + + @JvmField + val NEW_SPECIES_CAUGHT = EventObservable() + + @JvmField + val NEW_FORM_CAUGHT = EventObservable() +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewardHistory.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewardHistory.kt new file mode 100644 index 0000000..b0540b9 --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewardHistory.kt @@ -0,0 +1,90 @@ +package com.rafacasari.mod.cobbledex.api + +import com.cobblemon.mod.common.Cobblemon.playerData as CobblemonPlayerData +import com.cobblemon.mod.common.api.storage.player.PlayerDataExtension +import com.cobblemon.mod.common.api.text.bold +import com.cobblemon.mod.common.api.text.text +import com.cobblemon.mod.common.util.giveOrDropItemStack +import com.google.gson.GsonBuilder +import com.google.gson.JsonObject +import com.rafacasari.mod.cobbledex.Cobbledex +import com.rafacasari.mod.cobbledex.utils.MiscUtils.appendWithSeparator +import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexTextTranslation +import net.minecraft.item.ItemStack +import net.minecraft.registry.Registries +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.text.MutableText +import net.minecraft.util.Identifier + +class PokedexRewardHistory(val received: MutableList = mutableListOf()) : PlayerDataExtension { + override fun name(): String = NAME_KEY + + companion object { + const val NAME_KEY = "Cobbledex_RewardHistory" + private val GSON = GsonBuilder() + .disableHtmlEscaping() + .create() + + fun getPlayerRewards(player: ServerPlayerEntity): PokedexRewardHistory { + val playerData= CobblemonPlayerData.get(player) + val history = playerData.extraData.getOrPut(NAME_KEY) { + PokedexRewardHistory(mutableListOf()) + } as PokedexRewardHistory + + return history + } + + fun checkRewards(player: ServerPlayerEntity) { + if(!Cobbledex.getConfig().CaughtRewards) + return + + val playerData= CobblemonPlayerData.get(player) + var needToSave = false + + val history = playerData.extraData.getOrPut(NAME_KEY) { + // Add an empty reward history + needToSave = true + PokedexRewardHistory(mutableListOf()) + } as PokedexRewardHistory + + val totalCaught = CobbledexDiscovery.getPlayerData(player).getTotalCaught() + val possibleRewards = Cobbledex.getRewardManager().rewards.filter { + totalCaught >= it.pokemonCaught + } + + possibleRewards.forEach { reward -> + if (!history.received.contains(reward.id)) + { + val identifier = Identifier(reward.itemId) + val item = Registries.ITEM.get(identifier) + val itemStack = ItemStack(item, reward.quantity) + + player.giveOrDropItemStack(itemStack) + val itemNameBuilder = mutableListOf( + "${reward.quantity}x".text().bold(), + MutableText.of(item.name.content).bold() + ).appendWithSeparator(" ") + + val message = cobbledexTextTranslation("reward_received", itemNameBuilder, reward.pokemonCaught.toString().text().bold()) + player.sendMessage(message) + history.received.add(reward.id) + // Give item + needToSave = true + } + } + + if (needToSave) + CobblemonPlayerData.saveSingle(playerData) + } + } + + 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, PokedexRewardHistory::class.java) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewards.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewards.kt new file mode 100644 index 0000000..6c27a7e --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/PokedexRewards.kt @@ -0,0 +1,111 @@ +package com.rafacasari.mod.cobbledex.api + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.rafacasari.mod.cobbledex.Cobbledex.MOD_ID +import com.rafacasari.mod.cobbledex.utils.MiscUtils.logError +import java.io.File +import java.io.FileReader +import java.io.FileWriter + +class PokedexRewards(val rewards: List) { + companion object { + private val GSON: Gson = GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .create() + + private lateinit var instance: PokedexRewards + fun getInstance() : PokedexRewards { + if (!this::instance.isInitialized) + load() + + return instance + } + + private fun getDefaultRewards() : List { + return listOf( + PokedexReward("15", 15, "cobblemon:ancient_poke_ball", 15), + PokedexReward("30", 30, "cobblemon:thunder_stone", 1), + PokedexReward("45", 45, "cobblemon:ancient_great_ball", 15), + PokedexReward("60", 60, "cobblemon:exp_candy_s", 5), + PokedexReward("75", 75, "cobblemon:fire_stone", 1), + PokedexReward("90", 90, "cobblemon:net_ball", 15), + PokedexReward("105", 105, "cobblemon:water_stone", 1), + PokedexReward("120", 120, "cobblemon:nest_ball", 15), + PokedexReward("135", 135, "cobblemon:ancient_ultra_ball", 30), + PokedexReward("150", 150, "cobblemon:exp_candy_s", 5), + PokedexReward("165", 165, "cobblemon:quick_ball", 15), + PokedexReward("180", 180, "cobblemon:leaf_stone", 1), + PokedexReward("195", 195, "cobblemon:dusk_ball", 15), + PokedexReward("210", 210, "cobblemon:exp_candy_s", 5), + PokedexReward("225", 225, "cobblemon:thunder_stone", 1), + PokedexReward("240", 240, "cobblemon:dive_ball", 15), + PokedexReward("255", 255, "cobblemon:exp_candy_m", 3), + PokedexReward("270", 270, "cobblemon:luxury_ball", 15), + PokedexReward("285", 285, "cobblemon:sun_stone", 1), + PokedexReward("300", 300, "cobblemon:exp_candy_m", 3), + PokedexReward("315", 315, "cobblemon:ability_capsule", 1), + PokedexReward("330", 330, "cobblemon:timer_ball", 15), + PokedexReward("345", 345, "cobblemon:dusk_stone", 1), + PokedexReward("360", 360, "cobblemon:exp_candy_m", 3), + PokedexReward("375", 375, "cobblemon:everstone", 1), + PokedexReward("390", 390, "cobblemon:fast_ball", 15), + PokedexReward("405", 405, "cobblemon:ice_stone", 1), + PokedexReward("420", 420, "cobblemon:destiny_knot", 1), + PokedexReward("435", 435, "cobblemon:friend_ball", 15), + PokedexReward("450", 450, "cobblemon:exp_candy_l", 1), + PokedexReward("465", 465, "cobblemon:shiny_stone", 1), + PokedexReward("480", 480, "cobblemon:level_ball", 15), + PokedexReward("495", 495, "cobblemon:exp_candy_l", 1), + PokedexReward("510", 510, "cobblemon:lure_ball", 15), + PokedexReward("525", 525, "cobblemon:moon_stone", 1), + PokedexReward("540", 540, "cobblemon:heavy_ball", 15), + PokedexReward("555", 555, "cobblemon:exp_candy_xl", 1), + PokedexReward("570", 570, "cobblemon:moon_ball", 15), + PokedexReward("585", 585, "cobblemon:dawn_stone", 1), + PokedexReward("600", 600, "cobblemon:exp_candy_xl", 1), + PokedexReward("615", 615, "cobblemon:love_ball", 15), + PokedexReward("633", 633, "cobblemon:beast_ball", 1) + ) + } + + private const val PATH = "config/$MOD_ID/rewards.json" + + private fun load() { + val configFile = File(PATH) + configFile.parentFile.mkdirs() + + if (configFile.exists()) { + try { + val fileReader = FileReader(configFile) + instance = GSON.fromJson(fileReader, PokedexRewards::class.java) + fileReader.close() + } catch (error: Exception) { + logError("Failed to load Cobbledex Rewards! Using default default rewards") + instance = PokedexRewards(getDefaultRewards()) + error.printStackTrace() + } + } else { + instance = PokedexRewards(getDefaultRewards()) + } + + save() + } + + private fun save() { + try { + val fileWriter = FileWriter(File(PATH)) + GSON.toJson(instance, fileWriter) + fileWriter.flush() + fileWriter.close() + } catch (exception: Exception) { + logError("Failed to save rewards! Error stack trace:") + exception.printStackTrace() + } + } + } + + + data class PokedexReward(val id: String, val pokemonCaught: Int, val itemId: String, val quantity: Int) +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/events/DiscoveryEvent.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/events/DiscoveryEvent.kt new file mode 100644 index 0000000..c93dff3 --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/api/events/DiscoveryEvent.kt @@ -0,0 +1,21 @@ +package com.rafacasari.mod.cobbledex.api.events + +import com.cobblemon.mod.common.pokemon.FormData +import com.cobblemon.mod.common.pokemon.Species +import com.rafacasari.mod.cobbledex.api.classes.DiscoveryRegister +import net.minecraft.server.network.ServerPlayerEntity + +interface DiscoveryEvent { + val player: ServerPlayerEntity + val register: DiscoveryRegister + + /** + * Fired when a player discover a new [Species] + */ + data class OnSpeciesDiscoveryEvent(override val player: ServerPlayerEntity, override val register: DiscoveryRegister, val species: Species) : DiscoveryEvent + + /** + * Fired when a player discover a new [FormData] + */ + data class OnFormDiscoveryEvent(override val player: ServerPlayerEntity, override val register: DiscoveryRegister, val form: FormData) : DiscoveryEvent +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/gui/CobbledexCollectionGUI.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/gui/CobbledexCollectionGUI.kt index dda41d2..c4c42a9 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/gui/CobbledexCollectionGUI.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/gui/CobbledexCollectionGUI.kt @@ -26,7 +26,7 @@ import com.rafacasari.mod.cobbledex.client.widget.SearchWidget import com.rafacasari.mod.cobbledex.client.widget.SilhouetteModelWidget import com.rafacasari.mod.cobbledex.network.client.handlers.SyncServerSettingsHandler import com.rafacasari.mod.cobbledex.utils.CobblemonUtils.drawBlackSilhouettePokemon -import com.rafacasari.mod.cobbledex.utils.CobblemonUtils.getValidForms +import com.rafacasari.mod.cobbledex.utils.CobblemonUtils.validForms import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexResource import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexTextTranslation import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexTranslation @@ -117,6 +117,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { private var typeWidget: TypeIcon? = null private lateinit var searchWidget: SearchWidget private var currentHoveredEntry: Species? = null + //private lateinit var rewardWidget: DiscoveryRewardWidget override fun init() { val x = (width - CobbledexGUI.BASE_WIDTH) / 2 @@ -152,6 +153,9 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { currentPage = maxPages }) +// rewardWidget = DiscoveryRewardWidget(x + 5, y + 170) +// addDrawableChild(rewardWidget) + // val totalItems = (COLUMN_SIZE * LINES_SIZE) // // Get total items // maxPages = (implementedSpecies.size + totalItems - 1) / totalItems @@ -238,7 +242,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { // Discovered drawScaledText( context = context, - text = Text.literal("Discovered").bold(), + text = cobbledexTextTranslation("discover.discovered").bold(), x = x + 13, y = y + 135f, centered = false, @@ -258,7 +262,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { drawScaledText( context = context, text = percentageDiscovered.text().bold(), - x = x + 64F, + x = x + 64.5F, y = y + 138f, centered = true, scale = 0.5F @@ -267,7 +271,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { // Caught drawScaledText( context = context, - text = Text.literal("Caught").bold(), + text = cobbledexTextTranslation("discover.caught").bold(), x = x + 13, y = y + 154f, centered = false, @@ -283,11 +287,10 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { scale = 0.5F ) - drawScaledText( context = context, text = percentageCaught.text().bold(), - x = x + 64F, + x = x + 64.5F, y = y + 157f, centered = true, scale = 0.5F @@ -329,7 +332,6 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { scale = SCALE ) - } // Render widgets @@ -351,7 +353,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { species?.let { // TODO: If selected form is null, use the first discovered/caught form, if also is empty, use standardForm - val validForms = species.getValidForms() + val validForms = species.validForms val selectedForm = selectedFormMap[it.resourceIdentifier]?.let { formId -> validForms[formId] } ?: it.standardForm val isMouseOver = @@ -451,7 +453,6 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { scale = SCALE, opacity = 0.3 ) - if (isMouseOver) { //val formName = if (entryForm != null) selectedForm.name else "???" tooltip.add(cobbledexTextTranslation("discover.selected_form", selectedForm.name.text().bold()).formatted(Formatting.GRAY)) @@ -488,7 +489,6 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { } currentIndex++ - } } @@ -502,7 +502,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean { currentHoveredEntry?.let { - val validForms = it.getValidForms() + val validForms = it.validForms if (validForms.isNotEmpty()) { var current = selectedFormMap[it.resourceIdentifier] ?: 0 if (amount > 0) { @@ -525,7 +525,7 @@ class CobbledexCollectionGUI : Screen(cobbledexTextTranslation("cobbledex")) { override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { currentHoveredEntry?.let { species -> - val validForms = species.getValidForms() + val validForms = species.validForms val selectedForm = selectedFormMap[species.resourceIdentifier]?.let { formId -> validForms[formId] } ?: species.standardForm val config = SyncServerSettingsHandler.config val registerType = discoveredList[species.showdownId()]?.get(selectedForm.formOnlyShowdownId())?.status diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/widget/DiscoveryRewardWidget.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/widget/DiscoveryRewardWidget.kt new file mode 100644 index 0000000..fda5418 --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/client/widget/DiscoveryRewardWidget.kt @@ -0,0 +1,113 @@ +package com.rafacasari.mod.cobbledex.client.widget + +import com.cobblemon.mod.common.CobblemonItems +import com.cobblemon.mod.common.api.gui.blitk +import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget +import com.cobblemon.mod.common.client.render.drawScaledText +import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexResource +import net.minecraft.client.MinecraftClient +import net.minecraft.client.gui.DrawContext +import net.minecraft.client.render.DiffuseLighting +import net.minecraft.client.render.OverlayTexture +import net.minecraft.client.render.model.BakedModel +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.item.ItemStack +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import org.joml.Matrix4f + +class DiscoveryRewardWidget(x: Int, y: Int): SoundlessWidget(x, y, 74, 26, Text.literal("Rewards")) { + companion object { + private val ITEM_REWARD: Identifier = cobbledexResource("textures/gui/collection/item_reward.png") + } + + private fun drawItem(context: DrawContext, stack: ItemStack, x: Int, y: Int, itemSize: Float) { + if (!stack.isEmpty) { + val bakedModel: BakedModel = MinecraftClient.getInstance().itemRenderer.getModel(stack, null, null, 0) + context.matrices.push() + context.matrices.translate(x.toFloat(), y.toFloat(), 0f) + + try { + context.matrices.multiplyPositionMatrix(Matrix4f().scaling(1.0f, -1.0f, 1.0f)) + context.matrices.scale(itemSize, itemSize, itemSize) + val bl = !bakedModel.isSideLit + if (bl) DiffuseLighting.disableGuiDepthLighting() + + MinecraftClient.getInstance().itemRenderer.renderItem( + stack, ModelTransformationMode.GUI, false, + context.matrices, + context.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV, bakedModel + ) + context.draw() + if (bl) DiffuseLighting.enableGuiDepthLighting() + + } catch (_: Exception) { + + } + + context.matrices.pop() + } + } + + override fun renderButton(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { + val matrices = context.matrices + + context.enableScissor(x, y, x + 74, y + 26) + + blitk( + matrixStack = matrices, + texture = ITEM_REWARD, + x = x - 7, + y = y, + width = 26, + height = 26, + alpha = 0.5f + ) + + + blitk( + matrixStack = matrices, + texture = ITEM_REWARD, + x = x + width - 26 + 7, + y = y, + width = 26, + height = 26, + alpha = 0.5f + ) + + + blitk( + matrixStack = matrices, + texture = ITEM_REWARD, + x = x + 24, + y = y, + width = 26, + height = 26 + ) + + + + drawScaledText( + context = context, + text = Text.literal("Claim"), + x = x + 24 + (26 / 2), + y = y + 20, + centered = true, + scale = 0.5F, maxCharacterWidth = 26 * 2 + ) + + val shinyStone = ItemStack(CobblemonItems.SHINY_STONE, 1) + val iceStone = ItemStack(CobblemonItems.ICE_STONE, 1) + val fireStone = ItemStack(CobblemonItems.FIRE_STONE, 1) + + drawItem(context, shinyStone, x + 24 + (26 / 2), y + (26 / 2) - 2, 16f) + + drawItem(context, iceStone, x - 7 + (26 / 2), y + (26 / 2), 16f) + drawItem(context, fireStone, x + width - 26 + 7 + (26 / 2), y + (26 / 2), 16f) + + + context.disableScissor() + + + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/commands/server/CobbledexCommand.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/commands/server/CobbledexCommand.kt index d8449d3..fed8cc2 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/commands/server/CobbledexCommand.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/commands/server/CobbledexCommand.kt @@ -3,10 +3,7 @@ package com.rafacasari.mod.cobbledex.commands.server import com.cobblemon.mod.common.api.permission.CobblemonPermission import com.cobblemon.mod.common.api.permission.PermissionLevel import com.cobblemon.mod.common.api.pokemon.PokemonSpecies -import com.cobblemon.mod.common.api.text.bold -import com.cobblemon.mod.common.api.text.green -import com.cobblemon.mod.common.api.text.red -import com.cobblemon.mod.common.api.text.text +import com.cobblemon.mod.common.api.text.* import com.cobblemon.mod.common.command.argument.PokemonPropertiesArgumentType import com.cobblemon.mod.common.util.party import com.cobblemon.mod.common.util.pc @@ -17,6 +14,7 @@ import com.mojang.brigadier.arguments.StringArgumentType import com.mojang.brigadier.context.CommandContext import com.mojang.brigadier.exceptions.SimpleCommandExceptionType import com.rafacasari.mod.cobbledex.Cobbledex +import com.rafacasari.mod.cobbledex.CobbledexBuildDetails import com.rafacasari.mod.cobbledex.CobbledexConfig import com.rafacasari.mod.cobbledex.api.CobbledexCoopDiscovery import com.rafacasari.mod.cobbledex.api.CobbledexDiscovery @@ -25,12 +23,17 @@ import com.rafacasari.mod.cobbledex.commands.arguments.SettingArgumentSuggestion import com.rafacasari.mod.cobbledex.network.client.packets.OpenCobbledexPacket import com.rafacasari.mod.cobbledex.network.client.packets.OpenDiscoveryPacket import com.rafacasari.mod.cobbledex.network.client.packets.ReceiveCollectionDataPacket +import com.rafacasari.mod.cobbledex.utils.MiscUtils.appendWithSeparator import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexTextTranslation import com.rafacasari.mod.cobbledex.utils.MiscUtils.logError +import com.rafacasari.mod.cobbledex.utils.MiscUtils.openUrl +import com.rafacasari.mod.cobbledex.utils.MiscUtils.toMutableText import net.minecraft.command.argument.EntityArgumentType import net.minecraft.server.command.CommandManager import net.minecraft.server.command.ServerCommandSource +import net.minecraft.text.MutableText import net.minecraft.text.Text +import net.minecraft.util.Formatting import kotlin.reflect.* import kotlin.reflect.full.memberProperties @@ -52,7 +55,9 @@ object CobbledexCommand : IServerCommandInterface { val playersArgument = CommandManager.argument("players", EntityArgumentType.players()) val command = createLiteralArgument("cobbledex") - + .executes { + ctx -> executeCreditCommand(ctx) + } // Add config options here .then( CommandManager.literal("config").permission(CONFIG_COBBLEDEX_PERMISSION) @@ -90,6 +95,32 @@ object CobbledexCommand : IServerCommandInterface { } } + private fun executeCreditCommand(ctx: CommandContext): Int { + val creditsMessage: MutableList = mutableListOf() + creditsMessage.add("Cobblemon Pokedex ".text().formatted(Formatting.BOLD, Formatting.RED) + "v${CobbledexBuildDetails.VERSION}".text().formatted(Formatting.WHITE, Formatting.BOLD)) + + val creditBuilder: MutableList = mutableListOf() + creditBuilder.add(Text.literal("Made with")) + creditBuilder.add(Text.literal("❤").formatted(Formatting.RED)) + creditBuilder.add(Text.literal("by")) + creditBuilder.add(Text.literal("Rafa").formatted(Formatting.RED, Formatting.BOLD)) + creditBuilder.add(Text.literal("and")) + creditBuilder.add(Text.literal("Cobblemon Community").formatted(Formatting.RED, Formatting.BOLD)) + creditsMessage.add(creditBuilder.appendWithSeparator(" ")) + + val downloadLine: MutableList = mutableListOf() + downloadLine.add(Text.literal("Download at:")) + downloadLine.add(Text.literal("GitHub").bold().aqua().openUrl("https://github.com/rafacasari/cobbledex/releases")) + downloadLine.add(Text.literal("|")) + downloadLine.add(Text.literal("Modrinth").bold().aqua().openUrl("https://modrinth.com/mod/cobblemon-pokedex")) + downloadLine.add(Text.literal("|")) + downloadLine.add(Text.literal("CurseForge").bold().aqua().openUrl("https://curseforge.com/minecraft/mc-mods/cobbledex")) + creditsMessage.add(downloadLine.appendWithSeparator(" ")) + + ctx.source.sendMessage(creditsMessage.toMutableText()) + return Command.SINGLE_SUCCESS + } + private fun executeAuto(ctx: CommandContext): Int { val players = EntityArgumentType.getPlayers(ctx, "players") players.forEach { player -> @@ -104,13 +135,13 @@ object CobbledexCommand : IServerCommandInterface { val pc = player.pc() pc.forEach { pokemon -> - discovery.addOrUpdate(pokemon.species.showdownId(), pokemon.form.formOnlyShowdownId(), pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + discovery.addOrUpdate(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) CobbledexCoopDiscovery.addOrUpdateCoopWithoutSaving(pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) } val party = player.party() party.forEach { pokemon -> - discovery.addOrUpdate(pokemon.species.showdownId(), pokemon.form.formOnlyShowdownId(), pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) + discovery.addOrUpdate(player, pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) CobbledexCoopDiscovery.addOrUpdateCoopWithoutSaving(pokemon.form, pokemon.shiny, DiscoveryRegister.RegisterType.CAUGHT) } @@ -123,7 +154,6 @@ object CobbledexCommand : IServerCommandInterface { } catch (_: Exception) { // Suppress any error } - } CobbledexCoopDiscovery.save() diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/client/packets/SyncServerSettingsPacket.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/client/packets/SyncServerSettingsPacket.kt index 525fc7b..30f6c5b 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/client/packets/SyncServerSettingsPacket.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/client/packets/SyncServerSettingsPacket.kt @@ -6,10 +6,6 @@ import net.minecraft.network.PacketByteBuf import net.minecraft.util.Identifier class SyncServerSettingsPacket internal constructor(val config: CobbledexConfig): INetworkPacket { - - - - override val id = ID override fun encode(buffer: PacketByteBuf) { diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/handlers/ClaimRewardPacketHandler.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/handlers/ClaimRewardPacketHandler.kt new file mode 100644 index 0000000..f9a92be --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/handlers/ClaimRewardPacketHandler.kt @@ -0,0 +1,71 @@ +package com.rafacasari.mod.cobbledex.network.server.handlers + +import com.cobblemon.mod.common.api.text.bold +import com.cobblemon.mod.common.api.text.text +import com.cobblemon.mod.common.util.giveOrDropItemStack +import com.rafacasari.mod.cobbledex.Cobbledex +import com.rafacasari.mod.cobbledex.api.CobbledexDiscovery +import com.rafacasari.mod.cobbledex.api.PokedexRewardHistory +import com.rafacasari.mod.cobbledex.network.server.IServerNetworkPacketHandler +import com.rafacasari.mod.cobbledex.network.server.packets.ClaimRewardPacket +import com.rafacasari.mod.cobbledex.utils.MiscUtils.appendWithSeparator +import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexTextTranslation +import com.rafacasari.mod.cobbledex.utils.MiscUtils.logWarn +import net.minecraft.item.ItemStack +import net.minecraft.registry.Registries +import net.minecraft.server.MinecraftServer +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.text.MutableText +import net.minecraft.util.Identifier + +object ClaimRewardPacketHandler: IServerNetworkPacketHandler { + override fun handle(packet: ClaimRewardPacket, server: MinecraftServer, player: ServerPlayerEntity) { + if(!Cobbledex.getConfig().CaughtRewards) + { + logWarn("${player.name.string} tried to claim a reward (${packet.rewardId}) but CaughtRewards is disabled on this server") + return + } + + val playerHistory = PokedexRewardHistory.getPlayerRewards(player) + // Check if player already have this reward + if (playerHistory.received.contains(packet.rewardId)) { + logWarn("${player.name.string} tried to claim a reward (${packet.rewardId}) but they already got this reward") + return + } + + val rewardManager = Cobbledex.getRewardManager() + val targetReward = rewardManager.rewards.firstOrNull { it.id == packet.rewardId} + + // Check if this reward actually exists + if (targetReward == null) + { + logWarn("${player.name.string} tried to claim a reward (${packet.rewardId}) but this reward doesn't exist!") + return + } + + val playerDiscovery = CobbledexDiscovery.getPlayerData(player) + // Check if player meet the reward requirements + if (playerDiscovery.getTotalCaught() < targetReward.pokemonCaught) { + logWarn("${player.name.string} tried to claim a reward (${packet.rewardId}) but doesn't meet the requirements!") + return + } + + val identifier = Identifier(targetReward.itemId) + val item = Registries.ITEM.get(identifier) + val itemStack = ItemStack(item, targetReward.quantity) + + // Give reward for player + player.giveOrDropItemStack(itemStack) + val itemNameBuilder = mutableListOf( + "${targetReward.quantity}x".text().bold(), + MutableText.of(item.name.content).bold() + ).appendWithSeparator(" ") + + val message = cobbledexTextTranslation("reward_received", itemNameBuilder, targetReward.pokemonCaught.toString().text().bold()) + // Send a message telling our player that they got a reward + player.sendMessage(message) + + // Add to player history + playerHistory.received.add(targetReward.id) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/packets/ClaimRewardPacket.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/packets/ClaimRewardPacket.kt new file mode 100644 index 0000000..4163433 --- /dev/null +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/network/server/packets/ClaimRewardPacket.kt @@ -0,0 +1,23 @@ +package com.rafacasari.mod.cobbledex.network.server.packets + +import com.rafacasari.mod.cobbledex.network.INetworkPacket +import com.rafacasari.mod.cobbledex.utils.MiscUtils.cobbledexResource +import net.minecraft.network.PacketByteBuf +import net.minecraft.util.Identifier + +class ClaimRewardPacket internal constructor(val rewardId: String) : INetworkPacket { + + companion object { + val ID = cobbledexResource("claim_reward") + + fun decode(reader: PacketByteBuf) : ClaimRewardPacket { + return ClaimRewardPacket(reader.readString()) + } + } + + override val id: Identifier = ID + + override fun encode(buffer: PacketByteBuf) { + buffer.writeString(rewardId) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/BiomeUtils.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/BiomeUtils.kt index 8a9bdc6..451baea 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/BiomeUtils.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/BiomeUtils.kt @@ -7,7 +7,6 @@ import net.minecraft.world.World import net.minecraft.world.biome.Biome object BiomeUtils { - data class CobbledexBiome(val identifier: Identifier, val biome: Biome) fun getBiomesRegistry(world: World) : Registry { diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/CobblemonUtils.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/CobblemonUtils.kt index e97d74c..9152979 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/CobblemonUtils.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/CobblemonUtils.kt @@ -53,22 +53,16 @@ object CobblemonUtils { return spawnDetails } - private val validFormsCache: MutableMap> = mutableMapOf() - fun Species.getValidForms() : List { - if (validFormsCache[this.resourceIdentifier] == null) { - val forms = this.forms.filter { + private val formCache = mutableMapOf>() + val Species.validForms: List + get() = formCache.getOrPut(this.resourceIdentifier) { + this.forms.filter { PokemonModelRepository.variations[this.resourceIdentifier]?.variations?.any { x -> x.model != null && x.aspects.containsAll(it.aspects) - } == true + } ?: false } - - // Add to cache - validFormsCache[this.resourceIdentifier] = forms } - return validFormsCache[this.resourceIdentifier]!! - } - private val canSpawnCache: MutableMap = mutableMapOf() fun FormData.canSpawn() : Boolean { if (canSpawnCache[this.name] == null) diff --git a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/MiscUtils.kt b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/MiscUtils.kt index 970af7a..71b976f 100644 --- a/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/MiscUtils.kt +++ b/common/src/main/kotlin/com/rafacasari/mod/cobbledex/utils/MiscUtils.kt @@ -3,6 +3,7 @@ package com.rafacasari.mod.cobbledex.utils import net.minecraft.text.Text import net.minecraft.util.Identifier import com.rafacasari.mod.cobbledex.Cobbledex +import net.minecraft.text.ClickEvent import net.minecraft.text.MutableText import net.minecraft.text.TextContent @@ -19,6 +20,8 @@ object MiscUtils { fun Float.format(): String = if (this % 1 == 0f) this.toInt().toString() else this.toString() + fun MutableText.openUrl(url: String) = also { it.style = it.style.withClickEvent(ClickEvent(ClickEvent.Action.OPEN_URL, url)) } + fun cobbledexTextTranslation(key: String, vararg arg: Any): MutableText { return Text.translatable("cobbledex.texts.$key", *arg) } diff --git a/common/src/main/resources/assets/cobbledex/lang/en_us.json b/common/src/main/resources/assets/cobbledex/lang/en_us.json index 73980e0..b867b40 100644 --- a/common/src/main/resources/assets/cobbledex/lang/en_us.json +++ b/common/src/main/resources/assets/cobbledex/lang/en_us.json @@ -37,6 +37,9 @@ "cobbledex.texts.need.view_drops": "view drops", "cobbledex.texts.not_a_pokemon": "That's not a Pokémon!", "cobbledex.texts.discover.selected_form": "Selected form: %s", + "cobbledex.texts.discover.discovered": "Discovered", + "cobbledex.texts.discover.caught": "Caught", + "cobbledex.texts.reward_received": "§lCongrats!§r You received %s for catching %s Pokemon!", "cobbledex.texts.battle.title": "Damage Multipliers", "cobbledex.texts.battle.damage_from.multiplier_4": "%sx | §lSuper Weak§r against:", diff --git a/common/src/main/resources/assets/cobbledex/lang/fr_fr.json b/common/src/main/resources/assets/cobbledex/lang/fr_fr.json new file mode 100644 index 0000000..67b67b4 --- /dev/null +++ b/common/src/main/resources/assets/cobbledex/lang/fr_fr.json @@ -0,0 +1,230 @@ +{ + "item.cobbledex.cobbledex_item": "Cobbledex", + "cobbledex.texts.cobbledex": "Cobbledex", + "cobbledex.texts.weakness": "Faible contre :", + "cobbledex.texts.resistant": "Résistant face :", + "cobbledex.texts.immune": "Immunisé à :", + "cobbledex.texts.biomes": "Vit dans ces environnements :", + "cobbledex.texts.drops": "Butin :", + "cobbledex.texts.pokedex_number": "Pokédex N°", + "cobbledex.texts.evolutions": "Evolutions", + "cobbledex.texts.preevolutions": "Pré-Evolutions", + "cobbledex.texts.forms": "Formes", + "cobbledex.texts.weight": "Poids", + "cobbledex.texts.height": "Taille", + "cobbledex.texts.select": "Choisir", + "cobbledex.texts.battle.damage_from": "%sx dégât de :", + "cobbledex.texts.tab.info": "Info", + "cobbledex.texts.tab.battle": "Combat", + "cobbledex.texts.tab.evolve": "Evolution", + "cobbledex.texts.search": "Recherche", + "cobbledex.texts.commands.current_setting": "%s est actuellement configuré en %s", + "cobbledex.texts.commands.successfully_applied": "§a✔ Appliqué :§r %s configuré en %s", + "cobbledex.texts.discovery_status": "Status : %s", + "cobbledex.texts.discovery_status.discovered": "Découvert", + "cobbledex.texts.discovery_status.caught": "Attrapé", + "cobbledex.texts.shiny": "Brillant !", + "cobbledex.texts.discovered_on": "Découvert le : %s", + "cobbledex.texts.caught_on": "Attrapé le : %s", + "cobbledex.texts.info.height_value": "%sm", + "cobbledex.texts.info.weight_value": "%skg", + "cobbledex.texts.no_drops_found": "Ne possède pas de butin", + "cobbledex.texts.blocked_by_server": "Cette fonctionnalité est désactivée sur ce serveur", + "cobbledex.texts.need_seen": "Vous devez §lvoir§r ce Pokémon pour pouvoir le %s !", + "cobbledex.texts.need_catch": "Vous devez §lattraper§r ce Pokémon pour pouvoir le %s !", + "cobbledex.texts.need.view_evolutions": "voir les évolutions", + "cobbledex.texts.need.view_spawns": "voir les apparitions", + "cobbledex.texts.need.view_drops": "voir le butin", + "cobbledex.texts.not_a_pokemon": "Ce n'est pas un Pokémon !", + "cobbledex.texts.discover.selected_form": "Sélectionner la forme : %s", + + "cobbledex.texts.battle.title": "Multiplicateur de dégât", + "cobbledex.texts.battle.damage_from.multiplier_4": "%sx | §lTrès faible§r contre :", + "cobbledex.texts.battle.damage_from.multiplier_2": "%sx | §lFaible§r contre :", + "cobbledex.texts.battle.damage_from.multiplier_0_5": "%sx | §lRésistant§r face :", + "cobbledex.texts.battle.damage_from.multiplier_0_25": "%sx | §lTrès résistant§r face :", + "cobbledex.texts.battle.damage_from.multiplier_0": "%sx | §lImmunisé§r à :", + + "cobbledex.texts.tooltip.hold_shift_timestamp": "Maintenir pour l'horodatage", + "cobbledex.texts.new_pokemon_discovered": "Vous avez découvert un nouveau Pokémon : %s", + "cobbledex.texts.new_pokemon_discovered_coop": "%s a découvert un nouveau Pokémon : %s", + "cobbledex.texts.click_to_open_cobbledex": "Cliquez pour ouvrir le Cobbledex", + "cobbledex.texts.tooltip_description.discovered": "Découvert : %s/%s (%s)", + "cobbledex.texts.tooltip_description.total_forms_discovered": "Formes découvertes : %s", + "cobbledex.texts.tooltip_description.caught": "Attrapés : %s/%s (%s)", + "cobbledex.texts.tooltip_description.total_forms_caught": "Formes attrapées : %s", + "cobbledex.texts.tooltip_description.press_shift": "Maintenir pour plus d'informations", + "cobbledex.texts.tooltip_description.instructions1": "§a§lClic-droit§r sur un Pokémon pour le découvrir", + "cobbledex.texts.tooltip_description.instructions2": "§a§lClic-droit§r sur un Pokémon pour ouvrir le §lmenu d'information§r", + "cobbledex.texts.tooltip_description.instructions3": "§a§lClic-droit§r dans les airs pour ouvrir le §ldernier Pokémon consulté§r", + "cobbledex.texts.tooltip_description.instructions4": "§a§lMaj + clic droit§r pour ouvrir la §lcollection§r", + "cobbledex.texts.drops.item": "%s | %s%% | %sx", + "cobbledex.texts.weather.clear": "Clair", + "cobbledex.texts.weather.raining": "Pluvieux", + "cobbledex.texts.weather.thundering": "Orageux", + "cobbledex.texts.weather.raining_and_thundering": "Pluvieux et orageux", + "cobbledex.texts.no_evolution_found": "Pas d'évolution trouvée pour %s", + + "cobbledex.evolution.use_item": "Via %s", + "cobbledex.evolution.trade_any": "Via échange ou %s", + "cobbledex.evolution.trade_specific": "Echangé avec %s ou via %s", + "cobbledex.evolution.damage_taken": "En prenant %s de dégât", + "cobbledex.evolution.level": "Niveau : %s", + "cobbledex.evolution.friendship": "Amitié : %s", + "cobbledex.evolution.held_item": "En tenant : %s", + "cobbledex.evolution.any_requirement": "Nécessite n'importe lequel de ces prérequis :", + "cobbledex.evolution.attack_defence_ratio.attack_higher": "Plus d'attaque que de défense", + "cobbledex.evolution.attack_defence_ratio.defence_higher": "Plus de défense que d'attaque", + "cobbledex.evolution.attack_defence_ratio.equal": "Valeur d'attaque égale à celle de défense", + "cobbledex.evolution.battle_critical_hits": "%s coups critiques en combat", + "cobbledex.evolution.blocks_traveled": "Parcouru %s blocs", + "cobbledex.evolution.defeat": "%s défaites", + "cobbledex.evolution.move_set": "Capacité %s", + "cobbledex.evolution.move_type": "N'importe quelle capacité de type %s", + "cobbledex.evolution.party_member": "En présence de %s dans votre équipe", + "cobbledex.evolution.party_member.type": "En présence de Pokémon de type %s dans votre équipe", + "cobbledex.evolution.player_has_advancement": "Le dresseur possède le progrès : %s", + "cobbledex.evolution.property_range": "Nécessite entre %s et %s", + "cobbledex.evolution.recoil": "%s contrecoups", + "cobbledex.evolution.stat_equal": "Les statistiques %s et %s doivent être égales", + "cobbledex.evolution.stat_compare": "La statistique %s doit être supérieure à %s", + "cobbledex.evolution.time_range": "Moment de la journée : %s", + "cobbledex.evolution.use_move": "Doit utiliser la capacité %s %s fois", + "cobbledex.evolution.weather": "Météo : %s", + "cobbledex.evolution.biome.condition": "Le biome comporte le tag : %s", + "cobbledex.evolution.biome.anti_condition": "Le biome ne comporte pas le tag : %s", + "cobbledex.evolution.world": "Etre dans la dimension : %s", + "cobbledex.evolution.moon_phase": "Nécessite la phase de la lune : %s", + "cobbledex.evolution.structure.condition": "Nécessite la structure : %s", + "cobbledex.evolution.structure.anti_condition": "Ne pas être dans la structure : %s", + "cobbledex.evolution.properties": "Nécessite : %s", + "cobbledex.evolution.defeat_specific": "Battre %s %s fois", + + "cobblemon.evolution/alolan": "Alolan", + "cobblemon.evolution/hisui": "Hisui", + "cobblemon.evolution/rowlet_dartrix_hisui_bias": "Hisui", + "cobblemon.evolution/cyndaquil_quilava_hisui_bias": "Hisui", + "cobblemon.evolution/oshawott_dewott_hisui_bias": "Hisui", + "cobblemon.evolution/sliggoo_hisuian": "Hisui", + + "structure.cobblemon.ruins/crumbling_arch_ruins": "Crumbling Arch Ruins", + "structure.cobblemon.ruins/decaying_crypt_ruins": "Decaying Crypt Ruins", + "structure.cobblemon.ruins/deserted_gimmi_tower": "Deserted Gimmi Tower", + "structure.cobblemon.ruins/deserted_house_ruins": "Deserted House Ruins", + "structure.cobblemon.ruins/deserted_tower_ruins": "Deserted Tower Ruins", + "structure.cobblemon.ruins/deserted_town_center_ruins": "Deserted Town Center Ruins", + "structure.cobblemon.ruins/fallen_statue_ruins": "Fallen Statue Ruins", + "structure.cobblemon.ruins/frozen_gimmi_tower": "Frozen Gimmi Tower", + "structure.cobblemon.ruins/hidden_bunker_ruins": "Hidden Bunker Ruins", + "structure.cobblemon.ruins/lush_gimmi_tower": "Lush Gimmi Tower", + "structure.cobblemon.ruins/mossy_oubliette_ruins": "Mossy Oubliette Ruins", + "structure.cobblemon.ruins/rooted_arch_ruins": "Rooted Arch Ruins", + "structure.cobblemon.ruins/rooted_gimmi_tower": "Rooted Gimmi Tower", + "structure.cobblemon.ruins/sunscorched_gimmi_tower": "Sunscorched Gimmi Tower", + "structure.cobblemon.ruins/temperate_gimmi_tower": "Temperate Gimmi Tower", + "structure.cobblemon.ruins/toppled_pillars_ruins": "Toppled Pillars Ruins", + "structure.cobblemon.ruins/unstable_cave_ruins": "Unstable Cave Ruins", + + "the_bumblezone.the_bumblezone": "Bumblezone", + + "structure.minecraft.endcity": "End City", + "structure.minecraft.fortress": "Nether Fortress", + "structure.minecraft.mansion": "Woodland Mansion", + "structure.minecraft.mineshaft": "Mineshaft", + "structure.minecraft.monument": "Ocean Monument", + "structure.minecraft.stronghold": "Stronghold", + "structure.minecraft.temple": "Temple", + "structure.minecraft.village": "Village", + "structure.minecraft.shipwreck": "Shipwreck", + "structure.minecraft.buriedtreasure": "Buried Treasure", + "structure.minecraft.buried_treasure": "Buried Treasure", + "structure.minecraft.ruins": "Ocean Ruins", + "structure.minecraft.pillageroutpost": "Pillager Outpost", + "structure.minecraft.bastionremnant": "Bastion Remnant", + "structure.minecraft.bastion_remnant": "Bastion Remnant", + "structure.minecraft.ruinedportal": "Ruined Portal", + "structure.minecraft.pillager_outpost": "Pillar Outpost", + "structure.minecraft.swamp_hut": "Swamp Hut", + "structure.minecraft.desert_pyramid": "Desert Pyramid", + "structure.minecraft.desert_well": "Desert Well", + "structure.minecraft.jungle_pyramid": "Jungle Pyramid", + "structure.minecraft.ancient_city": "Ancient City", + "structure.minecraft.nether_fossil": "Nether Fossil", + "structure.minecraft.trail_ruins": "Trail Ruins", + + "minecraft.is_void": "Le vide", + "minecraft.is_end": "L'End", + "minecraft.is_nether": "Nether", + + "cobblemon.is_void": "Le vide", + "cobblemon.is_end": "L'End", + "cobblemon.is_nether": "Le Nether", + "cobblemon.is_overworld": "La surface", + + "cobblemon.is_arid": "Biomes arides", + "cobblemon.is_badlands": "Badlands", + "cobblemon.is_bamboo": "Jungle de bambous", + "cobblemon.is_beach": "Plage", + "cobblemon.is_cave": "Caves", + "cobblemon.is_cherry_blossom": "Bosquet de cerisiers", + "cobblemon.is_coast": "Côte", + "cobblemon.is_cold": "Cold Biomes", + "cobblemon.is_cold_ocean": "Océan froid", + "cobblemon.is_deep_dark": "Abîmes", + "cobblemon.is_deep_ocean": "Océan profond", + "cobblemon.is_desert": "Désert", + "cobblemon.is_dripstone": "Cavernes de spéléothèmes", + "cobblemon.is_floral": "Fleurie", + "cobblemon.is_forest": "Forêt", + "cobblemon.is_freezing": "Gelé", + "cobblemon.is_freshwater": "Eau douce", + "cobblemon.is_frozen_ocean": "Océan gelé", + "cobblemon.is_glacial": "Glacial", + "cobblemon.is_grassland": "Prairie", + "cobblemon.is_highlands": "Hauts plateaux", + "cobblemon.is_hills": "Collines", + "cobblemon.is_island": "Ile", + "cobblemon.is_jungle": "Jungle", + "cobblemon.is_lukewarm_ocean": "Océan tiède", + "cobblemon.is_lush": "Luxuriant", + "cobblemon.is_magical": "Biomes magiques", + "cobblemon.is_mountain": "Montagne", + "cobblemon.is_mushroom": "Champignon", + "cobblemon.is_ocean": "Océan", + "cobblemon.is_peak": "Sommet", + "cobblemon.is_plains": "Plaines", + "cobblemon.is_plateau": "Plateau", + "cobblemon.is_river": "Rivière", + "cobblemon.is_sandy": "Ensablé", + "cobblemon.is_savanna": "Savane", + "cobblemon.is_shrubland": "Arbustes", + "cobblemon.is_sky": "Ciel", + "cobblemon.is_snowy": "Enneigé", + "cobblemon.is_snowy_forest": "Forêt enneigée", + "cobblemon.is_snowy_taiga": "Taïga enneigée", + "cobblemon.is_spooky": "Effrayant", + "cobblemon.is_swamp": "Marais", + "cobblemon.is_taiga": "Taïga", + "cobblemon.is_temperate": "Tempéré", + "cobblemon.is_temperate_ocean": "Ocean tempéré", + "cobblemon.is_thermal": "Thermique", + "cobblemon.is_tropical_island": "Ile tropicale", + "cobblemon.is_tundra": "Tundra", + "cobblemon.is_volcanic": "Volcanique", + "cobblemon.is_warm_ocean": "Océan chaud", + + "cobblemon.nether/is_basalt": "Basalte", + "cobblemon.nether/is_crimson": "Carmin", + "cobblemon.nether/is_desert": "Désert (Nether)", + "cobblemon.nether/is_forest": "Forêt (Nether)", + "cobblemon.nether/is_frozen": "Gelé (Nether)", + "cobblemon.nether/is_fungus": "Champignon", + "cobblemon.nether/is_mountain": "Montagne (Nether)", + "cobblemon.nether/is_overgrowth": "Prolifère", + "cobblemon.nether/is_quartz": "Quartz", + "cobblemon.nether/is_soul_fire": "Feu des âmes", + "cobblemon.nether/is_soul_sand": "Sable des âmes", + "cobblemon.nether/is_toxic": "Toxique", + "cobblemon.nether/is_warped": "Biscornu", + "cobblemon.nether/is_wasteland": "Désertique" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/cobbledex/textures/gui/collection/collection_base.png b/common/src/main/resources/assets/cobbledex/textures/gui/collection/collection_base.png index 42cfa6f8ebb07a0a33aeb7ff62fdb50d0076576e..3ee54af3b81849a358bdb0033caa8658f6f134e5 100644 GIT binary patch delta 725 zcmaDU{z80$CF87(R(CnLL~3)NpYzLSbZDBa$SGWZ?E3%evM`~KtO7j#?c!--VkUbk zKW7yrFS`36tmqLp!`lq0SoIx+A|VB`E#eNlg?>BTI(qadP(Q=9Oo`ZKcfQUjW89)V zak5^pUc(Bnl#;`fF3>W%b ze0TZmtY=uXF0QMaMsxZDCXS}(-1qL7TWNK!?qPJWu8F^O zu~VPnzvTbd>( z$C2483|o`~A^v(?W@~5glqo|TXg~+hWlY;&XExnn;t&Gb$Kc#qrO3;$sP6?+gW@7? zhPDnp1_`BI3<)Q`-{fWx2rWPU;EmQIZUw=2aYk+ zRiL(I9eNEB-Iu3m3&t`SxRx*;3A?i_rW0tUCQ$FRM;1@LT*MiCfRY=94{Mq~t#N|* zUqHKX9$f#8j@whJ3vzU}ezOFcsJKEjrt|enHYGlBKekB+D@OZs= z_N-HBm8NnGPKTD5QfPb^H0E-q+?v3%3_#%N>gTe~DWM4fTH7qf delta 726 zcmaDM{!)B`CFAUkR(CnLuGHi{Kj)Xv=x}JVBByZuqwD{w%ff^{vI@xfw~MEViJ9!F z{G3&gylC!&u%buY3~#ffV%2vPintWWwun0j2>o`tb@b>_pnisHnG&(f?qvDwX1F!= zgy(ckafc99qg{zUI~fF8j<|yOQ&jbK0lACTB$m9Fmc2Sv+I-EoOWQUqkGZG9xFEK3 zR>{nwdPbMn%P)?l-by{iD!@KZEmnO`U|;@>V7-H^0wU+d_w39s2@wjHWNs+?v2V*_ z;dq9I`pzmvUWP?|FPIt>7jZMR?TGbf-ZOzsA>+=v<&1gPnL&)>%NvR&;Uk|%kr*YX4uFoU;?y{p-t$klN5uC>_t`vXBTk> z9>G`!1D6uU0~6kF7H3dc^{(&W%}^I{2c2jeA!-Q+@=B886 ze#)|8Xle1>&N?;tU5J@>oD1`V(9jZpaV{$hvuA$0efC_P^Iu&ijN!tnS<8E-s_zK; zS$td8bw;t>I^jF~;$kz37=KLCn(Fm>p3Q~p&#jJK>(mc1y;~H)=%AhDCe9$h7w5r@ d8ju(MGuGH#&eZ>(FrNVkJYD@<);T3K0RSEpB`E*^ diff --git a/common/src/main/resources/assets/cobbledex/textures/gui/collection/item_reward.png b/common/src/main/resources/assets/cobbledex/textures/gui/collection/item_reward.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0e2ab8fbe0b57754f6b304eec226ddfb59606c GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%oCO|{#S9GG!XV7ZFl&wkP;j}Y zi(`mK=i6xqc@G)zxX#xVTTzv)`|N~K3g5L;Yd^6WvQO$_(_675Xz8BC%0FK|f29A; z&pYI=%s+<{k+){ + content.add(CobbledexConstants.COBBLEDEX_ITEM) + }) } } \ No newline at end of file diff --git a/forge/src/main/kotlin/com/rafacasari/mod/cobbledex/forge/CobbledexForge.kt b/forge/src/main/kotlin/com/rafacasari/mod/cobbledex/forge/CobbledexForge.kt index 39f65cd..4b74358 100644 --- a/forge/src/main/kotlin/com/rafacasari/mod/cobbledex/forge/CobbledexForge.kt +++ b/forge/src/main/kotlin/com/rafacasari/mod/cobbledex/forge/CobbledexForge.kt @@ -4,11 +4,13 @@ import com.rafacasari.mod.cobbledex.* import com.rafacasari.mod.cobbledex.commands.CobbledexCommands import com.rafacasari.mod.cobbledex.utils.MiscUtils.logError import com.rafacasari.mod.cobbledex.utils.MiscUtils.logInfo +import net.minecraft.item.ItemGroups import net.minecraft.server.MinecraftServer import net.minecraft.util.Identifier import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.client.event.RegisterClientCommandsEvent import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.event.BuildCreativeModeTabContentsEvent import net.minecraftforge.event.RegisterCommandsEvent import net.minecraftforge.eventbus.api.IEventBus import net.minecraftforge.fml.DistExecutor @@ -54,6 +56,12 @@ class CobbledexForge : CobbledexImplementation { it.register(Identifier(Cobbledex.MOD_ID, "cobbledex_item"), CobbledexConstants.COBBLEDEX_ITEM) } } + + addListener { event -> + if (event.tabKey == ItemGroups.TOOLS) { + event.accept(CobbledexConstants::COBBLEDEX_ITEM) + } + } } } diff --git a/gradle.properties b/gradle.properties index 0ed4004..4f20a06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ mod_id=cobbledex generated_file_name_addon=-1.20.1 archives_base_name=cobbledex-1.20.1 -mod_version=1.0.35 +mod_version=1.0.36 mod_description=A mod to track your progress on Cobblemon. Fabric and Forge compatible. mod_icon=assets/cobbledex/icon.png repository=https://github.com/rafacasari/cobbledex