mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-21 14:46:25 -04:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
263bccca4b | ||
|
|
1d94adface | ||
|
|
c741ddbc2e | ||
|
|
8cad44ffb1 | ||
|
|
dec0376d11 | ||
|
|
007b2a49f4 | ||
|
|
082683723d |
+43
-219
@@ -1,196 +1,52 @@
|
||||
# Changelog
|
||||
## [1.7.0 (Month xth, 2025)](#1-7-0)
|
||||
## [1.6.1 (Release TBD)](#1-6-1)
|
||||
|
||||
### Additions
|
||||
- Added an in-game configuration screen, allowing all settings from `main.json` to be edited directly in-game.
|
||||
- Added `/cobblemonconfig reload` command to reload `main.json` configuration. **Note:** Some settings require a server restart to take effect; use this command cautiously.
|
||||
- Added `blacklisted_items_to_hold` and `whitelisted_items_to_hold` tags to allow for controlling which items players can give to their Pokémon. If the whitelist is empty, it will consider all item as allowed (unless they are in the blacklist).
|
||||
- Pokémon now follow the mouse cursor on the Summary screen, with an option to disable this in the settings.
|
||||
- Pokémon's held items can now be rendered, with a visibility toggle in the Summary screen.
|
||||
- Added cosmetic item functionality for Pokémon. Certain cosmetic items can be given to applicable Pokémon via the interact menu.
|
||||
- Added the various log blocks as cosmetic items for Timburr and Komala.
|
||||
- Added `visibility/hidden`, `visibility/hat` and `visibility/face` tags to control where and how certain items are rendered.
|
||||
|
||||
### Changes
|
||||
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
|
||||
- Made Blocks of Gold count as Big Nuggets when held by a Pokémon (for Fling functionality)
|
||||
- Substantially optimised spawning checks mainly by front-loading biome filtering.
|
||||
|
||||
### Fixes
|
||||
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
|
||||
- Fixed PCs always opening at box 2 instead of box 1.
|
||||
- Fixed not being able to do complex item requirements aside from just NBT with evolution conditions, requirements and fossil items.
|
||||
- Fixed the usage `hiddenability` in `pokegive` or other spawn commands resulting in a forced hidden ability
|
||||
- Fixed the consumption of friendship berries (or EV berries) not making any noise
|
||||
- Fixed Instantly breaking and replacing a fossil analyzer with any block entity crashing the game in a complete multi-structure
|
||||
- Fixed players getting disconnected when sidemods update a Pokémon's teratype
|
||||
- Fixed fling not using Item Names for minecraft held items that substitute Pokémon items
|
||||
- Fixed evolutions sometimes preventing players from logging in to servers
|
||||
- Fixed rendering of shoulder-mounted Pokémon desyncing between clients
|
||||
- Fixed apricorn chest boats forgetting their inventories when being unloaded
|
||||
- Fixed moves not updating correctly between form changes resulting in illegal movesets
|
||||
- Fixed crash sometimes occurring with the "Oritech" mod
|
||||
- Fixed crashes due to an incorrect Java version handing out an obscure crash.
|
||||
- Fixed some berries being able to rarely get too many berries and cause a crash.
|
||||
- Fixed status curing berries not playing the berry eating sound, same for healing berries used mid-battle.
|
||||
- Fixed owned Pokémon sometimes being un-interactable after the player relogs fast
|
||||
- Fixed field name in evolution requirements for Spewpa Pokeball.
|
||||
- Fixed LevelUpCriterion logic to correctly check that the Pokémon is a preEvo.
|
||||
- Fixed `hide_additional_tooltip` vanilla flag not properly hiding tooltips on pokerod and bait items
|
||||
|
||||
### Developer
|
||||
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
|
||||
- Dialogues are correctly removed from memory when they are stopped.
|
||||
- Dialogues with variably-set initial pages now properly start timeout tracking.
|
||||
- Added `EvGainedEvent.Pre` and `EvGainedEvent.Post`.
|
||||
- Deprecated `EVs#add(Stat, Int)`, you will not be able to compile against this code please migrate to the `EVs#add(Stat, Int, EvSource)` you most likely want to use `SidemodEvSource` but please check other implementations or make your own.
|
||||
- Removed the NbtItemPredicate class, all the mod usages now use the vanilla item predicate solution, this causes breaking changes on Fossil, HeldItemRequirement & ItemInteractionEvolution
|
||||
- Renamed Cobblemon's creative tabs to start with "Cobblemon: " to distinguish Cobblemon's tabs from tabs for other mods.
|
||||
- Various items now have a rarity value.
|
||||
|
||||
### Changes
|
||||
- When using the `cobblemon` or `generation_9` capture calculators a critical capture with a single shake will always play for successful captures when you've already registered the Pokémon as caught in your Pokédex.
|
||||
|
||||
### MoLang & Datapacks
|
||||
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
|
||||
- The `requiredContext` for an item interaction evolution
|
||||
- The `itemCondition` for a held item evolution requirement
|
||||
- The `fossils` for a fossil entry
|
||||
- Added MoLang flows for `poke_ball_capture_calculated`, `evolution_tested`, `evolution_accepted`, `evolution_completed`
|
||||
- Added `interpolate` boolean property to animated textures to allow gradual colour changes between frames.
|
||||
|
||||
## [1.6.1 (January 26th, 2025)](#1-6-1)
|
||||
|
||||
### Additions
|
||||
- Added crossover paintings from Close Combat: Premonition, Altar, Slumber, and Nomad.
|
||||
- Added Galarica Nuts, used for crafting Galarica Cuffs and Wreaths. Dropped from certain Pokémon. Take a wild guess which.
|
||||
- Added compatibility with Repurposed Structures. (Thank you, TelepathicGrunt!)
|
||||
- Added an evolution method for Karrablast to evolve into Escavalier in singleplayer.
|
||||
- Pokédexes can now be placed in Chiseled Bookshelves.
|
||||
- Added optional box argument to the /pc command.
|
||||
- Pokédex and Dialogue screens now close when the inventory keybind is pressed.
|
||||
- Added config setting `maxPokedexScanningDetectionRange` to control from what distance the player can scan Pokémon using the Pokédex.
|
||||
- Added the `is_standing_on_blocks(depth, blocks...)` MoLang function, which returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
|
||||
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
|
||||
- Added debug renderer for posable entity locators.
|
||||
|
||||
### Pokémon Added
|
||||
|
||||
#### Gen 5
|
||||
- Ducklett
|
||||
- Swanna
|
||||
- Shelmet
|
||||
- Accelgor
|
||||
- Karrablast
|
||||
- Escavalier
|
||||
- Rufflet
|
||||
- Braviary
|
||||
- Foongus
|
||||
- Amoonguss
|
||||
|
||||
#### Gen 6
|
||||
- Binacle
|
||||
- Barbaracle
|
||||
|
||||
#### Gen 7
|
||||
- Dewpider
|
||||
- Araquanid
|
||||
- Alolan Geodude
|
||||
- Alolan Graveler
|
||||
- Alolan Golem
|
||||
|
||||
#### Gen 8
|
||||
- Galarian Slowpoke
|
||||
- Galarian Slowbro
|
||||
- Galarian Slowking
|
||||
|
||||
#### Gen 9
|
||||
- Paldean Tauros
|
||||
|
||||
### Added cries to the following Pokémon
|
||||
- All Nidorans
|
||||
- Shellder, Cloyster
|
||||
- Pinsir
|
||||
- Tyrogue, Hitmontop
|
||||
- Spinda
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Primeape
|
||||
- Munchlax
|
||||
- Snorlax
|
||||
- Poliwrath
|
||||
- Goldeen
|
||||
- Seaking
|
||||
- Dondozo
|
||||
- Wobbuffet
|
||||
- Charcadet
|
||||
- Armarouge
|
||||
- Ceruledge
|
||||
- Geodude
|
||||
- Graveler
|
||||
- Golem
|
||||
- Sandile
|
||||
- Krokorok
|
||||
- Krookodile
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Slowpoke
|
||||
- Slowbro
|
||||
- Slowking
|
||||
- Eiscue
|
||||
- Tauros
|
||||
- Goldeen
|
||||
- Seaking
|
||||
- Charcadet
|
||||
- Armarouge
|
||||
- Ceruledge
|
||||
- Pinsir
|
||||
- Geodude
|
||||
- Graveler
|
||||
- Golem
|
||||
|
||||
### Cry updates for the following Pokémon
|
||||
- Sceptile
|
||||
- Added molang particle queries for getting distance to targeted entities.
|
||||
- Added debug renderer for poseable entity locators.
|
||||
- Added `baseScale` property to NPCs.
|
||||
- Added the player to `PokerodReelEvent`.
|
||||
- Pokédex and Dialogue API screens now close when the inventory keybind is pressed.
|
||||
- Added Galarica Nuts, used for crafting Galarica Cuffs and Wreaths. Dropped from certain Pokémon.
|
||||
- Added specific compatibility with Repurposed Structures. (Thank you, TelepathicGrunt!)
|
||||
|
||||
### Changes
|
||||
- Completely re-synced Pokémon move and stat data based on later games. Learnsets have changed considerably to maximise available moves.
|
||||
- Pokémon will now be dynamically revealed to the Pokédex as they're seen in battle instead of revealing entire parties at the end of battle.
|
||||
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to match how the battle UI shows the actual species name.
|
||||
- Pokémon will now be dynamically revealed to the Pokédex as they're seen instead of revealing entire parties at the end of battle regardless.
|
||||
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to reflect the battle UI showing the actual species name.
|
||||
- Pokémon under the illusion effect will reveal their disguise to the Pokédex first and then the base Pokémon once the disguise is broken.
|
||||
- Berries will now drop from berry trees if broken at age 0 so you aren't punished for mistaken planting.
|
||||
- Increased Fortune drops on Mint Seeds.
|
||||
- Updated Slowpoke's shiny texture.
|
||||
- Updated drops for many Pokémon.
|
||||
- Adjusted the evolution sound to match the timing of the particle effect.
|
||||
- Made berry trees shear-able by dispenser blocks. I'm sure nobody will make unholy contraptions with this.
|
||||
- Edited some recipes to utilize tags instead of direct item IDs, for better mod compatibility.
|
||||
- Added more support for a variety of Fabric/NeoForge conventional tags.
|
||||
- Reformatted some tags to be more consistent.
|
||||
|
||||
### Fixes
|
||||
- Fixed Pokédex sometimes crashing when switching forms.
|
||||
- Fixed Pokédex interface not transitioning out when closed.
|
||||
- Fixed texture dimensions for the player and Pokémon interact interface.
|
||||
- Fixed crash related to Tom's Simple Storage mod and the Fossil Machine.
|
||||
- Fixed texture dimensions for the interact interface.
|
||||
- Fixed crash related to Tom's Simple Storage mod and Fossil Machine.
|
||||
- Fixed not being able to retrieve a fossil from the Fossil Machine with an empty hand.
|
||||
- Fixed Pokémon being collidable (collidible? collissionable? kaleidoscopable?) while being captured by a Poké Ball.
|
||||
- Fixed Pokémon being collidable while being captured by a Poké Ball.
|
||||
- Fixed `full_party`, `own_zangoose_seviper`, `use_revive` and `use_candy` Advancement triggers.
|
||||
- Fixed `healing_machine` Advancement by using the correct 1.21 trigger.
|
||||
- Fix Display Cases not dropping items if destroyed through explosions.
|
||||
- Fixed an issue where the first Pokémon in the pastured Pokémon list clipped into the interface.
|
||||
- Fixed all Pokémon facing South on spawn.
|
||||
- Fixed bait being consumed even when not reeling in any Pokémon.
|
||||
- Parametric particle motion now works.
|
||||
- Event spawned particles now work.
|
||||
- Particles can now have independent coordinate spaces.
|
||||
- Fixed bait being consumed when not reeling in any Pokémon.
|
||||
- Fixed Miltank milk magically disappearing out of your bucket.
|
||||
- Fixed Pokémon nicknames migrating from 1.5.2 not being displayed properly.
|
||||
- Fixed capitalization in one of our config options. It was a very important fix. Very important. Old configs are fine.
|
||||
- Fixed Poké Rods not working if Lure or Luck of the Sea enchantments get removed by other mods.
|
||||
- Fixed crashes related to Pokémon when they are ready to evolve while holding an enchanted item. Very specific.
|
||||
- Fixed a crash that sometimes occurred when evolving Nincada.
|
||||
- Fixed Cobblemon plants not being compostable on NeoForge.
|
||||
- Fixed capitalization in one of our config fields, but allowing typo'd version to still be valid.
|
||||
- Fixed Poké Rods not working if lure or luck of the sea enchantments get removed by other mods.
|
||||
- Fixed crashes related to Pokémon when they are ready to evolve while holding an enchanted item.
|
||||
- Fixed crashes that sometimes occur when evolving Nincada.
|
||||
- Fixed plants not being compostible on NeoForge.
|
||||
- Fixed hide UI (F1 key) not hiding the party overlay.
|
||||
- Fixed NPC MoLang command `player_lose_command` not working.
|
||||
- Fixed misaligned tooltips with edit boxes in the NPC editor screen.
|
||||
- Corrected misaligned tooltips with editboxes in the NPC editor screen.
|
||||
- Fixed Pokémon riding two boats when attempting to deploy a platform on water.
|
||||
- Fixed the summary screen showing there's experience to reach the next level when they are at the level cap.
|
||||
- Made berry trees be shearable by dispenser blocks.
|
||||
- Fixed the summary screen showing there's experience to reach the next level when at level cap.
|
||||
- Fixed Pokémon forgetting moves when evolving on specific cases.
|
||||
- Fixed Adorn compatibility, including improvements when using JEI/REI (Apricorn items now show up under the collapsed entries rather than standalone).
|
||||
- Fixed error message appearing on battle log when using Solar Beam with Sunny Day.
|
||||
@@ -198,68 +54,35 @@
|
||||
- Fixed `/pokedex grant all` command not giving male/female/shininess completion for some Pokémon.
|
||||
- Fixed `/pokedex grant only` and `/pokedex remove only` not respecting the form parameter passed.
|
||||
- Fixed variant forms appearing incorrectly in the Pokédex when the normal form had not been unlocked.
|
||||
- Fixed Pokémon occasionally being shot into the sky during battle. No Pokémon were harmed by this bug, probably.
|
||||
- Fixed Pokémon occasionally being shot into the sky during battle.
|
||||
- Fixed NPC editing GUI not updating aspects until a game restart.
|
||||
- Fixed some users being unable to open their PC if a Pokémon in it had a lot of PP raises beyond normal bounds. How did you get those, anyway? Tell me or the Bellossom gets it.
|
||||
- Fixed some color variants (Dubwool, Conkeldurr and Undyed wooloo) being missing in the Pokédex.
|
||||
- Fixed invalid species or held items causing Players to not be able to load into their world anymore (commonly happening after removing addons/mods).
|
||||
- Fix some users being unable to open their PC if a Pokémon in said PC had a lot of pp raises beyond normal bounds
|
||||
- Fix some color variants (dubwool, conkeldurr and undyed wooloo) missing in the Pokédex
|
||||
- Fix invalid species or held_items causing Players to not be able to load into their world anymore (commonly happening after removing addons/mods)
|
||||
- Fixed Wooloo variants not being automatically registered in the owner's Pokédex when dyed.
|
||||
- Fixed Vivichoke Dip and Leek & Potato Stew not returning a bowl upon consumption.
|
||||
- Fixed Fossil Restoration Tank not accepting Hay Bales as organic material.
|
||||
- Fixed Potion items applying double their intended healing value.
|
||||
- Fixed Fast Ball capture bonuses applying to all Pokémon, making it the Best Ball instead of the Mediocre Edge-Case Ball.
|
||||
- Fixed "learned new move" messages appearing for already-known moves on Pokémon evolutions.
|
||||
- Fixed Pokémon Item Models breaking shadows nearby when being placed in Display Cases or Item Frames.
|
||||
- Fixed berries not giving bonus yields when planted in their preferred biomes. I'm sure we've fixed that 5 times now.
|
||||
- Fixed the NeoForge version not supporting "SodiumDynamicLights".
|
||||
- Fixed players disconnecting from servers if they made changes to certain config options.
|
||||
- Fixed players with shouldered Pokémon not being able to rejoin their 1.5.2 worlds using 1.6.
|
||||
- Fixed `PokemonProperties` utilizing `ability=<some ability>` being treated as a forced ability even when it is a legal ability for the Pokémon.
|
||||
- Fixed type formatting in Pokédex scanner mode when dual types require two lines.
|
||||
- Fixed trading sometimes crashing the game or server.
|
||||
- Fixed Wild shiny sounds not respecting the `shinyNoticeParticlesDistance` config setting.
|
||||
- Fixed Pokémon being able to evolve mid-battle.
|
||||
- Fixed NPC held items being able to be stolen by players. Don't be a thief!
|
||||
- Fixed evolutions that require a held item consuming it as soon as meeting requirements when it should only be consumed upon evolution.
|
||||
- Fixed Pokémon showing only the default form when selecting them as a target in battle.
|
||||
- Fixed a possible error coming out of reeling fishing rods in specific situations.
|
||||
- Fixed incorrect weights being used when Poké Fishing with Luck of the Sea.
|
||||
- Parametric particle motion now works.
|
||||
- Event-spawned particles now work.
|
||||
- Particles can now have independent coordinate spaces.
|
||||
- Fixed Vivichoke Dip and Leek and Potato Stew not returning a bowl upon consumption.
|
||||
- Fixed Fossil Restoration Machine not accepting Hay Bales.
|
||||
- Fixed Potion items so that they no longer apply over double their intended healing value.
|
||||
|
||||
### Developer
|
||||
- Updated the Pokédex data updated events to always include a `Pokemon` instance, and optionally a `DisguiseData` instance.
|
||||
- Updated fields in `SpawnNPCPacket` and `SpawnPokemonPacket` to be visible and mutable.
|
||||
- Updated `UnvalidatedPlaySoundS2CPacket` to be public instead of internal and made its fields mutable.
|
||||
- Added `hideNameTag` field and `HideNPCNameTag` nbt tag to `NPCEntity` to allow hiding the name tag of the NPC.
|
||||
- Added the player to `PokerodReelEvent` so you know who is doing the reeling.
|
||||
|
||||
### MoLang & Datapacks
|
||||
### Molang & Datapacks
|
||||
- Added flows for:
|
||||
- `forme_change`: Triggered when a Pokémon changes form in battle.
|
||||
- `mega_evolution`: Triggered when a Pokémon mega evolves in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `zpower_used`: Triggered when a Pokémon uses a Z-Power move in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `terastallization`: Triggered when a Pokémon terastallizes in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `mega_evolution`: Triggered when a Pokémon mega evolves in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `zpower_used`: Triggered when a Pokémon uses a Z-Power move in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `terastallization`: Triggered when a Pokémon terastallizes in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `battle_fainted`: Triggered when a Pokémon faints in battle.
|
||||
- `battle_fled`: Triggered when a player flees from battle.
|
||||
- `battle_fled`: Triggered when a Player flees from battle.
|
||||
- `battle_started_pre`: Triggered when a battle starts. Cancelable!
|
||||
- `battle_started_post`: Triggered when a battle starts.
|
||||
- `apricorn_harvested`: Triggered when an Apricorn is harvested.
|
||||
- `apricorn_harvested`: Triggered when an apricorn is harvested.
|
||||
- `thrown_pokeball_hit`: Triggered when a thrown Pokéball hits a Pokémon.
|
||||
- `level_up`: Triggered when a Pokémon levels up.
|
||||
- `pokemon_fainted`: Triggered when a Pokémon faints.
|
||||
- `pokemon_gained`: Triggered when a player gains a Pokémon.
|
||||
- Added MoLang functions:
|
||||
- `pokemon_gained`: Triggered when a Player gains a Pokémon.
|
||||
- Added molang functions:
|
||||
- For Pokémon:
|
||||
- `pokemon.apply(PokemonProperties)`: Applies the given properties to the Pokémon.
|
||||
- `pokemon.owner`: Returns the owner of the Pokémon or 0.0 if there is no owner or they are not online.
|
||||
- For all entities:
|
||||
- `entity.is_standing_on_blocks(depth, blocks...)`: Returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
|
||||
- Added NPC field:
|
||||
- `hideNameTag`: Hides the name tag of the NPC.
|
||||
- Added `baseScale` property to NPCs.
|
||||
- Added MoLang particle queries for getting distance to targeted entities.
|
||||
|
||||
## [1.6.0 - The Record Catch Update (December 25th, 2024)](#1-6-0)
|
||||
#### "Now that there's a fishing mechanic, the mod is actually good!"
|
||||
@@ -2162,4 +1985,5 @@ Thank you so much to all of our community translators that bring the mod to the
|
||||
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
|
||||
|
||||
## [1.0.0 (November 12th, 2022)](#1-0-0)
|
||||
- Initial release.
|
||||
- Initial release.
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
id("java-gradle-plugin")
|
||||
kotlin("jvm") version "2.1.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("net.neoforged:moddev-gradle:2.0.75")
|
||||
implementation("dev.architectury:at:1.0.1")
|
||||
implementation("net.fabricmc:access-widener:2.1.0")
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("cobblemongradle") {
|
||||
id = "com.cobblemon.gradle"
|
||||
implementationClass = "com.cobblemon.gradle.CobblemonGradle"
|
||||
version = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.cobblemon.gradle
|
||||
|
||||
import com.cobblemon.gradle.extension.CobblemonGradleExtension
|
||||
import com.cobblemon.gradle.extension.tasks.ConvertAccessWidenersTask
|
||||
import com.cobblemon.gradle.extension.tasks.UnzipAccessWidenersTask
|
||||
import net.neoforged.nfrtgradle.CreateMinecraftArtifacts
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
|
||||
class CobblemonGradle : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val cobblemonExtension = project.extensions.create(
|
||||
CobblemonGradleExtension.EXTENSION_NAME,
|
||||
CobblemonGradleExtension::class.java
|
||||
)
|
||||
|
||||
//This exists because all of
|
||||
// - com.cobblemon:mod
|
||||
// - com.cobblemon:mod-resources
|
||||
// - com.cobblemon:accesswidener
|
||||
//technically point to the same dependency (the :common project). To pick the proper artifact from that project
|
||||
//we set attributes in that project and check for them here.
|
||||
val accessWideners = project.configurations.register("accessWidener") { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = true
|
||||
configuration.isCanBeDeclared = true
|
||||
configuration.attributes {
|
||||
it.attribute(
|
||||
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
|
||||
project.objects.named(LibraryElements::class.java, LibraryElements.OBJECTS)
|
||||
)
|
||||
}
|
||||
}
|
||||
val includeRootResources = project.configurations.register("includeRootResources") { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = true
|
||||
configuration.isCanBeDeclared = true
|
||||
configuration.attributes {
|
||||
it.attribute(
|
||||
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
|
||||
project.objects.named(LibraryElements::class.java, LibraryElements.RESOURCES)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val unzipAwTask = project.tasks.register("unzipAccessWideners", UnzipAccessWidenersTask::class.java) {
|
||||
it.accessWidenerZips = accessWideners.get()
|
||||
}
|
||||
|
||||
|
||||
val convertAwTask = project.tasks.register(ConvertAccessWidenersTask.NAME, ConvertAccessWidenersTask::class.java) {
|
||||
it.enabled = cobblemonExtension.convertAccessWideners
|
||||
it.dependsOn(unzipAwTask)
|
||||
it.accessWideners = project.files(unzipAwTask).plus(project.files(cobblemonExtension.additionalAccessWideners))
|
||||
}
|
||||
|
||||
//Add root resources and access wideners to output jar
|
||||
project.tasks.named("processResources", ProcessResources::class.java) { task ->
|
||||
task.dependsOn(includeRootResources)
|
||||
if (cobblemonExtension.convertAccessWideners) {
|
||||
task.dependsOn(convertAwTask)
|
||||
task.from(convertAwTask)
|
||||
}
|
||||
else {
|
||||
task.dependsOn(unzipAwTask)
|
||||
task.from(unzipAwTask)
|
||||
}
|
||||
task.doLast {
|
||||
project.copy {
|
||||
it.from(project.provider {
|
||||
includeRootResources.get().resolve().map { project.zipTree(it) }
|
||||
})
|
||||
it.into(task.destinationDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.withType(CreateMinecraftArtifacts::class.java) {
|
||||
it.dependsOn(convertAwTask)
|
||||
it.accessTransformers.from(convertAwTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.cobblemon.gradle.extension
|
||||
|
||||
import org.gradle.api.file.FileCollection
|
||||
|
||||
abstract class CobblemonGradleExtension {
|
||||
var additionalAccessWideners: FileCollection? = null
|
||||
var convertAccessWideners = true
|
||||
|
||||
companion object {
|
||||
const val EXTENSION_NAME = "cobblemon"
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.cobblemon.gradle.extension.tasks
|
||||
|
||||
import dev.architectury.at.AccessChange
|
||||
import dev.architectury.at.AccessTransform
|
||||
import dev.architectury.at.AccessTransformSet
|
||||
import dev.architectury.at.ModifierChange
|
||||
import dev.architectury.at.io.AccessTransformFormats
|
||||
import net.fabricmc.accesswidener.AccessWidenerReader
|
||||
import net.fabricmc.accesswidener.AccessWidenerVisitor
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.Writer
|
||||
import java.nio.file.Files
|
||||
|
||||
abstract class ConvertAccessWidenersTask : DefaultTask() {
|
||||
abstract var accessWideners: FileCollection
|
||||
@InputFiles get
|
||||
|
||||
@Internal
|
||||
val accessTransformerDir = project.layout.buildDirectory.dir("access-transformers")
|
||||
|
||||
@OutputFiles
|
||||
val accessTransformers = project.files ({
|
||||
accessWideners.files.map {
|
||||
accessTransformerDir.get().file(it.name.replace("accesswidener", "accesstransformer.cfg"))
|
||||
}
|
||||
})
|
||||
|
||||
@TaskAction
|
||||
fun convertAccessWideners() {
|
||||
accessWideners.files.forEach { file ->
|
||||
val awFile = Files.newBufferedReader(file.toPath())
|
||||
val result = AccessTransformSet.create();
|
||||
|
||||
AccessWidenerReader(object : AccessWidenerVisitor {
|
||||
override fun visitClass(name: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(name).merge(toAt(access));
|
||||
}
|
||||
|
||||
override fun visitMethod(owner: String, name: String, descriptor: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(owner).mergeMethod(MethodSignature.of(name, descriptor), toAt(access));
|
||||
}
|
||||
|
||||
override fun visitField(owner: String, name: String, descriptor: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(owner).mergeField(name, toAt(access));
|
||||
}
|
||||
}).read(awFile)
|
||||
|
||||
val outputFile = accessTransformerDir.get().file(
|
||||
file.name.replace("accesswidener", "accesstransformer.cfg")
|
||||
)
|
||||
var outputWriter: Writer? = null
|
||||
try {
|
||||
outputWriter = outputFile.asFile.writer()
|
||||
AccessTransformFormats.FML.write(outputWriter, result)
|
||||
}
|
||||
finally {
|
||||
outputWriter?.flush()
|
||||
outputWriter?.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun toAt(access: AccessWidenerReader.AccessType): AccessTransform {
|
||||
return when (access) {
|
||||
AccessWidenerReader.AccessType.ACCESSIBLE -> AccessTransform.of(AccessChange.PUBLIC)
|
||||
AccessWidenerReader.AccessType.EXTENDABLE, AccessWidenerReader.AccessType.MUTABLE -> AccessTransform.of(
|
||||
AccessChange.PUBLIC,
|
||||
ModifierChange.REMOVE
|
||||
)
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
const val NAME = "convertAccessWideners"
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.cobblemon.gradle.extension.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class UnzipAccessWidenersTask : DefaultTask() {
|
||||
abstract var accessWidenerZips: FileCollection
|
||||
@InputFiles get
|
||||
|
||||
@OutputFiles
|
||||
val outputFiles = project.provider {
|
||||
project.files(accessWidenerZips.flatMap { zip ->
|
||||
project.zipTree(zip).files.map { OUTPUT_DIR.get().file(it.name) }
|
||||
})
|
||||
}
|
||||
|
||||
@Internal
|
||||
val OUTPUT_DIR = project.layout.buildDirectory.dir("cobblemon-working/access-wideners")
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
project.copy {
|
||||
it.from(accessWidenerZips.map(project::zipTree))
|
||||
it.into(OUTPUT_DIR)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,12 +1,14 @@
|
||||
plugins {
|
||||
id("cobblemon.root-conventions")
|
||||
//id("cobblemon.root-conventions")
|
||||
id ("net.nemerosa.versioning") version "3.1.0"
|
||||
}
|
||||
|
||||
version = "${project.property("mod_version")}+${project.property("mc_version")}"
|
||||
|
||||
val isSnapshot = project.property("snapshot")?.equals("true") ?: false
|
||||
/*
|
||||
if (isSnapshot) {
|
||||
val fixedBranchName = versioning.info.branch.substringAfter("/")
|
||||
version = "$version-${fixedBranchName}-${versioning.info.build}"
|
||||
}
|
||||
*/
|
||||
+90
-54
@@ -1,68 +1,102 @@
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
|
||||
/*
|
||||
*
|
||||
* * 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("cobblemon.base-conventions")
|
||||
id("cobblemon.publish-conventions")
|
||||
|
||||
id("net.kyori.blossom")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
id("net.nemerosa.versioning") version "3.1.0"
|
||||
kotlin("jvm") version "2.1.0"
|
||||
id ("net.neoforged.moddev") version "2.0.75"
|
||||
id("net.kyori.blossom") version "2.1.0"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("com.cobblemon.gradle")
|
||||
}
|
||||
|
||||
architectury {
|
||||
common("neoforge", "fabric")
|
||||
cobblemon {
|
||||
additionalAccessWideners = files(sourceSets.main.get().resources).filter { it.extension == "accesswidener" }
|
||||
}
|
||||
|
||||
val rootResources = configurations.create("rootResources") {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.RESOURCES))
|
||||
}
|
||||
}
|
||||
|
||||
val accessWidenerExport = configurations.create("accessWidenerExport") {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
exclude("*.accesswidener")
|
||||
}
|
||||
|
||||
tasks.create<Zip>("zipResources") {
|
||||
dependsOn("processResources")
|
||||
from(tasks.processResources.get().destinationDir)
|
||||
this.archiveBaseName = "mod-resources"
|
||||
}
|
||||
|
||||
tasks.create<Zip>("zipAccessWideners") {
|
||||
from(sourceSets.main.get().resources)
|
||||
include("*.accesswidener")
|
||||
this.archiveBaseName = "mod-accesswideners"
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
archiveBaseName = "mod"
|
||||
manifest {
|
||||
attributes(mapOf("FMLModType" to "GAMELIBRARY"))
|
||||
}
|
||||
exclude {
|
||||
it.file in tasks.processResources.get().outputs.files
|
||||
}
|
||||
}
|
||||
|
||||
tasks.assemble {
|
||||
dependsOn(tasks.named("zipResources"))
|
||||
dependsOn(tasks.named("zipAccessWideners"))
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("rootResources", tasks.getByName<Zip>("zipResources"))
|
||||
add("accessWidenerExport", tasks.getByName("zipAccessWideners"))
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven(url = "${rootProject.projectDir}/deps")
|
||||
maven(url = "https://api.modrinth.com/maven")
|
||||
maven(url = "https://maven.neoforged.net/releases")
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven("https://maven.fabricmc.net/")
|
||||
maven("https://maven.blamejared.com/")
|
||||
maven("https://api.modrinth.com/maven")
|
||||
maven(url = "../deps")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.bundles.kotlin)
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.molang)
|
||||
|
||||
// Integrations
|
||||
compileOnlyApi(libs.jei.api)
|
||||
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
compileOnly(libs.bundles.mongo)
|
||||
compileOnly(libs.bundles.kotlin)
|
||||
compileOnly(libs.molang)
|
||||
compileOnly(libs.graal)
|
||||
compileOnly(libs.jei.api)
|
||||
compileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
isTransitive = false
|
||||
}
|
||||
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
|
||||
// Showdown
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
// Data Storage
|
||||
modCompileOnly(libs.bundles.mongo)
|
||||
|
||||
// Unit Testing
|
||||
compileOnly("net.fabricmc:sponge-mixin:0.15.5+mixin.0.8.7")
|
||||
compileOnly("io.github.llamalad7:mixinextras-fabric:0.4.1")
|
||||
testImplementation(libs.bundles.unitTesting)
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
setEvents(listOf("failed"))
|
||||
setExceptionFormat("full")
|
||||
}
|
||||
neoForge {
|
||||
neoFormVersion = "1.21.1-20240808.144430"
|
||||
interfaceInjectionData.from("src/main/resources/interfaces.json")
|
||||
validateAccessTransformers = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -72,7 +106,7 @@ sourceSets {
|
||||
fun generateLicenseHeader() : String {
|
||||
val builder = StringBuilder()
|
||||
builder.append("/*\n")
|
||||
rootProject.file("HEADER").forEachLine {
|
||||
project.projectDir.parentFile.resolve("HEADER").forEachLine {
|
||||
if(it.isEmpty()) {
|
||||
builder.append(" *").append("\n")
|
||||
} else {
|
||||
@@ -85,12 +119,14 @@ sourceSets {
|
||||
|
||||
property("license", generateLicenseHeader())
|
||||
property("modid", "cobblemon")
|
||||
property("version", project.version())
|
||||
property("isSnapshot", if(rootProject.isSnapshot()) "true" else "false")
|
||||
property("version", project.version as String)
|
||||
property("isSnapshot", "true")
|
||||
/*
|
||||
property("gitCommit", versioning.info.commit)
|
||||
property("branch", versioning.info.branch)
|
||||
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
|
||||
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
|
||||
/*
|
||||
*
|
||||
* * 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("cobblemon.base-conventions")
|
||||
id("cobblemon.publish-conventions")
|
||||
|
||||
id("net.kyori.blossom")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
id("net.nemerosa.versioning") version "3.1.0"
|
||||
}
|
||||
|
||||
architectury {
|
||||
common("neoforge", "fabric")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven(url = "${rootProject.projectDir}/deps")
|
||||
maven(url = "https://api.modrinth.com/maven")
|
||||
maven(url = "https://maven.neoforged.net/releases")
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.bundles.kotlin)
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.molang)
|
||||
|
||||
// Integrations
|
||||
compileOnlyApi(libs.jei.api)
|
||||
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
isTransitive = false
|
||||
}
|
||||
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
|
||||
// Showdown
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
// Data Storage
|
||||
modCompileOnly(libs.bundles.mongo)
|
||||
|
||||
// Unit Testing
|
||||
testImplementation(libs.bundles.unitTesting)
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
setEvents(listOf("failed"))
|
||||
setExceptionFormat("full")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
blossom {
|
||||
kotlinSources {
|
||||
fun generateLicenseHeader() : String {
|
||||
val builder = StringBuilder()
|
||||
builder.append("/*\n")
|
||||
rootProject.file("HEADER").forEachLine {
|
||||
if(it.isEmpty()) {
|
||||
builder.append(" *").append("\n")
|
||||
} else {
|
||||
builder.append(" * ").append(it).append("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return builder.append(" */").append("\n").toString()
|
||||
}
|
||||
|
||||
property("license", generateLicenseHeader())
|
||||
property("modid", "cobblemon")
|
||||
property("version", project.version())
|
||||
property("isSnapshot", if(rootProject.isSnapshot()) "true" else "false")
|
||||
property("gitCommit", versioning.info.commit)
|
||||
property("branch", versioning.info.branch)
|
||||
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
|
||||
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
[versions]
|
||||
# Kotlin
|
||||
kotlin = "2.0.0"
|
||||
|
||||
# Plugins
|
||||
licenser = "0.6.1"
|
||||
shadow = "8.1.1"
|
||||
blossom = "2.1.0"
|
||||
idea-ext = "1.1.7"
|
||||
|
||||
# Loom
|
||||
loom = "1.7-SNAPSHOT"
|
||||
architectury-plugin = "3.4-SNAPSHOT"
|
||||
|
||||
# Common
|
||||
molang = "1.1.18"
|
||||
graal = "22.3.0"
|
||||
icu4j = "71.1"
|
||||
jei-api = "19.8.2.99"
|
||||
|
||||
# Fabric
|
||||
fabric-loader = "0.16.5"
|
||||
fabric-api = "0.104.0+1.21.1"
|
||||
fabric-kotlin = "1.11.0+kotlin.2.0.0"
|
||||
fabric-permissions-api = "0.2-SNAPSHOT"
|
||||
lambDynamicLights = "3.0.1+1.21.1"
|
||||
debugutils-fabric = "1.21-1.0.6-fabric"
|
||||
|
||||
# NeoForge
|
||||
neoforge = "21.1.66"
|
||||
neo-kotlin-for-forge = "5.5.0"
|
||||
debugutils-forge = "1.21-1.0.6-neoforge"
|
||||
|
||||
# Data Storage
|
||||
mongo = "4.10.2"
|
||||
|
||||
# Testing
|
||||
junit = "5.9.0"
|
||||
mockito = "5.2.0"
|
||||
mockk = "1.12.1"
|
||||
classgraph = "4.8.153"
|
||||
|
||||
[libraries]
|
||||
# General Buildscript Plugins
|
||||
kotlin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||
loom = { group = "dev.architectury", name = "architectury-loom", version.ref = "loom" }
|
||||
architectury = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" }
|
||||
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
|
||||
blossom = { group = "net.kyori", name = "blossom", version.ref = "blossom" }
|
||||
ideaExt = { group = "org.jetbrains.gradle.plugin.idea-ext", name = "org.jetbrains.gradle.plugin.idea-ext.gradle.plugin", version.ref = "idea-ext"}
|
||||
licenser = { group = "gradle.plugin.org.cadixdev.gradle", name = "licenser", version.ref = "licenser" }
|
||||
|
||||
# Kotlin
|
||||
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
||||
|
||||
# Common
|
||||
jei-api = { group = "mezz.jei", name = "jei-1.21-common-api", version.ref = "jei-api"}
|
||||
molang = { group = "local.com.bedrockk", name = "molang", version.ref = "molang" }
|
||||
graal = { group = "org.graalvm.js", name = "js", version.ref = "graal" }
|
||||
icu4j = { group = "com.ibm.icu", name = "icu4j", version.ref = "icu4j" }
|
||||
|
||||
# Fabric
|
||||
fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" }
|
||||
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" }
|
||||
fabric-kotlin = { group = "net.fabricmc", name = "fabric-language-kotlin", version.ref = "fabric-kotlin" }
|
||||
fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", version.ref = "fabric-permissions-api" }
|
||||
adorn-fabric = { group = "maven.modrinth", name = "adorn", version = "6.0.0-neoforge"}
|
||||
lambDynamicLights = { group = "maven.modrinth", name = "lambdynamiclights", version.ref = "lambDynamicLights"}
|
||||
jei-api-fabric = { group = "mezz.jei", name = "jei-1.21-fabric-api", version.ref = "jei-api" }
|
||||
jei-fabric = { group = "mezz.jei", name = "jei-1.21-fabric", version.ref = "jei-api"}
|
||||
fabric-debugutils = { group = "maven.modrinth", name = "debugutils", version.ref = "debugutils-fabric"}
|
||||
|
||||
# NeoForge
|
||||
neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge" }
|
||||
neo-kotlin-forge = { group = "thedarkcolour", name = "kotlinforforge-neoforge", version.ref = "neo-kotlin-for-forge" }
|
||||
neoforge-debugutils = { group = "maven.modrinth", name = "debugutils", version.ref = "debugutils-forge"}
|
||||
|
||||
# Data Storage
|
||||
mongo-driver-core = { group = "org.mongodb", name = "mongodb-driver-core", version.ref = "mongo" }
|
||||
mongo-driver-sync = { group = "org.mongodb", name = "mongodb-driver-sync", version.ref = "mongo" }
|
||||
|
||||
# Testing
|
||||
junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }
|
||||
mockito-core = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" }
|
||||
mock-kotlin = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
|
||||
classgraph = { group = "io.github.classgraph", name = "classgraph", version.ref = "classgraph" }
|
||||
|
||||
[bundles]
|
||||
kotlin = [ "kotlin-stdlib", "kotlin-reflect" ]
|
||||
fabric = [ "fabric-kotlin", "fabric-permissions" ]
|
||||
fabric-integrations-compileOnly = [ "adorn-fabric", "lambDynamicLights", "jei-api-fabric" ]
|
||||
fabric-integrations-runtimeOnly = [ "jei-fabric" ]
|
||||
mongo = [ "mongo-driver-core", "mongo-driver-sync" ]
|
||||
unitTesting = [ "junit", "mockito-core", "mock-kotlin", "classgraph" ]
|
||||
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore;
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity;
|
||||
@@ -179,10 +178,10 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
|
||||
@Override @Nullable
|
||||
public PokedexEntityData resolvePokemonScan() {
|
||||
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())){
|
||||
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())){
|
||||
return getDataFromShoulderPokemon(this.getShoulderEntityRight());
|
||||
}
|
||||
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())){
|
||||
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())){
|
||||
return getDataFromShoulderPokemon(this.getShoulderEntityLeft());
|
||||
}
|
||||
return null;
|
||||
@@ -191,34 +190,30 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
@Nullable @Unique
|
||||
private PokedexEntityData getDataFromShoulderPokemon(CompoundTag shoulderTag) {
|
||||
CompoundTag pokemonTag = shoulderTag.getCompound(DataKeys.POKEMON);
|
||||
if (pokemonTag.isEmpty()) return null;
|
||||
if(pokemonTag.isEmpty()) return null;
|
||||
Species species = PokemonSpecies.INSTANCE.getByIdentifier(ResourceLocation.parse(pokemonTag.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)));
|
||||
if (species == null) return null;
|
||||
if(species == null) return null;
|
||||
String formId = pokemonTag.getString(DataKeys.POKEMON_FORM_ID);
|
||||
FormData form = species.getStandardForm();
|
||||
List<FormData> formList = species.getForms().stream().filter(it -> it.formOnlyShowdownId().equals(formId)).toList();
|
||||
if (!formList.isEmpty()) form = formList.getFirst();
|
||||
if (form == null) return null;
|
||||
if(!formList.isEmpty()) form = formList.getFirst();
|
||||
if(form == null) return null;
|
||||
String genderString = pokemonTag.getString(DataKeys.POKEMON_GENDER);
|
||||
if (genderString.isEmpty()) return null;
|
||||
if(genderString.isEmpty()) return null;
|
||||
Gender gender = Gender.valueOf(genderString);
|
||||
boolean shiny = pokemonTag.getBoolean(DataKeys.POKEMON_SHINY);
|
||||
int level = pokemonTag.getInt(DataKeys.POKEMON_LEVEL);
|
||||
Set<String> aspects = shoulderTag.getList(DataKeys.SHOULDER_ASPECTS, Tag.TAG_STRING).stream().map(Tag::getAsString).collect(Collectors.toSet());
|
||||
|
||||
Pokemon pokemon = new Pokemon();
|
||||
if (level().isClientSide) {
|
||||
pokemon.setSpecies(species);
|
||||
pokemon.setForm(form);
|
||||
pokemon.setGender(gender);
|
||||
pokemon.setShiny(shiny);
|
||||
pokemon.setLevel(level);
|
||||
pokemon.setForcedAspects(aspects);
|
||||
} else {
|
||||
PlayerPartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.getUUID(), this.registryAccess());
|
||||
pokemon = party.get(shoulderTag.getUUID(DataKeys.SHOULDER_UUID));
|
||||
}
|
||||
return new PokedexEntityData(pokemon, null);
|
||||
return new PokedexEntityData(
|
||||
species,
|
||||
form,
|
||||
gender,
|
||||
aspects,
|
||||
shiny,
|
||||
level,
|
||||
this.getUUID()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.api.SeasonResolver
|
||||
import com.cobblemon.mod.common.api.data.DataProvider
|
||||
import com.cobblemon.mod.common.api.drop.CommandDropEntry
|
||||
import com.cobblemon.mod.common.api.drop.DropEntry
|
||||
import com.cobblemon.mod.common.api.drop.EvolutionItemDropEntry
|
||||
import com.cobblemon.mod.common.api.drop.ItemDropEntry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
|
||||
@@ -201,7 +200,6 @@ object Cobblemon {
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
|
||||
DropEntry.register("evolution", EvolutionItemDropEntry::class.java)
|
||||
|
||||
ExperienceGroups.registerDefaults()
|
||||
CaptureCalculators.registerDefaults()
|
||||
@@ -220,7 +218,7 @@ object Cobblemon {
|
||||
storage.onPlayerDataSync(it)
|
||||
playerDataManager.syncAllToPlayer(it)
|
||||
starterHandler.handleJoin(it)
|
||||
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel, this.config.displayEntityNameLabel, this.config.maxPokemonLevel, this.config.maxPokemonFriendship, this.config.maxDynamaxLevel).sendToPlayer(it)
|
||||
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel, this.config.displayEntityNameLabel, this.config.maxPokemonLevel).sendToPlayer(it)
|
||||
}
|
||||
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
|
||||
PCLinkManager.removeLink(it.player.uuid)
|
||||
@@ -258,8 +256,6 @@ object Cobblemon {
|
||||
// Lowest priority because this applies after luxury ball bonus as of gen 4
|
||||
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(Priority.LOWEST) { event ->
|
||||
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
|
||||
if (increment <= 0) //these affects are only meant to affect positive gains
|
||||
return@subscribe
|
||||
// Our Luxury ball spec is diff from official, but we will still assume these stack
|
||||
if (event.pokemon.heldItemNoCopy().`is`(CobblemonItemTags.IS_FRIENDSHIP_BOOSTER)) {
|
||||
increment += increment * 0.5F
|
||||
@@ -388,8 +384,8 @@ object Cobblemon {
|
||||
storage.unregisterAll(it.server.registryAccess())
|
||||
playerDataManager.saveAllStores()
|
||||
}
|
||||
PlatformEvents.SERVER_STARTED.subscribe { event ->
|
||||
bestSpawner.onServerStarted(event.server)
|
||||
PlatformEvents.SERVER_STARTED.subscribe {
|
||||
bestSpawner.onServerStarted()
|
||||
battleRegistry.onServerStarted()
|
||||
}
|
||||
PlatformEvents.SERVER_TICK_POST.subscribe { ServerTickHandler.onTick(it.server) }
|
||||
|
||||
@@ -317,7 +317,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField val RAZOR_FANG = noSettingsItem("razor_fang")
|
||||
@JvmField val AUSPICIOUS_ARMOR = heldItem("auspicious_armor")
|
||||
@JvmField val MALICIOUS_ARMOR = heldItem("malicious_armor")
|
||||
@JvmField val SHELL_HELMET = heldItem("shell_helmet")
|
||||
|
||||
private val berries = mutableMapOf<ResourceLocation, BerryItem>()
|
||||
// Plants
|
||||
|
||||
+1
-7
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.Registry
|
||||
|
||||
/**
|
||||
@@ -18,10 +17,5 @@ import net.minecraft.core.Registry
|
||||
* @since July 16th, 2022
|
||||
*/
|
||||
interface RegistryLikeCondition<T> {
|
||||
fun fits(t: T, registry: Registry<T>): Boolean {
|
||||
val holder = registry.wrapAsHolder(t)
|
||||
return holder != null && fits(holder)
|
||||
}
|
||||
|
||||
fun fits(holder: Holder<T>): Boolean
|
||||
fun fits(t: T, registry: Registry<T>): Boolean
|
||||
}
|
||||
+2
-3
@@ -9,7 +9,7 @@
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
@@ -24,6 +24,5 @@ open class RegistryLikeIdentifierCondition<T : Any>(val identifier: ResourceLoca
|
||||
constructor: (ResourceLocation) -> RegistryLikeIdentifierCondition<T>
|
||||
): (JsonElement) -> RegistryLikeIdentifierCondition<T>? = { constructor(ResourceLocation.parse(it.asString)) }
|
||||
}
|
||||
|
||||
override fun fits(t: Holder<T>) = t.`is`(identifier)
|
||||
override fun fits(t: T, registry: Registry<T>) = registry.getKey(t) == identifier
|
||||
}
|
||||
+12
-2
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -40,5 +39,16 @@ open class RegistryLikeTagCondition<T : Any>(val tag: TagKey<T>) : RegistryLikeC
|
||||
}
|
||||
}
|
||||
|
||||
override fun fits(t: Holder<T>) = t.`is`(tag)
|
||||
override fun fits(t: T, registry: Registry<T>): Boolean {
|
||||
// val registryHasTag = registry.containsTag(tag)
|
||||
// if (!registryHasTag) {
|
||||
//// LOGGER.warn("No tag in registry: ${tag.id}")
|
||||
// return false
|
||||
// }
|
||||
|
||||
return registry.getResourceKey(t)
|
||||
.flatMap(registry::getHolder)
|
||||
.map { entry -> entry.`is`(tag) }
|
||||
.orElse(false)
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.drop
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -41,23 +40,17 @@ interface DropEntry {
|
||||
* to be dropped.
|
||||
*/
|
||||
val percentage: Float
|
||||
|
||||
/**
|
||||
* The drop's quantity when doing selection from the [DropTable]. See the drop table documentation for more on how
|
||||
* this works.
|
||||
*/
|
||||
val quantity: Int
|
||||
|
||||
/**
|
||||
* The maximum number of times the item can be selected drop the [DropTable]. In most cases this will just be 1,
|
||||
* meaning that the item, once picked, cannot be picked again. A larger value will allow the same [DropEntry] from
|
||||
* appearing multiple times in a drop action.
|
||||
*/
|
||||
val maxSelectableTimes: Int
|
||||
|
||||
/** Whether this is considered a possible drop at the moment or not */
|
||||
fun canDrop(pokemon: Pokemon?): Boolean = true
|
||||
|
||||
/** The logic to use to actually drop the thing. */
|
||||
fun drop(entity: LivingEntity?, world: ServerLevel, pos: Vec3, player: ServerPlayer?)
|
||||
}
|
||||
@@ -11,13 +11,11 @@ package com.cobblemon.mod.common.api.drop
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LOOT_DROPPED
|
||||
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import kotlin.random.Random
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
@@ -47,11 +45,9 @@ class DropTable {
|
||||
* Gets a drop list from this table as a list of [DropEntry]. You can specify the range of drop quantity totals
|
||||
* that will be possible, or if you leave it blank it will use [DropTable.amount].
|
||||
*/
|
||||
fun getDrops(amount: IntRange = this.amount, pokemon: Pokemon? = null): List<DropEntry> {
|
||||
fun getDrops(amount: IntRange = this.amount): List<DropEntry> {
|
||||
val chosenAmount = amount.random()
|
||||
val possibleDrops = entries.filter {
|
||||
it.quantity <= chosenAmount && it.canDrop(pokemon)
|
||||
}.toMutableList()
|
||||
val possibleDrops = entries.filter { it.quantity <= chosenAmount }.toMutableList()
|
||||
|
||||
if (possibleDrops.isEmpty()) {
|
||||
return emptyList()
|
||||
@@ -91,10 +87,11 @@ class DropTable {
|
||||
world: ServerLevel,
|
||||
pos: Vec3,
|
||||
player: ServerPlayer?,
|
||||
amount: IntRange = this.amount,
|
||||
pokemon: Pokemon? = null,
|
||||
amount: IntRange = this.amount
|
||||
) {
|
||||
val drops = getDrops(amount, pokemon).toMutableList()
|
||||
val drops = getDrops(amount).toMutableList()
|
||||
val heldItem = (entity as PokemonEntity).pokemon.heldItemNoCopy()
|
||||
if (!heldItem.isEmpty) entity.spawnAtLocation(heldItem.item)
|
||||
LOOT_DROPPED.postThen(
|
||||
event = LootDroppedEvent(this, player, entity, drops),
|
||||
ifSucceeded = { it.drops.forEach { it.drop(entity, world, pos, player) } }
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* 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.api.drop
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.requirement.EvolutionRequirement
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
class EvolutionItemDropEntry : ItemDropEntry() {
|
||||
val requirements: MutableSet<EvolutionRequirement> = mutableSetOf()
|
||||
|
||||
override fun canDrop(pokemon: Pokemon?): Boolean = pokemon != null && requirements.all { it.check(pokemon) }
|
||||
}
|
||||
+6
-4
@@ -18,17 +18,19 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
data class PokemonScannedEvent(val player: ServerPlayer, val scannedPokemonEntityData: PokedexEntityData, val scannedEntity: ScannableEntity) {
|
||||
val pokedexEntityData: PokedexEntityData
|
||||
get() = scannedPokemonEntityData
|
||||
|
||||
val isOwned: Boolean
|
||||
get() = scannedPokemonEntityData.pokemon.getOwnerUUID() == player.uuid
|
||||
get() = scannedPokemonEntityData.ownerUUID == player.uuid
|
||||
|
||||
val context = mutableMapOf(
|
||||
"player" to player.asMoLangValue(),
|
||||
"pokemon" to scannedPokemonEntityData.pokemon.struct,
|
||||
"disguise" to (scannedPokemonEntityData.disguise?.struct ?: DoubleValue.ZERO),
|
||||
"pokemon" to scannedPokemonEntityData.struct,
|
||||
"entity" to {
|
||||
when (scannedEntity) {
|
||||
is LivingEntity -> scannedEntity.asMostSpecificMoLangValue()
|
||||
else -> DoubleValue.ZERO
|
||||
else -> DoubleValue(0.0)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
+2
-9
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
/**
|
||||
@@ -19,11 +18,5 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
*/
|
||||
data class FriendshipUpdatedEvent(
|
||||
val pokemon: Pokemon,
|
||||
val newFriendshipInitial: Int
|
||||
)
|
||||
{
|
||||
var newFriendship: Int = newFriendshipInitial
|
||||
set(value) {
|
||||
field = value.coerceIn(0, Cobblemon.config.maxPokemonFriendship)
|
||||
}
|
||||
}
|
||||
var newFriendship: Int
|
||||
)
|
||||
+7
-5
@@ -17,14 +17,16 @@ import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
|
||||
import com.cobblemon.mod.common.api.pokedex.FormDexRecord
|
||||
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
import com.mojang.datafixers.util.Either
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Event that fires when a Pokémon's information is gained or updated in the Pokédex.
|
||||
*/
|
||||
sealed interface PokedexDataChangedEvent {
|
||||
val dataSource: PokedexEntityData
|
||||
val dataSource: Either<PokedexEntityData, Pokemon>
|
||||
val knowledge: PokedexEntryProgress
|
||||
val playerUUID: UUID
|
||||
val record: FormDexRecord
|
||||
@@ -35,22 +37,22 @@ sealed interface PokedexDataChangedEvent {
|
||||
fun getContext(): MutableMap<String, MoValue> {
|
||||
return mutableMapOf(
|
||||
"player" to (playerUUID.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"pokemon" to dataSource.pokemon.struct,
|
||||
"disguise" to (dataSource.disguise?.struct ?: DoubleValue.ZERO),
|
||||
"pokemon" to dataSource.map({ DoubleValue.ZERO }, { it.struct }),
|
||||
"data" to dataSource.map({ it.struct }, { DoubleValue.ZERO }),
|
||||
"knowledge" to StringValue(knowledge.name.lowercase()),
|
||||
"pokedex" to pokedexManager.struct
|
||||
)
|
||||
}
|
||||
|
||||
class Pre(
|
||||
override val dataSource: PokedexEntityData,
|
||||
override val dataSource: Either<PokedexEntityData, Pokemon>,
|
||||
override val knowledge: PokedexEntryProgress,
|
||||
override val playerUUID: UUID,
|
||||
override val record: FormDexRecord
|
||||
) : PokedexDataChangedEvent, Cancelable()
|
||||
|
||||
class Post(
|
||||
override val dataSource: PokedexEntityData,
|
||||
override val dataSource: Either<PokedexEntityData, Pokemon>,
|
||||
override val knowledge: PokedexEntryProgress,
|
||||
override val playerUUID: UUID,
|
||||
override val record: FormDexRecord
|
||||
|
||||
@@ -850,7 +850,7 @@ object MoLangFunctions {
|
||||
{ spawningContext ->
|
||||
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
|
||||
val worldValue = spawningContext.world.registryAccess().registryOrThrow(Registries.DIMENSION).wrapAsHolder(spawningContext.world).asWorldMoLangValue()
|
||||
val biomeValue = spawningContext.biomeHolder.asBiomeMoLangValue()
|
||||
val biomeValue = spawningContext.biomeRegistry.wrapAsHolder(spawningContext.biome).asBiomeMoLangValue()
|
||||
map.put("biome") { _ -> biomeValue }
|
||||
map.put("world") { _ -> worldValue }
|
||||
map.put("light") { _ -> DoubleValue(spawningContext.light.toDouble()) }
|
||||
|
||||
@@ -54,15 +54,7 @@ class BenchedMoves : Iterable<BenchedMove> {
|
||||
}
|
||||
}
|
||||
|
||||
fun add(benchedMove: BenchedMove): Boolean {
|
||||
if (any { it.moveTemplate == benchedMove.moveTemplate }) {
|
||||
return false
|
||||
}
|
||||
|
||||
doThenEmit { benchedMoves.add(benchedMove) }
|
||||
return true
|
||||
}
|
||||
|
||||
fun add(benchedMove: BenchedMove) = doThenEmit { benchedMoves.add(benchedMove) }
|
||||
fun addAll(benchedMoves: Iterable<BenchedMove>) = doThenEmit { this.benchedMoves.addAll(benchedMoves) }
|
||||
fun clear() = doThenEmit { benchedMoves.clear() }
|
||||
fun remove(benchedMove: BenchedMove) = doThenEmit { benchedMoves.remove(benchedMove) }
|
||||
|
||||
@@ -134,21 +134,18 @@ class MoveSet : Iterable<Move> {
|
||||
return json
|
||||
}
|
||||
|
||||
fun add(move: Move): Boolean {
|
||||
fun add(move: Move) {
|
||||
if (any { it.template == move.template }) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
|
||||
for (i in 0 until MOVE_COUNT) {
|
||||
if (moves[i] == null) {
|
||||
moves[i] = move
|
||||
move.observable.subscribe { this.update() }
|
||||
update()
|
||||
return true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun update() {
|
||||
|
||||
@@ -57,7 +57,6 @@ class NPCClass {
|
||||
var isInvulnerable = false
|
||||
var isLeashable = true
|
||||
var allowProjectileHits = true
|
||||
var hideNameTag = false
|
||||
|
||||
// If you're adding stuff here, add it to NPCPreset and NPCClassAdapter too
|
||||
|
||||
@@ -98,7 +97,6 @@ class NPCClass {
|
||||
buffer.writeBoolean(isInvulnerable)
|
||||
buffer.writeBoolean(isLeashable)
|
||||
buffer.writeBoolean(allowProjectileHits)
|
||||
buffer.writeBoolean(hideNameTag)
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -150,6 +148,5 @@ class NPCClass {
|
||||
isInvulnerable = buffer.readBoolean()
|
||||
isLeashable = buffer.readBoolean()
|
||||
allowProjectileHits = buffer.readBoolean()
|
||||
hideNameTag = buffer.readBoolean()
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ class NPCPreset {
|
||||
var isInvulnerable: Boolean? = null
|
||||
var isLeashable: Boolean? = null
|
||||
var allowProjectileHits: Boolean? = null
|
||||
var hideNameTag: Boolean? = null
|
||||
|
||||
fun applyTo(npcClass: NPCClass) {
|
||||
resourceIdentifier?.let { npcClass.resourceIdentifier = it }
|
||||
@@ -64,6 +63,5 @@ class NPCPreset {
|
||||
isInvulnerable?.let { npcClass.isInvulnerable = it }
|
||||
isLeashable?.let { npcClass.isLeashable = it }
|
||||
allowProjectileHits?.let { npcClass.allowProjectileHits = it }
|
||||
hideNameTag?.let { npcClass.hideNameTag = it }
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,6 @@ any number of presets and the properties of those presets will be merged into th
|
||||
"skill": 5,
|
||||
"autoHealParty": true,
|
||||
"randomizePartyOrder": true,
|
||||
"hideNameTag": false,
|
||||
"party": {
|
||||
"type": "simple",
|
||||
"pokemon": [
|
||||
@@ -412,7 +411,4 @@ Pokémon in the party.
|
||||
|
||||
### ai
|
||||
The AI property is an array of brain configurations. This is used to configure the behaviours of the NPC. See
|
||||
the documentation for brain configurations at [AI Configuration](../ai/config/README.md).
|
||||
|
||||
### hideNameTag
|
||||
Whether the NPC's nametag should be hidden or not. Defaults to false.
|
||||
the documentation for brain configurations at [AI Configuration](../ai/config/README.md).
|
||||
@@ -202,8 +202,6 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
|
||||
// Luxury ball effect, low priority as it must be triggered before soothe bell as of gen 4
|
||||
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOW) { event ->
|
||||
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
|
||||
if (increment <= 0) //these affects are only meant to affect positive gains
|
||||
return@subscribe
|
||||
if (increment <= 1F) {
|
||||
event.pokemon.caughtBall.effects.filterIsInstance<FriendshipEarningBoostEffect>()
|
||||
.forEach { increment *= it.multiplier }
|
||||
|
||||
+1
-4
@@ -42,10 +42,7 @@ class BaseStatModifier(
|
||||
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean {
|
||||
val valStat = pokemon.form.baseStats[this.stat] ?: return false
|
||||
return comparator(valStat)
|
||||
}
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean = pokemon.form.baseStats[this.stat] != null
|
||||
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
|
||||
|
||||
+3
-9
@@ -96,21 +96,15 @@ abstract class AbstractPokedexManager {
|
||||
}
|
||||
|
||||
fun getNewInformation(pokedexEntityData: PokedexEntityData): PokedexLearnedInformation {
|
||||
val speciesRecord = getSpeciesRecord(pokedexEntityData.getApparentSpecies().resourceIdentifier)
|
||||
val speciesRecord = getSpeciesRecord(pokedexEntityData.species.resourceIdentifier)
|
||||
if (speciesRecord == null || speciesRecord.getKnowledge() == PokedexEntryProgress.NONE) {
|
||||
return PokedexLearnedInformation.SPECIES
|
||||
}
|
||||
val formRecord = speciesRecord.getFormRecord(pokedexEntityData.getApparentForm().name)
|
||||
val formRecord = speciesRecord.getFormRecord(pokedexEntityData.form.name)
|
||||
if (formRecord == null || formRecord.knowledge == PokedexEntryProgress.NONE) {
|
||||
return PokedexLearnedInformation.FORM
|
||||
}
|
||||
|
||||
// Can't update aspects on a disguise
|
||||
if (pokedexEntityData.disguise != null) {
|
||||
return PokedexLearnedInformation.NONE
|
||||
}
|
||||
|
||||
if (pokedexEntityData.pokemon.aspects.any { !speciesRecord.hasAspect(it) } || pokedexEntityData.pokemon.gender !in formRecord.getGenders() || !formRecord.hasSeenShinyState(pokedexEntityData.pokemon.shiny)) {
|
||||
if (pokedexEntityData.aspects.any{ !speciesRecord.hasAspect(it) } || pokedexEntityData.gender !in formRecord.getGenders() || !formRecord.hasSeenShinyState(pokedexEntityData.shiny)) {
|
||||
return PokedexLearnedInformation.VARIATION
|
||||
}
|
||||
return PokedexLearnedInformation.NONE
|
||||
|
||||
@@ -89,15 +89,21 @@ class FormDexRecord {
|
||||
it.knowledge = knowledge
|
||||
}
|
||||
|
||||
fun encountered(pokemon: Pokemon) {
|
||||
if (wouldBeDifferent(pokemon, PokedexEntryProgress.ENCOUNTERED)) {
|
||||
addInformation(pokemon, PokedexEntryProgress.ENCOUNTERED)
|
||||
}
|
||||
}
|
||||
|
||||
fun encountered(pokedexEntityData: PokedexEntityData) {
|
||||
if (wouldBeDifferent(pokedexEntityData, PokedexEntryProgress.ENCOUNTERED)) {
|
||||
addInformation(pokedexEntityData, PokedexEntryProgress.ENCOUNTERED)
|
||||
}
|
||||
}
|
||||
|
||||
fun caught(pokedexEntityData: PokedexEntityData) {
|
||||
if (wouldBeDifferent(pokedexEntityData, PokedexEntryProgress.CAUGHT)) {
|
||||
addInformation(pokedexEntityData, PokedexEntryProgress.CAUGHT)
|
||||
fun caught(pokemon: Pokemon) {
|
||||
if (wouldBeDifferent(pokemon, PokedexEntryProgress.CAUGHT)) {
|
||||
addInformation(pokemon, PokedexEntryProgress.CAUGHT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,18 +125,47 @@ class FormDexRecord {
|
||||
speciesDexRecord.onFormRecordUpdated(this)
|
||||
}
|
||||
|
||||
private fun addInformation(pokemon: Pokemon, knowledge: PokedexEntryProgress) {
|
||||
(speciesDexRecord.pokedexManager as? PokedexManager)?.let { pokedexManager ->
|
||||
CobblemonEvents.POKEDEX_DATA_CHANGED_PRE.postThen(
|
||||
PokedexDataChangedEvent.Pre(
|
||||
Either.right(pokemon),
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
),
|
||||
ifSucceeded = {
|
||||
genders.add(pokemon.gender)
|
||||
seenShinyStates.add(if (pokemon.shiny) "shiny" else "normal")
|
||||
if (knowledge.ordinal > this.knowledge.ordinal) {
|
||||
this.knowledge = knowledge
|
||||
}
|
||||
speciesDexRecord.addInformation(pokemon, knowledge)
|
||||
speciesDexRecord.onFormRecordUpdated(this)
|
||||
CobblemonEvents.POKEDEX_DATA_CHANGED_POST.post(
|
||||
PokedexDataChangedEvent.Post(
|
||||
Either.right(pokemon),
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun addInformation(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress) {
|
||||
(speciesDexRecord.pokedexManager as? PokedexManager)?.let { pokedexManager ->
|
||||
CobblemonEvents.POKEDEX_DATA_CHANGED_PRE.postThen(
|
||||
PokedexDataChangedEvent.Pre(
|
||||
pokedexEntityData,
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
Either.left(pokedexEntityData),
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
),
|
||||
ifSucceeded = {
|
||||
genders.add(pokedexEntityData.pokemon.gender)
|
||||
seenShinyStates.add(if (pokedexEntityData.pokemon.shiny) "shiny" else "normal")
|
||||
genders.add(pokedexEntityData.gender)
|
||||
seenShinyStates.add(if (pokedexEntityData.shiny) "shiny" else "normal")
|
||||
if (knowledge.ordinal > this.knowledge.ordinal) {
|
||||
this.knowledge = knowledge
|
||||
}
|
||||
@@ -138,10 +173,10 @@ class FormDexRecord {
|
||||
speciesDexRecord.onFormRecordUpdated(this)
|
||||
CobblemonEvents.POKEDEX_DATA_CHANGED_POST.post(
|
||||
PokedexDataChangedEvent.Post(
|
||||
pokedexEntityData,
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
Either.left(pokedexEntityData),
|
||||
knowledge,
|
||||
pokedexManager.uuid,
|
||||
this
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -149,10 +184,19 @@ class FormDexRecord {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns whether the given [Pokemon] and [knowledge] would add new information to the Pokédex.*/
|
||||
fun wouldBeDifferent(pokemon: Pokemon, knowledge: PokedexEntryProgress): Boolean {
|
||||
return pokemon.gender !in genders
|
||||
|| (pokemon.shiny && "shiny" !in seenShinyStates)
|
||||
|| (!pokemon.shiny && "normal" !in seenShinyStates)
|
||||
|| knowledge.ordinal > this.knowledge.ordinal
|
||||
|| speciesDexRecord.wouldBeDifferent(pokemon)
|
||||
}
|
||||
|
||||
fun wouldBeDifferent(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress): Boolean {
|
||||
return pokedexEntityData.pokemon.gender !in genders
|
||||
|| (pokedexEntityData.pokemon.shiny && "shiny" !in seenShinyStates)
|
||||
|| (!pokedexEntityData.pokemon.shiny && "normal" !in seenShinyStates)
|
||||
return pokedexEntityData.gender !in genders
|
||||
|| (pokedexEntityData.shiny && "shiny" !in seenShinyStates)
|
||||
|| (!pokedexEntityData.shiny && "normal" !in seenShinyStates)
|
||||
|| knowledge.ordinal > this.knowledge.ordinal
|
||||
|| speciesDexRecord.wouldBeDifferent(pokedexEntityData)
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ class PokedexManager(
|
||||
fun encounter(pokemon: Pokemon) {
|
||||
val speciesId = pokemon.species.resourceIdentifier
|
||||
val formName = pokemon.form.name
|
||||
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).encountered(PokedexEntityData(pokemon = pokemon, disguise = null))
|
||||
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).encountered(pokemon)
|
||||
}
|
||||
|
||||
fun encounter(pokedexEntityData: PokedexEntityData) {
|
||||
val speciesId = pokedexEntityData.getApparentSpecies().resourceIdentifier
|
||||
val formName = pokedexEntityData.getApparentForm().name
|
||||
val speciesId = pokedexEntityData.species.resourceIdentifier
|
||||
val formName = pokedexEntityData.form.name
|
||||
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).encountered(pokedexEntityData)
|
||||
}
|
||||
|
||||
fun catch(pokemon: Pokemon) {
|
||||
val speciesId = pokemon.species.resourceIdentifier
|
||||
val formName = pokemon.form.name
|
||||
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).caught(PokedexEntityData(pokemon = pokemon, disguise = null))
|
||||
getOrCreateSpeciesRecord(speciesId).getOrCreateFormRecord(formName).caught(pokemon)
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
|
||||
@@ -97,7 +97,7 @@ class SpeciesDexRecord {
|
||||
}
|
||||
|
||||
fun addInformation(pokedexEntityData: PokedexEntityData, knowledge: PokedexEntryProgress) {
|
||||
aspects.addAll(pokedexEntityData.pokemon.aspects)
|
||||
aspects.addAll(pokedexEntityData.aspects)
|
||||
}
|
||||
|
||||
fun addAspects(addedAspects: Set<String>) {
|
||||
@@ -107,7 +107,7 @@ class SpeciesDexRecord {
|
||||
/** Returns true if the given Pokémon contains new information. Internal because it's only to be called from [FormDexRecord.wouldBeDifferent]. */
|
||||
internal fun wouldBeDifferent(pokemon: Pokemon) = pokemon.aspects.any { it !in aspects }
|
||||
|
||||
internal fun wouldBeDifferent(pokedexEntityData: PokedexEntityData) = pokedexEntityData.pokemon.aspects.any { it !in aspects }
|
||||
internal fun wouldBeDifferent(pokedexEntityData: PokedexEntityData) = pokedexEntityData.aspects.any { it !in aspects }
|
||||
|
||||
fun getOrCreateFormRecord(formName: String): FormDexRecord {
|
||||
return formRecords.getOrPut(formName.lowercase()) {
|
||||
|
||||
@@ -468,10 +468,6 @@ open class PokemonProperties {
|
||||
return this.commonMatches(pokemonEntity.pokemon) && this.customProperties.none { !it.matches(pokemonEntity) }
|
||||
}
|
||||
|
||||
fun matches(properties: PokemonProperties): Boolean {
|
||||
return properties.asString() == this.asString()
|
||||
}
|
||||
|
||||
private fun commonMatches(pokemon: Pokemon): Boolean {
|
||||
level?.takeIf { it != pokemon.level }?.let { return false }
|
||||
shiny?.takeIf { it != pokemon.shiny }?.let { return false }
|
||||
@@ -809,7 +805,7 @@ open class PokemonProperties {
|
||||
private fun createAbility(id: String, form: FormData): Ability? {
|
||||
val ability = Abilities.get(id) ?: return null
|
||||
val potentialAbility = form.abilities.firstOrNull { potential -> potential.template == ability } ?: return ability.create(true)
|
||||
return potentialAbility.template.create(false, potentialAbility.priority)
|
||||
return potentialAbility.template.create(false)
|
||||
}
|
||||
|
||||
}
|
||||
+13
-37
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.criterion.EvolvePokemonContext
|
||||
import com.cobblemon.mod.common.api.drop.DropTable
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonGainedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
|
||||
@@ -33,8 +32,9 @@ import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.network.protocol.game.ClientboundSoundPacket
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@@ -80,11 +80,6 @@ interface Evolution : EvolutionLike {
|
||||
*/
|
||||
val learnableMoves: MutableSet<MoveTemplate>
|
||||
|
||||
/**
|
||||
* The items that will drop once the evolution finishes.
|
||||
*/
|
||||
val drops: DropTable
|
||||
|
||||
/**
|
||||
* Checks if the given [Pokemon] passes all the conditions and is ready to evolve.
|
||||
*
|
||||
@@ -105,6 +100,9 @@ interface Evolution : EvolutionLike {
|
||||
* @param pokemon The [Pokemon] being evolved.
|
||||
*/
|
||||
fun evolve(pokemon: Pokemon): Boolean {
|
||||
if (this.consumeHeldItem) {
|
||||
pokemon.swapHeldItem(ItemStack.EMPTY)
|
||||
}
|
||||
if (this.optional) {
|
||||
// All the networking is handled under the hood, see EvolutionController.
|
||||
return pokemon.evolutionProxy.server().add(this)
|
||||
@@ -200,41 +198,19 @@ interface Evolution : EvolutionLike {
|
||||
|
||||
val movesToLearn = previousSpeciesLearnableMoves + this.learnableMoves
|
||||
movesToLearn.forEach { move ->
|
||||
val couldAddMove =
|
||||
if (pokemon.moveSet.hasSpace()) {
|
||||
pokemon.moveSet.add(move.create())
|
||||
} else {
|
||||
pokemon.benchedMoves.add(BenchedMove(move, 0))
|
||||
}
|
||||
|
||||
val previousSpeciesKnewMove = previousSpeciesLearnableMoves.any { move.name == it.name }
|
||||
|
||||
if (couldAddMove && !previousSpeciesKnewMove) {
|
||||
pokemon.getOwnerPlayer()?.sendSystemMessage(lang("experience.learned_move", pokemon.getDisplayName(), move.displayName))
|
||||
if (pokemon.moveSet.hasSpace()) {
|
||||
pokemon.moveSet.add(move.create())
|
||||
} else {
|
||||
pokemon.benchedMoves.add(BenchedMove(move, 0))
|
||||
}
|
||||
|
||||
pokemon.getOwnerPlayer()?.sendSystemMessage(lang("experience.learned_move", pokemon.getDisplayName(), move.displayName))
|
||||
}
|
||||
|
||||
// we want to instantly tick for example you might only evolve your Bulbasaur at level 34 so Venusaur should be immediately available
|
||||
pokemon.evolutions.filterIsInstance<PassiveEvolution>().forEach { evolution -> evolution.attemptEvolution(pokemon) }
|
||||
pokemon.lockedEvolutions.filterIsInstance<PassiveEvolution>().forEach { evolution -> evolution.attemptEvolution(pokemon) }
|
||||
|
||||
this.shed(pokemon)
|
||||
|
||||
if (this.consumeHeldItem) {
|
||||
pokemon.swapHeldItem(ItemStack.EMPTY)
|
||||
}
|
||||
|
||||
val ownerPlayer = pokemon.getOwnerPlayer()
|
||||
if (ownerPlayer != null && ownerPlayer.level().gameRules.getBoolean(CobblemonGameRules.DO_POKEMON_LOOT)) {
|
||||
drops.drop(
|
||||
pokemon.entity,
|
||||
ownerPlayer.level() as ServerLevel,
|
||||
pokemon.entity?.position() ?: ownerPlayer.position(),
|
||||
ownerPlayer,
|
||||
pokemon = pokemon
|
||||
)
|
||||
}
|
||||
|
||||
CobblemonEvents.EVOLUTION_COMPLETE.post(EvolutionCompleteEvent(pokemon, this))
|
||||
CobblemonEvents.POKEMON_GAINED.post(PokemonGainedEvent(pokemon.getOwnerUUID()!!, pokemon))
|
||||
}
|
||||
@@ -242,4 +218,4 @@ interface Evolution : EvolutionLike {
|
||||
fun applyTo(pokemon: Pokemon) {
|
||||
result.apply(pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-54
@@ -21,12 +21,6 @@ object CobblemonPokemonLabels {
|
||||
*/
|
||||
const val LEGENDARY = "legendary"
|
||||
|
||||
/**
|
||||
* Represents a Pokémon who is typically banned or has restricted usage in competitive sanctions.
|
||||
* For example usage see this [VGC](https://www.pokemon.com/us/pokemon-news/trainers-can-once-again-use-a-restricted-pokemon-in-ranked-battles-series-10-starting-august-1-2021) page.
|
||||
*/
|
||||
const val RESTRICTED = "restricted"
|
||||
|
||||
/**
|
||||
* Represents a mythical Pokémon.
|
||||
* In Cobblemon terms they do not exist since we do not share the concept of timed event only Pokémon but the official ones are still tagged.
|
||||
@@ -34,21 +28,14 @@ object CobblemonPokemonLabels {
|
||||
const val MYTHICAL = "mythical"
|
||||
|
||||
/**
|
||||
* Represents Pokémon that receive a boosted catch rate from the Beast Ball. (Due to Beast Boost)
|
||||
* Does not include [thematically related](https://bulbapedia.bulbagarden.net/wiki/Ultra_Beast#Related_Pok%C3%A9mon) beasts.
|
||||
* Represents Pokémon that originate from Ultra Space.
|
||||
*/
|
||||
const val ULTRA_BEAST = "ultra_beast"
|
||||
|
||||
/**
|
||||
* Represents a Pokémon whose family could be derived from resurrecting a fossil.
|
||||
* Represents the pseudo legendary Pokémon.
|
||||
*/
|
||||
const val FOSSIL = "fossil"
|
||||
|
||||
/**
|
||||
* Represents the "pseudo-legendary" Pokémon. (Slow-rate three-stage lines with a base stat total of 600)
|
||||
* Term reference on this [Pokémon Center](https://www.pokemoncenter.com/search/powerhouse) page.
|
||||
*/
|
||||
const val POWERHOUSE = "powerhouse"
|
||||
const val PSEUDO_LEGENDARY = "pseudo_legendary"
|
||||
|
||||
/**
|
||||
* Represents a baby Pokémon, this is not just a first stage Pokémon species, it is also unable to breed.
|
||||
@@ -65,55 +52,52 @@ object CobblemonPokemonLabels {
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val KANTONIAN_FORM = "kantonian_form"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
* Source for adjectival form: [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Johto#Trivia)
|
||||
*/
|
||||
const val JOHTONIAN_FORM = "johtonian_form"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
* Source for adjectival form:[Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Hoenn#Trivia)
|
||||
*/
|
||||
const val HOENNIAN_FORM = "hoennian_form"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
* Source for adjectival form:[Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Sinnoh#Trivia)
|
||||
*/
|
||||
const val SINNOHAN_FORM = "sinnohan_form"
|
||||
const val REGIONAL_OF_KANTO = "kanto_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val UNOVAN_FORM = "unovan_form"
|
||||
const val REGIONAL_OF_JOHTO = "johto_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val KALOSIAN_FORM = "kalosian_form"
|
||||
const val REGIONAL_OF_HOENN = "hoenn_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val REGIONAL_OF_SINNOH = "sinnoh_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val REGIONAL_OF_UNOVA = "unova_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL], this has no official regionals but it consists of the "base" form that comes from the region.
|
||||
*/
|
||||
const val REGIONAL_OF_KALOS = "kalos_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL] and this [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Regional_form#Alolan_Form) page.
|
||||
*/
|
||||
const val ALOLAN_FORM = "alolan_form"
|
||||
const val REGIONAL_OF_ALOLA = "alola_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL] and this [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Regional_form#Galarian_Form) page.
|
||||
*/
|
||||
const val GALARIAN_FORM = "galarian_form"
|
||||
const val REGIONAL_OF_GALAR = "galar_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL] and this [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Regional_form#Hisuian_Form) page.
|
||||
*/
|
||||
const val HISUIAN_FORM = "hisuian_form"
|
||||
const val REGIONAL_OF_HISUI = "hisui_regional"
|
||||
|
||||
/**
|
||||
* See [REGIONAL] and this [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Regional_form#Paldean_Form) page.
|
||||
*/
|
||||
const val PALDEAN_FORM = "paldean_form"
|
||||
const val REGIONAL_OF_PALDEA = "paldea_regional"
|
||||
|
||||
/**
|
||||
* Represents a mega evolution.
|
||||
@@ -140,7 +124,7 @@ object CobblemonPokemonLabels {
|
||||
const val TOTEM = "totem"
|
||||
|
||||
/**
|
||||
* Represents Pokémon that trigger the Booster Energy item (due to Protosynthesis/Quark Drive)
|
||||
* Represents a Paradox species.
|
||||
* For more information see the [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Paradox_Pok%C3%A9mon) page.
|
||||
*/
|
||||
const val PARADOX = "paradox"
|
||||
@@ -187,24 +171,12 @@ object CobblemonPokemonLabels {
|
||||
*/
|
||||
const val GENERATION_7 = "gen7"
|
||||
|
||||
/**
|
||||
* The "official" designation for Pokémon from Gen 7 (Unknown) and not the Alola region
|
||||
* This may also include forms of Pokémon that had been previously introduced
|
||||
*/
|
||||
const val GENERATION_7B = "gen7b"
|
||||
|
||||
/**
|
||||
* Pokémon from the national Pokédex of 810 to 905
|
||||
* This may also include forms of Pokémon that had been previously introduced
|
||||
*/
|
||||
const val GENERATION_8 = "gen8"
|
||||
|
||||
/**
|
||||
* The "official" designation for Pokémon from Gen 8 (Hisui) and not the Galar region
|
||||
* This may also include forms of Pokémon that had been previously introduced
|
||||
*/
|
||||
const val GENERATION_8A = "gen8a"
|
||||
|
||||
/**
|
||||
* Pokémon from the national Pokédex from 906 to 1008
|
||||
* This may also include forms of Pokémon that had been previously introduced
|
||||
|
||||
@@ -53,7 +53,7 @@ enum class Stats(override val identifier: ResourceLocation, override val display
|
||||
fun getStat(statKey: String) = when(statKey.lowercase()) {
|
||||
"hp" -> HP
|
||||
"atk", "attack" -> ATTACK // Hyper Cutter states the full stat name "Attack"
|
||||
"def", "defense", "defence" -> DEFENCE // Big Pecks states the full stat name "Defense"
|
||||
"def", "defense" -> DEFENCE // Big Pecks states the full stat name "Defense"
|
||||
"spa" -> SPECIAL_ATTACK
|
||||
"spd" -> SPECIAL_DEFENCE
|
||||
"spe", "speed" -> SPEED
|
||||
|
||||
@@ -10,14 +10,7 @@ package com.cobblemon.mod.common.api.spawning
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.entity.Despawner
|
||||
import com.cobblemon.mod.common.api.spawning.condition.AreaSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.BasicSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.FishingSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.GroundedSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SeafloorSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SubmergedSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.SurfaceSpawningCondition
|
||||
import com.cobblemon.mod.common.api.spawning.condition.*
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
|
||||
import com.cobblemon.mod.common.api.spawning.context.FishingSpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.context.GroundedSpawningContext
|
||||
@@ -51,7 +44,6 @@ import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.TickingSpawner
|
||||
import com.cobblemon.mod.common.entity.pokemon.CobblemonAgingDespawner
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.server.MinecraftServer
|
||||
|
||||
/**
|
||||
* A grouping of all the overarching behaviours of the Best Spawner system. This is a convenient accessor to
|
||||
@@ -127,8 +119,7 @@ object BestSpawner {
|
||||
SpawnDetailPresets.registerPresetType(PokemonSpawnDetailPreset.NAME, PokemonSpawnDetailPreset::class.java)
|
||||
}
|
||||
|
||||
fun onServerStarted(server: MinecraftServer) {
|
||||
CobblemonSpawnPools.onServerLoad(server)
|
||||
fun onServerStarted() {
|
||||
spawnerManagers.forEach(SpawnerManager::onServerStarted)
|
||||
fishingSpawner = FishingSpawner()
|
||||
}
|
||||
|
||||
+1
-16
@@ -8,13 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.spawning
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.spawning.condition.BiomePrecalculation
|
||||
import com.cobblemon.mod.common.api.spawning.condition.BucketPrecalculation
|
||||
import com.cobblemon.mod.common.api.spawning.condition.ContextPrecalculation
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.data.CobblemonDataProvider
|
||||
import net.minecraft.server.MinecraftServer
|
||||
|
||||
/**
|
||||
* A collection of all of Cobblemon's general-purpose [SpawnPool]s. These
|
||||
@@ -29,18 +26,6 @@ object CobblemonSpawnPools {
|
||||
lateinit var WORLD_SPAWN_POOL: SpawnPool
|
||||
|
||||
fun load() {
|
||||
WORLD_SPAWN_POOL = CobblemonDataProvider.register(SpawnPool("world")
|
||||
.addPrecalculators(
|
||||
ContextPrecalculation,
|
||||
BucketPrecalculation,
|
||||
BiomePrecalculation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onServerLoad(server: MinecraftServer) {
|
||||
Cobblemon.LOGGER.info("Optimizing spawn pools...")
|
||||
WORLD_SPAWN_POOL.forEach { it.onServerLoad(server) }
|
||||
WORLD_SPAWN_POOL.precalculate()
|
||||
WORLD_SPAWN_POOL = CobblemonDataProvider.register(SpawnPool("world").addPrecalculators(ContextPrecalculation, BucketPrecalculation))
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ abstract class AreaTypeSpawningCondition<T : AreaSpawningContext> : SpawningCond
|
||||
return false
|
||||
} else if (maxHeight != null && ctx.height > maxHeight!!) {
|
||||
return false
|
||||
} else if (neededNearbyBlocks != null && neededNearbyBlocks!!.none { cond -> ctx.nearbyBlockHolders.any { cond.fits(it) } }) {
|
||||
} else if (neededNearbyBlocks != null && neededNearbyBlocks!!.none { cond -> ctx.nearbyBlockTypes.any { cond.fits(it, ctx.blockRegistry) } }) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
||||
-11
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.spawning.condition
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
|
||||
/**
|
||||
* A spawning condition that is composed of a list of conditions and anticonditions.
|
||||
@@ -32,15 +30,6 @@ class CompositeSpawningCondition {
|
||||
var conditions = mutableListOf<SpawningCondition<*>>()
|
||||
var anticonditions = mutableListOf<SpawningCondition<*>>()
|
||||
|
||||
fun isBiomeValid(holder: Holder<Biome>): Boolean {
|
||||
if (conditions.isEmpty() || conditions.any { it.biomes == null || it.biomes!!.isEmpty() || it.biomes!!.any { it.fits(holder) } }) {
|
||||
if (anticonditions.isEmpty() || anticonditions.none { it.biomes != null && it.biomes!!.any { it.fits(holder) } }) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun satisfiedBy(ctx: SpawningContext): Boolean {
|
||||
return if (conditions.isNotEmpty() && conditions.none { it.isSatisfiedBy(ctx) }) {
|
||||
false
|
||||
|
||||
+1
-5
@@ -30,11 +30,7 @@ abstract class GroundedTypeSpawningCondition<T : GroundedSpawningContext> : Area
|
||||
return false
|
||||
} else if (maxHeight != null && ctx.height > maxHeight!!) {
|
||||
return false
|
||||
} else if (neededBaseBlocks != null && neededBaseBlocks!!.none { it.fits(ctx.baseBlockHolder) }) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else !(neededBaseBlocks != null && neededBaseBlocks!!.none { it.fits(ctx.baseBlock.block, ctx.blockRegistry) })
|
||||
}
|
||||
|
||||
override fun copyFrom(other: SpawningCondition<*>, merger: Merger) {
|
||||
|
||||
+4
-8
@@ -30,14 +30,10 @@ abstract class SeafloorTypeSpawningCondition<T : SeafloorSpawningContext> : Area
|
||||
return if (!super.fits(ctx)) {
|
||||
false
|
||||
} else if (minHeight != null && ctx.height < minHeight!!) {
|
||||
false
|
||||
return false
|
||||
} else if (maxHeight != null && ctx.height > maxHeight!!) {
|
||||
false
|
||||
} else if (neededBaseBlocks != null && neededBaseBlocks!!.none { it.fits(ctx.baseBlockHolder) }) {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
return false
|
||||
} else !(neededBaseBlocks != null && neededBaseBlocks!!.none { it.fits(ctx.baseBlock.block, ctx.blockRegistry) })
|
||||
}
|
||||
|
||||
override fun copyFrom(other: SpawningCondition<*>, merger: Merger) {
|
||||
@@ -48,7 +44,7 @@ abstract class SeafloorTypeSpawningCondition<T : SeafloorSpawningContext> : Area
|
||||
}
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
val containsNullValues = neededBaseBlocks != null && neededBaseBlocks!!.any { it == null }
|
||||
val containsNullValues = neededBaseBlocks != null && neededBaseBlocks!!.any {it == null}
|
||||
return super.isValid() && !containsNullValues
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -42,7 +42,6 @@ abstract class SpawningCondition<T : SpawningContext> {
|
||||
}
|
||||
|
||||
var dimensions: MutableList<ResourceLocation>? = null
|
||||
/** This gets checked in a precalculation but still needs to be checked for things like rarity multipliers. */
|
||||
var biomes: MutableSet<RegistryLikeCondition<Biome>>? = null
|
||||
var moonPhase: MoonPhaseRange? = null
|
||||
var canSeeSky: Boolean? = null
|
||||
@@ -99,7 +98,7 @@ abstract class SpawningCondition<T : SpawningContext> {
|
||||
return false
|
||||
} else if (dimensions != null && dimensions!!.isNotEmpty() && ctx.world.dimensionType().effectsLocation !in dimensions!!) {
|
||||
return false
|
||||
} else if (biomes != null && biomes!!.isNotEmpty() && biomes!!.none { condition -> condition.fits(ctx.biomeHolder) }) {
|
||||
} else if (biomes != null && biomes!!.isNotEmpty() && biomes!!.none { condition -> condition.fits(ctx.biome, ctx.biomeRegistry) }) {
|
||||
return false
|
||||
} else if (appendages.any { !it.fits(ctx) }) {
|
||||
return false
|
||||
@@ -154,11 +153,11 @@ abstract class SpawningCondition<T : SpawningContext> {
|
||||
}
|
||||
|
||||
open fun isValid(): Boolean {
|
||||
if (biomes != null && biomes!!.any { it == null })
|
||||
if(biomes != null && biomes!!.any {it == null})
|
||||
return false
|
||||
if (dimensions != null && dimensions!!.any { it == null })
|
||||
if(dimensions != null && dimensions!!.any {it == null})
|
||||
return false
|
||||
if (structures != null && structures!!.any { it == null })
|
||||
if(structures != null && structures!!.any {it == null})
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
+2
-12
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* A type of precalculation that can occur on a list of [SpawnDetail] to accelerate
|
||||
@@ -32,7 +31,7 @@ import net.minecraft.resources.ResourceLocation
|
||||
*/
|
||||
interface SpawningPrecalculation<T : Any> {
|
||||
/** Retrieves the precalculation keys for the given spawn detail. */
|
||||
fun select(detail: SpawnDetail): Collection<T>
|
||||
fun select(detail: SpawnDetail): List<T>
|
||||
/** Retrieves the precalculation key for the given context, if that key exists for this context. */
|
||||
fun select(ctx: SpawningContext): T?
|
||||
|
||||
@@ -72,8 +71,7 @@ interface SpawningPrecalculation<T : Any> {
|
||||
* @since January 31st, 2022
|
||||
*/
|
||||
object RootPrecalculation : SpawningPrecalculation<Any> {
|
||||
val list = listOf(Unit)
|
||||
override fun select(detail: SpawnDetail): List<Any> = list
|
||||
override fun select(detail: SpawnDetail): List<Any> = listOf(Unit)
|
||||
override fun select(ctx: SpawningContext): Any = Unit
|
||||
}
|
||||
|
||||
@@ -91,15 +89,7 @@ object ContextPrecalculation : SpawningPrecalculation<Class<out SpawningContext>
|
||||
object BucketPrecalculation : SpawningPrecalculation<SpawnBucket> {
|
||||
override fun select(detail: SpawnDetail) = listOf(detail.bucket)
|
||||
override fun select(ctx: SpawningContext) = ctx.cause.bucket
|
||||
}
|
||||
|
||||
/**
|
||||
* This isn't so much of a precalculation as it is a yoinking of another precalculation.
|
||||
* Uses pre-established [SpawnDetail.validBiomes] to shortcut knowing which spawns are valid for a biome.
|
||||
*/
|
||||
object BiomePrecalculation : SpawningPrecalculation<ResourceLocation> {
|
||||
override fun select(detail: SpawnDetail) = detail.validBiomes
|
||||
override fun select(ctx: SpawningContext) = ctx.biomeHolder.unwrapKey().map { it.location() }.orElse(null)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-2
@@ -18,7 +18,6 @@ import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Holder
|
||||
|
||||
/**
|
||||
* A [SpawningContext] that is for a particular area, and therefore has spatial properties.
|
||||
@@ -40,7 +39,6 @@ open class AreaSpawningContext(
|
||||
val slice: WorldSlice
|
||||
) : SpawningContext() {
|
||||
val nearbyBlockTypes: List<Block> by lazy { nearbyBlocks.mapNotNull { it.block }.distinct() }
|
||||
val nearbyBlockHolders: List<Holder<Block>> by lazy { nearbyBlockTypes.mapNotNull(blockRegistry::wrapAsHolder) }
|
||||
|
||||
override fun getStructureCache(pos: BlockPos): StructureChunkCache {
|
||||
return slice.getStructureCache(pos)
|
||||
|
||||
-4
@@ -11,12 +11,9 @@ package com.cobblemon.mod.common.api.spawning.context
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.WorldSlice
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.util.blockRegistry
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.tags.FluidTags
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
/**
|
||||
@@ -39,7 +36,6 @@ abstract class FlooredSpawningContext(
|
||||
) : AreaSpawningContext(cause, world, position, light, skyLight, canSeeSky, influences, height, nearbyBlocks, slice) {
|
||||
/** The block that the spawning is occurring on. */
|
||||
val baseBlock = slice.getBlockState(position.x, position.y, position.z)
|
||||
val baseBlockHolder: Holder<Block> by lazy { world.blockRegistry.wrapAsHolder(baseBlock.block) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-3
@@ -82,9 +82,7 @@ abstract class SpawningContext {
|
||||
/** The current phase of the moon at this location. */
|
||||
val moonPhase: Int by lazy { world.moonPhase }
|
||||
/** The biome of this location. */
|
||||
val biome: Biome by lazy { biomeHolder.value() }
|
||||
/** The registry holder for the biome this context is in. */
|
||||
val biomeHolder: Holder<Biome> by lazy { world.getBiome(position) }
|
||||
val biome: Biome by lazy { world.getBiome(position).value() }
|
||||
|
||||
val biomeRegistry: Registry<Biome> by lazy { world.registryAccess().registryOrThrow(Registries.BIOME) }
|
||||
val blockRegistry: Registry<Block> by lazy { world.registryAccess().registryOrThrow(Registries.BLOCK) }
|
||||
|
||||
+1
-2
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.api.Priority
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.tags.FluidTags
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
@@ -30,7 +29,7 @@ import net.minecraft.world.level.block.state.BlockState
|
||||
*/
|
||||
interface SpawningContextCalculator<I : SpawningContextInput, O : SpawningContext> {
|
||||
companion object {
|
||||
val isAirCondition: (BlockState) -> Boolean = { it.isAir || (!it.isSolid && !it.fluidState.`is`(FluidTags.WATER) && !it.`is`(BlockTags.RAILS)) }
|
||||
val isAirCondition: (BlockState) -> Boolean = { it.isAir || (!it.isSolid && !it.fluidState.`is`(FluidTags.WATER)) }
|
||||
val isSolidCondition: (BlockState) -> Boolean = { it.isSolid }
|
||||
val isWaterCondition: (BlockState) -> Boolean = { it.fluidState.`is`(FluidTags.WATER) && it.fluidState.isSource }
|
||||
val isLavaCondition: (BlockState) -> Boolean = { it.fluidState.`is`(FluidTags.LAVA) && it.fluidState.isSource }
|
||||
|
||||
+1
@@ -88,6 +88,7 @@ class PokemonSpawnDetail : SpawnDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
struct.setDirectly("pokemon", pokemonStruct)
|
||||
super.autoLabel()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.api.spawning.detail
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.ArrayStruct
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.bedrockk.molang.runtime.struct.VariableStruct
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
@@ -23,9 +22,6 @@ import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.multiplier.WeightMultiplier
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.MinecraftServer
|
||||
|
||||
/**
|
||||
* A spawnable unit in the Best Spawner API. This is extended for any kind of entity
|
||||
@@ -59,41 +55,24 @@ abstract class SpawnDetail : ModDependant {
|
||||
|
||||
var labels = mutableListOf<String>()
|
||||
|
||||
/**
|
||||
* This is calculated when the server starts. It is a set of all biome identifiers in which this spawn
|
||||
* is possible. It is used as part of the [com.cobblemon.mod.common.api.spawning.condition.BiomePrecalculation].
|
||||
*/
|
||||
@Transient
|
||||
val validBiomes = mutableSetOf<ResourceLocation>()
|
||||
|
||||
@Transient
|
||||
val struct: QueryStruct = QueryStruct(hashMapOf())
|
||||
val struct: VariableStruct = VariableStruct()
|
||||
|
||||
override var neededInstalledMods = listOf<String>()
|
||||
override var neededUninstalledMods = listOf<String>()
|
||||
|
||||
open fun autoLabel() {
|
||||
struct.setDirectly("weight", DoubleValue(weight.toDouble()))
|
||||
struct.setDirectly("percentage", DoubleValue(percentage.toDouble()))
|
||||
struct.setDirectly("id", StringValue(id))
|
||||
struct.setDirectly("bucket", StringValue(bucket.name))
|
||||
struct.setDirectly("width", DoubleValue(width.toDouble()))
|
||||
struct.setDirectly("height", DoubleValue(height.toDouble()))
|
||||
struct.setDirectly("context", StringValue(context.name))
|
||||
struct.setDirectly("labels", ArrayStruct(labels.mapIndexed { index, s -> "$index" to StringValue(s) }.toMap()))
|
||||
}
|
||||
|
||||
open fun getName() = displayName?.asTranslated() ?: id.text()
|
||||
|
||||
open fun onServerLoad(server: MinecraftServer) {
|
||||
val biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME)
|
||||
validBiomes.clear()
|
||||
|
||||
// Calculate in advance what biomes of this world the spawn detail is valid for.
|
||||
biomeRegistry.holders().forEach { holder ->
|
||||
val key = holder.unwrapKey().orElse(null) ?: return@forEach
|
||||
if (conditions.isEmpty() || conditions.any { it.biomes == null || it.biomes!!.isEmpty() || it.biomes!!.any { it.fits(holder) } }) {
|
||||
if (anticonditions.isEmpty() || anticonditions.none { it.biomes != null && it.biomes!!.any { it.fits(holder) } }) {
|
||||
if (compositeCondition?.isBiomeValid(holder) != false) {
|
||||
validBiomes.add(key.location())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun isSatisfiedBy(ctx: SpawningContext): Boolean {
|
||||
if (!ctx.preFilter(this)) {
|
||||
return false
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.spawning.detail
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawnPools
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnLoader
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnSet
|
||||
import com.cobblemon.mod.common.api.spawning.condition.PrecalculationResult
|
||||
@@ -19,7 +18,6 @@ import com.cobblemon.mod.common.api.spawning.condition.SpawningPrecalculation
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -50,10 +48,6 @@ class SpawnPool(val name: String) : JsonDataRegistry<SpawnSet>, Iterable<SpawnDe
|
||||
for (set in data.values) {
|
||||
details.addAll(set.filter { it.isValid() })
|
||||
}
|
||||
val server = server()
|
||||
if (server != null && server.isRunning) {
|
||||
CobblemonSpawnPools.onServerLoad(server)
|
||||
}
|
||||
precalculate()
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -10,12 +10,15 @@ package com.cobblemon.mod.common.api.spawning.fishing
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.Priority
|
||||
import com.cobblemon.mod.common.api.abilities.Abilities
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.fishing.BobberSpawnPokemonEvent
|
||||
import com.cobblemon.mod.common.api.fishing.FishingBait
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.egg.EggGroup
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
@@ -24,6 +27,7 @@ import com.cobblemon.mod.common.api.spawning.detail.PokemonSpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.api.types.tera.TeraTypes
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.item.interactive.PokerodItem
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
@@ -125,8 +129,8 @@ class FishingSpawnCause(
|
||||
}
|
||||
|
||||
fun alterFriendshipAttempt(pokemonEntity: PokemonEntity, effect: FishingBait.Effect) {
|
||||
if (pokemonEntity.pokemon.friendship + effect.value > Cobblemon.config.maxPokemonFriendship)
|
||||
pokemonEntity.pokemon.setFriendship(Cobblemon.config.maxPokemonFriendship)
|
||||
if (pokemonEntity.pokemon.friendship + effect.value > 255)
|
||||
pokemonEntity.pokemon.setFriendship(255)
|
||||
else
|
||||
pokemonEntity.pokemon.setFriendship(pokemonEntity.pokemon.friendship + effect.value.toInt())
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.api.spawning.influence
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
|
||||
import net.minecraft.tags.BlockTags
|
||||
|
||||
/**
|
||||
* Implements a [SpawningInfluence] that prevents Pokémon spawning on certain blocks.
|
||||
* This ensures that Pokémon don't spawn in areas that could disrupt player-built structures or mechanisms.
|
||||
* The influence checks the block directly above the potential spawn location; if the block is in the restricted list,
|
||||
* the spawn is disallowed.
|
||||
*
|
||||
* @author Aethen
|
||||
* @since February 20th, 2024
|
||||
*/
|
||||
open class RestrictedSpawnBlocksInfluence
|
||||
: SpawningInfluence {
|
||||
|
||||
// The list of blocks that Pokémon are not allowed to spawn on.
|
||||
private val restrictedBlocks = BlockTags.RAILS
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Affects the spawnable status of a Pokémon spawn detail.
|
||||
* If the block directly above the spawn location is in the restricted list, the spawn is disallowed.
|
||||
*
|
||||
* @param detail The Pokémon spawn detail to be affected.
|
||||
* @param ctx The context of the spawning event.
|
||||
* @return `true` if the spawn is allowed, `false` if it is disallowed.
|
||||
*/
|
||||
override fun affectSpawnable(detail: SpawnDetail, ctx: SpawningContext): Boolean {
|
||||
// If the spawn detail is not a Pokémon, it is not affected by this influence.
|
||||
if (detail.type != "pokemon") return true
|
||||
|
||||
// Get the position of the potential spawn location.
|
||||
val pokemonSpawnPos = ctx.position
|
||||
|
||||
// Examine the block immediately above the spawn block to check for a rail
|
||||
// Potentially need a refactor if we ever want to check the spawn block itself.
|
||||
return ctx.world.getBlockState(pokemonSpawnPos.atY(pokemonSpawnPos.y + 1)).`is`(restrictedBlocks).not()
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -53,7 +53,7 @@ class BestSpawnerConfig {
|
||||
.create()
|
||||
|
||||
const val CONFIG_NAME = "best-spawner-config"
|
||||
const val INTERNAL_PATH = "/data/${Cobblemon.MODID}/spawning/$CONFIG_NAME.json"
|
||||
const val INTERNAL_PATH = "data/${Cobblemon.MODID}/spawning/$CONFIG_NAME.json"
|
||||
const val EXTERNAL_PATH = "config/${Cobblemon.MODID}/spawning/$CONFIG_NAME.json"
|
||||
|
||||
fun load(): BestSpawnerConfig {
|
||||
@@ -77,7 +77,7 @@ class BestSpawnerConfig {
|
||||
}
|
||||
|
||||
private fun loadInternal(): BestSpawnerConfig {
|
||||
val reader = InputStreamReader(Cobblemon::class.java.getResourceAsStream(INTERNAL_PATH)!!)
|
||||
val reader = InputStreamReader(Cobblemon.javaClass.classLoader.getResourceAsStream(INTERNAL_PATH)!!)
|
||||
val config = GSON.fromJson(reader, BestSpawnerConfig::class.java)
|
||||
reader.close()
|
||||
return config
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.spawning.SpawnerManager
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
|
||||
import com.cobblemon.mod.common.api.spawning.influence.PlayerLevelRangeInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.influence.PlayerLevelRangeInfluence.Companion.TYPICAL_VARIATION
|
||||
import com.cobblemon.mod.common.api.spawning.influence.RestrictedSpawnBlocksInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
|
||||
import com.cobblemon.mod.common.api.spawning.rules.SpawnRule
|
||||
import com.cobblemon.mod.common.util.mutableLazy
|
||||
@@ -44,7 +45,7 @@ object PlayerSpawnerFactory {
|
||||
it,
|
||||
variation = TYPICAL_VARIATION
|
||||
)
|
||||
})
|
||||
}, { RestrictedSpawnBlocksInfluence() })
|
||||
|
||||
fun create(spawnerManager: SpawnerManager, player: ServerPlayer): PlayerSpawner {
|
||||
val influences = influenceBuilders.mapNotNull { it(player) }
|
||||
|
||||
@@ -45,9 +45,9 @@ open class BottomlessStore(override val uuid: UUID) : PokemonStore<BottomlessPos
|
||||
override fun initialize() {
|
||||
pokemon.forEachIndexed { index, pokemon ->
|
||||
pokemon.storeCoordinates.set(StoreCoordinates(this, BottomlessPosition(index)))
|
||||
// pokemon.getChangeObservable().pipe(
|
||||
// stopAfter { it.storeCoordinates.get()?.store != this }
|
||||
// ).subscribe { storeChangeObservable.emit(Unit) }
|
||||
pokemon.getChangeObservable().pipe(
|
||||
stopAfter { it.storeCoordinates.get()?.store != this }
|
||||
).subscribe { storeChangeObservable.emit(Unit) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,10 +98,6 @@ open class BottomlessStore(override val uuid: UUID) : PokemonStore<BottomlessPos
|
||||
|
||||
override fun getAnyChangeObservable() = storeChangeObservable
|
||||
|
||||
override fun onPokemonChange(pokemon: Pokemon) {
|
||||
this.storeChangeObservable.emit(Unit)
|
||||
}
|
||||
|
||||
override fun setAtPosition(position: BottomlessPosition, pokemon: Pokemon?) {
|
||||
if (position.currentIndex == this.pokemon.size && pokemon != null) {
|
||||
this.pokemon.add(pokemon)
|
||||
|
||||
@@ -168,6 +168,4 @@ abstract class PokemonStore<T : StorePosition> : Iterable<Pokemon> {
|
||||
* each change, accessed by [Pokemon.getChangeObservable].
|
||||
*/
|
||||
abstract fun getAnyChangeObservable(): Observable<Unit>
|
||||
|
||||
abstract fun onPokemonChange(pokemon: Pokemon)
|
||||
}
|
||||
@@ -73,13 +73,9 @@ open class PartyStore(override val uuid: UUID) : PokemonStore<PartyPosition>() {
|
||||
}
|
||||
|
||||
fun trackPokemon(pokemon: Pokemon) {
|
||||
// pokemon.getChangeObservable()
|
||||
// .pipe(stopAfter { pokemon.storeCoordinates.get()?.store != this })
|
||||
// .subscribe { anyChangeObservable.emit(Unit) }
|
||||
}
|
||||
|
||||
override fun onPokemonChange(pokemon: Pokemon) {
|
||||
anyChangeObservable.emit(Unit)
|
||||
pokemon.getChangeObservable()
|
||||
.pipe(stopAfter { pokemon.storeCoordinates.get()?.store != this })
|
||||
.subscribe { anyChangeObservable.emit(Unit) }
|
||||
}
|
||||
|
||||
override fun getFirstAvailablePosition(): PartyPosition? {
|
||||
|
||||
@@ -89,14 +89,14 @@ open class PCBox(val pc: PCStore) : Iterable<Pokemon> {
|
||||
}
|
||||
|
||||
fun trackPokemon(pokemon: Pokemon) {
|
||||
// pokemon.getChangeObservable()
|
||||
// .pipe(
|
||||
// stopAfter {
|
||||
// val coordinates = it.storeCoordinates.get() ?: return@stopAfter true
|
||||
// return@stopAfter coordinates.store !is PCStore || coordinates.store.uuid != pc.uuid || (coordinates.position as PCPosition).box != boxNumber
|
||||
// }
|
||||
// )
|
||||
// .subscribe { boxChangeEmitter.emit(Unit) }
|
||||
pokemon.getChangeObservable()
|
||||
.pipe(
|
||||
stopAfter {
|
||||
val coordinates = it.storeCoordinates.get() ?: return@stopAfter true
|
||||
return@stopAfter coordinates.store !is PCStore || coordinates.store.uuid != pc.uuid || (coordinates.position as PCPosition).box != boxNumber
|
||||
}
|
||||
)
|
||||
.subscribe { boxChangeEmitter.emit(Unit) }
|
||||
}
|
||||
|
||||
fun sendTo(player: ServerPlayer) {
|
||||
|
||||
@@ -250,10 +250,6 @@ open class PCStore(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPokemonChange(pokemon: Pokemon) {
|
||||
this.pcChangeObservable.emit(Unit)
|
||||
}
|
||||
|
||||
fun clearPC() {
|
||||
boxes.forEach { box ->
|
||||
box.getNonEmptySlots().forEach{
|
||||
|
||||
+14
-14
@@ -27,15 +27,15 @@ import net.minecraft.world.entity.player.Player
|
||||
* @since February 21, 2024
|
||||
*/
|
||||
|
||||
open class PlayerInstancedDataStoreManager {
|
||||
class PlayerInstancedDataStoreManager {
|
||||
val factories = mutableMapOf<PlayerInstancedDataStoreType, PlayerInstancedDataFactory<*>>()
|
||||
val saveTasks = mutableMapOf<PlayerInstancedDataStoreType, ScheduledTask>()
|
||||
open fun setFactory(factory: PlayerInstancedDataFactory<*>, dataType: PlayerInstancedDataStoreType) {
|
||||
fun setFactory(factory: PlayerInstancedDataFactory<*>, dataType: PlayerInstancedDataStoreType) {
|
||||
factories[dataType] = factory
|
||||
}
|
||||
|
||||
|
||||
open fun setup(server: MinecraftServer) {
|
||||
fun setup(server: MinecraftServer) {
|
||||
factories.values.forEach {
|
||||
it.setup(server)
|
||||
}
|
||||
@@ -57,62 +57,62 @@ open class PlayerInstancedDataStoreManager {
|
||||
.build()
|
||||
}
|
||||
|
||||
open fun get(playerId: UUID, dataType: PlayerInstancedDataStoreType): InstancedPlayerData {
|
||||
fun get(playerId: UUID, dataType: PlayerInstancedDataStoreType): InstancedPlayerData {
|
||||
if (!factories.contains(dataType)) {
|
||||
throw UnsupportedOperationException("No factory registered for $dataType")
|
||||
}
|
||||
return factories[dataType]!!.getForPlayer(playerId)
|
||||
}
|
||||
|
||||
open fun get(player: Player, dataType: PlayerInstancedDataStoreType): InstancedPlayerData {
|
||||
fun get(player: Player, dataType: PlayerInstancedDataStoreType): InstancedPlayerData {
|
||||
return get(player.uuid, dataType)
|
||||
}
|
||||
|
||||
open fun saveAllOfOneType(dataType: PlayerInstancedDataStoreType) {
|
||||
fun saveAllOfOneType(dataType: PlayerInstancedDataStoreType) {
|
||||
if (!factories.contains(dataType)) {
|
||||
throw UnsupportedOperationException("No factory registered for $dataType")
|
||||
}
|
||||
return factories[dataType]!!.saveAll()
|
||||
}
|
||||
|
||||
open fun saveSingle(playerData: InstancedPlayerData, dataType: PlayerInstancedDataStoreType) {
|
||||
fun saveSingle(playerData: InstancedPlayerData, dataType: PlayerInstancedDataStoreType) {
|
||||
if (!factories.contains(dataType)) {
|
||||
throw UnsupportedOperationException("No factory registered for $dataType")
|
||||
}
|
||||
return factories[dataType]!!.saveSingle(playerData.uuid)
|
||||
}
|
||||
|
||||
open fun onPlayerDisconnect(player: ServerPlayer) {
|
||||
fun onPlayerDisconnect(player: ServerPlayer) {
|
||||
factories.values.forEach {
|
||||
it.onPlayerDisconnect(player)
|
||||
}
|
||||
}
|
||||
|
||||
open fun syncAllToPlayer(player: ServerPlayer) {
|
||||
fun syncAllToPlayer(player: ServerPlayer) {
|
||||
factories.values.forEach {
|
||||
it.sendToPlayer(player)
|
||||
}
|
||||
}
|
||||
|
||||
open fun saveAllStores() {
|
||||
fun saveAllStores() {
|
||||
factories.values.forEach {
|
||||
it.saveAll()
|
||||
}
|
||||
}
|
||||
|
||||
open fun getGenericData(player: ServerPlayer): GeneralPlayerData {
|
||||
fun getGenericData(player: ServerPlayer): GeneralPlayerData {
|
||||
return getGenericData(player.uuid)
|
||||
}
|
||||
|
||||
open fun getGenericData(playerId: UUID): GeneralPlayerData {
|
||||
fun getGenericData(playerId: UUID): GeneralPlayerData {
|
||||
return get(playerId, PlayerInstancedDataStoreTypes.GENERAL) as GeneralPlayerData
|
||||
}
|
||||
|
||||
open fun getPokedexData(player: ServerPlayer): PokedexManager {
|
||||
fun getPokedexData(player: ServerPlayer): PokedexManager {
|
||||
return getPokedexData(player.uuid)
|
||||
}
|
||||
|
||||
open fun getPokedexData(playerId: UUID): PokedexManager {
|
||||
fun getPokedexData(playerId: UUID): PokedexManager {
|
||||
return get(playerId, PlayerInstancedDataStoreTypes.POKEDEX) as PokedexManager
|
||||
}
|
||||
}
|
||||
@@ -23,72 +23,30 @@ object CobblemonBlockTags {
|
||||
|
||||
@JvmField val ALL_HANGING_SIGNS = createTag("all_hanging_signs")
|
||||
@JvmField val ALL_SIGNS = createTag("all_signs")
|
||||
@JvmField val ANCIENT_CITY_BLOCKS = createTag("ancient_city_blocks")
|
||||
@JvmField val APRICORN_LEAVES = createTag("apricorn_leaves")
|
||||
@JvmField val APRICORN_LOGS = createTag("apricorn_logs")
|
||||
@JvmField val APRICORN_SAPLINGS = createTag("apricorn_saplings")
|
||||
@JvmField val APRICORNS = createTag("apricorns")
|
||||
@JvmField val BERRIES = createTag("berries")
|
||||
@JvmField val BERRY_REPLACEABLE = createTag("berry_replaceable")
|
||||
@JvmField val BERRY_SOIL = createTag("berry_soil")
|
||||
@JvmField val BERRY_WILD_SOIL = createTag("berry_wild_soil")
|
||||
@JvmField val BLACK_TUMBLESTONE_BRICKS = createTag("black_tumblestone_bricks")
|
||||
@JvmField val BLACK_TUMBLESTONES = createTag("black_tumblestones")
|
||||
@JvmField val BLUE_FLOWERS = createTag("blue_flowers")
|
||||
@JvmField val BERRY_SOIL = createTag("berry_soil")
|
||||
@JvmField val BERRY_REPLACEABLE = createTag("berry_replaceable")
|
||||
@JvmField val CEILING_HANGING_SIGNS = createTag("ceiling_hanging_signs")
|
||||
@JvmField val CROPS = createTag("crops")
|
||||
@JvmField val DAWN_STONE_ORES = createTag("dawn_stone_ores")
|
||||
@JvmField val DESERT_PYRAMID_BLOCKS = createTag("desert_pyramid_blocks")
|
||||
@JvmField val DRIPSTONE_GROWABLE = createTag("dripstone_growable")
|
||||
@JvmField val DRIPSTONE_REPLACEABLES = createTag("dripstone_replaceables")
|
||||
@JvmField val DUSK_STONE_ORES = createTag("dusk_stone_ores")
|
||||
@JvmField val END_CITY_BLOCKS = createTag("end_city_blocks")
|
||||
@JvmField val EVOLUTION_STONE_BLOCKS = createTag("evolution_stone_blocks")
|
||||
@JvmField val FIRE_STONE_ORES = createTag("fire_stone_ores")
|
||||
@JvmField val FLOWERS = createTag("flowers")
|
||||
@JvmField val FOSSIL_MACHINE_PARTS = createTag("fossil_machine_parts")
|
||||
@JvmField val GEMSTONES = createTag("gemstones")
|
||||
@JvmField val GILDED_CHESTS = createTag("gilded_chests")
|
||||
@JvmField val GLAZED_TERRACOTTA_BLOCKS = createTag("glazed_terracotta_blocks")
|
||||
@JvmField val ICE_STONE_ORES = createTag("ice_stone_ores")
|
||||
@JvmField val JUNGLE_PYRAMID_BLOCKS = createTag("jungle_pyramid_blocks")
|
||||
@JvmField val LEAF_STONE_ORES = createTag("leaf_stone_ores")
|
||||
@JvmField val MACHINES = createTag("machines")
|
||||
@JvmField val MANSION_BLOCKS = createTag("mansion_blocks")
|
||||
@JvmField val MEDICINAL_LEEK_PLANTABLE = createTag("medicinal_leek_plantable")
|
||||
@JvmField val MINTS = createTag("mints")
|
||||
@JvmField val MOON_STONE_ORES = createTag("moon_stone_ores")
|
||||
@JvmField val NATURAL = createTag("natural")
|
||||
@JvmField val NETHER_STRUCTURE_BLOCKS = createTag("nether_structure_blocks")
|
||||
@JvmField val PINK_FLOWERS = createTag("pink_flowers")
|
||||
@JvmField val RED_FLOWERS = createTag("red_flowers")
|
||||
@JvmField val RED_TUMBLESTONE_BRICKS = createTag("red_tumblestone_bricks")
|
||||
@JvmField val RED_TUMBLESTONES = createTag("red_tumblestones")
|
||||
@JvmField val REDSTONE_BLOCKS = createTag("redstone_blocks")
|
||||
@JvmField val ROOTS = createTag("roots")
|
||||
@JvmField val ROOTS_SPREADABLE = createTag("roots_spreadable")
|
||||
@JvmField val RUINED_PORTAL_BLOCKS = createTag("ruined_portal_blocks")
|
||||
@JvmField val SEES_SKY = createTag("sees_sky")
|
||||
@JvmField val SHINY_STONE_ORES = createTag("shiny_stone_ores")
|
||||
@JvmField val SIGNS = createTag("signs")
|
||||
@JvmField val SKY_TUMBLESTONE_BRICKS = createTag("sky_tumblestone_bricks")
|
||||
@JvmField val SKY_TUMBLESTONES = createTag("sky_tumblestones")
|
||||
@JvmField val SMALL_FLOWERS = createTag("small_flowers")
|
||||
@JvmField val SEES_SKY = createTag("sees_sky")
|
||||
@JvmField val SNOW_BLOCK = createTag("snow_block")
|
||||
@JvmField val ROOTS = createTag("roots")
|
||||
@JvmField val STANDING_SIGNS = createTag("standing_signs")
|
||||
@JvmField val SUN_STONE_ORES = createTag("sun_stone_ores")
|
||||
@JvmField val THUNDER_STONE_ORES = createTag("thunder_stone_ores")
|
||||
@JvmField val TRAIL_RUINS_BLOCKS = createTag("trail_ruins_blocks")
|
||||
@JvmField val TRASH = createTag("trash")
|
||||
@JvmField val TREES = createTag("trees")
|
||||
@JvmField val TUMBLESTONE_BRICKS = createTag("tumblestone_bricks")
|
||||
@JvmField val TUMBLESTONES = createTag("tumblestones")
|
||||
@JvmField val TUMBLESTONE_HEAT_SOURCE = createTag("tumblestone_heat_source")
|
||||
@JvmField val WALL_HANGING_SIGNS = createTag("wall_hanging_signs")
|
||||
@JvmField val WALL_SIGNS = createTag("wall_signs")
|
||||
@JvmField val WATER_STONE_ORES = createTag("water_stone_ores")
|
||||
@JvmField val WHITE_FLOWERS = createTag("white_flowers")
|
||||
@JvmField val YELLOW_FLOWERS = createTag("yellow_flowers")
|
||||
|
||||
private fun createTag(name: String) = TagKey.create(Registries.BLOCK, cobblemonResource(name))
|
||||
|
||||
|
||||
@@ -21,108 +21,137 @@ import net.minecraft.tags.TagKey
|
||||
*/
|
||||
@Suppress("unused", "HasPlatformType")
|
||||
object CobblemonItemTags {
|
||||
@JvmField val ABILITY_CHANGERS = create("ability_changers")
|
||||
@JvmField val ANCIENT_POKE_BALLS = create("ancient_poke_balls")
|
||||
@JvmField val APPLES = create("apples")
|
||||
@JvmField val APRICORN_LOGS = create("apricorn_logs")
|
||||
@JvmField val APRICORN_POKE_BALLS = create("apricorn_poke_balls")
|
||||
@JvmField val APRICORN_SPROUTS = create("apricorn_sprouts")
|
||||
@JvmField val APRICORNS = create("apricorns")
|
||||
/** This tag is only used for a Torterra aspect based easter egg evolution at the moment.
|
||||
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default. */
|
||||
@JvmField val AZALEA_TREE = create("azalea_tree")
|
||||
@JvmField val BATTLE_ITEMS = create("battle_items")
|
||||
@JvmField val BERRIES = create("berries")
|
||||
@JvmField val BLACK_TUMBLESTONE_BRICKS = create("black_tumblestone_bricks")
|
||||
@JvmField val BLACK_TUMBLESTONES = create("black_tumblestones")
|
||||
@JvmField val BOATS = create("boats")
|
||||
/** This tag is used for Fossil Machine natural materials */
|
||||
@JvmField val COOKED_MEAT = create("cooked_meat")
|
||||
@JvmField val DAWN_STONE_ORES = create("dawn_stone_ores")
|
||||
@JvmField val POTTERY_SHERDS = create("decorated_pot_sherds")
|
||||
@JvmField val DEEP_SEAS = create("deep_seas")
|
||||
@JvmField val DUSK_STONE_ORES = create("dusk_stone_ores")
|
||||
@JvmField val ETHERS = create("ethers")
|
||||
@JvmField val EVOLUTION_ITEMS = create("evolution_items")
|
||||
@JvmField val EVOLUTION_STONE_BLOCKS = create("evolution_stone_blocks")
|
||||
@JvmField val EVOLUTION_STONES = create("evolution_stones")
|
||||
@JvmField val EXPERIENCE_CANDIES = create("experience_candies")
|
||||
@JvmField val FEATHERS = create("feathers")
|
||||
@JvmField val FIRE_STONE_ORES = create("fire_stone_ores")
|
||||
@JvmField val FOSSIL_MACHINE_PARTS = create("fossil_machine_parts")
|
||||
@JvmField val FOSSILS = create("fossils")
|
||||
@JvmField val GILDED_CHESTS = create("gilded_chests")
|
||||
@JvmField val HANGING_SIGNS = create("hanging_signs")
|
||||
@JvmField val HERBS = create("herbs")
|
||||
@JvmField val ICE_STONE_ORES = create("ice_stone_ores")
|
||||
@JvmField val LEAF_STONE_ORES = create("leaf_stone_ores")
|
||||
@JvmField val MACHINES = create("machines")
|
||||
@JvmField val MINT_LEAF = create("mint_leaf")
|
||||
@JvmField val MINT_SEEDS = create("mint_seeds")
|
||||
@JvmField val MINTS = create("mints")
|
||||
@JvmField val MOON_STONE_ORES = create("moon_stone_ores")
|
||||
@JvmField val MUTATED_BERRIES = create("mutated_berries")
|
||||
@JvmField val PLANTS = create("plants")
|
||||
@JvmField val POKE_BALLS = create("poke_balls")
|
||||
@JvmField val POKE_RODS = create("poke_rods")
|
||||
@JvmField val POKEDEX = create("pokedex")
|
||||
@JvmField val POKEDEX_SCREEN = create("pokedex_screen")
|
||||
@JvmField val POTIONS = create("potions")
|
||||
@JvmField val PROTEIN_INGREDIENTS = create("protein_ingredients")
|
||||
@JvmField
|
||||
val ANCIENT_POKE_BALLS = create("ancient_poke_balls")
|
||||
@JvmField
|
||||
val APRICORN_LOGS = create("apricorn_logs")
|
||||
@JvmField
|
||||
val APRICORN_SPROUTS = create("apricorn_sprouts")
|
||||
@JvmField
|
||||
val APRICORNS = create("apricorns")
|
||||
@JvmField
|
||||
val POKEDEX = create("pokedex")
|
||||
/**
|
||||
* This tag is only used for a Torterra aspect based easter egg evolution at the moment.
|
||||
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default.
|
||||
*/
|
||||
@JvmField
|
||||
val AZALEA_TREE = create("azalea_tree")
|
||||
@JvmField
|
||||
val BERRIES = create("berries")
|
||||
@JvmField
|
||||
val BOATS = create("boats")
|
||||
@JvmField
|
||||
val COBBLEMON_SEEDS = create("cobblemon_seeds")
|
||||
/**
|
||||
* This tag is used for Fossil Machine natural materials
|
||||
*/
|
||||
@JvmField
|
||||
val COOKED_MEAT = create("cooked_meat")
|
||||
@JvmField
|
||||
val DAWN_STONE_ORES = create("dawn_stone_ores")
|
||||
@JvmField
|
||||
val DUSK_STONE_ORES = create("dusk_stone_ores")
|
||||
@JvmField
|
||||
val EVOLUTION_ITEMS = create("evolution_items")
|
||||
@JvmField
|
||||
val EVOLUTION_STONES = create("evolution_stones")
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDIES = create("experience_candies")
|
||||
@JvmField
|
||||
val FIRE_STONE_ORES = create("fire_stone_ores")
|
||||
@JvmField
|
||||
val FOSSILS = create("fossils")
|
||||
@JvmField
|
||||
val HANGING_SIGNS = create("hanging_signs")
|
||||
@JvmField
|
||||
val HERBS = create("herbs")
|
||||
@JvmField
|
||||
val ICE_STONE_ORES = create("ice_stone_ores")
|
||||
@JvmField
|
||||
val LEAF_STONE_ORES = create("leaf_stone_ores")
|
||||
@JvmField
|
||||
val MINT_LEAF = create("mint_leaf")
|
||||
@JvmField
|
||||
val MINT_SEEDS = create("mint_seeds")
|
||||
@JvmField
|
||||
val MINTS = create("mints")
|
||||
@JvmField
|
||||
val MOON_STONE_ORES = create("moon_stone_ores")
|
||||
@JvmField
|
||||
val MUTATED_BERRIES = create("mutated_berries")
|
||||
@JvmField
|
||||
val PLANTS = create("plants")
|
||||
@JvmField
|
||||
val POKE_BALLS = create("poke_balls")
|
||||
@JvmField
|
||||
val PROTEIN_INGREDIENTS = create("protein_ingredients")
|
||||
/** See [COOKED_MEAT] */
|
||||
@JvmField val RAW_MEAT = create("raw_meat")
|
||||
@JvmField val RED_TUMBLESTONE_BRICKS = create("red_tumblestone_bricks")
|
||||
@JvmField val RED_TUMBLESTONES = create("red_tumblestones")
|
||||
@JvmField val REMEDIES = create("remedies")
|
||||
@JvmField val RESTORES = create("restores")
|
||||
@JvmField val REVIVES = create("revives")
|
||||
@JvmField val SEEDS = create("seeds")
|
||||
@JvmField val SHINY_STONE_ORES = create("shiny_stone_ores")
|
||||
@JvmField val SIGNS = create("signs")
|
||||
@JvmField val SKY_TUMBLESTONE_BRICKS = create("sky_tumblestone_bricks")
|
||||
@JvmField val SKY_TUMBLESTONES = create("sky_tumblestones")
|
||||
@JvmField val SUN_STONE_ORES = create("sun_stone_ores")
|
||||
@JvmField val SWEETS = create("sweets")
|
||||
@JvmField val TEACUPS = create("teacups")
|
||||
@JvmField val TEAPOTS = create("teapots")
|
||||
@JvmField val THUNDER_STONE_ORES = create("thunder_stone_ores")
|
||||
@JvmField val TIER_1_POKE_BALL_MATERIALS = create("tier_1_poke_ball_materials")
|
||||
@JvmField val TIER_1_POKE_BALLS = create("tier_1_poke_balls")
|
||||
@JvmField val TIER_2_POKE_BALL_MATERIALS = create("tier_2_poke_ball_materials")
|
||||
@JvmField val TIER_2_POKE_BALLS = create("tier_2_poke_balls")
|
||||
@JvmField val TIER_3_POKE_BALL_MATERIALS = create("tier_3_poke_ball_materials")
|
||||
@JvmField val TIER_3_POKE_BALLS = create("tier_3_poke_balls")
|
||||
@JvmField val TIER_4_POKE_BALL_MATERIALS = create("tier_4_poke_ball_materials")
|
||||
@JvmField val TIER_4_POKE_BALLS = create("tier_4_poke_balls")
|
||||
@JvmField val TIER_5_POKE_BALLS = create("tier_5_poke_balls")
|
||||
@JvmField val TUMBLESTONE_BRICKS = create("tumblestone_bricks")
|
||||
@JvmField val TUMBLESTONES = create("tumblestones")
|
||||
@JvmField val TYPE_GEMS = create("type_gems")
|
||||
@JvmField val VITAMINS = create("vitamins")
|
||||
@JvmField val WATER_STONE_ORES = create("water_stone_ores")
|
||||
@JvmField val ZINC_INGREDIENTS = create("zinc_ingredients")
|
||||
@JvmField
|
||||
val RAW_MEAT = create("raw_meat")
|
||||
@JvmField
|
||||
val SEEDS = create("seeds")
|
||||
@JvmField
|
||||
val SHINY_STONE_ORES = create("shiny_stone_ores")
|
||||
@JvmField
|
||||
val SIGNS = create("signs")
|
||||
@JvmField
|
||||
val SUN_STONE_ORES = create("sun_stone_ores")
|
||||
@JvmField
|
||||
val THUNDER_STONE_ORES = create("thunder_stone_ores")
|
||||
@JvmField
|
||||
val TUMBLESTONES = create("tumblestones")
|
||||
@JvmField
|
||||
val WATER_STONE_ORES = create("water_stone_ores")
|
||||
@JvmField
|
||||
val ZINC_INGREDIENTS = create("zinc_ingredients")
|
||||
|
||||
// Held Item Tags
|
||||
@JvmField val CONSUMED_IN_NPC_BATTLE = create("held/consumed_in_npc_battle")
|
||||
@JvmField val CONSUMED_IN_PVP_BATTLE = create("held/consumed_in_pvp_battle")
|
||||
@JvmField val CONSUMED_IN_WILD_BATTLE = create("held/consumed_in_wild_battle")
|
||||
@JvmField val DESTINY_KNOT = create("held/destiny_knot")
|
||||
@JvmField val EVERSTONE = create("held/everstone")
|
||||
@JvmField val EXPERIENCE_SHARE = create("held/experience_share")
|
||||
@JvmField val IS_FRIENDSHIP_BOOSTER = create("is_friendship_booster")
|
||||
@JvmField val ANY_HELD_ITEM = create("held/is_held_item")
|
||||
/** Tag that flags items as being able to "create" [CobblemonItems.LEFTOVERS]. */
|
||||
@JvmField val LEAVES_LEFTOVERS = create("held/leaves_leftovers")
|
||||
@JvmField val LUCKY_EGG = create("held/lucky_egg")
|
||||
@JvmField val POWER_ANKLET = create("held/power_anklet")
|
||||
@JvmField val POWER_BAND = create("held/power_band")
|
||||
@JvmField val POWER_BELT = create("held/power_belt")
|
||||
@JvmField val POWER_BRACER = create("held/power_bracer")
|
||||
@JvmField val POWER_LENS = create("held/power_lens")
|
||||
@JvmField val POWER_WEIGHT = create("held/power_weight")
|
||||
@JvmField val TERRAIN_SEEDS = create("held/terrain_seeds")
|
||||
@JvmField
|
||||
val ANY_HELD_ITEM = create("held/is_held_item")
|
||||
@JvmField
|
||||
val EXPERIENCE_SHARE = create("held/experience_share")
|
||||
@JvmField
|
||||
val LUCKY_EGG = create("held/lucky_egg")
|
||||
@JvmField
|
||||
val DESTINY_KNOT = create("held/destiny_knot")
|
||||
@JvmField
|
||||
val EVERSTONE = create("held/everstone")
|
||||
@JvmField
|
||||
val POWER_ANKLET = create("held/power_anklet")
|
||||
@JvmField
|
||||
val POWER_BAND = create("held/power_band")
|
||||
@JvmField
|
||||
val POWER_BELT = create("held/power_belt")
|
||||
@JvmField
|
||||
val POWER_BRACER = create("held/power_bracer")
|
||||
@JvmField
|
||||
val POWER_LENS = create("held/power_lens")
|
||||
@JvmField
|
||||
val POWER_WEIGHT = create("held/power_weight")
|
||||
@JvmField
|
||||
val CONSUMED_IN_NPC_BATTLE = create("held/consumed_in_npc_battle")
|
||||
@JvmField
|
||||
val CONSUMED_IN_PVP_BATTLE = create("held/consumed_in_pvp_battle")
|
||||
@JvmField
|
||||
val CONSUMED_IN_WILD_BATTLE = create("held/consumed_in_wild_battle")
|
||||
@JvmField
|
||||
val TERRAIN_SEEDS = create("held/terrain_seeds")
|
||||
|
||||
/**
|
||||
* Tag that flags items as being able to "create" [CobblemonItems.LEFTOVERS].
|
||||
*/
|
||||
@JvmField
|
||||
val LEAVES_LEFTOVERS = create("held/leaves_leftovers")
|
||||
|
||||
@JvmField
|
||||
val POTTERY_SHERDS = create("decorated_pot_sherds")
|
||||
|
||||
@JvmField
|
||||
val ABILITY_CHANGERS = create("ability_changers")
|
||||
|
||||
@JvmField
|
||||
val IS_FRIENDSHIP_BOOSTER = create("is_friendship_booster")
|
||||
|
||||
private fun create(path: String) = TagKey.create(Registries.ITEM, cobblemonResource(path))
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.battles.dispatch
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import org.objectweb.asm.tree.analysis.Interpreter
|
||||
|
||||
class InstructionSet {
|
||||
val instructions: MutableList<InterpreterInstruction> = mutableListOf()
|
||||
|
||||
+3
-3
@@ -65,8 +65,8 @@ class GraalShowdownUnbundler {
|
||||
}
|
||||
|
||||
if (extract) {
|
||||
FileUtils.copyInternalToExternal("/data/${Cobblemon.MODID}/showdown.zip", showdownZip.toPath())
|
||||
FileUtils.copyInternalToExternal("/data/${Cobblemon.MODID}/showdown.json", showdownMetadataFile.toPath())
|
||||
FileUtils.copyInternalToExternal("data/${Cobblemon.MODID}/showdown.zip", showdownZip.toPath())
|
||||
FileUtils.copyInternalToExternal("data/${Cobblemon.MODID}/showdown.json", showdownMetadataFile.toPath())
|
||||
FileUtils.unzipFile(showdownZip.toPath(), showdownDir.toPath())
|
||||
showdownZip.delete()
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class GraalShowdownUnbundler {
|
||||
|
||||
private fun loadShowdownMetadata() : ShowdownMetadata? {
|
||||
try {
|
||||
val inputStream = javaClass.getResourceAsStream("/data/${Cobblemon.MODID}/showdown.json")!!
|
||||
val inputStream = javaClass.classLoader.getResourceAsStream("data/${Cobblemon.MODID}/showdown.json")!!
|
||||
return gson.fromJson<ShowdownMetadata>(InputStreamReader(inputStream))
|
||||
} catch (exception: Exception) {
|
||||
exception.printStackTrace()
|
||||
|
||||
+13
-13
@@ -372,24 +372,24 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
|
||||
|
||||
override fun tick(entity: PokemonEntity) {
|
||||
incrementAge(entity)
|
||||
playWildShinySounds()
|
||||
if(currentEntity.ownerUUID == null && currentEntity.pokemon.shiny && secondsSinceLastShinyParticle > SHINY_PARTICLE_COOLDOWN && !currentEntity.isBattling) {
|
||||
//wild shiny not looked at
|
||||
playShinyEffect("cobblemon:shiny_sparkle_ambient_wild")
|
||||
lastShinyParticle = System.currentTimeMillis()
|
||||
}
|
||||
getClientShinyPokemon()
|
||||
}
|
||||
|
||||
fun playWildShinySounds() {
|
||||
fun getClientShinyPokemon() {
|
||||
val player = Minecraft.getInstance().player ?: return
|
||||
val isWithinRange = player.position().distanceTo(currentEntity.position()) <= Cobblemon.config.shinyNoticeParticlesDistance
|
||||
|
||||
if (currentEntity.pokemon.shiny && currentEntity.ownerUUID == null) {
|
||||
if (isWithinRange) {
|
||||
if (secondsSinceLastShinyParticle > SHINY_PARTICLE_COOLDOWN && !currentEntity.isBattling) {
|
||||
playShinyEffect("cobblemon:shiny_sparkle_ambient_wild")
|
||||
lastShinyParticle = System.currentTimeMillis()
|
||||
}
|
||||
if (!shined && !player.isSpectator) {
|
||||
playShinyEffect("cobblemon:wild_shiny_ring")
|
||||
shined = true
|
||||
}
|
||||
} else {
|
||||
if (currentEntity.pokemon.shiny && currentEntity.ownerUUID == null && !player.isSpectator ) {
|
||||
if (isWithinRange && !shined) {
|
||||
playShinyEffect("cobblemon:wild_shiny_ring")
|
||||
shined = true
|
||||
lastShinyParticle = System.currentTimeMillis()
|
||||
} else if (!isWithinRange) {
|
||||
shined = false
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -191,8 +191,6 @@ class BattleTargetSelection(
|
||||
matrices.pushPose()
|
||||
matrices.translate(x + TARGET_WIDTH - (25 / 2.0) - 2, y + 5.0, 0.0)
|
||||
matrices.scale(2.5F, 2.5F, 1F)
|
||||
// Grab aspects for right variant
|
||||
state.currentAspects = battlePokemon.state.currentAspects
|
||||
drawProfilePokemon(
|
||||
species = battlePokemon.species.resourceIdentifier,
|
||||
matrixStack = matrices,
|
||||
|
||||
@@ -17,10 +17,6 @@ class GrabbedStorageSlot(
|
||||
private val pokemon: Pokemon
|
||||
) : StorageSlot(x, y, parent, {}) {
|
||||
|
||||
init {
|
||||
isSelected = true
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
renderSlot(context = context, posX = mouseX - (width / 2), posY = mouseY - (height / 2), partialTicks = delta)
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ import net.minecraft.sounds.SoundEvent
|
||||
class PCGUI(
|
||||
val pc: ClientPC,
|
||||
val party: ClientParty,
|
||||
val configuration: PCGUIConfiguration,
|
||||
val openOnBox: Int = 0
|
||||
val configuration: PCGUIConfiguration
|
||||
) : Screen(Component.translatable("cobblemon.ui.pc.title")), CobblemonRenderable {
|
||||
|
||||
companion object {
|
||||
@@ -111,7 +110,6 @@ class PCGUI(
|
||||
pc = pc,
|
||||
party = party
|
||||
)
|
||||
this.storageWidget.box = openOnBox
|
||||
|
||||
this.setPreviewPokemon(null)
|
||||
this.addRenderableWidget(storageWidget)
|
||||
|
||||
@@ -46,8 +46,6 @@ open class StorageSlot(
|
||||
private val slotOverlayMoveIconResource = cobblemonResource("textures/gui/pasture/pc_slot_icon_move.png")
|
||||
}
|
||||
|
||||
protected var isSelected = false;
|
||||
|
||||
override fun playDownSound(soundManager: SoundManager) {
|
||||
}
|
||||
|
||||
@@ -84,52 +82,50 @@ open class StorageSlot(
|
||||
|
||||
context.disableScissor()
|
||||
|
||||
if (!isSelected) {
|
||||
// Ensure elements are not hidden behind Pokémon render
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 100.0)
|
||||
// Level
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = lang("ui.lv.number", pokemon.level),
|
||||
x = posX + 1,
|
||||
y = posY + 1,
|
||||
shadow = true,
|
||||
// Ensure elements are not hidden behind Pokémon render
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 100.0)
|
||||
// Level
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = lang("ui.lv.number", pokemon.level),
|
||||
x = posX + 1,
|
||||
y = posY + 1,
|
||||
shadow = true,
|
||||
scale = PCGUI.SCALE
|
||||
)
|
||||
|
||||
if (pokemon.gender != Gender.GENDERLESS) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (pokemon.gender == Gender.MALE) genderIconMale else genderIconFemale,
|
||||
x = (posX + 21) / PCGUI.SCALE,
|
||||
y = (posY + 1) / PCGUI.SCALE,
|
||||
width = 6,
|
||||
height = 8,
|
||||
scale = PCGUI.SCALE
|
||||
)
|
||||
|
||||
if (pokemon.gender != Gender.GENDERLESS) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = if (pokemon.gender == Gender.MALE) genderIconMale else genderIconFemale,
|
||||
x = (posX + 21) / PCGUI.SCALE,
|
||||
y = (posY + 1) / PCGUI.SCALE,
|
||||
width = 6,
|
||||
height = 8,
|
||||
scale = PCGUI.SCALE
|
||||
)
|
||||
}
|
||||
|
||||
// Held Item
|
||||
val heldItem = pokemon.heldItemNoCopy()
|
||||
if (!heldItem.isEmpty) {
|
||||
renderScaledGuiItemIcon(
|
||||
itemStack = heldItem,
|
||||
x = posX + 16.0,
|
||||
y = posY + 16.0,
|
||||
scale = 0.5,
|
||||
matrixStack = matrices
|
||||
)
|
||||
}
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
// Held Item
|
||||
val heldItem = pokemon.heldItemNoCopy()
|
||||
if (!heldItem.isEmpty) {
|
||||
renderScaledGuiItemIcon(
|
||||
itemStack = heldItem,
|
||||
x = posX + 16.0,
|
||||
y = posY + 16.0,
|
||||
scale = 0.5,
|
||||
matrixStack = matrices
|
||||
)
|
||||
}
|
||||
matrices.popPose()
|
||||
|
||||
// Ensure overlay elements are on top
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 500.0)
|
||||
|
||||
val config = parent.pcGui.configuration
|
||||
if (pokemon.tetheringId != null && !isSelected) {
|
||||
if (pokemon.tetheringId != null) {
|
||||
if (isStationary()) {
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
|
||||
@@ -286,10 +286,7 @@ class StorageWidget(
|
||||
}
|
||||
|
||||
pastureWidget?.render(context, mouseX, mouseY, delta)
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 1000.0)
|
||||
grabbedSlot?.render(context, mouseX, mouseY, delta)
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
|
||||
|
||||
@@ -163,8 +163,8 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
},
|
||||
text = lang("ui.evolve"),
|
||||
resource = evolveButtonResource,
|
||||
renderRequirement = { selectedPokemon.evolutionProxy.client().isNotEmpty() && CobblemonClient.battle == null },
|
||||
clickRequirement = { selectedPokemon.evolutionProxy.client().isNotEmpty() && CobblemonClient.battle == null }
|
||||
renderRequirement = { selectedPokemon.evolutionProxy.client().isNotEmpty() },
|
||||
clickRequirement = { selectedPokemon.evolutionProxy.client().isNotEmpty() }
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
package com.cobblemon.mod.common.client.gui.toast
|
||||
|
||||
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
|
||||
import net.fabricmc.api.EnvType
|
||||
import net.fabricmc.api.Environment
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.toasts.Toast
|
||||
import net.minecraft.client.gui.components.toasts.ToastComponent
|
||||
@@ -21,7 +19,6 @@ import net.minecraft.util.Mth
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
class CobblemonToast(
|
||||
val id: UUID,
|
||||
var icon: ItemStack,
|
||||
|
||||
-2
@@ -19,8 +19,6 @@ object ServerSettingsPacketHandler : ClientNetworkPacketHandler<ServerSettingsPa
|
||||
ServerSettings.displayEntityLevelLabel = packet.displayEntityLevelLabel
|
||||
ServerSettings.displayEntityNameLabel = packet.displayEntityNameLabel
|
||||
ServerSettings.maxPokemonLevel = packet.maxPokemonLevel
|
||||
ServerSettings.maxPokemonFriendship = packet.maxPokemonFriendship
|
||||
ServerSettings.maxDynamaxLevel = packet.maxDynamaxLevel
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -18,6 +18,6 @@ import net.minecraft.client.Minecraft
|
||||
object OpenPCHandler : ClientNetworkPacketHandler<OpenPCPacket> {
|
||||
override fun handle(packet: OpenPCPacket, client: Minecraft) {
|
||||
val pc = CobblemonClient.storage.pcStores[packet.storeID] ?: return
|
||||
Minecraft.getInstance().setScreen(PCGUI(pc, CobblemonClient.storage.myParty, PCGUIConfiguration(), packet.box))
|
||||
Minecraft.getInstance().setScreen(PCGUI(pc, CobblemonClient.storage.myParty, PCGUIConfiguration()))
|
||||
}
|
||||
}
|
||||
+7
-8
@@ -116,7 +116,7 @@ class PokedexScannerRenderer {
|
||||
drawScaledText(
|
||||
context = graphics,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = lang("ui.lv.number", pokedexEntityData.pokemon.level).bold(),
|
||||
text = lang("ui.lv.number", pokedexEntityData.level).bold(),
|
||||
x = centerX + xOffset + xOffsetText,
|
||||
y = centerY + yOffset + yOffsetText,
|
||||
shadow = true,
|
||||
@@ -126,7 +126,7 @@ class PokedexScannerRenderer {
|
||||
|
||||
if (infoDisplayedCounter == 2) {
|
||||
val hasTrainer = (usageContext.scannableEntityInFocus?.resolveEntityScan() as? PokemonEntity)?.ownerUUID !== null
|
||||
val speciesName = pokedexEntityData.getApparentSpecies().translatedName.bold()
|
||||
val speciesName = pokedexEntityData.species.translatedName.bold()
|
||||
var yOffsetName = if (hasTrainer) 2 else 0
|
||||
if (hasTrainer) {
|
||||
drawScaledText(
|
||||
@@ -149,7 +149,7 @@ class PokedexScannerRenderer {
|
||||
centered = true
|
||||
)
|
||||
|
||||
val gender = pokedexEntityData.pokemon.gender
|
||||
val gender = pokedexEntityData.gender
|
||||
val speciesNameWidth = Minecraft.getInstance().font.width(speciesName.font(CobblemonResources.DEFAULT_LARGE))
|
||||
if (gender != Gender.GENDERLESS) {
|
||||
val isMale = gender == Gender.MALE
|
||||
@@ -179,15 +179,14 @@ class PokedexScannerRenderer {
|
||||
}
|
||||
|
||||
if (infoDisplayedCounter == 3) {
|
||||
val typeText = lang("type.suffix", pokedexEntityData.getApparentForm().types.map { it.displayName.copy() }.reduce { acc, next -> acc.plus("/").plus(next) }).bold()
|
||||
val typeText = lang("type.suffix", pokedexEntityData.form.types.map { it.displayName.copy() }.reduce { acc, next -> acc.plus("/").plus(next) }).bold()
|
||||
val typeWidth = Minecraft.getInstance().font.width(typeText.font(CobblemonResources.DEFAULT_LARGE))
|
||||
// Split into 2 lines if text width is too long
|
||||
if (typeWidth > (OUTER_INFO_FRAME_WIDTH - 8) && pokedexEntityData.getApparentForm().secondaryType !== null) {
|
||||
val splitLines = typeText.string.split("/")
|
||||
if (typeWidth > (OUTER_INFO_FRAME_WIDTH - 8) && pokedexEntityData.form.secondaryType !== null) {
|
||||
drawScaledText(
|
||||
context = graphics,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = text(splitLines[0], "/").bold(),
|
||||
text = lang("type.suffix", pokedexEntityData.form.primaryType.displayName).bold(),
|
||||
x = centerX + xOffset + xOffsetText,
|
||||
y = centerY + yOffset + yOffsetText - 4,
|
||||
shadow = true,
|
||||
@@ -197,7 +196,7 @@ class PokedexScannerRenderer {
|
||||
drawScaledText(
|
||||
context = graphics,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = text(splitLines[1]).bold(),
|
||||
text = lang("type.suffix", pokedexEntityData.form.secondaryType!!.displayName).bold(),
|
||||
x = centerX + xOffset + xOffsetText,
|
||||
y = centerY + yOffset + yOffsetText + 3,
|
||||
shadow = true,
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.client.render
|
||||
|
||||
import com.cobblemon.mod.common.util.math.geometry.getOrigin
|
||||
import com.cobblemon.mod.common.util.math.geometry.transformPosition
|
||||
import net.fabricmc.loader.impl.lib.sat4j.core.Vec
|
||||
import org.joml.Matrix4f
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
|
||||
@@ -204,8 +204,8 @@ class SnowstormParticle(
|
||||
val spriteURange = sprite.u1 - sprite.u0
|
||||
val spriteVRange = sprite.v1 - sprite.v0
|
||||
|
||||
val maxU = uvs.startU * spriteURange + sprite.u0
|
||||
val minU = uvs.endU * spriteURange + sprite.u0
|
||||
val minU = uvs.startU * spriteURange + sprite.u0
|
||||
val maxU = uvs.endU * spriteURange + sprite.u0
|
||||
val minV = uvs.startV * spriteVRange + sprite.v0
|
||||
val maxV = uvs.endV * spriteVRange + sprite.v0
|
||||
|
||||
|
||||
-3
@@ -14,8 +14,6 @@ import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.item.interactive.PokerodItem
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import java.awt.Color
|
||||
import net.fabricmc.api.EnvType
|
||||
import net.fabricmc.api.Environment
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
@@ -33,7 +31,6 @@ import net.minecraft.world.entity.HumanoidArm
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import org.joml.Quaternionf
|
||||
|
||||
@Environment(value = EnvType.CLIENT)
|
||||
class PokeBobberEntityRenderer(context: EntityRendererProvider.Context?) : EntityRenderer<PokeRodFishingBobberEntity>(context) {
|
||||
|
||||
override fun render(fishingBobberEntity: PokeRodFishingBobberEntity, elapsedPartialTicks: Float, tickDelta: Float, matrixStack: PoseStack, vertexConsumerProvider: MultiBufferSource, light: Int) {
|
||||
|
||||
+7
-13
@@ -15,12 +15,12 @@ import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.item.PokemonItem
|
||||
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
|
||||
import com.mojang.blaze3d.platform.Lighting
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import net.minecraft.client.renderer.LightTexture
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.renderer.LightTexture
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.joml.Quaternionf
|
||||
@@ -50,10 +50,7 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
|
||||
|
||||
val transformations = positions[mode]!!
|
||||
|
||||
if (mode == ItemDisplayContext.GUI) {
|
||||
Lighting.setupForFlatItems()
|
||||
}
|
||||
|
||||
Lighting.setupForFlatItems()
|
||||
matrices.scale(transformations.scale.x, transformations.scale.y, transformations.scale.z)
|
||||
matrices.translate(transformations.translation.x, transformations.translation.y, transformations.translation.z)
|
||||
state.setPoseToFirstSuitable(PoseType.PORTRAIT)
|
||||
@@ -87,10 +84,7 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
|
||||
model.setDefault()
|
||||
matrices.popPose()
|
||||
matrices.popPose()
|
||||
|
||||
if (mode == ItemDisplayContext.GUI) {
|
||||
Lighting.setupFor3DItems()
|
||||
}
|
||||
Lighting.setupFor3DItems()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.SingleBoneLookAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class ExeggutorAlolanModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("exeggutor")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
val head2 = object : HeadedFrame {
|
||||
override val rootPart = this@ExeggutorAlolanModel.rootPart
|
||||
override val head: ModelPart = getPart("head2")
|
||||
}
|
||||
val head3 = object : HeadedFrame {
|
||||
override val rootPart = this@ExeggutorAlolanModel.rootPart
|
||||
override val head: ModelPart = getPart("head3")
|
||||
}
|
||||
|
||||
override var portraitScale = 1.0F
|
||||
override var portraitTranslation = Vec3(-1.4, 16.55, 0.0)
|
||||
|
||||
override var profileScale = 0.45F
|
||||
override var profileTranslation = Vec3(0.0, 1.0, -30.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var sleep: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink1 = quirk { bedrockStateful("exeggutor_alolan", "blink") }
|
||||
val blink2 = quirk { bedrockStateful("exeggutor_alolan", "blink2") }
|
||||
val blink3 = quirk { bedrockStateful("exeggutor_alolan", "blink3") }
|
||||
val blink4 = quirk { bedrockStateful("exeggutor_alolan", "blink4") }
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("exeggutor_alolan", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
quirks = arrayOf(blink1, blink2, blink3, blink4),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
SingleBoneLookAnimation(head2, false, false, disableX = false, disableY = false),
|
||||
SingleBoneLookAnimation(head3, false, false, disableX = false, disableY = false),
|
||||
bedrock("exeggutor_alolan", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink1, blink2, blink3, blink4),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
SingleBoneLookAnimation(head2, false, false, disableX = false, disableY = false),
|
||||
SingleBoneLookAnimation(head3, false, false, disableX = false, disableY = false),
|
||||
bedrock("exeggutor_alolan", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink1, blink2, blink3, blink4),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
SingleBoneLookAnimation(head2, false, false, disableX = false, disableY = false),
|
||||
SingleBoneLookAnimation(head3, false, false, disableX = false, disableY = false),
|
||||
bedrock("exeggutor_alolan", "battle_idle")
|
||||
)
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("exeggutor_alolan", "faint") else null
|
||||
}
|
||||
-3
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedW
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
@@ -41,8 +40,6 @@ class NidokingModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, B
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoking", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoking", "blink")}
|
||||
standing = registerPose(
|
||||
|
||||
-3
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedW
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
@@ -41,8 +40,6 @@ class NidoqueenModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoqueen", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoqueen", "blink")}
|
||||
val spg = quirk(secondsBetweenOccurrences = 600F to 900F) { bedrockStateful("nidoqueen", "spgs_happy_place") }
|
||||
|
||||
-3
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
@@ -38,8 +37,6 @@ class NidoranfModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, Q
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoranf", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoranf", "blink") }
|
||||
standing = registerPose(
|
||||
|
||||
-3
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
@@ -38,8 +37,6 @@ class NidoranmModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, Q
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoranm", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoranm", "blink") }
|
||||
standing = registerPose(
|
||||
|
||||
-3
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
@@ -41,8 +40,6 @@ class NidorinaModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, Q
|
||||
lateinit var walk: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidorina", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidorina", "blink")}
|
||||
standing = registerPose(
|
||||
|
||||
-3
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonP
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
@@ -37,8 +36,6 @@ class NidorinoModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, Q
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidorino", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidorino", "blink")}
|
||||
standing = registerPose(
|
||||
|
||||
-3
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
@@ -33,8 +32,6 @@ class PinsirModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("pinsir", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("pinsir", "blink")}
|
||||
sleep = registerPose(
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import com.cobblemon.mod.common.util.isUnderWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class SlowbroModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("slowbro")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.0F
|
||||
override var portraitTranslation = Vec3(-0.23, -0.1, 0.0)
|
||||
|
||||
override var profileScale = 0.95F
|
||||
override var profileTranslation = Vec3(0.0, 0.3, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var float: Pose
|
||||
lateinit var swim: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("slowbro", "blink1") }
|
||||
val blink2 = quirk { bedrockStateful("slowbro", "blink2") }
|
||||
val bite = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("slowbro", "bite_quirk") }
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = UI_POSES + PoseType.STAND,
|
||||
quirks = arrayOf(blink, blink2, bite),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowbro", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink, blink2, bite),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowbro", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
float = registerPose(
|
||||
poseName = "float",
|
||||
poseType = PoseType.FLOAT,
|
||||
quirks = arrayOf(blink, blink2, bite),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowbro", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swim = registerPose(
|
||||
poseName = "swim",
|
||||
poseType = PoseType.SWIM,
|
||||
quirks = arrayOf(blink, blink2, bite),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowbro", "water_swim")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink, blink2, bite),
|
||||
condition = { it.isBattling && !it.isUnderWater },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowbro", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("slowbro", "faint") else null
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class SlowpokeModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("slowpoke")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val foreLeftLeg= getPart("leftfrontleg")
|
||||
override val foreRightLeg = getPart("rightfrontleg")
|
||||
override val hindLeftLeg = getPart("leftbackleg")
|
||||
override val hindRightLeg = getPart("rightbackleg")
|
||||
|
||||
override var portraitScale = 2.2F
|
||||
override var portraitTranslation = Vec3(-0.6, -1.6, 0.0)
|
||||
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.0, 0.52, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var float: Pose
|
||||
lateinit var swim: Pose
|
||||
lateinit var sleep: Pose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("slowpoke", "blink") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("slowpoke", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = UI_POSES + PoseType.STAND,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowpoke", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
QuadrupedWalkAnimation(this, periodMultiplier = 3.6F, amplitudeMultiplier = 2.2F),
|
||||
singleBoneLook(),
|
||||
bedrock("slowpoke", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
float = registerPose(
|
||||
poseName = "float",
|
||||
poseType = PoseType.FLOAT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowpoke", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swim = registerPose(
|
||||
poseName = "swim",
|
||||
poseType = PoseType.SWIM,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowpoke", "water_swim")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("slowpoke", "faint") else null
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class SnorlaxModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("snorlax")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.3F
|
||||
override var portraitTranslation = Vec3(-0.45, 0.75, 0.0)
|
||||
|
||||
override var profileScale = 0.75F
|
||||
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("snorlax", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("snorlax", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("snorlax", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("snorlax", "faint") else null
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class TaurosModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("tauros")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 1.9F
|
||||
override var portraitTranslation = Vec3(-0.7, -0.25, 0.0)
|
||||
|
||||
override var profileScale = 0.75F
|
||||
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("tauros", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("tauros", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tauros", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tauros", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("tauros", "faint") else null
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ import net.minecraft.world.phys.Vec3
|
||||
|
||||
class FeraligatrModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("feraligatr")
|
||||
override val head = getPart("head_ai")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
+1
-2
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
@@ -33,7 +32,7 @@ class HitmontopModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
lateinit var walk: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("hitmontop", "cry") }
|
||||
// override val cryAnimation = CryProvider { bedrockStateful("hitmontop", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("hitmontop", "blink") }
|
||||
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import com.cobblemon.mod.common.util.isInWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class SlowkingModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("slowking")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.0F
|
||||
override var portraitTranslation = Vec3(-0.1, 0.1, 0.0)
|
||||
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var float: Pose
|
||||
lateinit var swim: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("slowking", "blink") }
|
||||
val blink2 = quirk { bedrockStateful("slowking", "blink2") }
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = UI_POSES + PoseType.STAND,
|
||||
quirks = arrayOf(blink, blink2),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowking", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink, blink2),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowking", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
float = registerPose(
|
||||
poseName = "float",
|
||||
poseType = PoseType.FLOAT,
|
||||
quirks = arrayOf(blink, blink2),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowking", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swim = registerPose(
|
||||
poseName = "swim",
|
||||
poseType = PoseType.SWIM,
|
||||
quirks = arrayOf(blink, blink2),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowking", "water_swim")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink, blink2),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("slowking", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("slowking", "faint") else null
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen5
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class KrokorokModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("krokorok")
|
||||
|
||||
override var portraitScale = 1.86F
|
||||
override var portraitTranslation = Vec3(-0.43, 0.98, 0.0)
|
||||
|
||||
override var profileScale = 0.55F
|
||||
override var profileTranslation = Vec3(0.05, 0.93, 0.0)
|
||||
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
// animations["physical"] = "q.bedrock_primary('krokorok', 'physical', 'look', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["special"] = "q.bedrock_primary('krokorok', 'special', 'look', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["status"] = "q.bedrock_primary('krokorok', 'status', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["recoil"] = "q.bedrock_stateful('krokorok', 'recoil')".asExpressionLike()
|
||||
animations["cry"] = "q.bedrock_stateful('krokorok', 'cry')".asExpressionLike()
|
||||
|
||||
val faint = "q.bedrock_primary('krokorok', 'faint', q.curve('one'))".asExpressionLike()
|
||||
|
||||
val blink = quirk { bedrockStateful("krokorok", "blink") }
|
||||
val look = quirk { bedrockStateful("krokorok", "look_quirk") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(bedrock("krokorok", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink, look),
|
||||
condition = { !it.isBattling },
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("krokorok", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("krokorok", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
quirks = arrayOf(blink, look),
|
||||
condition = { it.isBattling },
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("krokorok", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen5
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class SandileModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("sandile")
|
||||
|
||||
override var portraitScale = 2.54F
|
||||
override var portraitTranslation = Vec3(-0.5, -1.9, 0.0)
|
||||
|
||||
override var profileScale = 0.84F
|
||||
override var profileTranslation = Vec3(0.05, 0.48, 0.0)
|
||||
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var battle_idle: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
// animations["physical"] = "q.bedrock_primary('sandile', 'physical', 'look', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["special"] = "q.bedrock_primary('sandile', 'special', 'look', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["status"] = "q.bedrock_primary('sandile', 'status', q.curve('symmetrical_wide'))".asExpressionLike()
|
||||
// animations["recoil"] = "q.bedrock_stateful('sandile', 'recoil')".asExpressionLike()
|
||||
animations["cry"] = "q.bedrock_stateful('sandile', 'cry')".asExpressionLike()
|
||||
|
||||
val faint = "q.bedrock_primary('sandile', 'faint', q.curve('one'))".asExpressionLike()
|
||||
|
||||
val blink = quirk { bedrockStateful("sandile", "blink") }
|
||||
val bite = quirk { bedrockStateful("sandile", "bite_quirk") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
quirks = arrayOf(bite),
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(bedrock("sandile", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink, bite),
|
||||
condition = { !it.isBattling },
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("sandile", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("sandile", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battle_idle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
quirks = arrayOf(blink, bite),
|
||||
condition = { it.isBattling },
|
||||
namedAnimations = mutableMapOf("faint" to faint),
|
||||
animations = arrayOf(
|
||||
bedrock("sandile", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user