mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-20 22:26:24 -04:00
Compare commits
87
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48ff865c55 | ||
|
|
e0abdb900d | ||
|
|
1b74c2906d | ||
|
|
d3a616e308 | ||
|
|
9a06463871 | ||
|
|
46b5a046ed | ||
|
|
ab811ead56 | ||
|
|
09a549ffcd | ||
|
|
b393293025 | ||
|
|
2f87d53af6 | ||
|
|
542839ba69 | ||
|
|
efab1bba08 | ||
|
|
8f986bc326 | ||
|
|
e155d32aaf | ||
|
|
743e0b7d66 | ||
|
|
1518d703f9 | ||
|
|
af9d851d67 | ||
|
|
20ca91f1c9 | ||
|
|
6fb3c0e49a | ||
|
|
5cb4ff5f5f | ||
|
|
d035c08a5c | ||
|
|
fda7b13f50 | ||
|
|
f595724971 | ||
|
|
0511ba147b | ||
|
|
760f48d850 | ||
|
|
bf296b4921 | ||
|
|
49886389cf | ||
|
|
643bf9068b | ||
|
|
53f3258246 | ||
|
|
1e9895ec84 | ||
|
|
52dacb03ae | ||
|
|
85b0f3f393 | ||
|
|
68a760a595 | ||
|
|
a04a91bf24 | ||
|
|
5e814f7ab5 | ||
|
|
2780f491d6 | ||
|
|
2d3ec7aff1 | ||
|
|
cb7baf2696 | ||
|
|
5cc069df78 | ||
|
|
9222476c1f | ||
|
|
f220755f99 | ||
|
|
d55bbf237c | ||
|
|
83a9d44c3a | ||
|
|
c5a802eaf6 | ||
|
|
2e27875460 | ||
|
|
cd66887faa | ||
|
|
d665c87c21 | ||
|
|
044d3102b6 | ||
|
|
c421a93b06 | ||
|
|
2865aa2272 | ||
|
|
7c4aae3e9d | ||
|
|
d9f671f2a8 | ||
|
|
69733b530b | ||
|
|
d4471c30bc | ||
|
|
185f7e03f5 | ||
|
|
a45eb0eb21 | ||
|
|
ed67142379 | ||
|
|
13169c6848 | ||
|
|
ae7bc6e681 | ||
|
|
8be134ee2f | ||
|
|
ed007fe429 | ||
|
|
8c3206a413 | ||
|
|
4d4c071b95 | ||
|
|
b82c27754f | ||
|
|
63afec184e | ||
|
|
65699f045e | ||
|
|
90dc489547 | ||
|
|
b2142fed1d | ||
|
|
fef21516e9 | ||
|
|
95d43de79f | ||
|
|
92bccf620f | ||
|
|
15f8a9ee71 | ||
|
|
e5750cbba0 | ||
|
|
c6482c82cd | ||
|
|
c470894bd3 | ||
|
|
a940e32f8d | ||
|
|
b6b59eccad | ||
|
|
b520b94fae | ||
|
|
1969af65b9 | ||
|
|
905d63e098 | ||
|
|
1ea8ab7dcc | ||
|
|
a45d21b279 | ||
|
|
efe8f34413 | ||
|
|
6bb23582c4 | ||
|
|
56ccb43997 | ||
|
|
5fbbcb5707 | ||
|
|
580a24eac3 |
+16
-169
@@ -1,200 +1,47 @@
|
||||
# Changelog
|
||||
## [1.8.2 (MONTH xth, 2026)](#1-8-2)
|
||||
## [1.8.3 (MONTH xth, 2026)](#1-8-3)
|
||||
|
||||
### Additions
|
||||
- The following items can now be placed on the ground as blocks:
|
||||
- King's Rock, Galarica Cuff, Unremarkable Teacup, Masterpiece Teacup, Chipped Pot, Cracked Pot, Sachet, Metal Powder, Quick Powder, Bright Powder, Soft Sand, Electirizer, Magmarizer, Icy Rock, Heat Rock, Smooth Rock, Damp Rock, Destiny Knot, Luminous Moss, Never-Melt Ice, Wide Lens, Scope Lens, and Zoom Lens.
|
||||
- Iron Ball, Metal Coat, Throat Spray, Terrain Extender, Medicinal Brew, Moomoo Milk, HP Up, Protein, Iron, Carbos, Calcium, Zinc, PP Up, PP Max, Upgrade, Dubious Disc, and Loaded Dice.
|
||||
- The following items can now be placed on various surfaces:
|
||||
- Galarica Wreath, Magnet, Flame Orb, Life Orb, Toxic Orb, Light Ball, and Smoke Ball.
|
||||
- The following items can now be placed as blocks and have additional functionality:
|
||||
- Ring Target, Metronome, and Eject Button.
|
||||
- The following items can now be worn by Players and Pokémon:
|
||||
- Galarica Wreath, Cleanse Tag, Spell Tag, Sharp Beak, Covert Cloak, Shell Helmet, and Never-Melt Ice.
|
||||
- Wearable items can now be equipped by a player by holding it and right-clicking (or rebound use/interact)
|
||||
- Wearable items that can be placed down are exempt from this behaviour.
|
||||
- Mint Leaves can now be placed on the ground as Leaf Litter, or in Flower Pots
|
||||
- Added Oricorio Flowers
|
||||
- Added Terrain Plants
|
||||
- Berries can now be placed in Flower Pots
|
||||
- The evolution tree can now be viewed on the Pokédex, showing a Pokémon's full family line and what's needed to evolve into each stage.
|
||||
- Added custom sounds to a bunch of items that can be placed as blocks: liquid bottles, pill bottles, powders and dice.
|
||||
- New Cosmetic Item for Pikachu: Paper
|
||||
- Burmy changes its cloak after a battle it took part in, based on the biome: Trash Cloak in the Deep Dark, Nether and End, Plant Cloak in lush biomes such as forests, jungles, plains and swamps, and Sandy Cloak in sandy biomes, beaches and caves.
|
||||
- You can now drag to select multiple Pokémon inside the PC menu.
|
||||
|
||||
### Fixes
|
||||
- Medicinal Leeks can now be eaten when they aren't being planted, matching their food properties.
|
||||
- Sweeping attacks no longer set owned Pokémon on fire (e.g. with Fire Aspect) or knock them back.
|
||||
- Fixed #updateMovesOnFormChange not properly initializing a form-swapped Pokemon's non-form_change moves.
|
||||
### TEST
|
||||
### Pokémon Added
|
||||
#### Generation 4
|
||||
- Snover
|
||||
- Abomasnow
|
||||
- Burmy
|
||||
- Wormadam
|
||||
- Mothim
|
||||
|
||||
#### Generation 5
|
||||
- Tympole
|
||||
- Palpitoad
|
||||
- Seismitoad
|
||||
|
||||
#### Generation 6
|
||||
- Helioptile
|
||||
- Heliolisk
|
||||
|
||||
#### Generation 7
|
||||
- Grubbin
|
||||
- Charjabug
|
||||
- Vikavolt
|
||||
- Minior
|
||||
|
||||
#### Generation 8
|
||||
- Eternatus
|
||||
|
||||
#### Generation 9
|
||||
- Greavard
|
||||
- Houndstone
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Sudowoodo
|
||||
- Spheal
|
||||
- Cacnea
|
||||
- Cacturne
|
||||
- Binacle
|
||||
- Barbaracle
|
||||
- Glimmet
|
||||
- Glimmora
|
||||
- Deerling
|
||||
- Sawsbuck (All forms)
|
||||
- Absol
|
||||
- Poliwag
|
||||
- Politoed
|
||||
- Ekans
|
||||
- Oddish
|
||||
- Gloom
|
||||
- Vileplume
|
||||
- Bellossom
|
||||
- Shroomish
|
||||
- Chespin
|
||||
- Quilladin
|
||||
- Chesnaught
|
||||
- Fennekin
|
||||
- Braixen
|
||||
- Delphox
|
||||
- Froakie
|
||||
- Frogadier
|
||||
- Greninja
|
||||
- Shinx
|
||||
- Luxio
|
||||
- Luxray
|
||||
- Slakoth
|
||||
- Riolu
|
||||
- Lucario
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Treecko (New Shoulder Mount!)
|
||||
- Bonsly (New Shoulder Mount!)
|
||||
- Sudowoodo
|
||||
- Cacnea
|
||||
- Cacturne
|
||||
- Ekans
|
||||
- Arbok
|
||||
- Oddish
|
||||
- Gloom
|
||||
- Vileplume
|
||||
- Bellossom
|
||||
- Pichu
|
||||
- Pikachu
|
||||
- Raichu (+ Alolan)
|
||||
- Greninja
|
||||
- Slakoth
|
||||
|
||||
### Changes
|
||||
- Terrain Seeds can now be planted
|
||||
- Terrain Seeds are now consumed during PvP and NPC battles
|
||||
- Glow Item Frames can be crafted using Bright Powder as an alternative to Glow Ink Sacs
|
||||
- Bright Powder can be used on Signs and Hanging Signs to make text glow, as an alternative to Glow Ink Sacs
|
||||
- Updated various recipes to display in Recipe Groups within the Recipe Book
|
||||
- Updated most recipes to display more logically/consistently within the Recipe Book's categories
|
||||
- Updated the following recipes
|
||||
- Never-Melt Ice, Focus Sash, Blunder Policy, Weakness Policy, Blank TM
|
||||
- Make ride rotations less jittery in multiplayer.
|
||||
- Changes Disc Shelf TMs to use textures instead of tinting and overlays to line up with item display
|
||||
- Blank TM can now be inserted into the Disc Shelf
|
||||
- Added TM creative tab
|
||||
- Recall animation now renders ball in hand with the player arm raised.
|
||||
- Made regional and Vivillon split-evo locations now mutually exclusive
|
||||
- Item evolutions now unlock **all** locked evolutions whose requirements are met instead of stopping after the first.
|
||||
- Exceptions being "forced" evolutions which will continue to stop after the first one
|
||||
- Removed Mega Drain as a TM
|
||||
- Vivillon's patterns are now viewable as forms with form names and unique Pokedex entries displayed.
|
||||
- Slowed the speed of Type Gem growth, and revamped their generation to grow in a more crystal-like shape
|
||||
- PokeSnacks (and other area spawns) will now start the vertical offset checking from the center rather than base coordinate
|
||||
- This will help PokeSnacks to work inside caves or tighter spaces better
|
||||
|
||||
### Fixes
|
||||
- Correctly grants "They're Minerals!" advancement when planting a type gem
|
||||
- Shoulder mounted Pokémon now follow player body animations, improving their positioning with custom player animations and default actions.
|
||||
- Shoulder mounted Pokémon now sit slightly higher with chest armor equipped for better alignment, with a configurable blacklist.
|
||||
- Type Gem Blocks now have advancements to give you the recipe in the recipe book (the data for the advancements were inside the recipes somehow??)
|
||||
- Some other recipes without advancements have also been corrected
|
||||
- Corrected the TM Recipes for Charge Beam and Payday
|
||||
- Type Gem blocks now properly generate clusters off of the block.
|
||||
- Starter Screen Categories will no longer stop rendering if they are bigger than the viewport, and you are not viewing top or bottom edges
|
||||
- Random Starter option now properly handled in height calculation, so now it won't run off into other categories or be un-accessible due to scroll limits if it causes a new row
|
||||
- Mochi and Feathers no longer drop glass bottles on use
|
||||
- Fixed a rare set of concurrency bugs related to reloading packs on NeoForge; fixes a ModernFix issue
|
||||
- Removed unnecessary conditions for Mimikyu's standing pose. Hopefully fixes the rare instance of it using its shoulder animations during battle in multiplayer scenarios.
|
||||
- Fixed Rockruff line not blinking
|
||||
- Fixed Flygon sometimes using its running animation instead of walking
|
||||
- Fixed Bramblin always sleeping outside of battle
|
||||
- Fixed Dragonair using its battle idle as a normal idle
|
||||
- Fixed Lycanroc's head movement
|
||||
- Added head movement to Archaludon
|
||||
- Fixed Duraludon line not having any sleep animations
|
||||
- Fixed Diglett line not having their faint animations
|
||||
- Fixed Kingambit moving its legs while walking
|
||||
- Fixed Alolan Diglett's cry not playing
|
||||
- Fixed shiny alpha Snorlax using the non-shiny texture
|
||||
- Various Structure fixes
|
||||
- Fixed shiny Pokémon under certain circumstances forgetting taught TMs
|
||||
- Fixed certain Pokémon sounds sometimes being doubled when played at specific times in their animations
|
||||
- Fixed ball capture beam origin coming from behind the ball.
|
||||
- Fixed Safari Ball catch rate outside of battle
|
||||
- Fixed alpha eye (and other) particles not respecting client particle density setting in video options
|
||||
- Fixed TM-Machine UI not closing when player is moving away from it
|
||||
- Fixed config category for alpha/shiny chance config fields for fossil machine and honey log slathering to Spawning
|
||||
- Fixed crashes for addon species with non-Cobblemon namespaces, in evolution, fishing bait and Pokédex lookups.
|
||||
- Bees now grow Apricorns and the Galarica Nut Bush, which were in the bee growables tag but never handled, and correctly spend their nectar when they do
|
||||
- Saccharine Leaves can now be bone mealed
|
||||
- Fixed equipping a stack of items instead of one item of a stack
|
||||
- Fixed TM stack consumption in TMM screen when player teaches a move to species
|
||||
- Fixed every Miltank giving mushroom stew, not only mushroom variants
|
||||
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
|
||||
- Fixed the Pokédex evolution tree crashing when a datapack's dex entry is missing an evolution's form.
|
||||
- Fixed the Pokédex evolution tree crashing with a stack overflow on evolutions that loop back on themselves.
|
||||
- Fixed the Pokédex evolution tree crashing when looking at a dex that is not part of the "National Dex" aggregate.
|
||||
- Fixed evolution trees not building properly when a pokemon has several pokedex entries for different regions.
|
||||
- Fixed form-changing evolutions sometimes resolving to the source form in the Pokédex evolution tree.
|
||||
- Broken datapack evolutions are now logged and skipped in the Pokédex evolution tree instead of crashing.
|
||||
- Fixed friendship booster items not being recognised as such
|
||||
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot)
|
||||
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event
|
||||
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands
|
||||
|
||||
### Developer
|
||||
- Evolution requirements can now set `pokedexIcon` and `pokedexTooltip` directly in their JSON to control how they're shown on the Pokédex's evolution tree, for example:
|
||||
```json
|
||||
{
|
||||
"variant": "attack_defence_ratio",
|
||||
"pokedexIcon": "minecraft:diamond_sword",
|
||||
"pokedexTooltip": "cobblemon.ui.pokedex.requirement.attack_defence_ratio.tooltip"
|
||||
}
|
||||
```
|
||||
- Fixed wrong order of operations in the code flow prior to the `FOSSIL_REVIVED` event causing pokemon to appear without entity link
|
||||
- Fixed TestPartySlot command not correctly comparing the provided spec with the target Pokémon
|
||||
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation
|
||||
|
||||
### Molang & Datapacks
|
||||
- A new `negate` variant for evolution requirements has been added, which will negate (invert) the provided inner condition.
|
||||
- Added Molang functions for individual Pokédex ids, wherein a subdex is passed in as a string to `dex_caught_count` etc.
|
||||
- Added a `battle_ended` callback, backed by the new `BATTLE_ENDED` event, which fires whenever a battle ends for any reason, alongside a multitude of flags not previously covered by `BATTLE_VICTORY`.
|
||||
- Added `battle_pokemon` to battle actor structs and `has_faced_opponents` to battle Pokémon structs.
|
||||
- Added the `cobblemon:form_change/bagworm_cloak/plant_cloak`, `sandy_cloak` and `trash_cloak` biome tags, which control Burmy's cloak after battle.
|
||||
|
||||
### Particles
|
||||
|
||||
#### New Move Animations
|
||||
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`)
|
||||
- Fixed `q.entity.is_looking_at` result being always `1` for whatever entity passed as target
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
- Added `cobblemon:catch_alpha_pokemon` advancement trigger and `totalAlphaCaptureCount` stat for captured Alpha Pokémon.
|
||||
|
||||
### New rideable Pokémon
|
||||
- Pidgeot
|
||||
- Crobat
|
||||
- Skarmory
|
||||
- Milotic
|
||||
@@ -106,7 +107,9 @@
|
||||
- Avalugg (Hisuian Form)
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
|
||||
- Pidgey
|
||||
- Pidgeotto
|
||||
- Pidgeot
|
||||
- Sandshrew
|
||||
- Sandslash
|
||||
- Nidoking
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
# Changelog
|
||||
## [1.8.2 (October 11th, 2026)](#1-8-2)
|
||||
|
||||
### Additions
|
||||
- The following items can now be placed on the ground as blocks:
|
||||
- King's Rock, Galarica Cuff, Unremarkable Teacup, Masterpiece Teacup, Chipped Pot, Cracked Pot, Sachet, Metal Powder, Quick Powder, Bright Powder, Soft Sand, Electirizer, Magmarizer, Icy Rock, Heat Rock, Smooth Rock, Damp Rock, Destiny Knot, Luminous Moss, Never-Melt Ice, Wide Lens, Scope Lens, and Zoom Lens.
|
||||
- I wasn't finished. Iron Ball, Metal Coat, Throat Spray, Terrain Extender, Medicinal Brew, Moomoo Milk, HP Up, Protein, Iron, Carbos, Calcium, Zinc, PP Up, PP Max, Upgrade, Dubious Disc, and Loaded Dice.
|
||||
- The following items can now be placed on various surfaces:
|
||||
- Galarica Wreath, Magnet, Flame Orb, Life Orb, Toxic Orb, Light Ball, and Smoke Ball.
|
||||
- The following items can now be placed as blocks and have additional functionality:
|
||||
- Ring Target, Metronome, and Eject Button.
|
||||
- The following items can now be worn by Players and Pokémon:
|
||||
- Galarica Wreath, Cleanse Tag, Spell Tag, Sharp Beak, Covert Cloak, Shell Helmet, and Never-Melt Ice.
|
||||
- Wearable items can now be equipped by a player by holding it and right-clicking (or whatever you've rebound use/interact to).
|
||||
- Wearable items that can be placed down are exempt from this behaviour.
|
||||
- Mint Leaves can now be placed on the ground as Leaf Litter, or in Flower Pots.
|
||||
- The recall animation now renders the ball in hand with the player's arm raised.
|
||||
- Added Oricorio Flowers.
|
||||
- Added Terrain Plants, four plants grown from Electric, Grassy, Misty, and Psychic Seeds, which glow under specific environmental conditions and can be farmed for more of their seeds.
|
||||
- Berries can now be placed in Flower Pots.
|
||||
- The evolution tree for a Pokémon can now be viewed in the Pokédex, showing the Pokémon's full family line and what's needed to evolve into each stage.
|
||||
- Added custom sounds to a bunch of items that can be placed as blocks: liquid bottles, pill bottles, powders, and dice.
|
||||
- Added paper as a new cosmetic item for Pikachu.
|
||||
- Burmy changes its cloak after a battle it took part in, based on the biome.
|
||||
- Trash Cloak in the Deep Dark, Nether and End.
|
||||
- Plant Cloak in lush biomes such as forests, jungles, plains and swamps.
|
||||
- Sandy Cloak in sandy biomes, beaches and caves.
|
||||
|
||||
### Pokémon Added
|
||||
#### Generation 4
|
||||
- Snover
|
||||
- Abomasnow
|
||||
- Burmy
|
||||
- Wormadam
|
||||
- Mothim
|
||||
|
||||
#### Generation 5
|
||||
- Tympole
|
||||
- Palpitoad
|
||||
- Seismitoad
|
||||
|
||||
#### Generation 6
|
||||
- Helioptile
|
||||
- Heliolisk
|
||||
|
||||
#### Generation 7
|
||||
- Grubbin
|
||||
- Charjabug
|
||||
- Vikavolt
|
||||
- Minior
|
||||
|
||||
#### Generation 8
|
||||
- Eternatus
|
||||
|
||||
#### Generation 9
|
||||
- Greavard
|
||||
- Houndstone
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Sudowoodo
|
||||
- Spheal
|
||||
- Cacnea
|
||||
- Cacturne
|
||||
- Binacle
|
||||
- Barbaracle
|
||||
- Glimmet
|
||||
- Glimmora
|
||||
- Deerling
|
||||
- Sawsbuck (All forms)
|
||||
- Absol
|
||||
- Poliwag
|
||||
- Politoed
|
||||
- Ekans
|
||||
- Oddish
|
||||
- Gloom
|
||||
- Vileplume
|
||||
- Bellossom
|
||||
- Shroomish
|
||||
- Chespin
|
||||
- Quilladin
|
||||
- Chesnaught
|
||||
- Fennekin
|
||||
- Braixen
|
||||
- Delphox
|
||||
- Froakie
|
||||
- Frogadier
|
||||
- Greninja
|
||||
- Shinx
|
||||
- Luxio
|
||||
- Luxray
|
||||
- Slakoth
|
||||
- Riolu
|
||||
- Lucario
|
||||
- Corsola
|
||||
- Mime Jr.
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Treecko (New Shoulder Mount!)
|
||||
- Bonsly (New Shoulder Mount!)
|
||||
- Sudowoodo
|
||||
- Cacnea
|
||||
- Cacturne
|
||||
- Ekans
|
||||
- Arbok
|
||||
- Oddish
|
||||
- Gloom
|
||||
- Vileplume
|
||||
- Bellossom
|
||||
- Pichu
|
||||
- Pikachu
|
||||
- Raichu (+ Alolan)
|
||||
- Greninja
|
||||
- Slakoth
|
||||
|
||||
### Changes
|
||||
- Slowed the speed of Type Gem growth, and revamped their generation to grow in a more crystal-like shape.
|
||||
- Terrain Seeds can now be planted.
|
||||
- Terrain Seeds are now consumed during PvP and NPC battles.
|
||||
- Glow Item Frames can be crafted using Bright Powder as an alternative to Glow Ink Sacs.
|
||||
- Bright Powder can be used on Signs and Hanging Signs to make text glow, as an alternative to Glow Ink Sacs.
|
||||
- Updated various recipes to display in Recipe Groups within the Recipe Book.
|
||||
- Updated most recipes to display more logically and consistently within the Recipe Book's categories.
|
||||
- Updated the following recipes
|
||||
- Never-Melt Ice, Focus Sash, Blunder Policy, Weakness Policy, Blank TM.
|
||||
- Made ride rotations less jittery in multiplayer.
|
||||
- Changes Disc Shelf TMs to use textures instead of tinting and overlays to line up with item display.
|
||||
- Blank TM can now be inserted into the Disc Shelf.
|
||||
- Added a TM creative tab.
|
||||
- Made regional and Vivillon split-evo locations mutually exclusive.
|
||||
- Vivillon's patterns are now viewable as forms with form names and unique Pokédex entries displayed.
|
||||
- Item evolutions now unlock **all** locked evolutions whose requirements are met instead of stopping after the first.
|
||||
- Exceptions being "forced" evolutions which stop after the first one.
|
||||
- Removed Mega Drain as a TM.
|
||||
- PokeSnacks (and other area spawns) will now start the vertical offset checking from the center rather than base coordinate
|
||||
- This will help PokeSnacks to work inside caves or tighter spaces better.
|
||||
|
||||
### Fixes
|
||||
- Type Gem blocks now properly generate clusters off of the block.
|
||||
- Correctly grant "They're Minerals!" advancement when planting a Type Gem.
|
||||
- Shoulder mounted Pokémon now follow player body animations, improving their positioning with custom player animations and default actions.
|
||||
- Shoulder mounted Pokémon now sit slightly higher with chest armor equipped for better alignment, with a configurable blacklist.
|
||||
- Type Gem Blocks now have advancements to give you the recipe in the recipe book (the data for the advancements were inside the recipes somehow??).
|
||||
- Some other recipes without advancements have also been corrected.
|
||||
- Corrected the TM Recipes for Charge Beam and Payday.
|
||||
- Starter Screen Categories will no longer stop rendering if they are bigger than the viewport and you are not viewing the top or bottom edges.
|
||||
- The Random Starter option no longer runs off into other categories or becomes unaccessible due to scroll limits if it causes a new row.
|
||||
- Mochi and Feathers no longer drop glass bottles on use.
|
||||
- Fixed a rare set of concurrency bugs related to reloading packs on NeoForge; fixes a ModernFix compatibility issue.
|
||||
- Removed unnecessary conditions for Mimikyu's standing pose. Hopefully fixes the rare instance of it using its shoulder animations during battle in multiplayer scenarios.
|
||||
- Fixed Rockruff line not blinking.
|
||||
- Fixed Flygon sometimes using its running animation instead of walking.
|
||||
- Fixed Bramblin always sleeping outside of battle.
|
||||
- Fixed Dragonair using its battle idle as a normal idle.
|
||||
- Fixed Lycanroc's head movement.
|
||||
- Added head movement to Archaludon.
|
||||
- Fixed Duraludon line not having any sleep animations.
|
||||
- Fixed Diglett line not having their faint animations.
|
||||
- Fixed Kingambit moving its legs while walking.
|
||||
- Fixed Alolan Diglett's cry not playing.
|
||||
- Fixed shiny alpha Snorlax using the non-shiny texture.
|
||||
- Fixed Crabominable's head breaking when looking around.
|
||||
- Fixed Shiny Dipplin and Hydrapple's textures.
|
||||
- Various structure fixes.
|
||||
- Fixed shiny Pokémon under certain circumstances forgetting taught TMs.
|
||||
- Fixed certain Pokémon sounds sometimes being doubled when played at specific times in their animations.
|
||||
- Fixed ball capture beam origin coming from behind the ball.
|
||||
- Fixed Safari Ball catch rate outside of battle.
|
||||
- Fixed alpha eye (and other) particles not respecting the client particle density setting in video options.
|
||||
- Fixed the TM Machine UI not closing when player is moving away from it.
|
||||
- Moved the config category for alpha/shiny chance config fields for fossil machine and honey log slathering to Spawning.
|
||||
- Fixed crashes for addon species with non-Cobblemon namespaces in evolution, fishing bait, and Pokédex lookups.
|
||||
- Bees will now grow Apricorns and the Galarica Nut Bush, which were in the bee growables tag but never handled, and correctly spend their nectar when they do.
|
||||
- Saccharine Leaves can now be bone mealed.
|
||||
- Fixed equipping a stack of wearable items instead of one item of a stack.
|
||||
- Fixed TM stack consumption in TM Machine screen when a player teaches a move to a Pokémon.
|
||||
- Fixed every Miltank giving mushroom stew, not only mushroom variants.
|
||||
- Medicinal Leeks can now be eaten when they aren't being planted, matching their food properties.
|
||||
- Sweeping attacks no longer set owned Pokémon on fire (e.g. with Fire Aspect) or knock them back. Friendly Fire is now off.
|
||||
- Fixed Pokémon not losing their previous form's signature moves when changing forms (e.g. Rotom keeping Overheat after leaving its Heat form).
|
||||
- Form-specific moves gained from a form change are now only granted if the Pokémon is high enough level to learn them, and no longer create duplicates in benched moves.
|
||||
- Spinda now learns Teeter Dance at level 32 instead of via TM.
|
||||
- Fixed Oricorio Pa'u form description in the Pokédex.
|
||||
- Fixed PC playing sound on close when opened via command.
|
||||
|
||||
### Developer
|
||||
- Evolution requirements can now set `pokedexIcon` and `pokedexTooltip` directly in their JSON to control how they're shown on the Pokédex's evolution tree, for example:
|
||||
```json
|
||||
{
|
||||
"variant": "attack_defence_ratio",
|
||||
"pokedexIcon": "minecraft:diamond_sword",
|
||||
"pokedexTooltip": "cobblemon.ui.pokedex.requirement.attack_defence_ratio.tooltip"
|
||||
}
|
||||
```
|
||||
- Fixed the wrong order of operations in the code flow prior to the `FOSSIL_REVIVED` event causing Pokémon to appear without the entity link.
|
||||
- Fixed TestPartySlot command not correctly comparing the provided spec with the target Pokémon.
|
||||
|
||||
### Molang & Datapacks
|
||||
- A new `negate` variant for evolution requirements has been added, which will negate (invert) the provided inner condition.
|
||||
- Added Molang functions for individual Pokédex ids, wherein a subdex is passed in as a string to `dex_caught_count` etc.
|
||||
- Added a `battle_ended` callback, backed by the new `BATTLE_ENDED` event, which fires whenever a battle ends for any reason, alongside a multitude of flags not previously covered by `BATTLE_VICTORY`.
|
||||
- Added `battle_pokemon` to battle actor structs and `has_faced_opponents` to battle Pokémon structs.
|
||||
- Added the `cobblemon:form_change/bagworm_cloak/plant_cloak`, `sandy_cloak` and `trash_cloak` biome tags, which control Burmy's cloak after battle.
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- Brazilian Portuguese
|
||||
- Canadian French
|
||||
- Japanese
|
||||
- Korean
|
||||
- Russian
|
||||
- Ukrainian
|
||||
+7
-17
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
||||
@@ -63,23 +64,12 @@ public abstract class ClientRecipeBookMixin {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "setupCollections", at = @At("RETURN"))
|
||||
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci) {
|
||||
Map<RecipeBookCategories, List<List<RecipeHolder<?>>>> map = categorizeAndGroupRecipes(recipes);
|
||||
Map<RecipeBookCategories, List<RecipeCollection>> map2 = Maps.newHashMap();
|
||||
ImmutableList.Builder<RecipeCollection> builder = ImmutableList.builder();
|
||||
|
||||
map.forEach((recipeBookCategories, list) -> {
|
||||
List<RecipeCollection> collections = list.stream()
|
||||
.map(listx -> new RecipeCollection(registryAccess, listx))
|
||||
.peek(builder::add)
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
map2.put(recipeBookCategories, collections);
|
||||
});
|
||||
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
|
||||
@Inject(method = "setupCollections",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lcom/google/common/collect/ImmutableMap;copyOf(Ljava/util/Map;)Lcom/google/common/collect/ImmutableMap;"
|
||||
))
|
||||
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci, @Local(name = "map2") Map<RecipeBookCategories, List<RecipeCollection>> map2) {
|
||||
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
|
||||
|
||||
this.collectionsByTab = ImmutableMap.copyOf(map2);
|
||||
this.allCollections = builder.build();
|
||||
}
|
||||
}
|
||||
+13
-43
@@ -9,55 +9,25 @@
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import com.llamalad7.mixinextras.expression.Definition;
|
||||
import com.llamalad7.mixinextras.expression.Expression;
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookPage;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RecipeBookComponent.class)
|
||||
public class RecipeBookComponentMixin {
|
||||
|
||||
@Shadow private ClientRecipeBook book;
|
||||
|
||||
@Shadow protected Minecraft minecraft;
|
||||
|
||||
@Shadow private int width;
|
||||
|
||||
@Shadow private int xOffset;
|
||||
|
||||
@Shadow private int height;
|
||||
|
||||
@Shadow @Final private RecipeBookPage recipeBookPage;
|
||||
|
||||
@Inject(method = "updateTabs", at = @At("HEAD"), cancellable = true)
|
||||
private void customUpdateTabs(CallbackInfo ci) {
|
||||
RecipeBookComponent instance = (RecipeBookComponent) (Object) this;
|
||||
int i = (width - 147) / 2 - xOffset - 30;
|
||||
int j = (height - 166) / 2 + 3;
|
||||
int k = 27;
|
||||
int l = 0;
|
||||
|
||||
for (RecipeBookTabButton recipeBookTabButton : instance.tabButtons) {
|
||||
RecipeBookCategories recipeBookCategories = recipeBookTabButton.getCategory();
|
||||
if (recipeBookCategories != RecipeBookCategories.CRAFTING_SEARCH && recipeBookCategories != RecipeBookCategories.FURNACE_SEARCH && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory()) {
|
||||
if (recipeBookTabButton.updateVisibility(book)) {
|
||||
recipeBookTabButton.setPosition(i, j + 27 * l++);
|
||||
recipeBookTabButton.startAnimation(minecraft);
|
||||
}
|
||||
} else {
|
||||
recipeBookTabButton.visible = true;
|
||||
recipeBookTabButton.setPosition(i, j + k * l++);
|
||||
}
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
@Definition(id = "recipeBookCategories", local = @Local(name = "recipeBookCategories"))
|
||||
@Definition(id = "FURNACE_SEARCH", field = "Lnet/minecraft/client/RecipeBookCategories;FURNACE_SEARCH:Lnet/minecraft/client/RecipeBookCategories;")
|
||||
@Expression("recipeBookCategories != FURNACE_SEARCH")
|
||||
@ModifyExpressionValue(
|
||||
method = "updateTabs",
|
||||
at = @At(value = "MIXINEXTRAS:EXPRESSION")
|
||||
)
|
||||
private boolean notCookingPotSearch(boolean original, @Local(name = "recipeBookCategories") RecipeBookCategories recipeBookCategories) {
|
||||
return original && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory();
|
||||
}
|
||||
}
|
||||
@@ -425,7 +425,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SpeciesEvolutionSyncPacket.ID, SpeciesEvolutionSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(DexEvolutionDisplaySyncPacket.ID, DexEvolutionDisplaySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(StandardSpeciesFeatureSyncPacket.ID, StandardSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(GlobalSpeciesFeatureSyncPacket.ID, GlobalSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
@@ -566,6 +566,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(SwapPartyPokemonPacket.ID, SwapPartyPokemonPacket::decode, SwapPartyPokemonHandler))
|
||||
|
||||
list.add(PacketRegisterInfo(MovePCPokemonPacket.ID, MovePCPokemonPacket::decode, MovePCPokemonHandler))
|
||||
list.add(PacketRegisterInfo(MovePCPokemonBatchPacket.ID, MovePCPokemonBatchPacket::decode, MovePCPokemonBatchHandler))
|
||||
list.add(PacketRegisterInfo(MovePartyPokemonPacket.ID, MovePartyPokemonPacket::decode, MovePartyPokemonHandler))
|
||||
|
||||
list.add(PacketRegisterInfo(SwapPCPartyPokemonPacket.ID, SwapPCPartyPokemonPacket::decode, SwapPCPartyPokemonHandler))
|
||||
|
||||
+1
-12
@@ -11,9 +11,6 @@ package com.cobblemon.mod.common.api.conditional
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
/**
|
||||
@@ -24,19 +21,11 @@ import java.lang.reflect.Type
|
||||
* @author Hiroku
|
||||
* @since July 17th, 2022
|
||||
*/
|
||||
interface RegistryLikeAdapter<B> : JsonDeserializer<RegistryLikeCondition<B>>, JsonSerializer<RegistryLikeCondition<B>> {
|
||||
interface RegistryLikeAdapter<B> : JsonDeserializer<RegistryLikeCondition<B>> {
|
||||
val registryLikeConditions: MutableList<(JsonElement) -> RegistryLikeCondition<B>?>
|
||||
|
||||
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): RegistryLikeCondition<B> {
|
||||
return registryLikeConditions.firstNotNullOfOrNull { it(json) }
|
||||
?: throw IllegalArgumentException("Unable to deserialize $json")
|
||||
}
|
||||
|
||||
override fun serialize(src: RegistryLikeCondition<B>, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
|
||||
return when (src) {
|
||||
is RegistryLikeTagCondition<B> -> JsonPrimitive(RegistryLikeTagCondition.PREFIX + src.tag.location())
|
||||
is RegistryLikeIdentifierCondition<B> -> JsonPrimitive(src.identifier.toString())
|
||||
else -> throw IllegalArgumentException("Unable to serialize $src")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -98,14 +98,14 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
|
||||
val targetEntity = params.get<MoValue>(0)
|
||||
val maxDistance = params.getDoubleOrNull(1)?.toFloat() ?: 2.0F
|
||||
|
||||
val entity =
|
||||
val target =
|
||||
if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
|
||||
targetEntity.obj as Entity
|
||||
} else {
|
||||
return@isLookingAt DoubleValue.ZERO
|
||||
}
|
||||
|
||||
DoubleValue(entity.isLookingAt(entity, maxDistance))
|
||||
DoubleValue(entity.isLookingAt(target, maxDistance))
|
||||
}
|
||||
functions["is_living_entity"] = { DoubleValue.ONE }
|
||||
functions["is_flying"] = { DoubleValue(entity.isFallFlying) }
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
||||
// Lol. Lmao, even.
|
||||
// TO-DO: Subscribe to [PokemonSpecies.observable].
|
||||
functions["pre_evolution"] = { pokemon.species.preEvolution ?: DoubleValue.ZERO }
|
||||
functions["nature"] = { StringValue(pokemon.nature.toString()) }
|
||||
functions["nature"] = { StringValue(pokemon.nature.name.toString()) }
|
||||
functions["is_wild"] = { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
|
||||
functions["is_shiny"] = { DoubleValue(pokemon.shiny) }
|
||||
functions["is_in_party"] = { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
|
||||
|
||||
@@ -10,9 +10,6 @@ package com.cobblemon.mod.common.api.pokedex
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.pokedex.def.PokedexDef
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PokedexDexSyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.CodecBackedAdapter
|
||||
@@ -64,38 +61,6 @@ object Dexes : JsonDataRegistry<PokedexDef> {
|
||||
PokedexDexSyncPacket(dexEntryMap.values).sendToPlayer(player)
|
||||
}
|
||||
|
||||
fun findDexEntryBySpeciesId(regionId: ResourceLocation, speciesId: ResourceLocation): PokedexEntry? {
|
||||
return dexEntryMap[regionId]?.getEntries()?.firstOrNull { it -> it.speciesId == speciesId }
|
||||
}
|
||||
|
||||
fun findDexEntryBySpeciesId(speciesId: ResourceLocation): PokedexEntry? {
|
||||
return findDexEntryBySpeciesId(cobblemonResource("national"), speciesId)
|
||||
}
|
||||
|
||||
fun findRootDexEntryBySpeciesId(speciesId: ResourceLocation, formName: String): Pair<PokedexEntry, PokedexForm> {
|
||||
var rootSpecies = PokemonSpecies.getByIdentifier(speciesId)!!
|
||||
val initialFormEquivalents = getFormEquivalents(formName)
|
||||
var rootForm = rootSpecies.forms.firstOrNull { initialFormEquivalents.contains(it.name.lowercase()) }
|
||||
?: rootSpecies.standardForm
|
||||
|
||||
var preEvolution = rootForm.preEvolution
|
||||
while (preEvolution != null) {
|
||||
rootSpecies = preEvolution.species
|
||||
rootForm = preEvolution.resolveForm(rootForm.aspects.toSet())
|
||||
preEvolution = rootForm.preEvolution
|
||||
}
|
||||
|
||||
val entry = findDexEntryBySpeciesId(rootSpecies.resourceIdentifier)
|
||||
?: throw RuntimeException("Root dex entry not found")
|
||||
|
||||
val formEquivalents = getFormEquivalents(rootForm.name)
|
||||
val form =
|
||||
entry.forms.firstOrNull { formEquivalents.contains(it.displayForm.lowercase()) } ?:
|
||||
entry.forms.first { it.displayForm.equals("Normal", ignoreCase = true) }
|
||||
|
||||
return entry to form
|
||||
}
|
||||
|
||||
fun getFormEquivalents(formName: String): List<String> {
|
||||
val key = equivalentFormsLookup[formName.lowercase()]
|
||||
return equivalentForms[key] ?: listOf(formName.lowercase())
|
||||
|
||||
@@ -8,13 +8,20 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.pokedex.entry
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.DexEntrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.DexEvolutionDisplaySyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
@@ -38,6 +45,8 @@ object DexEntries : JsonDataRegistry<PokedexEntry> {
|
||||
|
||||
val entries = mutableMapOf<ResourceLocation, PokedexEntry>()
|
||||
|
||||
val evolutionDisplays = mutableListOf<DexEvolutionDisplay>()
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokedexEntry>) {
|
||||
data.forEach { _, entry ->
|
||||
entries[entry.id] = entry
|
||||
@@ -50,6 +59,7 @@ object DexEntries : JsonDataRegistry<PokedexEntry> {
|
||||
}
|
||||
}
|
||||
}
|
||||
computeEvolutionDisplays()
|
||||
observable.emit(this)
|
||||
}
|
||||
|
||||
@@ -57,5 +67,58 @@ object DexEntries : JsonDataRegistry<PokedexEntry> {
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
DexEntrySyncPacket(entries.values).sendToPlayer(player)
|
||||
DexEvolutionDisplaySyncPacket(evolutionDisplays).sendToPlayer(player)
|
||||
}
|
||||
}
|
||||
|
||||
fun computeEvolutionDisplays() {
|
||||
evolutionDisplays.clear()
|
||||
PokemonSpecies.species.forEach {
|
||||
try {
|
||||
evolutionDisplays.addAll(buildDisplays(it.standardForm) + it.forms.flatMap { form -> buildDisplays(form) })
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Failed to build dex evolution displays for ${it.resourceIdentifier}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildDisplays(form: FormData): List<DexEvolutionDisplay> {
|
||||
val result = mutableListOf<DexEvolutionDisplay>()
|
||||
(form.ownEvolutions ?: form.evolutions).forEach { evolution ->
|
||||
val requirements = mutableListOf<DexEvolutionRequirementDisplay>()
|
||||
getToolTipHeaderIcon(evolution)?.let { header ->
|
||||
requirements.add(header)
|
||||
}
|
||||
evolution.requirements.mapNotNull { resolveRequirementData(it) }.forEach { requirement ->
|
||||
requirements.add(requirement)
|
||||
}
|
||||
|
||||
listOfNotNull(evolution.result, evolution.shedder).forEach resultLoop@{ resultProperties ->
|
||||
val resultSpecies = resultProperties.species
|
||||
?.let { PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
|
||||
?: return@resultLoop
|
||||
|
||||
// The result's own aspects win, otherwise carry the source form's aspects over
|
||||
// like a real evolution does (Alola-Bias Pichu -> Alola-Bias Pikachu)
|
||||
val resultForm = resultSpecies.getForm(resultProperties.aspects).takeIf { it != resultSpecies.standardForm }
|
||||
?: resultSpecies.getForm(form.aspects.toSet() + resultProperties.aspects)
|
||||
val toAspects = resultProperties.aspects + resultForm.aspects
|
||||
val resultRequirements = if (resultProperties === evolution.shedder) {
|
||||
requirements + CobblemonDexEvolutionRequirementDisplay(CobblemonItems.POKE_BALL, lang("ui.pokedex.evolution.shedder.tooltip"))
|
||||
} else {
|
||||
requirements
|
||||
}
|
||||
|
||||
result.add(DexEvolutionDisplay(
|
||||
fromSpecies = form.species.resourceIdentifier,
|
||||
fromForm = form.name,
|
||||
fromAspects = form.aspects.toSet(),
|
||||
toSpecies = resultSpecies.resourceIdentifier,
|
||||
toForm = resultForm.name,
|
||||
toAspects = toAspects,
|
||||
requirements = resultRequirements,
|
||||
))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* 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.pokedex.entry
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeTagCondition
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.text.add
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
|
||||
import com.cobblemon.mod.common.pokemon.requirements.*
|
||||
import com.cobblemon.mod.common.util.adapters.RegistryAccessResolver
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.ExtraCodecs
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
import net.minecraft.world.level.levelgen.structure.Structure
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
data class DexEvolutionDisplay(
|
||||
val fromSpecies: ResourceLocation,
|
||||
val fromForm: String,
|
||||
val fromAspects: Set<String>,
|
||||
val toSpecies: ResourceLocation,
|
||||
val toForm: String,
|
||||
val toAspects: Set<String>,
|
||||
val requirements: List<DexEvolutionRequirementDisplay>,
|
||||
)
|
||||
|
||||
interface DexEvolutionRequirementDisplay {
|
||||
val icon: Item
|
||||
val tooltip: MutableComponent
|
||||
}
|
||||
|
||||
data class CobblemonDexEvolutionRequirementDisplay(
|
||||
override val icon: Item,
|
||||
override val tooltip: MutableComponent,
|
||||
) : DexEvolutionRequirementDisplay
|
||||
|
||||
data class CobblemonBiomeDexEvolutionRequirementDisplay(
|
||||
override val icon: Item,
|
||||
override val tooltip: MutableComponent,
|
||||
val condition: ExtraCodecs.TagOrElementLocation? = null,
|
||||
val antiCondition: ExtraCodecs.TagOrElementLocation? = null,
|
||||
) : DexEvolutionRequirementDisplay
|
||||
|
||||
fun getToolTipHeaderIcon(evolution: Evolution): DexEvolutionRequirementDisplay? {
|
||||
when (evolution) {
|
||||
is ItemInteractionEvolution -> return getToolTipHeaderIcon(evolution)
|
||||
is TradeEvolution -> return getToolTipHeaderIcon(evolution)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun getToolTipHeaderIcon(itemInteractionEvolution: ItemInteractionEvolution): CobblemonDexEvolutionRequirementDisplay? {
|
||||
val item = itemInteractionEvolution.requiredContext.items.orElse(null)?.firstOrNull()?.value() ?: return null
|
||||
return CobblemonDexEvolutionRequirementDisplay(item, lang("ui.pokedex.evolution.item_interact.tooltip", item.description.plainCopy().green()))
|
||||
}
|
||||
|
||||
fun getToolTipHeaderIcon(tradeEvolution: TradeEvolution): CobblemonDexEvolutionRequirementDisplay {
|
||||
val species = tradeEvolution.requiredContext.species
|
||||
val tooltip = if (species == null) {
|
||||
lang("ui.pokedex.evolution.trade.tooltip.with_any_species")
|
||||
} else {
|
||||
PokemonSpecies.getByIdentifier(species.asIdentifierDefaultingNamespace())
|
||||
?.let { lang("ui.pokedex.evolution.trade.tooltip.with_species", it.translatedName.green()) }
|
||||
?: lang("ui.pokedex.evolution.trade.tooltip.with_any_species")
|
||||
}
|
||||
return CobblemonDexEvolutionRequirementDisplay(CobblemonItems.LINK_CABLE, tooltip)
|
||||
}
|
||||
|
||||
fun resolveRequirementData(requirement: Requirement): DexEvolutionRequirementDisplay? {
|
||||
val icon = requirement.pokedexIcon?.let {
|
||||
RegistryAccessResolver.getAccess().registryOrThrow(Registries.ITEM).get(it)
|
||||
}
|
||||
|
||||
val tooltip = requirement.pokedexTooltip?.let {
|
||||
Component.translatable(it)
|
||||
}
|
||||
|
||||
if (icon != null && tooltip != null) {
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
return buildRequirementData(requirement)
|
||||
}
|
||||
|
||||
fun buildRequirementData(requirement: Requirement): DexEvolutionRequirementDisplay? {
|
||||
when (requirement) {
|
||||
is AdvancementRequirement -> return buildAdvancementRequirement(requirement)
|
||||
is BattleCriticalHitsRequirement -> return buildBattleCriticalHitsRequirement(requirement)
|
||||
is BiomeRequirement -> return buildBiomeRequirement(requirement)
|
||||
is BlocksTraveledRequirement -> return buildBlocksTraveledRequirement(requirement)
|
||||
is DamageTakenRequirement -> return buildDamageTakenRequirement(requirement)
|
||||
is DefeatRequirement -> return buildDefeatRequirement(requirement)
|
||||
is FriendshipRequirement -> return buildFriendshipRequirement(requirement)
|
||||
is HeldItemRequirement -> return buildHeldItemRequirement(requirement)
|
||||
is LevelRequirement -> return buildLevelRequirement(requirement)
|
||||
is MoonPhaseRequirement -> return buildMoonPhaseRequirement(requirement)
|
||||
is MoveSetRequirement -> return buildMoveSetRequirement(requirement)
|
||||
is MoveTypeRequirement -> return buildMoveTypeRequirement(requirement)
|
||||
is NegateRequirement -> return buildNegateRequirement(requirement)
|
||||
is OwnerHoldsItemRequirement -> return buildOwnerHoldsItemRequirement(requirement)
|
||||
is PartyMemberRequirement -> return buildPartyMemberRequirement(requirement)
|
||||
is PokemonPropertiesRequirement -> return buildPokemonPropertiesRequirement(requirement)
|
||||
is PropertyRangeRequirement -> return buildPropertyRangeRequirement(requirement)
|
||||
is RecoilRequirement -> return buildRecoilRequirement(requirement)
|
||||
is StatCompareRequirement -> return buildStatCompareRequirement(requirement)
|
||||
is StatEqualRequirement -> return buildStatEqualRequirement(requirement)
|
||||
is StructureRequirement -> return buildStructureRequirement(requirement)
|
||||
is TimeRangeRequirement -> return buildTimeRangeRequirement(requirement)
|
||||
is UseMoveRequirement -> return buildUseMoveRequirement(requirement)
|
||||
is WeatherRequirement -> return buildWeatherRequirement(requirement)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun buildAdvancementRequirement(advancementRequirement: AdvancementRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = Items.BOOK
|
||||
val identifier = advancementRequirement.requiredAdvancement
|
||||
val advancementLanguageKey = "${identifier.namespace}.${identifier.path.substringAfterLast('/')}"
|
||||
val advancementComponent = Component.translatable("advancements.$advancementLanguageKey").green()
|
||||
val tooltip = lang("ui.pokedex.requirement.advancement.tooltip", advancementComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildBattleCriticalHitsRequirement(battleCriticalHitsRequirement: BattleCriticalHitsRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.MEDICINAL_LEEK
|
||||
val criticalsComponent = Component.literal(battleCriticalHitsRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.battle_critical_hits.tooltip", criticalsComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
private fun tagDisplayName(registry: String, id: ResourceLocation): MutableComponent {
|
||||
return Component.translatableWithFallback("tag.$registry.${id.namespace}.${id.path.replace('/', '.')}", prettifyPath(id.path))
|
||||
}
|
||||
|
||||
private fun prettifyPath(path: String): String {
|
||||
return path.substringAfterLast('/').removePrefix("is_").split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) }
|
||||
}
|
||||
|
||||
fun buildNegateRequirement(negateRequirement: NegateRequirement): DexEvolutionRequirementDisplay? {
|
||||
val inner = negateRequirement.inner
|
||||
when (inner) {
|
||||
is BiomeRequirement -> buildBiomeRequirement(inner, negated = true)?.let { return it }
|
||||
is StructureRequirement -> buildStructureRequirement(inner, negated = true)?.let { return it }
|
||||
}
|
||||
val innerDisplay = resolveRequirementData(inner) ?: return null
|
||||
return CobblemonDexEvolutionRequirementDisplay(innerDisplay.icon, lang("ui.pokedex.requirement.negate.tooltip", innerDisplay.tooltip))
|
||||
}
|
||||
|
||||
fun buildBiomeRequirement(biomeRequirement: BiomeRequirement, negated: Boolean = false): DexEvolutionRequirementDisplay? {
|
||||
// Negating "in X" is "not in X"; negating both a condition and an anticondition isn't expressible as one line
|
||||
if (negated && biomeRequirement.biomeCondition != null && biomeRequirement.biomeAnticondition != null) return null
|
||||
val condition = if (negated) biomeRequirement.biomeAnticondition else biomeRequirement.biomeCondition
|
||||
val antiCondition = if (negated) biomeRequirement.biomeCondition else biomeRequirement.biomeAnticondition
|
||||
if (condition == null && antiCondition == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val icon = Items.COMPASS
|
||||
val displayName: (RegistryLikeCondition<Biome>) -> MutableComponent = {
|
||||
when (it) {
|
||||
is RegistryLikeTagCondition -> tagDisplayName("worldgen.biome", it.tag.location())
|
||||
is RegistryLikeIdentifierCondition -> Component.translatable("biome.${it.identifier.namespace}.${it.identifier.path}")
|
||||
else -> Component.literal(it.toString())
|
||||
}
|
||||
}
|
||||
|
||||
val tooltip = if (condition != null && antiCondition != null) {
|
||||
lang("ui.pokedex.requirement.biome.both.tooltip", displayName(condition).green(), displayName(antiCondition).green())
|
||||
} else if (condition != null) {
|
||||
lang("ui.pokedex.requirement.biome.tooltip", displayName(condition).green())
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.biome.anticondition.tooltip", displayName(antiCondition!!).green())
|
||||
}
|
||||
|
||||
var conditionConverted: ExtraCodecs.TagOrElementLocation? = null
|
||||
if (condition != null) {
|
||||
val conditionIdentifier = if (condition is RegistryLikeIdentifierCondition) condition.identifier else (condition as RegistryLikeTagCondition).tag.location
|
||||
conditionConverted = ExtraCodecs.TagOrElementLocation(conditionIdentifier, condition is RegistryLikeTagCondition)
|
||||
}
|
||||
|
||||
var antiConditionConverted: ExtraCodecs.TagOrElementLocation? = null
|
||||
if (antiCondition != null) {
|
||||
val conditionIdentifier = if (antiCondition is RegistryLikeIdentifierCondition) antiCondition.identifier else (antiCondition as RegistryLikeTagCondition).tag.location
|
||||
antiConditionConverted = ExtraCodecs.TagOrElementLocation(conditionIdentifier, antiCondition is RegistryLikeTagCondition)
|
||||
}
|
||||
|
||||
return CobblemonBiomeDexEvolutionRequirementDisplay(icon, tooltip, conditionConverted, antiConditionConverted)
|
||||
}
|
||||
|
||||
fun buildBlocksTraveledRequirement(blocksTraveledRequirement: BlocksTraveledRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = Items.LEATHER_BOOTS
|
||||
val blocksComponent = Component.literal(blocksTraveledRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.blocks_traveled.tooltip", blocksComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildDamageTakenRequirement(damageTakenRequirement: DamageTakenRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.PUNCHING_GLOVE
|
||||
val blocksComponent = Component.literal(damageTakenRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.damage_taken.tooltip", blocksComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildDefeatRequirement(defeatRequirement: DefeatRequirement): DexEvolutionRequirementDisplay? {
|
||||
val description = describePokemonProperties(defeatRequirement.target) ?: return null
|
||||
val icon = CobblemonItems.PUNCHING_GLOVE
|
||||
val defeatedAmount = defeatRequirement.amount
|
||||
|
||||
val descriptionComponent = Component.literal(defeatedAmount.toString()).green().add(" ").add(description)
|
||||
val tooltip = lang("ui.pokedex.requirement.defeat.tooltip", descriptionComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildFriendshipRequirement(friendshipRequirement: FriendshipRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.SOOTHE_BELL
|
||||
val friendshipAmountComponent = Component.literal(friendshipRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.friendship.tooltip", friendshipAmountComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildHeldItemRequirement(heldItemRequirement: HeldItemRequirement): DexEvolutionRequirementDisplay? {
|
||||
val items = heldItemRequirement.itemCondition.items.getOrNull() ?: return null
|
||||
val item = items.firstOrNull()?.value() ?: return null
|
||||
val itemComponent = items.unwrapKey().map { tag ->
|
||||
val id = tag.location()
|
||||
val fallback = id.path.substringAfterLast('/').split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) }
|
||||
Component.translatableWithFallback("tag.item.${id.namespace}.${id.path.replace('/', '.')}", fallback)
|
||||
}.orElseGet { item.description.plainCopy() }
|
||||
val tooltip = lang("ui.pokedex.requirement.held_item.tooltip", itemComponent.green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(item, tooltip)
|
||||
}
|
||||
|
||||
fun buildLevelRequirement(levelRequirement: LevelRequirement): DexEvolutionRequirementDisplay {
|
||||
val minLevel = levelRequirement.minLevel
|
||||
val maxLevel = levelRequirement.maxLevel
|
||||
|
||||
val icon = CobblemonItems.RARE_CANDY
|
||||
val tooltip =
|
||||
if (minLevel == maxLevel || maxLevel == Int.MAX_VALUE)
|
||||
lang("ui.pokedex.requirement.level.tooltip.min", Component.literal(minLevel.toString()).green())
|
||||
else
|
||||
lang("ui.pokedex.requirement.level.tooltip.between", Component.literal(minLevel.toString()).green(), Component.literal(maxLevel.toString()).green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildMoonPhaseRequirement(moonPhaseRequirement: MoonPhaseRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = Items.CLOCK
|
||||
val moonPhaseComponent = moonPhaseRequirement.moonPhase.displayName().green()
|
||||
val tooltip = lang("ui.pokedex.requirement.moon_phase.tooltip", moonPhaseComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildMoveSetRequirement(moveSetRequirement: MoveSetRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.TECHNICAL_MACHINE
|
||||
val tooltip = lang("ui.pokedex.requirement.has_move.tooltip", moveSetRequirement.move.displayName.green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildMoveTypeRequirement(moveTypeRequirement: MoveTypeRequirement): DexEvolutionRequirementDisplay {
|
||||
val type = ElementalTypes.get(moveTypeRequirement.type.name)
|
||||
val icon = when (type) {
|
||||
ElementalTypes.NORMAL -> CobblemonItems.NORMAL_GEM
|
||||
ElementalTypes.FIRE -> CobblemonItems.FIRE_GEM
|
||||
ElementalTypes.WATER -> CobblemonItems.WATER_GEM
|
||||
ElementalTypes.GRASS -> CobblemonItems.GRASS_GEM
|
||||
ElementalTypes.ELECTRIC -> CobblemonItems.ELECTRIC_GEM
|
||||
ElementalTypes.ICE -> CobblemonItems.ICE_GEM
|
||||
ElementalTypes.FIGHTING -> CobblemonItems.FIGHTING_GEM
|
||||
ElementalTypes.POISON -> CobblemonItems.POISON_GEM
|
||||
ElementalTypes.GROUND -> CobblemonItems.GROUND_GEM
|
||||
ElementalTypes.FLYING -> CobblemonItems.FLYING_GEM
|
||||
ElementalTypes.PSYCHIC -> CobblemonItems.PSYCHIC_GEM
|
||||
ElementalTypes.BUG -> CobblemonItems.BUG_GEM
|
||||
ElementalTypes.ROCK -> CobblemonItems.ROCK_GEM
|
||||
ElementalTypes.GHOST -> CobblemonItems.GHOST_GEM
|
||||
ElementalTypes.DRAGON -> CobblemonItems.DRAGON_GEM
|
||||
ElementalTypes.DARK -> CobblemonItems.DARK_GEM
|
||||
ElementalTypes.STEEL -> CobblemonItems.STEEL_GEM
|
||||
ElementalTypes.FAIRY -> CobblemonItems.FAIRY_GEM
|
||||
else -> CobblemonItems.NORMAL_GEM
|
||||
}
|
||||
|
||||
val tooltip = lang("ui.pokedex.requirement.has_move_type.tooltip", moveTypeRequirement.type.displayName.green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildOwnerHoldsItemRequirement(ownerHoldsItemRequirement: OwnerHoldsItemRequirement): DexEvolutionRequirementDisplay? {
|
||||
val item = ownerHoldsItemRequirement.itemCondition.items.orElse(null)?.firstOrNull()?.value() ?: return null
|
||||
val tooltip = lang("ui.pokedex.requirement.owner_held_item.tooltip", item.description.plainCopy().green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(item, tooltip)
|
||||
}
|
||||
|
||||
fun buildPartyMemberRequirement(partyMemberRequirement: PartyMemberRequirement): DexEvolutionRequirementDisplay? {
|
||||
val description = describePokemonProperties(partyMemberRequirement.target) ?: return null
|
||||
val icon = CobblemonItems.POKE_BALL
|
||||
val tooltip = if (partyMemberRequirement.contains) {
|
||||
lang("ui.pokedex.requirement.party_member.tooltip", description)
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.party_member.anticondition.tooltip", description)
|
||||
}
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildPokemonPropertiesRequirement(pokemonPropertiesRequirement: PokemonPropertiesRequirement): DexEvolutionRequirementDisplay? {
|
||||
val description = describePokemonProperties(pokemonPropertiesRequirement.target) ?: return null
|
||||
val icon = Items.NAME_TAG
|
||||
val tooltip = lang("ui.pokedex.requirement.pokemon_properties.tooltip", description)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildPropertyRangeRequirement(propertyRangeRequirement: PropertyRangeRequirement): DexEvolutionRequirementDisplay? {
|
||||
val provider = SpeciesFeatures.getFeature(propertyRangeRequirement.feature) as? IntSpeciesFeatureProvider ?: return null
|
||||
val displayName = provider.display?.name?.takeIf { it.isNotBlank() }?.asTranslated()?.green() ?: return null
|
||||
val icon = provider.itemPoints.keys.firstOrNull()?.let { BuiltInRegistries.ITEM.get(it) } ?: Items.NAME_TAG
|
||||
|
||||
val range = propertyRangeRequirement.range
|
||||
val tooltip = lang(
|
||||
"ui.pokedex.requirement.property_range.tooltip",
|
||||
displayName,
|
||||
Component.literal(range.first.toString()).green(),
|
||||
Component.literal(range.last.toString()).green()
|
||||
)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildRecoilRequirement(recoilRequirement: RecoilRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.LIFE_ORB
|
||||
val recoilComponent = Component.literal(recoilRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.recoil.tooltip", recoilComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildStatCompareRequirement(statCompareRequirement: StatCompareRequirement): DexEvolutionRequirementDisplay {
|
||||
val highStat = Stats.getStat(statCompareRequirement.highStat)
|
||||
val lowStat = Stats.getStat(statCompareRequirement.lowStat)
|
||||
|
||||
val icon = when (highStat) {
|
||||
Stats.HP, Stats.EVASION, Stats.ACCURACY -> CobblemonItems.HEALTH_MOCHI
|
||||
Stats.ATTACK -> CobblemonItems.MUSCLE_MOCHI
|
||||
Stats.DEFENCE -> CobblemonItems.RESIST_MOCHI
|
||||
Stats.SPECIAL_ATTACK -> CobblemonItems.GENIUS_MOCHI
|
||||
Stats.SPECIAL_DEFENCE -> CobblemonItems.CLEVER_MOCHI
|
||||
Stats.SPEED -> CobblemonItems.SWIFT_MOCHI
|
||||
}
|
||||
|
||||
val highStatComponent = highStat.displayName.plainCopy().green()
|
||||
val lowStatComponent = lowStat.displayName.plainCopy().green()
|
||||
val tooltip = lang("ui.pokedex.requirement.stat_compare.tooltip", highStatComponent, lowStatComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildStatEqualRequirement(statEqualRequirement: StatEqualRequirement): DexEvolutionRequirementDisplay {
|
||||
val statOne = Stats.getStat(statEqualRequirement.statOne)
|
||||
val statTwo = Stats.getStat(statEqualRequirement.statTwo)
|
||||
|
||||
val statOneComponent = statOne.displayName.plainCopy().green()
|
||||
val statTwoComponent = statTwo.displayName.plainCopy().green()
|
||||
|
||||
val icon = CobblemonItems.FRESH_START_MOCHI
|
||||
val tooltip = lang("ui.pokedex.requirement.stat_equal.tooltip", statOneComponent, statTwoComponent)
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildStructureRequirement(structureRequirement: StructureRequirement, negated: Boolean = false): DexEvolutionRequirementDisplay? {
|
||||
if (negated && structureRequirement.structureCondition != null && structureRequirement.structureAnticondition != null) return null
|
||||
val condition = if (negated) structureRequirement.structureAnticondition else structureRequirement.structureCondition
|
||||
val anticondition = if (negated) structureRequirement.structureCondition else structureRequirement.structureAnticondition
|
||||
if (condition == null && anticondition == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val icon = Items.FILLED_MAP
|
||||
val displayName: (RegistryLikeCondition<Structure>) -> MutableComponent = {
|
||||
when (it) {
|
||||
is RegistryLikeTagCondition -> tagDisplayName("worldgen.structure", it.tag.location())
|
||||
is RegistryLikeIdentifierCondition -> Component.literal(prettifyPath(it.identifier.path))
|
||||
else -> Component.literal(it.toString())
|
||||
}
|
||||
}
|
||||
val tooltip = if (condition != null && anticondition != null) {
|
||||
lang("ui.pokedex.requirement.structure.both.tooltip", displayName(condition).green(), displayName(anticondition).green())
|
||||
} else if (condition != null) {
|
||||
lang("ui.pokedex.requirement.structure.tooltip", displayName(condition).green())
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.structure.anticondition.tooltip", displayName(anticondition!!).green())
|
||||
}
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildTimeRangeRequirement(timeRangeRequirement: TimeRangeRequirement): DexEvolutionRequirementDisplay? {
|
||||
val icon = Items.CLOCK
|
||||
val timeRangeComponent = timeRangeRequirement.range.displayName() ?: return null
|
||||
val tooltip = lang("ui.pokedex.requirement.time_range.tooltip", timeRangeComponent.green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildUseMoveRequirement(useMoveRequirement: UseMoveRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon = CobblemonItems.CHOICE_BAND
|
||||
val tooltip = lang("ui.pokedex.requirement.use_move.tooltip", useMoveRequirement.move.displayName.green())
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
|
||||
fun buildWeatherRequirement(weatherRequirement: WeatherRequirement): DexEvolutionRequirementDisplay {
|
||||
val icon: Item
|
||||
val tooltip: MutableComponent
|
||||
|
||||
if (weatherRequirement.isThundering == true) {
|
||||
icon = Items.LIGHTNING_ROD
|
||||
tooltip = lang("ui.pokedex.requirement.weather.tooltip.thundering")
|
||||
} else {
|
||||
icon = Items.WATER_BUCKET
|
||||
tooltip = lang("ui.pokedex.requirement.weather.tooltip.raining")
|
||||
}
|
||||
|
||||
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree
|
||||
package com.cobblemon.mod.common.api.pokedex.entry
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
@@ -28,7 +28,7 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.world.item.Items
|
||||
|
||||
internal fun describePokemonProperties(properties: PokemonProperties): MutableComponent? {
|
||||
fun describePokemonProperties(properties: PokemonProperties): MutableComponent? {
|
||||
if (hasUndescribedProperty(properties)) {
|
||||
return null
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import com.cobblemon.mod.common.api.moves.MoveTemplate
|
||||
import com.cobblemon.mod.common.api.moves.MovesetBuilder
|
||||
import com.cobblemon.mod.common.api.moves.adapters.MoveTemplateAdapter
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies.getByIdentifier
|
||||
import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffect
|
||||
import com.cobblemon.mod.common.api.pokemon.effect.adapter.ShoulderEffectAdapter
|
||||
import com.cobblemon.mod.common.api.pokemon.egg.EggGroup
|
||||
@@ -44,9 +43,6 @@ import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
|
||||
import com.cobblemon.mod.common.api.spawning.TimeRange
|
||||
import com.cobblemon.mod.common.api.types.ElementalType
|
||||
import com.cobblemon.mod.common.api.types.adapters.ElementalTypeAdapter
|
||||
import com.cobblemon.mod.common.net.messages.client.data.FormEvolutionOverride
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionEntry
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
@@ -246,18 +242,6 @@ object PokemonSpecies : JsonDataRegistry<Species> {
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
SpeciesRegistrySyncPacket(species.toList()).sendToPlayer(player)
|
||||
// Sent after the species themselves so every species is already registered by the time this is decoded.
|
||||
val evolutionEntries = species.map { singleSpecies ->
|
||||
val formOverrides = singleSpecies.forms.mapNotNull { form ->
|
||||
if (form.ownEvolutions == null && form.ownPreEvolution == null) {
|
||||
null
|
||||
} else {
|
||||
FormEvolutionOverride(form.name, form.ownEvolutions, form.ownPreEvolution)
|
||||
}
|
||||
}
|
||||
SpeciesEvolutionEntry(singleSpecies.resourceIdentifier, singleSpecies.evolutions, singleSpecies.preEvolution, formOverrides)
|
||||
}
|
||||
SpeciesEvolutionSyncPacket(evolutionEntries).sendToPlayer(player)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,8 +25,6 @@ interface PreEvolution {
|
||||
|
||||
val form: FormData
|
||||
|
||||
fun resolveForm(extraAspects: Set<String> = emptySet()): FormData = form
|
||||
|
||||
companion object {
|
||||
|
||||
fun of(species: Species, form: FormData = species.standardForm): PreEvolution = StandardPreEvolution(species, form)
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacke
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
@@ -270,6 +271,34 @@ open class PCStore(
|
||||
}
|
||||
}
|
||||
|
||||
fun moveBatch(moves: List<Triple<UUID, PCPosition, PCPosition>>): Boolean {
|
||||
if (moves.isEmpty() || moves.size > MovePCPokemonBatchPacket.MAX_MOVES) return false
|
||||
if (moves.map { it.second }.toSet().size != moves.size ||
|
||||
moves.map { it.third }.toSet().size != moves.size ||
|
||||
moves.map { it.first }.toSet().size != moves.size
|
||||
) return false
|
||||
if (moves.any { (_, source, target) -> !isValidPosition(source) || !isValidPosition(target) }) return false
|
||||
|
||||
val sourcePositions = moves.mapTo(mutableSetOf()) { it.second }
|
||||
val pokemonMoves = moves.map { (pokemonID, source, target) ->
|
||||
val pokemon = get(source)?.takeIf { it.uuid == pokemonID } ?: return false
|
||||
Triple(source, target, pokemon)
|
||||
}
|
||||
if (pokemonMoves.any { (_, target, _) -> get(target) != null && target !in sourcePositions }) return false
|
||||
|
||||
pokemonMoves.forEach { (source, _, _) -> setAtPosition(source, null) }
|
||||
pokemonMoves.forEach { (_, target, pokemon) -> setAtPosition(target, pokemon) }
|
||||
|
||||
pokemonMoves.forEach { (_, _, pokemon) ->
|
||||
sendPacketToObservers(RemoveClientPokemonPacket(this, pokemon.uuid))
|
||||
}
|
||||
pokemonMoves.forEach { (_, target, pokemon) ->
|
||||
sendPacketToObservers(SetPCPokemonPacket(uuid, target) { pokemon })
|
||||
}
|
||||
pcChangeObservable.emit(Unit)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun loadPositionFromNBT(nbt: CompoundTag): StoreCoordinates<PCPosition> {
|
||||
return StoreCoordinates(this, PCPosition(nbt.getShort(DataKeys.STORE_BOX).toInt(), nbt.getByte(DataKeys.STORE_SLOT).toInt()))
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ object CobblemonItemTags {
|
||||
@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 IS_FRIENDSHIP_BOOSTER = create("held/is_friendship_booster")
|
||||
@JvmField val ANY_HELD_ITEM = create("held/is_held_item")
|
||||
@JvmField val BLACKLISTED_ITEMS_TO_HOLD = create("held/blacklisted_items_to_hold")
|
||||
@JvmField val WHITELISTED_ITEMS_TO_HOLD = create("held/whitelisted_items_to_hold")
|
||||
|
||||
@@ -29,7 +29,8 @@ class BoxStorageSlot(
|
||||
|
||||
val grabbedSlot = parent.grabbedSlot
|
||||
return if (grabbedSlot == null) {
|
||||
true
|
||||
val pokemon = getPokemon()
|
||||
pokemon == null || !parent.isInMultiSelection(pokemon, position)
|
||||
} else {
|
||||
grabbedSlot.getPokemon() != getPokemon()
|
||||
}
|
||||
|
||||
@@ -50,13 +50,15 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import kotlin.isInitialized
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FastColor
|
||||
|
||||
class PCGUI(
|
||||
val pc: ClientPC,
|
||||
val party: ClientParty,
|
||||
val configuration: PCGUIConfiguration,
|
||||
val openOnBox: Int = CobblemonClient.lastPcBoxViewed,
|
||||
val unseenWallpapers: MutableSet<ResourceLocation> = mutableSetOf()
|
||||
val unseenWallpapers: MutableSet<ResourceLocation> = mutableSetOf(),
|
||||
val silent: Boolean = false
|
||||
) : Screen(Component.translatable("cobblemon.ui.pc.title")), CobblemonRenderable {
|
||||
|
||||
companion object {
|
||||
@@ -128,6 +130,55 @@ class PCGUI(
|
||||
var selectPointerOffsetIncrement = false
|
||||
var displayOptions = false
|
||||
|
||||
private var dragStartX: Int? = null
|
||||
private var dragStartY: Int? = null
|
||||
private var dragEndX: Int? = null
|
||||
private var dragEndY: Int? = null
|
||||
private var selectionDragActive = false
|
||||
|
||||
data class SelectionArea(val left: Int, val top: Int, val right: Int, val bottom: Int)
|
||||
|
||||
private data class BoxGridBounds(val left: Int, val top: Int, val right: Int, val bottom: Int) {
|
||||
fun contains(x: Int, y: Int) = x in left..< right && y >= top && y < bottom
|
||||
}
|
||||
|
||||
private fun getBoxGridBounds(): BoxGridBounds {
|
||||
val left = storageWidget.x
|
||||
val top = storageWidget.y
|
||||
return BoxGridBounds(
|
||||
left,
|
||||
top,
|
||||
left + StorageWidget.SCREEN_WIDTH,
|
||||
top + StorageWidget.SCREEN_HEIGHT
|
||||
)
|
||||
}
|
||||
|
||||
fun getSelectionArea(): SelectionArea? {
|
||||
if (!selectionDragActive) return null
|
||||
val startX = dragStartX ?: return null
|
||||
val startY = dragStartY ?: return null
|
||||
val endX = dragEndX ?: return null
|
||||
val endY = dragEndY ?: return null
|
||||
val bounds = getBoxGridBounds()
|
||||
if (!bounds.contains(startX, startY)) return null
|
||||
|
||||
val columns = 6
|
||||
val rows = 5
|
||||
val slotPitch = StorageSlot.SIZE + StorageWidget.BOX_SLOT_PADDING
|
||||
val gridLeft = bounds.left + StorageWidget.BOX_SLOT_START_OFFSET_X
|
||||
val gridTop = bounds.top + StorageWidget.BOX_SLOT_START_OFFSET_Y + if (displayOptions) 5 else 0
|
||||
val startColumn = ((startX - gridLeft) / slotPitch).coerceIn(0, columns - 1)
|
||||
val endColumn = (((endX.coerceIn(bounds.left, bounds.right - 1)) - gridLeft) / slotPitch).coerceIn(0, columns - 1)
|
||||
val startRow = ((startY - gridTop) / slotPitch).coerceIn(0, rows - 1)
|
||||
val endRow = (((endY.coerceIn(bounds.top, bounds.bottom - 1)) - gridTop) / slotPitch).coerceIn(0, rows - 1)
|
||||
return SelectionArea(
|
||||
gridLeft + minOf(startColumn, endColumn) * slotPitch, // left
|
||||
gridTop + minOf(startRow, endRow) * slotPitch, // top
|
||||
gridLeft + (maxOf(startColumn, endColumn) * slotPitch) + StorageSlot.SIZE, // right
|
||||
gridTop + (maxOf(startRow, endRow) * slotPitch) + StorageSlot.SIZE // bottom
|
||||
)
|
||||
}
|
||||
|
||||
override fun renderBlurredBackground(delta: Float) {}
|
||||
|
||||
override fun renderMenuBackground(context: GuiGraphics) {}
|
||||
@@ -249,7 +300,7 @@ class PCGUI(
|
||||
configuration.showParty = isVisible
|
||||
wallpaperWidget.visible = !isVisible
|
||||
(it as IconButton).highlighted = !isVisible
|
||||
if (!unseenWallpapers.isEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
|
||||
if (unseenWallpapers.isNotEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
|
||||
}.also {
|
||||
it.visible = displayOptions
|
||||
optionButtons.add(it)
|
||||
@@ -314,6 +365,20 @@ class PCGUI(
|
||||
super.init()
|
||||
}
|
||||
|
||||
private fun renderSelectionBox(context: GuiGraphics, area: SelectionArea) {
|
||||
context.pose().pushPose()
|
||||
context.pose().translate(0.0, 0.0, 1500.0)
|
||||
val borderColor = FastColor.ARGB32.color(255, 205, 212, 255)
|
||||
val bgColor = FastColor.ARGB32.color(75, 133, 183, 230)
|
||||
val thickness = 1
|
||||
context.fill(area.left, area.top, area.right, area.bottom, bgColor)
|
||||
context.fill(area.left, area.top, area.right, area.top + thickness, borderColor)
|
||||
context.fill(area.left, area.bottom - thickness, area.right, area.bottom, borderColor)
|
||||
context.fill(area.left, area.top, area.left + thickness, area.bottom, borderColor)
|
||||
context.fill(area.right - thickness, area.top, area.right, area.bottom, borderColor)
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
override fun render(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val matrices = context.pose()
|
||||
renderBackground(context, mouseX, mouseY, delta)
|
||||
@@ -684,12 +749,14 @@ class PCGUI(
|
||||
scale = SCALE
|
||||
)
|
||||
|
||||
if (!optionButtons.isEmpty() && displayOptions) {
|
||||
if (optionButtons.isNotEmpty() && displayOptions) {
|
||||
for (button in optionButtons) button.showAlt = hasShiftDown()
|
||||
}
|
||||
|
||||
super.render(context, mouseX, mouseY, delta)
|
||||
|
||||
getSelectionArea()?.let { renderSelectionBox(context, it) }
|
||||
|
||||
// Item Tooltip
|
||||
if (pokemon != null) {
|
||||
val displayedItem = if (showCosmeticItem) pokemon.cosmeticItem else pokemon.heldItemNoCopy()
|
||||
@@ -703,7 +770,7 @@ class PCGUI(
|
||||
}
|
||||
|
||||
fun closeNormally(unlink: Boolean = true) {
|
||||
playSound(CobblemonSounds.PC_OFF)
|
||||
if (!silent) playSound(CobblemonSounds.PC_OFF)
|
||||
Minecraft.getInstance().setScreen(null)
|
||||
if (unlink) {
|
||||
UnlinkPlayerFromPCPacket().sendToServer()
|
||||
@@ -711,6 +778,20 @@ class PCGUI(
|
||||
}
|
||||
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
selectionDragActive = false
|
||||
val clickX = mouseX.toInt()
|
||||
val clickY = mouseY.toInt()
|
||||
if (storageWidget.multiSelection == null && button == 0 &&
|
||||
getBoxGridBounds().contains(clickX, clickY) &&
|
||||
storageWidget.pastureWidget == null) {
|
||||
dragStartX = clickX
|
||||
dragStartY = clickY
|
||||
} else {
|
||||
dragStartX = null
|
||||
dragStartY = null
|
||||
}
|
||||
|
||||
// Trigger child component function as they will need to check the entire screen click area
|
||||
if (::boxNameWidget.isInitialized) boxNameWidget.mouseClicked(mouseX, mouseY, button)
|
||||
return super.mouseClicked(mouseX, mouseY, button)
|
||||
@@ -739,16 +820,50 @@ class PCGUI(
|
||||
storageWidget.pastureWidget?.let { pasture ->
|
||||
if (pasture.pastureScrollList.isHovered) pasture.pastureScrollList.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
||||
}
|
||||
if (button == 0 && storageWidget.pastureWidget == null) {
|
||||
val startX = dragStartX
|
||||
val startY = dragStartY
|
||||
if (startX != null && startY != null) {
|
||||
val offsetX = mouseX - startX
|
||||
val offsetY = mouseY - startY
|
||||
if (offsetX * offsetX + offsetY * offsetY >= 25.0) {
|
||||
selectionDragActive = true
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
dragEndX = mouseX.toInt()
|
||||
dragEndY = mouseY.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
||||
}
|
||||
|
||||
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
val handled = super.mouseReleased(mouseX, mouseY, button)
|
||||
if (button == 0) {
|
||||
if (selectionDragActive) {
|
||||
dragEndX = mouseX.toInt()
|
||||
dragEndY = mouseY.toInt()
|
||||
storageWidget.updateSelection()
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
} else {
|
||||
storageWidget.completePendingStorageSlotClick(mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
dragStartX = null
|
||||
dragStartY = null
|
||||
dragEndX = null
|
||||
dragEndY = null
|
||||
selectionDragActive = false
|
||||
return handled
|
||||
}
|
||||
|
||||
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
||||
val boxNameFocused = this::boxNameWidget.isInitialized && boxNameWidget.isFocused
|
||||
val filterFocused = this::filterWidget.isInitialized && filterWidget.isFocused
|
||||
|
||||
if (isInventoryKeyPressed(minecraft, keyCode, scanCode) && !boxNameFocused && !filterFocused) {
|
||||
saveMarkings(isPreviewInParty ?: false)
|
||||
playSound(CobblemonSounds.PC_OFF)
|
||||
if (!silent) playSound(CobblemonSounds.PC_OFF)
|
||||
UnlinkPlayerFromPCPacket().sendToServer()
|
||||
Minecraft.getInstance().setScreen(null)
|
||||
return true
|
||||
@@ -759,7 +874,7 @@ class PCGUI(
|
||||
if (!filterFocused && !boxNameFocused) {
|
||||
when (keyCode) {
|
||||
InputConstants.KEY_ESCAPE -> {
|
||||
playSound(CobblemonSounds.PC_OFF)
|
||||
if (!silent) playSound(CobblemonSounds.PC_OFF)
|
||||
UnlinkPlayerFromPCPacket().sendToServer()
|
||||
onClose()
|
||||
return true
|
||||
@@ -831,4 +946,4 @@ class PCGUI(
|
||||
markingsWidget.setActivePokemon(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.cobblemon.mod.common.client.gui.pc
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
data class PCMultiSelection(
|
||||
private val grid: MutableList<MutableList<Pokemon?>> = mutableListOf(),
|
||||
val sourceBox: Int = 0,
|
||||
val sourceColumn: Int = 0,
|
||||
val sourceRow: Int = 0
|
||||
) {
|
||||
fun getHorizontalSize(): Int = grid.firstOrNull()?.size ?: 0
|
||||
fun getVerticalSize(): Int = grid.size
|
||||
|
||||
constructor(horizontalSize: Int, verticalSize: Int, sourceBox: Int, sourceColumn: Int, sourceRow: Int) : this(
|
||||
MutableList(verticalSize) { MutableList<Pokemon?>(horizontalSize) { null } },
|
||||
sourceBox,
|
||||
sourceColumn,
|
||||
sourceRow
|
||||
)
|
||||
|
||||
fun getPokemon(x: Int, y: Int): Pokemon? {
|
||||
return grid[y][x]
|
||||
}
|
||||
|
||||
fun setPokemon(x: Int, y: Int, pokemon: Pokemon?) {
|
||||
grid[y][x] = pokemon
|
||||
}
|
||||
|
||||
fun pokemonEntries(): List<Triple<Int, Int, Pokemon>> {
|
||||
return grid.flatMapIndexed { y, row ->
|
||||
row.mapIndexedNotNull { x, pokemon -> pokemon?.let { Triple(x, y, it) } }
|
||||
}
|
||||
}
|
||||
|
||||
fun getPokemonCount(): Int = pokemonEntries().size
|
||||
|
||||
}
|
||||
@@ -45,11 +45,13 @@ class ReleaseButton(
|
||||
vOffset = if (isHovered(mouseX.toDouble(), mouseY.toDouble())) HEIGHT else 0,
|
||||
textureHeight = HEIGHT * 2
|
||||
)
|
||||
val pokemonCount = parent.multiSelection?.getPokemonCount() ?: 0
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = lang("ui.pc.release").bold(),
|
||||
text = if (pokemonCount > 1)
|
||||
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
|
||||
x = x + (WIDTH / 2),
|
||||
y = y + 3.5,
|
||||
centered = true,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.client.gui.pc
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.gui.ColourLibrary
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
@@ -54,9 +55,17 @@ open class StorageSlot(
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val selectionArea = parent.pcGui.getSelectionArea()
|
||||
if (selectionArea != null && parent.getSelectedPokemon(selectionArea).contains(this)) {
|
||||
val highlightColor = 0x40FFFFFF
|
||||
context.fill(x + 1, y, x + (SIZE - 1), y + SIZE, highlightColor)
|
||||
context.fill(x, y + 1, x + 1, y + (SIZE - 1), highlightColor)
|
||||
context.fill(x + SIZE - 1, y + 1, x + SIZE, y + (SIZE - 1), highlightColor)
|
||||
}
|
||||
if (shouldRender()) {
|
||||
renderSlot(context, x, y, delta)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun renderSlot(context: GuiGraphics, posX: Int, posY: Int, partialTicks: Float) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.gui.pc
|
||||
import com.cobblemon.mod.common.CobblemonNetwork
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.storage.StorePosition
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
@@ -39,8 +38,9 @@ import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import java.util.UUID
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket.PCPokemonMove
|
||||
|
||||
class StorageWidget(
|
||||
pX: Int, pY: Int,
|
||||
@@ -77,9 +77,13 @@ class StorageWidget(
|
||||
|
||||
var displayConfirmRelease = false
|
||||
var screenLoaded = false
|
||||
var selectedPosition: StorePosition? = null
|
||||
var selectedPosition: PartyPosition? = null
|
||||
var grabbedSlot: GrabbedStorageSlot? = null
|
||||
|
||||
var multiSelection: PCMultiSelection? = null
|
||||
private val multiGrabbedSlots = mutableMapOf<UUID, GrabbedStorageSlot>()
|
||||
private var pendingStorageSlotClick: Button? = null
|
||||
|
||||
var box = 0
|
||||
set(value) {
|
||||
field =
|
||||
@@ -113,16 +117,22 @@ class StorageWidget(
|
||||
subKey = "ui.generic.yes",
|
||||
onPress = {
|
||||
if (canDeleteSelected() && displayConfirmRelease) {
|
||||
val position = selectedPosition ?: return@ReleaseConfirmButton
|
||||
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
|
||||
val selection = multiSelection
|
||||
if (selection != null) {
|
||||
selection.pokemonEntries().forEach { (column, row, pokemon) ->
|
||||
val position = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
CobblemonNetwork.sendToServer(ReleasePCPokemonPacket(pokemon.uuid, position))
|
||||
}
|
||||
} else {
|
||||
val position = selectedPosition ?: return@ReleaseConfirmButton
|
||||
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
|
||||
|
||||
val packet = when (position) {
|
||||
is PartyPosition -> ReleasePartyPokemonPacket(pokemon.uuid, position)
|
||||
is PCPosition -> ReleasePCPokemonPacket(pokemon.uuid, position)
|
||||
else -> return@ReleaseConfirmButton
|
||||
CobblemonNetwork.sendToServer(ReleasePartyPokemonPacket(pokemon.uuid, position))
|
||||
}
|
||||
|
||||
CobblemonNetwork.sendToServer(packet)
|
||||
playSound(CobblemonSounds.PC_RELEASE)
|
||||
resetSelected()
|
||||
displayConfirmRelease = false
|
||||
@@ -149,9 +159,8 @@ class StorageWidget(
|
||||
}
|
||||
|
||||
fun canDeleteSelected(): Boolean {
|
||||
return !(selectedPosition is PartyPosition && party.filterNotNull().size <= 1)
|
||||
&& selectedPosition != null
|
||||
&& grabbedSlot != null
|
||||
multiSelection?.let { return it.pokemonEntries().isNotEmpty() }
|
||||
return party.filterNotNull().size > 1 && selectedPosition != null && grabbedSlot != null
|
||||
}
|
||||
|
||||
fun setupStorageSlots() {
|
||||
@@ -170,7 +179,7 @@ class StorageWidget(
|
||||
parent = this,
|
||||
pc = pc,
|
||||
position = PCPosition(box, index),
|
||||
onPress = { this.onStorageSlotClicked(it) }
|
||||
onPress = { pendingStorageSlotClick = it }
|
||||
).also { widget ->
|
||||
this.addWidget(widget)
|
||||
this.boxSlots.add(widget)
|
||||
@@ -200,7 +209,7 @@ class StorageWidget(
|
||||
parent = this,
|
||||
party = party,
|
||||
position = PartyPosition(partyIndex),
|
||||
onPress = { this.onStorageSlotClicked(it) }
|
||||
onPress = { pendingStorageSlotClick = it }
|
||||
).also { widget ->
|
||||
this.addWidget(widget)
|
||||
this.partySlots.add(widget)
|
||||
@@ -210,13 +219,115 @@ class StorageWidget(
|
||||
|
||||
private fun getSelectedPokemon(): Pokemon? {
|
||||
val selectedPosition = this.selectedPosition ?: return null
|
||||
return when (selectedPosition) {
|
||||
is PCPosition -> pc.get(selectedPosition)
|
||||
is PartyPosition -> party.get(selectedPosition)
|
||||
else -> null
|
||||
return party.get(selectedPosition)
|
||||
}
|
||||
|
||||
fun getSelectedPokemon(area: PCGUI.SelectionArea): List<BoxStorageSlot> {
|
||||
return boxSlots.filter { slot ->
|
||||
slot.x < area.right && slot.x + StorageSlot.SIZE > area.left &&
|
||||
slot.y < area.bottom && slot.y + StorageSlot.SIZE > area.top &&
|
||||
slot.getPokemon()?.let(pcGui.search::passes) == true
|
||||
}
|
||||
}
|
||||
|
||||
fun clearPendingStorageSlotClick() {
|
||||
pendingStorageSlotClick = null
|
||||
}
|
||||
|
||||
fun completePendingStorageSlotClick(mouseX: Double, mouseY: Double) {
|
||||
val button = pendingStorageSlotClick ?: return
|
||||
pendingStorageSlotClick = null
|
||||
if (button.isMouseOver(mouseX, mouseY)) {
|
||||
onStorageSlotClicked(button)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSelection() {
|
||||
val area = pcGui.getSelectionArea()
|
||||
if (area == null) {
|
||||
multiSelection = null
|
||||
return
|
||||
}
|
||||
|
||||
selectedPosition = null
|
||||
grabbedSlot = null
|
||||
pcGui.setPreviewPokemon(null)
|
||||
|
||||
val selectedSlots = getSelectedPokemon(area)
|
||||
if (selectedSlots.isEmpty()) {
|
||||
multiSelection = null
|
||||
return
|
||||
}
|
||||
|
||||
val minColumn = selectedSlots.minOf { it.position.slot % 6 }
|
||||
val maxColumn = selectedSlots.maxOf { it.position.slot % 6 }
|
||||
val minRow = selectedSlots.minOf { it.position.slot / 6 }
|
||||
val maxRow = selectedSlots.maxOf { it.position.slot / 6 }
|
||||
val selection = PCMultiSelection(maxColumn - minColumn + 1, maxRow - minRow + 1, box, minColumn, minRow)
|
||||
|
||||
selectedSlots.forEach { slot ->
|
||||
val pokemon = slot.getPokemon() ?: return@forEach
|
||||
val slotIndex = slot.position.slot
|
||||
val column = slotIndex % 6
|
||||
val row = slotIndex / 6
|
||||
if (column in minColumn..maxColumn && row in minRow..maxRow) {
|
||||
selection.setPokemon(column - minColumn, row - minRow, pokemon)
|
||||
}
|
||||
}
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
|
||||
multiSelection = selection
|
||||
}
|
||||
|
||||
private fun moveMultiSelectionTo(destination: PCPosition): Boolean {
|
||||
val selection = multiSelection ?: return false
|
||||
|
||||
val width = selection.getHorizontalSize()
|
||||
val height = selection.getVerticalSize()
|
||||
val destinationColumn = destination.slot % 6
|
||||
val destinationRow = destination.slot / 6
|
||||
if (destinationColumn + width > 6 || destinationRow + height > 5) return false
|
||||
|
||||
val moves = mutableListOf<PCPokemonMove>()
|
||||
val selectedSources = mutableSetOf<PCPosition>()
|
||||
for (row in 0 until height) {
|
||||
for (column in 0 until width) {
|
||||
val pokemon = selection.getPokemon(column, row) ?: continue
|
||||
val source = PCPosition(selection.sourceBox, (selection.sourceRow + row) * 6 + selection.sourceColumn + column)
|
||||
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
|
||||
selectedSources.add(source)
|
||||
moves.add(PCPokemonMove(pokemon.uuid, source, target))
|
||||
}
|
||||
}
|
||||
|
||||
if (moves.isEmpty()) return false
|
||||
|
||||
for (row in 0 until height) {
|
||||
for (column in 0 until width) {
|
||||
if (selection.getPokemon(column, row) == null) continue
|
||||
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
|
||||
val displacedPokemon = pc.get(target) ?: continue
|
||||
if (target in selectedSources) continue
|
||||
|
||||
val displacedSource = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
if (pc.get(displacedSource) != null && displacedSource !in selectedSources) return false
|
||||
moves.add(PCPokemonMove(displacedPokemon.uuid, target, displacedSource))
|
||||
}
|
||||
}
|
||||
|
||||
if (moves.map { it.newPosition }.toSet().size != moves.size) return false
|
||||
MovePCPokemonBatchPacket(moves).sendToServer()
|
||||
return true
|
||||
}
|
||||
|
||||
fun isInMultiSelection(pokemon: Pokemon, position: PCPosition): Boolean {
|
||||
val selection = multiSelection ?: return false
|
||||
return selection.sourceBox == position.box && selection.pokemonEntries().any { it.third == pokemon }
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val matrices = context.pose()
|
||||
// Party Label
|
||||
@@ -240,11 +351,14 @@ class StorageWidget(
|
||||
shadow = true
|
||||
)
|
||||
|
||||
val pokemonCount = multiSelection?.getPokemonCount() ?: 0
|
||||
|
||||
if (canDeleteSelected() && displayConfirmRelease) {
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = lang("ui.pc.release").bold(),
|
||||
text = if (pokemonCount > 1)
|
||||
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
|
||||
x = x + 223,
|
||||
y = y + 119,
|
||||
centered = true
|
||||
@@ -308,6 +422,7 @@ class StorageWidget(
|
||||
slot.render(context, mouseX, mouseY, delta)
|
||||
val pokemon = slot.getPokemon()
|
||||
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
|
||||
&& multiSelection == null
|
||||
&& pokemon != null && pokemon != pcGui.previewPokemon
|
||||
) {
|
||||
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: false)
|
||||
@@ -324,6 +439,7 @@ class StorageWidget(
|
||||
slot.render(context, mouseX, mouseY, delta)
|
||||
val pokemon = slot.getPokemon()
|
||||
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
|
||||
&& multiSelection == null
|
||||
&& pokemon != null && pokemon != pcGui.previewPokemon
|
||||
) {
|
||||
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: true)
|
||||
@@ -335,10 +451,31 @@ class StorageWidget(
|
||||
pastureWidget?.render(context, mouseX, mouseY, delta)
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 1000.0)
|
||||
grabbedSlot?.render(context, mouseX, mouseY, delta)
|
||||
renderSelectedPokemon(context, mouseX, mouseY, delta)
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
private fun renderSelectedPokemon(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val selection = multiSelection
|
||||
if (selection == null) {
|
||||
grabbedSlot?.render(context, mouseX, mouseY, delta)
|
||||
return
|
||||
}
|
||||
|
||||
val slotOffset = StorageSlot.SIZE + BOX_SLOT_PADDING
|
||||
selection.pokemonEntries().forEach { (column, row, pokemon) ->
|
||||
val grabbed = multiGrabbedSlots.getOrPut(pokemon.uuid) {
|
||||
GrabbedStorageSlot(0, 0, this, pokemon)
|
||||
}
|
||||
grabbed.render(
|
||||
context,
|
||||
mouseX + column * slotOffset,
|
||||
mouseY + row * slotOffset,
|
||||
delta
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
|
||||
if (displayConfirmRelease) {
|
||||
if (releaseYesButton.isHovered(pMouseX, pMouseY)) releaseYesButton.mouseClicked(pMouseX, pMouseY, pButton)
|
||||
@@ -371,23 +508,55 @@ class StorageWidget(
|
||||
else -> return
|
||||
}
|
||||
|
||||
val clickedPokemon = when (clickedPosition) {
|
||||
is PCPosition -> pc.get(clickedPosition)
|
||||
is PartyPosition -> party.get(clickedPosition)
|
||||
else -> null
|
||||
}
|
||||
|
||||
multiSelection?.let { selection ->
|
||||
when (clickedPosition) {
|
||||
is PCPosition -> {
|
||||
if (clickedPosition.box == selection.sourceBox &&
|
||||
clickedPosition.slot == selection.sourceRow * 6 + selection.sourceColumn
|
||||
) {
|
||||
resetSelected()
|
||||
} else if (moveMultiSelectionTo(clickedPosition)) {
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
}
|
||||
is PartyPosition -> {
|
||||
val selectedPokemon = selection.pokemonEntries().singleOrNull() ?: return
|
||||
val (column, row, pokemon) = selectedPokemon
|
||||
val source = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
if (pc.get(source) !== pokemon) return
|
||||
val packet = clickedPokemon?.let {
|
||||
SwapPCPartyPokemonPacket(it.uuid, clickedPosition, pokemon.uuid, source)
|
||||
} ?: MovePCPokemonToPartyPacket(pokemon.uuid, source, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Reset release confirmation
|
||||
displayConfirmRelease = false
|
||||
|
||||
// Clicking on itself, so unselect position
|
||||
if (this.selectedPosition != null && this.selectedPosition == clickedPosition) {
|
||||
if (selectedPosition == clickedPosition) {
|
||||
if (grabbedSlot != null) playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
return
|
||||
}
|
||||
|
||||
// Check for selecting a Pokémon
|
||||
val clickedPokemon = when(button) {
|
||||
is BoxStorageSlot -> pc.get(clickedPosition as PCPosition)
|
||||
is PartyStorageSlot -> party.get(clickedPosition as PartyPosition)
|
||||
else -> null
|
||||
}
|
||||
|
||||
val selectOverride = pcGui.configuration.selectOverride
|
||||
if (selectOverride != null) {
|
||||
selectOverride(pcGui, clickedPosition, clickedPokemon)
|
||||
@@ -420,56 +589,44 @@ class StorageWidget(
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedPosition = clickedPosition
|
||||
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
|
||||
grabbedSlot = GrabbedStorageSlot(
|
||||
x = button.x,
|
||||
y = button.y,
|
||||
parent = this,
|
||||
pokemon = clickedPokemon
|
||||
)
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
|
||||
if (clickedPosition is PCPosition) {
|
||||
val column = clickedPosition.slot % 6
|
||||
val row = clickedPosition.slot / 6
|
||||
multiSelection = PCMultiSelection(1, 1, clickedPosition.box, column, row).also {
|
||||
it.setPokemon(0, 0, clickedPokemon)
|
||||
}
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
return
|
||||
} else if (clickedPosition is PartyPosition) {
|
||||
this.selectedPosition = clickedPosition
|
||||
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
|
||||
grabbedSlot = GrabbedStorageSlot(
|
||||
x = button.x,
|
||||
y = button.y,
|
||||
parent = this,
|
||||
pokemon = clickedPokemon
|
||||
)
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle movement within the Box
|
||||
val selectedPokemon = when(this.selectedPosition) {
|
||||
is PCPosition -> pc.get(this.selectedPosition as PCPosition)
|
||||
is PartyPosition -> party.get(this.selectedPosition as PartyPosition)
|
||||
else -> null
|
||||
} ?: return
|
||||
|
||||
// Box to Box
|
||||
if (this.selectedPosition is PCPosition && clickedPosition is PCPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPCPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
|
||||
?: MovePCPokemonPacket(selectedPokemon.uuid, selectedPosition as PCPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
// Box to Party
|
||||
else if (this.selectedPosition is PCPosition && clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(clickedPokemon.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
|
||||
?: MovePCPokemonToPartyPacket(selectedPokemon.uuid, this.selectedPosition as PCPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
val sourcePosition = selectedPosition ?: return
|
||||
val selectedPokemon = party.get(sourcePosition) ?: return
|
||||
// Party to Box
|
||||
else if (this.selectedPosition is PartyPosition && clickedPosition is PCPosition) {
|
||||
if (clickedPosition is PCPosition) {
|
||||
if (ServerSettings.preventCompletePartyDeposit && this.party.filterNotNull().size == 1 && clickedPokemon == null) {
|
||||
return
|
||||
}
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPokemon.uuid, clickedPosition) }
|
||||
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPosition)
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPokemon.uuid, clickedPosition) }
|
||||
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
// Party to Party
|
||||
else if (this.selectedPosition is PartyPosition && clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PartyPosition) }
|
||||
?: MovePartyPokemonPacket(selectedPokemon.uuid, selectedPosition as PartyPosition, clickedPosition)
|
||||
else if (clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, sourcePosition) }
|
||||
?: MovePartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
@@ -480,6 +637,8 @@ class StorageWidget(
|
||||
fun resetSelected() {
|
||||
selectedPosition = null
|
||||
grabbedSlot = null
|
||||
multiSelection = null
|
||||
multiGrabbedSlots.clear()
|
||||
pcGui.setPreviewPokemon(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_HEIG
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HEADER_BAR_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.ICONS_ARROW_PADDING_AROUND
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.ICONS_PADDING_AROUND
|
||||
@@ -52,8 +51,7 @@ import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_MOVES
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_SIZE
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_STATS
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.widgets.*
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree.EvolutionTreeWidget
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree.debugEvolutionRequirementRendering
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.widgets.EvolutionTreeWidget
|
||||
import com.cobblemon.mod.common.client.pokedex.PokedexType
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||
@@ -194,6 +192,7 @@ class PokedexGUI private constructor(
|
||||
public override fun init() {
|
||||
super.init()
|
||||
clearWidgets()
|
||||
evolutionTreeExpanded = false
|
||||
|
||||
availableRegions = Dexes.dexEntryMap.keys.toList()
|
||||
selectedRegionIndex = 0
|
||||
@@ -828,10 +827,6 @@ class PokedexGUI private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (tabInfoIndex == TAB_EVOLUTION_TREE && keyCode == InputConstants.KEY_SEMICOLON) {
|
||||
debugEvolutionRequirementRendering()
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
|
||||
+23
-2
@@ -16,13 +16,17 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.network.chat.Style
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.util.Optional
|
||||
|
||||
private val tooltipEdge = cobblemonResource("textures/gui/pokedex/tooltip_edge.png")
|
||||
private val tooltipBackground = cobblemonResource("textures/gui/pokedex/tooltip_background.png")
|
||||
|
||||
private const val TOOLTIP_SLICE_SIZE = 11
|
||||
private const val TOOLTIP_MAX_TEXT_WIDTH = 160
|
||||
|
||||
fun renderTooltip(
|
||||
context: GuiGraphics,
|
||||
@@ -49,7 +53,12 @@ fun renderTooltip(
|
||||
posY: Int,
|
||||
delta: Float,
|
||||
offsetY: Int = 0,
|
||||
maxTextWidth: Int = TOOLTIP_MAX_TEXT_WIDTH,
|
||||
) {
|
||||
val text = text.flatMap { wrapTooltipLine(it, maxTextWidth) }
|
||||
// Only a tooltip that fits on a single line is centered; wrapped text is left-aligned
|
||||
val centered = text.size == 1
|
||||
|
||||
val poseStack = context.pose()
|
||||
val textWidth = text.maxOf { Minecraft.getInstance().font.width(it.font(CobblemonResources.DEFAULT_LARGE)) }
|
||||
val tooltipPadding = 6
|
||||
@@ -78,8 +87,6 @@ fun renderTooltip(
|
||||
blitSlicedVertical(poseStack, tooltipBackground, posX - (tooltipWidth / 2), tooltipTop, tooltipWidth, totalHeight)
|
||||
blitSlicedVertical(poseStack, tooltipEdge, posX + (tooltipWidth / 2), tooltipTop, 1, totalHeight)
|
||||
|
||||
val centered = text.size == 1
|
||||
|
||||
text.forEachIndexed { index, it ->
|
||||
drawScaledText(
|
||||
context = context,
|
||||
@@ -95,6 +102,20 @@ fun renderTooltip(
|
||||
poseStack.popPose()
|
||||
}
|
||||
|
||||
private fun wrapTooltipLine(line: MutableComponent, maxWidth: Int): List<MutableComponent> {
|
||||
val styled = line.copy().font(CobblemonResources.DEFAULT_LARGE)
|
||||
if (Minecraft.getInstance().font.width(styled) <= maxWidth) return listOf(line)
|
||||
|
||||
return Minecraft.getInstance().font.splitter.splitLines(styled, maxWidth, Style.EMPTY).map { wrapped ->
|
||||
val component = Component.empty()
|
||||
wrapped.visit({ style, string ->
|
||||
component.append(Component.literal(string).withStyle(style))
|
||||
Optional.empty<Unit>()
|
||||
}, Style.EMPTY)
|
||||
component
|
||||
}
|
||||
}
|
||||
|
||||
// Stretching the whole 11px image over an arbitrary height thickens the caps as more lines are added, so
|
||||
// instead the caps are drawn 1:1 and only the flat fill row is stretched to cover the remaining height
|
||||
private fun blitSlicedVertical(
|
||||
|
||||
+178
-81
@@ -6,20 +6,18 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree
|
||||
package com.cobblemon.mod.common.client.gui.pokedex.widgets
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.gui.*
|
||||
import com.cobblemon.mod.common.api.pokedex.Dexes
|
||||
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.*
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
||||
import com.cobblemon.mod.common.api.text.add
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUI
|
||||
@@ -29,18 +27,22 @@ import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_D
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_SLOT_SIZE
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.ScaledButton
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.renderTooltip
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.widgets.PokemonSlotWidget
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
import com.cobblemon.mod.common.pokemon.RenderablePokemon
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.locale.Language
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
|
||||
class EvolutionTreeWidget(
|
||||
val parent: PokedexGUI,
|
||||
@@ -92,6 +94,8 @@ class EvolutionTreeWidget(
|
||||
|
||||
private var hoveredTooltips: List<MutableComponent>? = null
|
||||
|
||||
private var viewedForm: FormData? = null
|
||||
|
||||
private val expandButton: ScaledButton = ScaledButton(
|
||||
0f,
|
||||
0f,
|
||||
@@ -100,11 +104,14 @@ class EvolutionTreeWidget(
|
||||
resource = expandResource,
|
||||
clickAction = {
|
||||
parent.evolutionTreeExpanded = !parent.evolutionTreeExpanded
|
||||
expandButton.resource = if (parent.evolutionTreeExpanded) minimizeResource else expandResource
|
||||
updatePositioning()
|
||||
}
|
||||
).apply { addWidget(this) }
|
||||
|
||||
init {
|
||||
updatePositioning()
|
||||
}
|
||||
|
||||
override fun renderWidget(
|
||||
guiGraphics: GuiGraphics,
|
||||
mouseX: Int,
|
||||
@@ -146,9 +153,31 @@ class EvolutionTreeWidget(
|
||||
if (pokedexEntry == null || pokedexForm == null) return
|
||||
|
||||
updatePositioning()
|
||||
var rootSpecies = pokedexEntry
|
||||
var rootForm = pokedexForm
|
||||
var preEvolution = findPreEvolution(rootSpecies, rootForm)
|
||||
// Stop at whatever the dex can't resolve, and at cycles (datapacks)
|
||||
val visited = mutableSetOf(rootSpecies.speciesId to rootForm.displayForm)
|
||||
while (preEvolution != null) {
|
||||
val preEvolutionSpecies = DexEntries.entries.values.firstOrNull { it.speciesId == preEvolution.fromSpecies &&
|
||||
it.forms.any {form -> form.displayForm.equals(preEvolution.fromForm, ignoreCase = true)}} ?: break
|
||||
val preEvolutionForm = preEvolutionSpecies.forms.firstOrNull { it.displayForm.equals(preEvolution.fromForm, ignoreCase = true) } ?: break
|
||||
if (!visited.add(preEvolutionSpecies.speciesId to preEvolutionForm.displayForm)) break
|
||||
rootSpecies = preEvolutionSpecies
|
||||
rootForm = preEvolutionForm
|
||||
preEvolution = findPreEvolution(rootSpecies, rootForm)
|
||||
}
|
||||
|
||||
val (rootPokedexEntry, rootPokedexForm) = Dexes.findRootDexEntryBySpeciesId(pokedexEntry.speciesId, pokedexForm.displayForm)
|
||||
val rootEvolutionNode = buildEvolutionTree(rootPokedexEntry, rootPokedexForm, null)
|
||||
val viewedFormEquivalents = Dexes.getFormEquivalents(pokedexForm.displayForm)
|
||||
viewedForm = PokemonSpecies.getByIdentifier(pokedexEntry.speciesId)
|
||||
?.forms?.firstOrNull { viewedFormEquivalents.contains(it.name.lowercase()) }
|
||||
|
||||
val formEquivalents = Dexes.getFormEquivalents(rootForm.displayForm)
|
||||
val form =
|
||||
rootSpecies.forms.firstOrNull { formEquivalents.contains(it.displayForm.lowercase()) } ?:
|
||||
rootSpecies.forms.first { it.displayForm.equals("Normal", ignoreCase = true) }
|
||||
|
||||
val rootEvolutionNode = buildEvolutionTree(rootSpecies, form)
|
||||
|
||||
// val isSameEntry = previousRootPokedexEntry != null && pokedexEntry?.id == previousRootPokedexEntry?.id
|
||||
// val isSameForm =
|
||||
@@ -172,6 +201,13 @@ class EvolutionTreeWidget(
|
||||
panningY = 0.0
|
||||
}
|
||||
|
||||
/** The evolution leading to [form]; the standard form falls back to any form of the species (no evolution leads to regular Vivillon). */
|
||||
private fun findPreEvolution(entry: PokedexEntry, form: PokedexForm): DexEvolutionDisplay? {
|
||||
return DexEntries.evolutionDisplays.firstOrNull { it.toSpecies == entry.speciesId && form.displayForm.equals(it.toForm, ignoreCase = true) }
|
||||
?: DexEntries.evolutionDisplays.takeIf { form.displayForm.equals("Normal", ignoreCase = true) }
|
||||
?.firstOrNull { it.toSpecies == entry.speciesId }
|
||||
}
|
||||
|
||||
fun updatePositioning() {
|
||||
x = pX + X_MARGIN
|
||||
y = pY + if (parent.evolutionTreeExpanded) Y_MARGIN_EXPANDED else Y_MARGIN_MINIMIZED
|
||||
@@ -180,6 +216,7 @@ class EvolutionTreeWidget(
|
||||
panningX = 0.0
|
||||
panningY = 0.0
|
||||
|
||||
expandButton.resource = if (parent.evolutionTreeExpanded) minimizeResource else expandResource
|
||||
expandButton.buttonX = x + EXPAND_BUTTON_X_MARGIN
|
||||
expandButton.buttonY = y + EXPAND_BUTTON_Y_MARGIN
|
||||
}
|
||||
@@ -187,61 +224,62 @@ class EvolutionTreeWidget(
|
||||
private fun buildEvolutionTree(
|
||||
pokedexEntry: PokedexEntry,
|
||||
pokedexForm: PokedexForm,
|
||||
evolution: Evolution? = null,
|
||||
resultProperties: PokemonProperties? = evolution?.result,
|
||||
renderData: RenderEvolutionData? = evolution?.let { renderEvolutionData(it) }
|
||||
aspects: Set<String> = emptySet(),
|
||||
ancestors: Set<Pair<ResourceLocation, String>> = emptySet(),
|
||||
): EvolutionNode {
|
||||
val species = PokemonSpecies.getByIdentifier(pokedexEntry.speciesId)!!
|
||||
// Datapack evolutions can loop back (A -> B -> A), so stop at anything already on this branch
|
||||
val path = ancestors + (pokedexEntry.speciesId to pokedexForm.displayForm.lowercase())
|
||||
val discoveryLevel = CobblemonClient.clientPokedexData.getHighestKnowledgeFor(pokedexEntry, pokedexForm, aspects.toMutableSet())
|
||||
|
||||
val formEquivalents = Dexes.getFormEquivalents(pokedexForm.displayForm)
|
||||
val form = species.forms.firstOrNull { formEquivalents.contains(it.name.lowercase()) }
|
||||
val parentSpecies = Dexes.findDexEntryBySpeciesId(species.resourceIdentifier)!!
|
||||
val parentPokedexForm = parentSpecies.forms.first { formEquivalents.contains(it.displayForm.lowercase()) }
|
||||
val evolutions = DexEntries.evolutionDisplays.filter { it.fromSpecies == pokedexEntry.speciesId && formEquivalents.contains(it.fromForm.lowercase()) }
|
||||
|
||||
val aspects = resultProperties?.aspects?.toMutableSet() ?: mutableSetOf()
|
||||
form?.aspects?.let { aspects.addAll(it) }
|
||||
|
||||
val discoveryLevel = CobblemonClient.clientPokedexData.getHighestKnowledgeFor(pokedexEntry, pokedexForm, aspects)
|
||||
|
||||
val evolutions = form?.evolutions ?: species.evolutions
|
||||
|
||||
// Avoid evolution.result.create() here: it builds a full battle-ready Pokemon (initializeMovesetFromDefault
|
||||
// etc.) which relies on server-only data like CobblemonMovesetBuilders and crashes on the client
|
||||
val children = evolutions.flatMap { evolution ->
|
||||
val baseRenderData = renderEvolutionData(evolution)
|
||||
|
||||
listOfNotNull(evolution.result, evolution.shedder).mapNotNull { resultProperties ->
|
||||
val resultSpecies = resultProperties.species
|
||||
?.let { PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
|
||||
?: return@mapNotNull null
|
||||
|
||||
val resultForm = resultSpecies.getForm(aspects + resultProperties.aspects)
|
||||
|
||||
val speciesId = resultSpecies.resourceIdentifier
|
||||
val childPokedexEntry = Dexes.findDexEntryBySpeciesId(speciesId)
|
||||
|
||||
if (childPokedexEntry == null) {
|
||||
Cobblemon.LOGGER.warn("Dex entry not found for species: $speciesId")
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
val formEquivalents = Dexes.getFormEquivalents(resultForm.name.lowercase())
|
||||
val childPokedexForm = childPokedexEntry.forms.first { formEquivalents.contains(it.displayForm.lowercase()) }
|
||||
|
||||
val childRenderData = if (resultProperties === evolution.shedder) {
|
||||
RenderEvolutionData(
|
||||
icons = (baseRenderData?.icons ?: emptyList()) + CobblemonItems.POKE_BALL,
|
||||
tooltips = (baseRenderData?.tooltips ?: emptyList()) + lang("ui.pokedex.evolution.shedder.tooltip"),
|
||||
)
|
||||
} else {
|
||||
baseRenderData
|
||||
}
|
||||
|
||||
return@mapNotNull buildEvolutionTree(childPokedexEntry, childPokedexForm, evolution, resultProperties, childRenderData)
|
||||
val children = evolutions.mapNotNull {
|
||||
val childPokedexEntry = DexEntries.entries.values.firstOrNull { entry -> entry.speciesId == it.toSpecies &&
|
||||
entry.forms.any {form -> form.displayForm.equals(it.toForm, ignoreCase = true)}}
|
||||
if (childPokedexEntry == null) {
|
||||
Cobblemon.LOGGER.warn("Dex entry not found for species: ${it.toSpecies}")
|
||||
return@mapNotNull null
|
||||
}
|
||||
val formEquivalents = Dexes.getFormEquivalents(it.toForm.lowercase())
|
||||
val childPokedexForm = childPokedexEntry.forms.firstOrNull { formEquivalents.contains(it.displayForm.lowercase()) }
|
||||
if (childPokedexForm == null) {
|
||||
Cobblemon.LOGGER.warn("Dex form ${it.toForm} not found for species: ${it.toSpecies}")
|
||||
return@mapNotNull null
|
||||
}
|
||||
if ((childPokedexEntry.speciesId to childPokedexForm.displayForm.lowercase()) in path) {
|
||||
Cobblemon.LOGGER.warn("Evolution loop found at species: ${it.toSpecies} form: ${it.toForm}")
|
||||
return@mapNotNull null
|
||||
}
|
||||
buildEvolutionTree(childPokedexEntry, childPokedexForm, it.toAspects, path)
|
||||
}
|
||||
|
||||
return EvolutionNode(pokedexEntry, parentPokedexForm, aspects, discoveryLevel, children, renderData)
|
||||
return EvolutionNode(
|
||||
pokedexEntry = pokedexEntry,
|
||||
pokedexForm = pokedexForm,
|
||||
aspects = aspects,
|
||||
pokedexEntryProgress = discoveryLevel,
|
||||
children = mergeEquivalentChildren(children),
|
||||
renderDataAlternatives = evolutions,
|
||||
)
|
||||
}
|
||||
|
||||
private fun mergeEquivalentChildren(children: List<EvolutionNode>): List<EvolutionNode> {
|
||||
return children
|
||||
.groupBy { Triple(it.pokedexEntry.speciesId, it.pokedexForm.displayForm.lowercase(), it.aspects) }
|
||||
.values
|
||||
.map { group ->
|
||||
if (group.size == 1) return@map group.first()
|
||||
val first = group.first()
|
||||
EvolutionNode(
|
||||
first.pokedexEntry,
|
||||
first.pokedexForm,
|
||||
first.aspects,
|
||||
first.pokedexEntryProgress,
|
||||
first.children,
|
||||
group.flatMap { it.renderDataAlternatives }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderTreeDrawingNode(
|
||||
@@ -258,15 +296,19 @@ class EvolutionTreeWidget(
|
||||
val (childX, _) = getDrawingCoordinates(child)
|
||||
|
||||
val lineStartX = treeX + SCROLL_SLOT_SIZE
|
||||
val lineEndX = childX
|
||||
val lineY = treeY + SCROLL_SLOT_SIZE / 2
|
||||
|
||||
child.value.renderData?.let { renderData ->
|
||||
val formEquivalents = Dexes.getFormEquivalents(child.value.pokedexForm.displayForm)
|
||||
val alternatives = treeDrawingNode.value.renderDataAlternatives.filter {
|
||||
it.toSpecies == child.value.pokedexEntry.speciesId && formEquivalents.contains(it.toForm.lowercase()) && it.toAspects == child.value.aspects
|
||||
}
|
||||
|
||||
alternatives.takeIf { it.isNotEmpty() }?.let {
|
||||
drawEvolutionInfo(
|
||||
guiGraphics,
|
||||
renderData,
|
||||
it,
|
||||
lineStartX,
|
||||
lineEndX,
|
||||
childX,
|
||||
lineY,
|
||||
mouseX,
|
||||
mouseY,
|
||||
@@ -298,16 +340,19 @@ class EvolutionTreeWidget(
|
||||
treeDrawingNode.children.forEach { child ->
|
||||
val (childX, childY) = getDrawingCoordinates(child)
|
||||
|
||||
val lineStartX = treeForkEnd
|
||||
val lineEndX = childX
|
||||
val lineY = childY + SCROLL_SLOT_SIZE / 2
|
||||
|
||||
child.value.renderData?.let { renderData ->
|
||||
val formEquivalents = Dexes.getFormEquivalents(child.value.pokedexForm.displayForm)
|
||||
val alternatives = treeDrawingNode.value.renderDataAlternatives.filter {
|
||||
it.toSpecies == child.value.pokedexEntry.speciesId && formEquivalents.contains(it.toForm.lowercase()) && it.toAspects == child.value.aspects
|
||||
}
|
||||
|
||||
alternatives.takeIf { it.isNotEmpty() }?.let {
|
||||
drawEvolutionInfo(
|
||||
guiGraphics,
|
||||
renderData,
|
||||
lineStartX,
|
||||
lineEndX,
|
||||
it,
|
||||
treeForkEnd,
|
||||
childX,
|
||||
lineY,
|
||||
mouseX,
|
||||
mouseY,
|
||||
@@ -346,7 +391,7 @@ class EvolutionTreeWidget(
|
||||
if (formName == "normal") null
|
||||
else lang("ui.pokedex.info.form.${species}-${formName.replace("-", "")}")
|
||||
|
||||
formComponent?.add(" ")?.add(speciesComponent) ?: speciesComponent
|
||||
formComponent?.let { speciesComponent.copy().add(" (").add(it).add(")") } ?: speciesComponent
|
||||
}
|
||||
|
||||
guiGraphics.disableScissor()
|
||||
@@ -408,7 +453,7 @@ class EvolutionTreeWidget(
|
||||
|
||||
private fun drawEvolutionInfo(
|
||||
guiGraphics: GuiGraphics,
|
||||
renderData: RenderEvolutionData,
|
||||
renderDataAlternatives: List<DexEvolutionDisplay>,
|
||||
lineStartX: Int,
|
||||
lineEndX: Int,
|
||||
lineY: Int,
|
||||
@@ -416,6 +461,26 @@ class EvolutionTreeWidget(
|
||||
mouseY: Int,
|
||||
delta: Float,
|
||||
) {
|
||||
val icons = renderDataAlternatives.flatMap { it.requirements.filter(::isDisplayable).map { req -> req.icon } }.distinct()
|
||||
val playerBiome = Minecraft.getInstance().player?.let { it.level().getBiome(it.blockPosition()) }
|
||||
val alternativeTooltips = renderDataAlternatives.map { alternative ->
|
||||
alternative.requirements.filter(::isDisplayable).map { req ->
|
||||
if (req is CobblemonBiomeDexEvolutionRequirementDisplay) {
|
||||
val tooltip = req.tooltip.copy()
|
||||
if (playerBiome != null) {
|
||||
val conditionFits = req.condition?.let { if (it.tag) playerBiome.`is`(TagKey.create(Registries.BIOME, it.id)) else playerBiome.`is`(it.id) } ?: true
|
||||
val antiConditionFits = req.antiCondition?.let { if (it.tag) playerBiome.`is`(TagKey.create(Registries.BIOME, it.id)) else playerBiome.`is`(it.id) } ?: false
|
||||
val isMet = conditionFits && !antiConditionFits
|
||||
tooltip.add(if (isMet) Component.literal(" ✔").green() else Component.literal(" ✘").red())
|
||||
}
|
||||
tooltip
|
||||
} else {
|
||||
req.tooltip
|
||||
}
|
||||
}
|
||||
}
|
||||
val tooltips = combineAlternativeTooltips(alternativeTooltips)
|
||||
|
||||
val lineXMiddle = (lineStartX + lineEndX) / 2
|
||||
val iconX = (lineXMiddle + ICON_X_PADDING - ICON_SLOT_HALF_PADDING).toInt()
|
||||
val iconY = (lineY + ICON_Y_PADDING - ICON_SLOT_HALF_PADDING).toInt()
|
||||
@@ -431,7 +496,7 @@ class EvolutionTreeWidget(
|
||||
return
|
||||
}
|
||||
|
||||
if (renderData.icons.isEmpty()) {
|
||||
if (icons.isEmpty()) {
|
||||
guiGraphics.hLine(
|
||||
lineStartX,
|
||||
lineEndX,
|
||||
@@ -462,8 +527,8 @@ class EvolutionTreeWidget(
|
||||
height = iconSize,
|
||||
)
|
||||
|
||||
val index = (System.currentTimeMillis() / MILLIS_BETWEEN_ICONS_CYCLE) % renderData.icons.size
|
||||
val item = renderData.icons[index.toInt()]
|
||||
val index = (System.currentTimeMillis() / MILLIS_BETWEEN_ICONS_CYCLE) % icons.size
|
||||
val item = icons[index.toInt()]
|
||||
|
||||
renderScaledGuiItemIcon(
|
||||
itemStack = item.defaultInstance,
|
||||
@@ -478,17 +543,49 @@ class EvolutionTreeWidget(
|
||||
val isIconHovered = isElementHovered(
|
||||
mouseX,
|
||||
mouseY,
|
||||
iconX.toInt(),
|
||||
iconX.toInt() + iconSize,
|
||||
iconY.toInt(),
|
||||
iconY.toInt() + iconSize,
|
||||
iconX,
|
||||
iconX + iconSize,
|
||||
iconY,
|
||||
iconY + iconSize,
|
||||
)
|
||||
|
||||
if (renderData.tooltips.isNotEmpty() &&
|
||||
if (tooltips.isNotEmpty() &&
|
||||
(isLineHovered || isIconHovered) &&
|
||||
this.isHovered(mouseX.toDouble(), mouseY.toDouble())
|
||||
) {
|
||||
hoveredTooltips = renderData.tooltips
|
||||
hoveredTooltips = tooltips.map { it.copy() }
|
||||
}
|
||||
}
|
||||
|
||||
/** Hides biome requirements naming untranslated biomes, e.g. from mods that aren't installed (aether:skyroot_forest) */
|
||||
private fun isDisplayable(requirement: DexEvolutionRequirementDisplay): Boolean {
|
||||
if (requirement !is CobblemonBiomeDexEvolutionRequirementDisplay) return true
|
||||
return listOfNotNull(requirement.condition, requirement.antiCondition).all {
|
||||
it.tag || Language.getInstance().has("biome.${it.id.namespace}.${it.id.path}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun combineAlternativeTooltips(alternatives: List<List<Component>>): List<Component> {
|
||||
val groups = alternatives.filter { it.isNotEmpty() }
|
||||
if (groups.size <= 1) return groups.firstOrNull() ?: emptyList()
|
||||
|
||||
val sharedStrings = groups.map { group -> group.map { it.string }.toSet() }.reduce { acc, strings -> acc intersect strings }
|
||||
val shared = groups.first().filter { it.string in sharedStrings }.distinctBy { it.string }
|
||||
val remainders = groups
|
||||
.map { group -> group.filter { it.string !in sharedStrings } }
|
||||
.distinctBy { group -> group.map { it.string } }
|
||||
|
||||
// An alternative needing nothing beyond the shared lines makes the others irrelevant
|
||||
if (remainders.any { it.isEmpty() }) return shared
|
||||
if (remainders.size == 1) return shared + remainders.first()
|
||||
|
||||
return if (remainders.size >= 3 && remainders.all { it.size == 1 }) {
|
||||
shared + lang("ui.pokedex.evolution.one_of").bold() + remainders.map { it.first() }
|
||||
} else {
|
||||
// Show each alternative in full, otherwise it's unclear where the first one starts
|
||||
groups.distinctBy { group -> group.map { it.string } }.flatMapIndexed { index, group ->
|
||||
if (index == 0) group else listOf(lang("ui.pokedex.evolution.or").bold()) + group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +663,6 @@ class EvolutionTreeWidget(
|
||||
val aspects: Set<String>,
|
||||
val pokedexEntryProgress: PokedexEntryProgress,
|
||||
override val children: List<EvolutionNode>,
|
||||
val renderData: RenderEvolutionData?,
|
||||
val renderDataAlternatives: List<DexEvolutionDisplay>,
|
||||
) : TreeNode<EvolutionNode>
|
||||
}
|
||||
-48
@@ -1,48 +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.client.gui.pokedex.widgets.evolutiontree
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
fun debugEvolutionRequirementRendering() {
|
||||
if (!Cobblemon.config.enableDebugKeys) {
|
||||
return
|
||||
}
|
||||
|
||||
val gaps = mutableListOf<Pair<String, String>>()
|
||||
|
||||
for (species in PokemonSpecies.implemented) {
|
||||
val evolutions = species.evolutions + species.forms.flatMap { it.evolutions }
|
||||
for (evolution in evolutions) {
|
||||
if (renderEvolutionData(evolution) == null) {
|
||||
gaps.add("Evolution: ${evolution::class.simpleName}" to species.showdownId())
|
||||
}
|
||||
for (requirement in evolution.requirements) {
|
||||
if (resolveRequirementData(requirement) == null) {
|
||||
gaps.add("Requirement: ${requirement::class.simpleName}" to species.showdownId())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val player = Minecraft.getInstance().player
|
||||
if (gaps.isEmpty()) {
|
||||
player?.sendSystemMessage(Component.literal("Evolution render debug: no gaps found."))
|
||||
return
|
||||
}
|
||||
|
||||
val byType = gaps.groupBy({ it.first }, { it.second })
|
||||
println("Evolution render debug found ${gaps.size} gap(s) across ${byType.size} type(s):")
|
||||
byType.forEach { (type, species) -> println(" $type: ${species.distinct().joinToString(", ")}") }
|
||||
|
||||
player?.sendSystemMessage(Component.literal("Evolution render debug: ${gaps.size} gap(s) across ${byType.size} type(s), see log for details."))
|
||||
}
|
||||
-123
@@ -1,123 +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.client.gui.pokedex.widgets.evolutiontree
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.DummyEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.itemRegistry
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.world.item.Item
|
||||
|
||||
data class RenderEvolutionData(
|
||||
val icons: List<Item>,
|
||||
val tooltips: List<MutableComponent>,
|
||||
)
|
||||
|
||||
internal fun resolveRequirementData(requirement: Requirement): RenderRequirementData? {
|
||||
val icon = requirement.pokedexIcon?.let {
|
||||
Minecraft.getInstance()?.player?.level()?.itemRegistry?.get(it)
|
||||
}
|
||||
|
||||
val tooltip = requirement.pokedexTooltip?.let {
|
||||
Component.translatable(it)
|
||||
}
|
||||
|
||||
if (icon != null && tooltip != null) {
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
return renderRequirementData(requirement)
|
||||
}
|
||||
|
||||
fun renderEvolutionData(evolution: Evolution): RenderEvolutionData? {
|
||||
when (evolution) {
|
||||
is BlockClickEvolution -> return renderBlockClickEvolution(evolution)
|
||||
is DummyEvolution -> return renderDummyEvolution(evolution)
|
||||
is ItemInteractionEvolution -> return renderItemInteractionEvolution(evolution)
|
||||
is LevelUpEvolution -> return renderLevelUpEvolution(evolution)
|
||||
is TradeEvolution -> return renderTradeEvolution(evolution)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderBlockClickEvolution(blockClickEvolution: BlockClickEvolution): RenderEvolutionData? {
|
||||
return null
|
||||
}
|
||||
|
||||
// TODO: Use dummyEvolution?
|
||||
fun renderDummyEvolution(evolution: Evolution): RenderEvolutionData? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderItemInteractionEvolution(itemInteractionEvolution: ItemInteractionEvolution): RenderEvolutionData? {
|
||||
val item = itemInteractionEvolution.requiredContext.items.get().first().value()
|
||||
val icons = mutableListOf(item)
|
||||
val tooltips =
|
||||
mutableListOf(lang("ui.pokedex.evolution.item_interact.tooltip", item.description.plainCopy().green()))
|
||||
|
||||
val requirementsDataList = itemInteractionEvolution.requirements.mapNotNull { requirement ->
|
||||
resolveRequirementData(requirement)
|
||||
}
|
||||
|
||||
requirementsDataList.forEach { requirement ->
|
||||
icons.add(requirement.icon)
|
||||
tooltips.add(requirement.tooltip)
|
||||
}
|
||||
|
||||
return RenderEvolutionData(icons, tooltips)
|
||||
}
|
||||
|
||||
fun renderLevelUpEvolution(levelUpEvolution: LevelUpEvolution): RenderEvolutionData? {
|
||||
val requirementsDataList = levelUpEvolution.requirements.map { requirement ->
|
||||
resolveRequirementData(requirement)
|
||||
}
|
||||
|
||||
val icons = requirementsDataList.mapNotNull { requirementData -> requirementData?.icon }
|
||||
val tooltips = requirementsDataList.mapNotNull { requirementData -> requirementData?.tooltip }
|
||||
|
||||
return RenderEvolutionData(icons, tooltips)
|
||||
}
|
||||
|
||||
fun renderTradeEvolution(tradeEvolution: TradeEvolution): RenderEvolutionData? {
|
||||
val icons = mutableListOf<Item>(CobblemonItems.LINK_CABLE)
|
||||
val tooltips = mutableListOf<MutableComponent>()
|
||||
|
||||
val species = tradeEvolution.requiredContext.species
|
||||
if (species == null) {
|
||||
tooltips.add(lang("ui.pokedex.evolution.trade.tooltip.with_any_species"))
|
||||
} else {
|
||||
PokemonSpecies.getByIdentifier(species.asIdentifierDefaultingNamespace())?.let {
|
||||
tooltips.add(lang("ui.pokedex.evolution.trade.tooltip.with_species", it.translatedName.green()))
|
||||
}
|
||||
}
|
||||
|
||||
val requirementsDataList = tradeEvolution.requirements.mapNotNull { requirement ->
|
||||
resolveRequirementData(requirement)
|
||||
}
|
||||
|
||||
requirementsDataList.forEach { requirement ->
|
||||
icons.add(requirement.icon)
|
||||
tooltips.add(requirement.tooltip)
|
||||
}
|
||||
|
||||
return RenderEvolutionData(icons, tooltips)
|
||||
}
|
||||
-379
@@ -1,379 +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.client.gui.pokedex.widgets.evolutiontree
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeTagCondition
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.text.add
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.pokemon.requirements.*
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
import net.minecraft.world.level.levelgen.structure.Structure
|
||||
|
||||
data class RenderRequirementData(
|
||||
val icon: Item,
|
||||
val tooltip: MutableComponent,
|
||||
)
|
||||
|
||||
fun renderRequirementData(requirement: Requirement): RenderRequirementData? {
|
||||
when (requirement) {
|
||||
is AdvancementRequirement -> return renderAdvancementRequirement(requirement)
|
||||
is AnyRequirement -> return renderAnyRequirement(requirement)
|
||||
is AreaRequirement -> return renderAreaRequirement(requirement)
|
||||
is AttackDefenceRatioRequirement -> return renderAttackDefenceRatioRequirement(requirement)
|
||||
is BattleCriticalHitsRequirement -> return renderBattleCriticalHitsRequirement(requirement)
|
||||
is BiomeRequirement -> return renderBiomeRequirement(requirement)
|
||||
is BlocksTraveledRequirement -> return renderBlocksTraveledRequirement(requirement)
|
||||
is DamageTakenRequirement -> return renderDamageTakenRequirement(requirement)
|
||||
is DefeatRequirement -> return renderDefeatRequirement(requirement)
|
||||
is FriendshipRequirement -> return renderFriendshipRequirement(requirement)
|
||||
is HeldItemRequirement -> return renderHeldItemRequirement(requirement)
|
||||
is LevelRequirement -> return renderLevelRequirement(requirement)
|
||||
is MoonPhaseRequirement -> return renderMoonPhaseRequirement(requirement)
|
||||
is MoveSetRequirement -> return renderMoveSetRequirement(requirement)
|
||||
is MoveTypeRequirement -> return renderMoveTypeRequirement(requirement)
|
||||
is OwnerHoldsItemRequirement -> return renderOwnerHoldsItemRequirement(requirement)
|
||||
is PartyMemberRequirement -> return renderPartyMemberRequirement(requirement)
|
||||
is PokemonPropertiesRequirement -> return renderPokemonPropertiesRequirement(requirement)
|
||||
is PropertyRangeRequirement -> return renderPropertyRangeRequirement(requirement)
|
||||
is RecoilRequirement -> return renderRecoilRequirement(requirement)
|
||||
is StatCompareRequirement -> return renderStatCompareRequirement(requirement)
|
||||
is StatEqualRequirement -> return renderStatEqualRequirement(requirement)
|
||||
is StructureRequirement -> return renderStructureRequirement(requirement)
|
||||
is TimeRangeRequirement -> return renderTimeRangeRequirement(requirement)
|
||||
is UseMoveRequirement -> return renderUseMoveRequirement(requirement)
|
||||
is WeatherRequirement -> return renderWeatherRequirement(requirement)
|
||||
is WorldRequirement -> return renderWorldRequirement(requirement)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderAdvancementRequirement(advancementRequirement: AdvancementRequirement): RenderRequirementData? {
|
||||
val icon = Items.BOOK
|
||||
val identifier = advancementRequirement.requiredAdvancement
|
||||
val advancementLanguageKey = "${identifier.namespace}.${identifier.path.substringAfterLast('/')}"
|
||||
val advancementComponent = Component.translatable("advancements.$advancementLanguageKey").green()
|
||||
val tooltip = lang("ui.pokedex.requirement.advancement.tooltip", advancementComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderAnyRequirement(anyRequirement: AnyRequirement): RenderRequirementData? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderAreaRequirement(areaRequirement: AreaRequirement): RenderRequirementData? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderAttackDefenceRatioRequirement(attackDefenceRatioRequirement: AttackDefenceRatioRequirement): RenderRequirementData? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun renderBattleCriticalHitsRequirement(battleCriticalHitsRequirement: BattleCriticalHitsRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.MEDICINAL_LEEK
|
||||
val criticalsComponent = Component.literal(battleCriticalHitsRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.battle_critical_hits.tooltip", criticalsComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderBiomeRequirement(biomeRequirement: BiomeRequirement): RenderRequirementData? {
|
||||
val condition = biomeRequirement.biomeCondition
|
||||
val anticondition = biomeRequirement.biomeAnticondition
|
||||
if (condition == null && anticondition == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val icon = Items.COMPASS
|
||||
val displayName: (RegistryLikeCondition<Biome>) -> MutableComponent = {
|
||||
when (it) {
|
||||
is RegistryLikeTagCondition -> Component.literal(it.tag.location().path.substringAfterLast('/').split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) })
|
||||
is RegistryLikeIdentifierCondition -> Component.translatable("biome.${it.identifier.namespace}.${it.identifier.path}")
|
||||
else -> Component.literal(it.toString())
|
||||
}
|
||||
}
|
||||
val tooltip = if (condition != null && anticondition != null) {
|
||||
lang("ui.pokedex.requirement.biome.both.tooltip", displayName(condition).green(), displayName(anticondition).green())
|
||||
} else if (condition != null) {
|
||||
lang("ui.pokedex.requirement.biome.tooltip", displayName(condition).green())
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.biome.anticondition.tooltip", displayName(anticondition!!).green())
|
||||
}
|
||||
|
||||
val playerBiome = Minecraft.getInstance()?.player?.let { it.level().getBiome(it.blockPosition()) }
|
||||
if (playerBiome != null) {
|
||||
val isMet = (condition == null || condition.fits(playerBiome)) && (anticondition == null || !anticondition.fits(playerBiome))
|
||||
tooltip.add(if (isMet) Component.literal(" ✔").green() else Component.literal(" ✘").red())
|
||||
}
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderBlocksTraveledRequirement(blocksTraveledRequirement: BlocksTraveledRequirement): RenderRequirementData? {
|
||||
val icon = Items.LEATHER_BOOTS
|
||||
val blocksComponent = Component.literal(blocksTraveledRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.blocks_traveled.tooltip", blocksComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderDamageTakenRequirement(damageTakenRequirement: DamageTakenRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.PUNCHING_GLOVE
|
||||
val blocksComponent = Component.literal(damageTakenRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.damage_taken.tooltip", blocksComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderDefeatRequirement(defeatRequirement: DefeatRequirement): RenderRequirementData? {
|
||||
val description = describePokemonProperties(defeatRequirement.target) ?: return null
|
||||
val icon = CobblemonItems.PUNCHING_GLOVE
|
||||
val defeatedAmount = defeatRequirement.amount
|
||||
|
||||
val descriptionComponent = Component.literal(defeatedAmount.toString()).green().add(" ").add(description)
|
||||
val tooltip = lang("ui.pokedex.requirement.defeat.tooltip", descriptionComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderFriendshipRequirement(friendshipRequirement: FriendshipRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.SOOTHE_BELL
|
||||
val friendshipAmountComponent = Component.literal(friendshipRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.friendship.tooltip", friendshipAmountComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderHeldItemRequirement(heldItemRequirement: HeldItemRequirement): RenderRequirementData? {
|
||||
val item = heldItemRequirement.itemCondition.items.get().first().value()
|
||||
val tooltip = lang("ui.pokedex.requirement.held_item.tooltip", item.description.plainCopy().green())
|
||||
|
||||
return RenderRequirementData(item, tooltip)
|
||||
}
|
||||
|
||||
fun renderLevelRequirement(levelRequirement: LevelRequirement): RenderRequirementData? {
|
||||
val minLevel = levelRequirement.minLevel
|
||||
val maxLevel = levelRequirement.maxLevel
|
||||
|
||||
val icon = CobblemonItems.RARE_CANDY
|
||||
val tooltip =
|
||||
if (minLevel == maxLevel || maxLevel == Int.MAX_VALUE)
|
||||
lang("ui.pokedex.requirement.level.tooltip.min", Component.literal(minLevel.toString()).green())
|
||||
else
|
||||
lang("ui.pokedex.requirement.level.tooltip.between", Component.literal(minLevel.toString()).green(), Component.literal(maxLevel.toString()).green())
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderMoonPhaseRequirement(moonPhaseRequirement: MoonPhaseRequirement): RenderRequirementData? {
|
||||
val icon = Items.CLOCK
|
||||
val moonPhaseComponent = moonPhaseRequirement.moonPhase.displayName().green()
|
||||
val tooltip = lang("ui.pokedex.requirement.moon_phase.tooltip", moonPhaseComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderMoveSetRequirement(moveSetRequirement: MoveSetRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.TECHNICAL_MACHINE
|
||||
val tooltip = lang("ui.pokedex.requirement.has_move.tooltip", moveSetRequirement.move.displayName.green())
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderMoveTypeRequirement(moveTypeRequirement: MoveTypeRequirement): RenderRequirementData? {
|
||||
val type = ElementalTypes.get(moveTypeRequirement.type.name)
|
||||
val icon = when (type) {
|
||||
ElementalTypes.NORMAL -> CobblemonItems.NORMAL_GEM
|
||||
ElementalTypes.FIRE -> CobblemonItems.FIRE_GEM
|
||||
ElementalTypes.WATER -> CobblemonItems.WATER_GEM
|
||||
ElementalTypes.GRASS -> CobblemonItems.GRASS_GEM
|
||||
ElementalTypes.ELECTRIC -> CobblemonItems.ELECTRIC_GEM
|
||||
ElementalTypes.ICE -> CobblemonItems.ICE_GEM
|
||||
ElementalTypes.FIGHTING -> CobblemonItems.FIGHTING_GEM
|
||||
ElementalTypes.POISON -> CobblemonItems.POISON_GEM
|
||||
ElementalTypes.GROUND -> CobblemonItems.GROUND_GEM
|
||||
ElementalTypes.FLYING -> CobblemonItems.FLYING_GEM
|
||||
ElementalTypes.PSYCHIC -> CobblemonItems.PSYCHIC_GEM
|
||||
ElementalTypes.BUG -> CobblemonItems.BUG_GEM
|
||||
ElementalTypes.ROCK -> CobblemonItems.ROCK_GEM
|
||||
ElementalTypes.GHOST -> CobblemonItems.GHOST_GEM
|
||||
ElementalTypes.DRAGON -> CobblemonItems.DRAGON_GEM
|
||||
ElementalTypes.DARK -> CobblemonItems.DARK_GEM
|
||||
ElementalTypes.STEEL -> CobblemonItems.STEEL_GEM
|
||||
ElementalTypes.FAIRY -> CobblemonItems.FAIRY_GEM
|
||||
else -> CobblemonItems.NORMAL_GEM
|
||||
}
|
||||
|
||||
val tooltip = lang("ui.pokedex.requirement.has_move_type.tooltip", moveTypeRequirement.type.displayName.green())
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderOwnerHoldsItemRequirement(ownerHoldsItemRequirement: OwnerHoldsItemRequirement): RenderRequirementData? {
|
||||
val item = ownerHoldsItemRequirement.itemCondition.items.get().first().value()
|
||||
val tooltip = lang("ui.pokedex.requirement.owner_held_item.tooltip", item.description.plainCopy().green())
|
||||
|
||||
return RenderRequirementData(item, tooltip)
|
||||
}
|
||||
|
||||
fun renderPartyMemberRequirement(partyMemberRequirement: PartyMemberRequirement): RenderRequirementData? {
|
||||
val description = describePokemonProperties(partyMemberRequirement.target) ?: return null
|
||||
val icon = CobblemonItems.POKE_BALL
|
||||
val tooltip = if (partyMemberRequirement.contains) {
|
||||
lang("ui.pokedex.requirement.party_member.tooltip", description)
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.party_member.anticondition.tooltip", description)
|
||||
}
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderPokemonPropertiesRequirement(pokemonPropertiesRequirement: PokemonPropertiesRequirement): RenderRequirementData? {
|
||||
val description = describePokemonProperties(pokemonPropertiesRequirement.target) ?: return null
|
||||
val icon = Items.NAME_TAG
|
||||
val tooltip = lang("ui.pokedex.requirement.pokemon_properties.tooltip", description)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderPropertyRangeRequirement(propertyRangeRequirement: PropertyRangeRequirement): RenderRequirementData? {
|
||||
val provider = SpeciesFeatures.getFeature(propertyRangeRequirement.feature) as? IntSpeciesFeatureProvider ?: return null
|
||||
val displayName = provider.display?.name?.takeIf { it.isNotBlank() }?.asTranslated()?.green() ?: return null
|
||||
val icon = provider.itemPoints.keys.firstOrNull()?.let { BuiltInRegistries.ITEM.get(it) } ?: Items.NAME_TAG
|
||||
|
||||
val range = propertyRangeRequirement.range
|
||||
val tooltip = lang(
|
||||
"ui.pokedex.requirement.property_range.tooltip",
|
||||
displayName,
|
||||
Component.literal(range.first.toString()).green(),
|
||||
Component.literal(range.last.toString()).green()
|
||||
)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderRecoilRequirement(recoilRequirement: RecoilRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.LIFE_ORB
|
||||
val recoilComponent = Component.literal(recoilRequirement.amount.toString()).green()
|
||||
val tooltip = lang("ui.pokedex.requirement.recoil.tooltip", recoilComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderStatCompareRequirement(statCompareRequirement: StatCompareRequirement): RenderRequirementData? {
|
||||
val highStat = Stats.getStat(statCompareRequirement.highStat)
|
||||
val lowStat = Stats.getStat(statCompareRequirement.lowStat)
|
||||
|
||||
val icon = when (highStat) {
|
||||
Stats.HP, Stats.EVASION, Stats.ACCURACY -> CobblemonItems.HEALTH_MOCHI
|
||||
Stats.ATTACK -> CobblemonItems.MUSCLE_MOCHI
|
||||
Stats.DEFENCE -> CobblemonItems.RESIST_MOCHI
|
||||
Stats.SPECIAL_ATTACK -> CobblemonItems.GENIUS_MOCHI
|
||||
Stats.SPECIAL_DEFENCE -> CobblemonItems.CLEVER_MOCHI
|
||||
Stats.SPEED -> CobblemonItems.SWIFT_MOCHI
|
||||
}
|
||||
|
||||
val highStatComponent = highStat.displayName.plainCopy().green()
|
||||
val lowStatComponent = lowStat.displayName.plainCopy().green()
|
||||
val tooltip = lang("ui.pokedex.requirement.stat_compare.tooltip", highStatComponent, lowStatComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderStatEqualRequirement(statEqualRequirement: StatEqualRequirement): RenderRequirementData? {
|
||||
val statOne = Stats.getStat(statEqualRequirement.statOne)
|
||||
val statTwo = Stats.getStat(statEqualRequirement.statTwo)
|
||||
|
||||
val statOneComponent = statOne.displayName.plainCopy().green()
|
||||
val statTwoComponent = statTwo.displayName.plainCopy().green()
|
||||
|
||||
val icon = CobblemonItems.FRESH_START_MOCHI
|
||||
val tooltip = lang("ui.pokedex.requirement.stat_equal.tooltip", statOneComponent, statTwoComponent)
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderStructureRequirement(structureRequirement: StructureRequirement): RenderRequirementData? {
|
||||
val condition = structureRequirement.structureCondition
|
||||
val anticondition = structureRequirement.structureAnticondition
|
||||
if (condition == null && anticondition == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val icon = Items.STRUCTURE_BLOCK
|
||||
val displayName: (RegistryLikeCondition<Structure>) -> MutableComponent = {
|
||||
val path = when (it) {
|
||||
is RegistryLikeTagCondition -> it.tag.location().path
|
||||
is RegistryLikeIdentifierCondition -> it.identifier.path
|
||||
else -> it.toString()
|
||||
}
|
||||
Component.literal(path.substringAfterLast('/').split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) })
|
||||
}
|
||||
val tooltip = if (condition != null && anticondition != null) {
|
||||
lang("ui.pokedex.requirement.structure.both.tooltip", displayName(condition).green(), displayName(anticondition).green())
|
||||
} else if (condition != null) {
|
||||
lang("ui.pokedex.requirement.structure.tooltip", displayName(condition).green())
|
||||
} else {
|
||||
lang("ui.pokedex.requirement.structure.anticondition.tooltip", displayName(anticondition!!).green())
|
||||
}
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderTimeRangeRequirement(timeRangeRequirement: TimeRangeRequirement): RenderRequirementData? {
|
||||
val icon = Items.CLOCK
|
||||
val timeRangeComponent = timeRangeRequirement.range.displayName() ?: return null
|
||||
val tooltip = lang("ui.pokedex.requirement.time_range.tooltip", timeRangeComponent.green())
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderUseMoveRequirement(useMoveRequirement: UseMoveRequirement): RenderRequirementData? {
|
||||
val icon = CobblemonItems.CHOICE_BAND
|
||||
val tooltip = lang("ui.pokedex.requirement.use_move.tooltip", useMoveRequirement.move.displayName.green())
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderWeatherRequirement(weatherRequirement: WeatherRequirement): RenderRequirementData? {
|
||||
val icon: Item
|
||||
val tooltip: MutableComponent
|
||||
|
||||
if (weatherRequirement.isThundering == true) {
|
||||
icon = Items.LIGHTNING_ROD
|
||||
tooltip = lang("ui.pokedex.requirement.weather.tooltip.thundering")
|
||||
} else {
|
||||
icon = Items.WATER_BUCKET
|
||||
tooltip = lang("ui.pokedex.requirement.weather.tooltip.raining")
|
||||
}
|
||||
|
||||
return RenderRequirementData(icon, tooltip)
|
||||
}
|
||||
|
||||
fun renderWorldRequirement(worldRequirement: WorldRequirement): RenderRequirementData? {
|
||||
return null
|
||||
}
|
||||
+3
-2
@@ -24,8 +24,9 @@ object OpenPCHandler : ClientNetworkPacketHandler<OpenPCPacket> {
|
||||
party = CobblemonClient.storage.party,
|
||||
configuration = PCGUIConfiguration(),
|
||||
openOnBox = packet.box ?: CobblemonClient.lastPcBoxViewed,
|
||||
unseenWallpapers = packet.unseenWallpapers.toMutableSet()
|
||||
unseenWallpapers = packet.unseenWallpapers.toMutableSet(),
|
||||
silent = packet.silent
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-98
@@ -1,98 +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.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
|
||||
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.client.render.models.blockbench.pose.ModelPartTransformation
|
||||
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 net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class CaterpieModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("caterpie")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.1F
|
||||
override var portraitTranslation = Vec3(-0.55, -1.55, 0.0)
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var shoulderLeft: CobblemonPose
|
||||
lateinit var shoulderRight: CobblemonPose
|
||||
|
||||
val shoulderOffset = 3
|
||||
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("caterpie", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("caterpie", "blink")}
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
transformTicks = 10,
|
||||
animations = arrayOf(bedrock("caterpie", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("caterpie", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walking",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("caterpie", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
shoulderLeft = registerPose(
|
||||
poseType = PoseType.SHOULDER_LEFT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("caterpie", "ground_idle")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
|
||||
)
|
||||
)
|
||||
|
||||
shoulderRight = registerPose(
|
||||
poseType = PoseType.SHOULDER_RIGHT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("caterpie", "ground_idle")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("caterpie", "faint")
|
||||
}
|
||||
-98
@@ -1,98 +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.client.render.models.blockbench.pokemon.gen1
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
|
||||
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.ModelPartTransformation
|
||||
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 net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class WeedleModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("weedle")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.2F
|
||||
override var portraitTranslation = Vec3(-0.31, -1.83, 0.0)
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.1, 0.6, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var shoulderLeft: Pose
|
||||
lateinit var shoulderRight: Pose
|
||||
|
||||
val shoulderOffset = 3.8
|
||||
val shoulderZOffset = -3
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("weedle", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("weedle", "blink")}
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("weedle", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("weedle", "ground_idle2")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("weedle", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
shoulderLeft = registerPose(
|
||||
poseType = PoseType.SHOULDER_LEFT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("weedle", "ground_idle")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset),
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.Z_AXIS, shoulderZOffset)
|
||||
)
|
||||
)
|
||||
|
||||
shoulderRight = registerPose(
|
||||
poseType = PoseType.SHOULDER_RIGHT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("weedle", "ground_idle")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset),
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.Z_AXIS, shoulderZOffset)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("weedle", "faint")
|
||||
}
|
||||
-59
@@ -1,59 +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.client.render.models.blockbench.pokemon.gen5
|
||||
|
||||
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.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class JellicentModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("jellicent")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 1.13F
|
||||
override var portraitTranslation = Vec3(-0.56, 1.64, 0.0)
|
||||
|
||||
override var profileScale = 0.51F
|
||||
override var profileTranslation = Vec3(0.0, 1.05, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("jellicent", "blink") }
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("jellicent", "render")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("jellicent", "render")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("jellicent", "faint") else null
|
||||
}
|
||||
-57
@@ -1,57 +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.client.render.models.blockbench.pokemon.gen7
|
||||
|
||||
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 net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class CrabominableModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("crabominable")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 1.0F
|
||||
override var portraitTranslation = Vec3(-0.55, 1.65, 0.0)
|
||||
|
||||
override var profileScale = 0.3F
|
||||
override var profileTranslation = Vec3(0.0, 1.2, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override fun registerPoses() {
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + UI_POSES,
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("crabominable", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("crabominable", "ground_idle"),
|
||||
bedrock("crabominable", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("crabominable", "faint") else null
|
||||
}
|
||||
-4
@@ -220,10 +220,8 @@ object VaryingModelRepository {
|
||||
|
||||
inbuilt("squirtle", ::SquirtleModel)
|
||||
inbuilt("wartortle", ::WartortleModel)
|
||||
inbuilt("caterpie", ::CaterpieModel)
|
||||
inbuilt("metapod", ::MetapodModel)
|
||||
inbuilt("butterfree", ::ButterfreeModel)
|
||||
inbuilt("weedle", ::WeedleModel)
|
||||
inbuilt("beedrill", ::BeedrillModel)
|
||||
inbuilt("raticate", ::RaticateModel)
|
||||
inbuilt("raticate_alolan", ::RaticateAlolanModel)
|
||||
@@ -446,7 +444,6 @@ object VaryingModelRepository {
|
||||
inbuilt("bayleef", ::BayleefModel)
|
||||
inbuilt("meganium", ::MeganiumModel)
|
||||
inbuilt("crabrawler", ::CrabrawlerModel)
|
||||
inbuilt("crabominable", ::CrabominableModel)
|
||||
inbuilt("wimpod", ::WimpodModel)
|
||||
inbuilt("golisopod", ::GolisopodModel)
|
||||
inbuilt("ralts", ::RaltsModel)
|
||||
@@ -502,7 +499,6 @@ object VaryingModelRepository {
|
||||
inbuilt("woobat", ::WoobatModel)
|
||||
inbuilt("swoobat", ::SwoobatModel)
|
||||
inbuilt("frillish", ::FrillishModel)
|
||||
inbuilt("jellicent", ::JellicentModel)
|
||||
inbuilt("cubchoo", ::CubchooModel)
|
||||
inbuilt("beartic", ::BearticModel)
|
||||
inbuilt("dreepy", ::DreepyModel)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.command
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.permission.CobblemonPermissions
|
||||
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
|
||||
import com.cobblemon.mod.common.api.storage.pc.link.PermissiblePcLink
|
||||
@@ -54,8 +53,8 @@ object PcCommand {
|
||||
throw SimpleCommandExceptionType(lang("command.pc.invalid-box", box, pc.boxes.size).red()).create()
|
||||
}
|
||||
PCLinkManager.addLink(PermissiblePcLink(pc, player, CobblemonPermissions.PC))
|
||||
OpenPCPacket(pc, box = if (box != null) (box - 1) else null).sendToPlayer(player)
|
||||
OpenPCPacket(pc, box = if (box != null) (box - 1) else null, silent = true).sendToPlayer(player)
|
||||
return Command.SINGLE_SUCCESS
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +269,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
attemptCatch(pokemonEntity)
|
||||
},
|
||||
ifCanceled = {
|
||||
captureFuture.complete(false)
|
||||
drop()
|
||||
return
|
||||
}
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.CobblemonBiomeDexEvolutionRequirementDisplay
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.CobblemonDexEvolutionRequirementDisplay
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.DexEntries
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.DexEvolutionDisplay
|
||||
import com.cobblemon.mod.common.api.pokedex.entry.DexEvolutionRequirementDisplay
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readIdentifier
|
||||
import com.cobblemon.mod.common.util.readNullable
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.readText
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
import com.cobblemon.mod.common.util.writeNullable
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.cobblemon.mod.common.util.writeText
|
||||
import com.google.common.collect.Lists
|
||||
import com.google.common.collect.Sets
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.util.ExtraCodecs
|
||||
|
||||
class DexEvolutionDisplaySyncPacket(entries: MutableList<DexEvolutionDisplay>)
|
||||
: DataRegistrySyncPacket<DexEvolutionDisplay, DexEvolutionDisplaySyncPacket>(entries) {
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: DexEvolutionDisplay) {
|
||||
buffer.writeIdentifier(entry.fromSpecies)
|
||||
buffer.writeString(entry.fromForm)
|
||||
buffer.writeCollection(entry.fromAspects) { _, aspect -> buffer.writeString(aspect) }
|
||||
buffer.writeIdentifier(entry.toSpecies)
|
||||
buffer.writeString(entry.toForm)
|
||||
buffer.writeCollection(entry.toAspects) { _, aspect -> buffer.writeString(aspect) }
|
||||
buffer.writeCollection(entry.requirements) { _, req ->
|
||||
when (req) {
|
||||
is CobblemonBiomeDexEvolutionRequirementDisplay -> {
|
||||
buffer.writeByte(1)
|
||||
buffer.writeIdentifier(BuiltInRegistries.ITEM.getKey(req.icon))
|
||||
buffer.writeText(req.tooltip)
|
||||
buffer.writeNullable(req.condition) { b, cond ->
|
||||
b.writeIdentifier(cond.id)
|
||||
b.writeBoolean(cond.tag)
|
||||
}
|
||||
buffer.writeNullable(req.antiCondition) { b, cond ->
|
||||
b.writeIdentifier(cond.id)
|
||||
b.writeBoolean(cond.tag)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
buffer.writeByte(0)
|
||||
buffer.writeIdentifier(BuiltInRegistries.ITEM.getKey(req.icon))
|
||||
buffer.writeText(req.tooltip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): DexEvolutionDisplay? {
|
||||
val fromSpecies = buffer.readIdentifier()
|
||||
val fromForm = buffer.readString()
|
||||
val fromAspects = buffer.readCollection(Sets::newHashSetWithExpectedSize) { buffer.readString() }
|
||||
val toSpecies = buffer.readIdentifier()
|
||||
val toForm = buffer.readString()
|
||||
val toAspects = buffer.readCollection(Sets::newHashSetWithExpectedSize) { buffer.readString() }
|
||||
val requirements = buffer.readCollection(Lists::newArrayListWithExpectedSize) {
|
||||
val type = buffer.readByte().toInt()
|
||||
val icon = BuiltInRegistries.ITEM.get(buffer.readIdentifier())
|
||||
val tooltip = buffer.readText().copy()
|
||||
if (type == 1) {
|
||||
val condition = buffer.readNullable { b ->
|
||||
val id = b.readIdentifier()
|
||||
val tag = b.readBoolean()
|
||||
ExtraCodecs.TagOrElementLocation(id, tag)
|
||||
}
|
||||
val antiCondition = buffer.readNullable { b ->
|
||||
val id = b.readIdentifier()
|
||||
val tag = b.readBoolean()
|
||||
ExtraCodecs.TagOrElementLocation(id, tag)
|
||||
}
|
||||
CobblemonBiomeDexEvolutionRequirementDisplay(icon, tooltip, condition, antiCondition)
|
||||
} else {
|
||||
CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
|
||||
}
|
||||
}.toList()
|
||||
return DexEvolutionDisplay(fromSpecies, fromForm, fromAspects, toSpecies, toForm, toAspects, requirements)
|
||||
}
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<DexEvolutionDisplay>) {
|
||||
DexEntries.evolutionDisplays.clear()
|
||||
DexEntries.evolutionDisplays.addAll(entries)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("dex_evolution_display_sync")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): DexEvolutionDisplaySyncPacket =
|
||||
DexEvolutionDisplaySyncPacket(mutableListOf()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
-100
@@ -1,100 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.PreEvolution
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readIdentifier
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Carries the evolutions/preEvolution of every [Species] (and any [FormData] overrides), sent right after
|
||||
* [SpeciesRegistrySyncPacket] so that every species is already registered by the time this is decoded. This avoids
|
||||
* the cross-species lookup ordering hazards that come with resolving evolutions during the species sync itself.
|
||||
*/
|
||||
class SpeciesEvolutionSyncPacket(entries: Collection<SpeciesEvolutionEntry>) : DataRegistrySyncPacket<SpeciesEvolutionEntry, SpeciesEvolutionSyncPacket>(entries) {
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: SpeciesEvolutionEntry) {
|
||||
try {
|
||||
buffer.writeIdentifier(entry.speciesIdentifier)
|
||||
buffer.writeString(PokemonSpecies.gson.toJson(entry.evolutions, EVOLUTION_SET_TYPE))
|
||||
buffer.writeNullable(entry.preEvolution) { _, preEvolution -> buffer.writeString(PokemonSpecies.gson.toJson(preEvolution, PreEvolution::class.java)) }
|
||||
buffer.writeCollection(entry.formOverrides) { _, override ->
|
||||
buffer.writeString(override.formName)
|
||||
buffer.writeNullable(override.evolutions) { _, evolutions -> buffer.writeString(PokemonSpecies.gson.toJson(evolutions, EVOLUTION_SET_TYPE)) }
|
||||
buffer.writeNullable(override.preEvolution) { _, preEvolution -> buffer.writeString(PokemonSpecies.gson.toJson(preEvolution, PreEvolution::class.java)) }
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Caught exception encoding evolution data for species {}", entry.speciesIdentifier, e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): SpeciesEvolutionEntry? {
|
||||
val identifier = buffer.readIdentifier()
|
||||
return try {
|
||||
val evolutions: MutableSet<Evolution> = PokemonSpecies.gson.fromJson(buffer.readString(), EVOLUTION_SET_TYPE)
|
||||
val preEvolution = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson(buffer.readString(), PreEvolution::class.java) }
|
||||
val formOverrides = buffer.readList { _ ->
|
||||
val formName = buffer.readString()
|
||||
val formEvolutions = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson<MutableSet<Evolution>>(buffer.readString(), EVOLUTION_SET_TYPE) }
|
||||
val formPreEvolution = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson(buffer.readString(), PreEvolution::class.java) }
|
||||
FormEvolutionOverride(formName, formEvolutions, formPreEvolution)
|
||||
}
|
||||
SpeciesEvolutionEntry(identifier, evolutions, preEvolution, formOverrides)
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Caught exception decoding evolution data for species {}", identifier, e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<SpeciesEvolutionEntry>) {
|
||||
entries.forEach { entry ->
|
||||
val species = PokemonSpecies.getByIdentifier(entry.speciesIdentifier)
|
||||
if (species == null) {
|
||||
Cobblemon.LOGGER.error("Received evolution data for unknown species {}", entry.speciesIdentifier)
|
||||
return@forEach
|
||||
}
|
||||
species.applyEvolutionData(entry.evolutions, entry.preEvolution)
|
||||
entry.formOverrides.forEach { override ->
|
||||
species.getFormByName(override.formName).applyEvolutionData(override.evolutions, override.preEvolution)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("species_evolution_sync")
|
||||
private val EVOLUTION_SET_TYPE = TypeToken.getParameterized(MutableSet::class.java, Evolution::class.java).type
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): SpeciesEvolutionSyncPacket = SpeciesEvolutionSyncPacket(emptyList()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
|
||||
class SpeciesEvolutionEntry(
|
||||
val speciesIdentifier: ResourceLocation,
|
||||
val evolutions: MutableSet<Evolution>,
|
||||
val preEvolution: PreEvolution?,
|
||||
val formOverrides: List<FormEvolutionOverride>
|
||||
)
|
||||
|
||||
class FormEvolutionOverride(
|
||||
val formName: String,
|
||||
val evolutions: MutableSet<Evolution>?,
|
||||
val preEvolution: PreEvolution?
|
||||
)
|
||||
+8
-4
@@ -34,17 +34,19 @@ class OpenPCPacket : NetworkPacket<OpenPCPacket> {
|
||||
val storeID: UUID
|
||||
val box: Int?
|
||||
val unseenWallpapers: Set<ResourceLocation>
|
||||
val silent: Boolean
|
||||
|
||||
@JvmOverloads
|
||||
@Deprecated("Use the constructor with the PCStore object instead, this will become private in a future title update", level = DeprecationLevel.WARNING)
|
||||
constructor(storeID: UUID, box: Int? = null, unseenWallpapers: Set<ResourceLocation> = emptySet()) {
|
||||
constructor(storeID: UUID, box: Int? = null, unseenWallpapers: Set<ResourceLocation> = emptySet(), silent: Boolean? = false) {
|
||||
this.storeID = storeID
|
||||
this.box = box
|
||||
this.unseenWallpapers = unseenWallpapers
|
||||
this.silent = silent ?: false
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
constructor(pc: PCStore, box: Int? = null): this(pc.uuid, box, pc.unseenWallpapers)
|
||||
constructor(pc: PCStore, box: Int? = null, silent: Boolean? = false): this(pc.uuid, box, pc.unseenWallpapers, silent ?: false)
|
||||
|
||||
override val id = ID
|
||||
|
||||
@@ -52,6 +54,7 @@ class OpenPCPacket : NetworkPacket<OpenPCPacket> {
|
||||
buffer.writeUUID(storeID)
|
||||
buffer.writeNullable(box) { buf, value -> buf.writeInt(value)}
|
||||
buffer.writeCollection(unseenWallpapers) { _, it -> buffer.writeResourceLocation(it) }
|
||||
buffer.writeBoolean(silent)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -59,7 +62,8 @@ class OpenPCPacket : NetworkPacket<OpenPCPacket> {
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) = OpenPCPacket(
|
||||
buffer.readUUID(),
|
||||
buffer.readNullable { it.readInt() },
|
||||
buffer.readList { buffer.readResourceLocation() }.toSet()
|
||||
buffer.readList { buffer.readResourceLocation() }.toSet(),
|
||||
buffer.readBoolean()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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://www.mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.server.storage.pc
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readPCPosition
|
||||
import com.cobblemon.mod.common.util.writePCPosition
|
||||
import java.util.UUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class MovePCPokemonBatchPacket(val moves: List<PCPokemonMove>) : NetworkPacket<MovePCPokemonBatchPacket> {
|
||||
override val id = ID
|
||||
|
||||
data class PCPokemonMove(
|
||||
val pokemonID: UUID,
|
||||
val oldPosition: PCPosition,
|
||||
val newPosition: PCPosition
|
||||
)
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeVarInt(moves.size)
|
||||
moves.forEach { move ->
|
||||
buffer.writeUUID(move.pokemonID)
|
||||
buffer.writePCPosition(move.oldPosition)
|
||||
buffer.writePCPosition(move.newPosition)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("move_pc_pokemon_batch")
|
||||
const val MAX_MOVES = 60
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): MovePCPokemonBatchPacket {
|
||||
val size = buffer.readVarInt()
|
||||
require(size in 1..MAX_MOVES) { "Invalid batch PC move size: $size" }
|
||||
return MovePCPokemonBatchPacket(
|
||||
List(size) {
|
||||
PCPokemonMove(
|
||||
pokemonID = buffer.readUUID(),
|
||||
oldPosition = buffer.readPCPosition(),
|
||||
newPosition = buffer.readPCPosition()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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://www.mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.serverhandling.storage.pc
|
||||
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
object MovePCPokemonBatchHandler : ServerNetworkPacketHandler<MovePCPokemonBatchPacket> {
|
||||
override fun handle(packet: MovePCPokemonBatchPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val pc = PCLinkManager.getPC(player) ?: return run { ClosePCPacket(null).sendToPlayer(player) }
|
||||
pc.moveBatch(packet.moves.map { Triple(it.pokemonID, it.oldPosition, it.newPosition) })
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class FormData(
|
||||
@SerializedName("moves")
|
||||
private var _moves: Learnset? = null,
|
||||
@SerializedName("evolutions")
|
||||
private var _evolutions: MutableSet<Evolution>? = null,
|
||||
private val _evolutions: MutableSet<Evolution>? = null,
|
||||
@SerializedName("abilities")
|
||||
private var _abilities: AbilityPool? = null,
|
||||
@SerializedName("drops")
|
||||
@@ -84,7 +84,7 @@ class FormData(
|
||||
@SerializedName("pokedex")
|
||||
private var _pokedex: MutableList<String>? = null,
|
||||
@SerializedName("preEvolution")
|
||||
private var _preEvolution: PreEvolution? = null,
|
||||
private val _preEvolution: PreEvolution? = null,
|
||||
private var standingEyeHeight: Float? = null,
|
||||
private var swimmingEyeHeight: Float? = null,
|
||||
private var flyingEyeHeight: Float? = null,
|
||||
@@ -269,22 +269,13 @@ class FormData(
|
||||
this.species = species
|
||||
this.behaviour.parent = species.behaviour
|
||||
Cobblemon.statProvider.provide(this)
|
||||
this._lightingData?.let { this._lightingData = it.copy(lightLevel = it.lightLevel.coerceIn(0, 15)) }
|
||||
behaviour.herd.initialize()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies decoded evolution data onto this form, received separately via [com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket]
|
||||
* after every species has already been registered.
|
||||
*/
|
||||
internal fun applyEvolutionData(evolutions: MutableSet<Evolution>?, preEvolution: PreEvolution?) {
|
||||
this._evolutions = evolutions
|
||||
this._preEvolution = preEvolution
|
||||
// These properties are lazy, force resolution now that every species is guaranteed to be registered
|
||||
// These properties are lazy, these need all species to be reloaded but SpeciesAdditions is what will eventually trigger this after all species have been loaded
|
||||
this.preEvolution?.species
|
||||
this.preEvolution?.form
|
||||
this.evolutions.size
|
||||
this._lightingData?.let { this._lightingData = it.copy(lightLevel = it.lightLevel.coerceIn(0, 15)) }
|
||||
behaviour.herd.initialize()
|
||||
return this
|
||||
}
|
||||
|
||||
internal fun resolveEvolutionMoves() {
|
||||
|
||||
@@ -181,20 +181,11 @@ class Species : ShowdownIdentifiable {
|
||||
this.forms.add(0, this.standardForm)
|
||||
}
|
||||
this.lightingData?.let { this.lightingData = it.copy(lightLevel = it.lightLevel.coerceIn(0, 15)) }
|
||||
behaviour.herd.initialize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies decoded evolution data onto this species, received separately via [com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket]
|
||||
* after every species has already been registered.
|
||||
*/
|
||||
internal fun applyEvolutionData(evolutions: MutableSet<Evolution>, preEvolution: PreEvolution?) {
|
||||
// Mutate in place rather than reassign: standardForm may have already captured this.evolutions by reference.
|
||||
this.evolutions.clear()
|
||||
this.evolutions.addAll(evolutions)
|
||||
this.preEvolution = preEvolution
|
||||
// These properties are lazy, these need all species to be reloaded but SpeciesAdditions is what will eventually trigger this after all species have been loaded
|
||||
this.preEvolution?.species
|
||||
this.preEvolution?.form
|
||||
this.evolutions.size
|
||||
behaviour.herd.initialize()
|
||||
}
|
||||
|
||||
// Ran after initialize due to us creating a Pokémon here which requires all the properties in #initialize to be present for both this and the results, this is the easiest way to quickly resolve species + form
|
||||
|
||||
+2
-10
@@ -25,20 +25,12 @@ internal class CobblemonLazyPreEvolution(private val rawData: String) : PreEvolu
|
||||
this.properties.species?.asIdentifierDefaultingNamespace()?.let { PokemonSpecies.getByIdentifier(it) } ?: throw IllegalArgumentException("A PreEvolution needs a valid species")
|
||||
}
|
||||
|
||||
private fun computeForm(extraAspects: Set<String>): FormData {
|
||||
val properties = this.properties
|
||||
return properties.form?.let { formId -> this.species.forms.firstOrNull { it.formOnlyShowdownId().equals(formId, true) } }
|
||||
?: this.species.getForm(properties.aspects + this.rawData.split(" ").map { it.lowercase() }.toSet() + extraAspects)
|
||||
private val lazyForm: FormData by lazy {
|
||||
this.properties.form?.let { formId -> this.species.forms.firstOrNull { it.formOnlyShowdownId().equals(formId, true) } } ?: this.species.standardForm
|
||||
}
|
||||
|
||||
private val lazyForm: FormData by lazy { computeForm(emptySet()) }
|
||||
|
||||
override val species: Species
|
||||
get() = this.lazySpecies
|
||||
override val form: FormData
|
||||
get() = this.lazyForm
|
||||
|
||||
override fun resolveForm(extraAspects: Set<String>): FormData {
|
||||
return if (extraAspects.isEmpty()) this.form else computeForm(extraAspects)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.abilities.Abilities
|
||||
import com.cobblemon.mod.common.api.data.DataRegistry
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.AbstractChoiceSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
@@ -134,7 +135,7 @@ internal object PropertiesCompletionProvider : DataRegistry {
|
||||
private fun addDefaults() {
|
||||
this.inject(setOf("level", "lvl", "l"), setOf("1", "${Cobblemon.config.maxPokemonLevel}") )
|
||||
this.inject(setOf("shiny", "s"), setOf("yes", "no"))
|
||||
this.inject(setOf("gender"), Gender.values().map { it.name.lowercase() })
|
||||
this.inject(setOf("gender"), Gender.entries.map { it.name.lowercase() })
|
||||
this.inject(setOf("friendship"), setOf("0", Cobblemon.config.maxPokemonFriendship.toString()))
|
||||
this.inject(setOf("fullness"), setOf("0", "255"))
|
||||
this.inject(setOf("pokeball"), PokeBalls.all().map { it.name.simplify() })
|
||||
@@ -164,7 +165,11 @@ internal object PropertiesCompletionProvider : DataRegistry {
|
||||
private fun addCustom() {
|
||||
CustomPokemonProperty.properties.forEach { property ->
|
||||
// We won't tab complete properties that have no key attached to them as it would be fairly hard to determine which one to suggest
|
||||
if (property.needsKey) {
|
||||
if (property.needsKey && property !is AbstractChoiceSpeciesFeatureProvider<*>) {
|
||||
this.inject(property.keys, property.examples())
|
||||
}
|
||||
// Except choice features that fill examples with all available choices - Gito
|
||||
if (property is AbstractChoiceSpeciesFeatureProvider<*>) {
|
||||
this.inject(property.keys, property.examples())
|
||||
}
|
||||
}
|
||||
@@ -175,4 +180,4 @@ internal object PropertiesCompletionProvider : DataRegistry {
|
||||
val suggestions: Collection<String>
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,10 @@ import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
import net.minecraft.world.phys.AABB
|
||||
|
||||
object BoxAdapter : JsonDeserializer<AABB>, JsonSerializer<AABB> {
|
||||
object BoxAdapter : JsonDeserializer<AABB> {
|
||||
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): AABB {
|
||||
json as JsonObject
|
||||
return AABB(
|
||||
@@ -29,15 +27,4 @@ object BoxAdapter : JsonDeserializer<AABB>, JsonSerializer<AABB> {
|
||||
json.get("maxZ")?.asDouble ?: 9999999.0
|
||||
)
|
||||
}
|
||||
|
||||
override fun serialize(src: AABB, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
|
||||
val json = JsonObject()
|
||||
json.addProperty("minX", src.minX)
|
||||
json.addProperty("minY", src.minY)
|
||||
json.addProperty("minZ", src.minZ)
|
||||
json.addProperty("maxX", src.maxX)
|
||||
json.addProperty("maxY", src.maxY)
|
||||
json.addProperty("maxZ", src.maxZ)
|
||||
return json
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,6 @@ import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
/**
|
||||
@@ -24,7 +22,7 @@ import java.lang.reflect.Type
|
||||
* @author Hiroku
|
||||
* @since July 24th, 2022
|
||||
*/
|
||||
object DropEntryAdapter : JsonDeserializer<DropEntry>, JsonSerializer<DropEntry> {
|
||||
object DropEntryAdapter : JsonDeserializer<DropEntry> {
|
||||
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): DropEntry {
|
||||
json as JsonObject
|
||||
val entryClass = json.get("type")?.asString
|
||||
@@ -32,12 +30,4 @@ object DropEntryAdapter : JsonDeserializer<DropEntry>, JsonSerializer<DropEntry>
|
||||
?: DropEntry.defaultType
|
||||
return ctx.deserialize(json, entryClass)
|
||||
}
|
||||
|
||||
override fun serialize(src: DropEntry, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
|
||||
val json = ctx.serialize(src, src::class.java).asJsonObject
|
||||
val name = DropEntry.entryTypes.entries.find { it.value == src::class.java }?.key
|
||||
?: throw IllegalArgumentException("Cannot resolve drop entry type for ${src::class.qualifiedName}")
|
||||
json.addProperty("type", name)
|
||||
return json
|
||||
}
|
||||
}
|
||||
@@ -10,21 +10,13 @@ package com.cobblemon.mod.common.util.adapters
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.MoLang
|
||||
import com.cobblemon.mod.common.util.getString
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
object ExpressionAdapter : JsonDeserializer<Expression>, JsonSerializer<Expression> {
|
||||
object ExpressionAdapter : JsonDeserializer<Expression> {
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type, ctx: JsonDeserializationContext): Expression {
|
||||
return MoLang.createParser(json.asString).parseExpression()
|
||||
}
|
||||
|
||||
override fun serialize(src: Expression, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
|
||||
return JsonPrimitive(src.getString())
|
||||
}
|
||||
}
|
||||
+1
-8
@@ -13,9 +13,6 @@ import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
/**
|
||||
@@ -25,7 +22,7 @@ import java.lang.reflect.Type
|
||||
* @author Hiroku
|
||||
* @since October 22nd, 2023
|
||||
*/
|
||||
object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike>, JsonSerializer<ExpressionLike> {
|
||||
object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike> {
|
||||
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): ExpressionLike {
|
||||
return if (json.isJsonPrimitive) {
|
||||
json.asString.asExpressionLike()
|
||||
@@ -35,8 +32,4 @@ object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike>, JsonSerializer<
|
||||
throw IllegalArgumentException("Invalid expression JSON: $json")
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(src: ExpressionLike, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
|
||||
return JsonPrimitive(src.getString())
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -11,23 +11,22 @@ package com.cobblemon.mod.common.util.adapters
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.Environment
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.google.gson.JsonElement
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.resources.RegistryOps
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
|
||||
/**
|
||||
* Utility for getting RegistryAccess with the correct client/server registry access.
|
||||
* Used when as a fallback when manually encoding/decoding registry-backed values (e.g., items, predicates).
|
||||
*/
|
||||
object RegistryAccessResolver {
|
||||
private val builtInAccess: RegistryAccess by lazy { RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY) }
|
||||
|
||||
fun getAccess(): RegistryAccess {
|
||||
try {
|
||||
Cobblemon.implementation
|
||||
} catch (e: UninitializedPropertyAccessException) {
|
||||
return RegistryAccess.EMPTY
|
||||
return builtInAccess
|
||||
}
|
||||
if (Cobblemon.implementation.environment() == Environment.CLIENT) {
|
||||
val minecraft = Minecraft.getInstance()
|
||||
@@ -35,13 +34,12 @@ object RegistryAccessResolver {
|
||||
return minecraft.level!!.registryAccess()
|
||||
}
|
||||
|
||||
|
||||
if (Cobblemon.implementation.environment() == Environment.SERVER) {
|
||||
val server = server()
|
||||
if (server != null)
|
||||
return server.registryAccess()
|
||||
}
|
||||
|
||||
return RegistryAccess.EMPTY
|
||||
return builtInAccess
|
||||
}
|
||||
}
|
||||
+2438
-11
File diff suppressed because it is too large
Load Diff
+11
-11
@@ -364,7 +364,7 @@
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": [55, 0, 0],
|
||||
"position": [0, "-8+Math.cos((query.anim_time) * 90 * 2) * 0.2", -1]
|
||||
"position": [0, "-3+Math.cos((query.anim_time) * 90 * 2) * 0.2", -1]
|
||||
},
|
||||
"torso2": {
|
||||
"rotation": ["-12.5+Math.cos((query.anim_time-0.4) * 90 * 2) * 2", 0, 0]
|
||||
@@ -426,16 +426,16 @@
|
||||
"body": {
|
||||
"rotation": [55, 0, 0],
|
||||
"position": {
|
||||
"0.0": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.5],
|
||||
"0.25": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 0.5],
|
||||
"0.5": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 3.5],
|
||||
"0.6667": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 5.17],
|
||||
"0.75": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 5.25],
|
||||
"0.7917": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 3.92],
|
||||
"1.0": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 1],
|
||||
"1.2083": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.25],
|
||||
"1.375": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.75],
|
||||
"1.5": [0, "-9+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.5]
|
||||
"0.0": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.5],
|
||||
"0.25": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 0.5],
|
||||
"0.5": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 3.5],
|
||||
"0.6667": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 5.17],
|
||||
"0.75": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 5.25],
|
||||
"0.7917": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 3.92],
|
||||
"1.0": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", 1],
|
||||
"1.2083": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.25],
|
||||
"1.375": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.75],
|
||||
"1.5": [0, "-3+Math.cos((query.anim_time) * 90 * (2+2/3)) * 0.2", -1.5]
|
||||
}
|
||||
},
|
||||
"torso2": {
|
||||
|
||||
+2
-2
@@ -313,7 +313,7 @@
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": [47.5, 0, 0],
|
||||
"position": [0, "-10+Math.cos((query.anim_time) * 90 * 1) * 0.3", 0]
|
||||
"position": [0, "-6+Math.cos((query.anim_time) * 90 * 1) * 0.3", 0]
|
||||
},
|
||||
"torso": {
|
||||
"rotation": [35, 0, 0],
|
||||
@@ -426,7 +426,7 @@
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": [47.5, 0, 0],
|
||||
"position": [0, -10, "Math.cos((query.anim_time-0.5) * 90 * (2+2/3)) * 4"]
|
||||
"position": [0, -6, "Math.cos((query.anim_time-0.5) * 90 * (2+2/3)) * 4"]
|
||||
},
|
||||
"torso": {
|
||||
"rotation": [35, 0, 0],
|
||||
|
||||
+1
-1
@@ -1925,7 +1925,7 @@
|
||||
},
|
||||
"body": {
|
||||
"rotation": ["68.5-Math.cos((query.anim_time)*360/1-20)*-3", 0, 0],
|
||||
"position": [0, "-24+Math.cos((query.anim_time)*360/1-90)*-0.5", "-1+Math.cos((query.anim_time)*360/1-45)*4"]
|
||||
"position": [0, "Math.cos((query.anim_time)*360/1-90)*-0.5", "-1+Math.cos((query.anim_time)*360/1-45)*4"]
|
||||
},
|
||||
"neck": {
|
||||
"rotation": [-7.5, 0, 0]
|
||||
|
||||
+7
-9
@@ -96,13 +96,13 @@
|
||||
"parent": "head",
|
||||
"pivot": [0, 6, 0.25],
|
||||
"cubes": [
|
||||
{"origin": [-2.4, 4.4, -5.28], "size": [1, 1, 0], "inflate": 0.01, "pivot": [-2, 5, 0], "rotation": [0, 0, -45], "uv": [12, 19]},
|
||||
{"origin": [-1.75, 5.25, 5.76], "size": [1, 1, 0], "pivot": [-2, 5, 0], "rotation": [0, 0, -45], "uv": [8, 10]},
|
||||
{"origin": [1.25, 1.25, 5.76], "size": [1, 1, 0], "pivot": [-2, 5, 0], "rotation": [0, 0, -45], "uv": [9, 2]},
|
||||
{"origin": [-4.51, 6, -2.75], "size": [0, 1, 1], "pivot": [-2, 6.5, -2.25], "rotation": [-45, 0, 0], "uv": [7, 1]},
|
||||
{"origin": [4.51, 6.75, -2.75], "size": [0, 1, 1], "pivot": [-2, 6.5, -2.25], "rotation": [-45, 0, 0], "uv": [0, 5]},
|
||||
{"origin": [4.51, 8, 0.5], "size": [0, 1, 1], "pivot": [-2, 6.5, -2.25], "rotation": [-45, 0, 0], "uv": [0, 1]},
|
||||
{"origin": [-4.51, 6.5, 1.25], "size": [0, 1, 1], "pivot": [-2, 7, 1.75], "rotation": [-45, 0, 0], "uv": [0, 6]}
|
||||
{"origin": [-2.5, 4.4, -5.28], "size": [1, 1, 0], "uv": [12, 19]},
|
||||
{"origin": [-2.5, 5.5, 5.76], "size": [1, 1, 0], "uv": [8, 10]},
|
||||
{"origin": [2.5, 4.5, 5.76], "size": [1, 1, 0], "uv": [9, 2]},
|
||||
{"origin": [-4.51, 6, -2.75], "size": [0, 1, 1], "uv": [7, 1]},
|
||||
{"origin": [4.51, 6.5, -2.25], "size": [0, 1, 1], "uv": [0, 5]},
|
||||
{"origin": [4.51, 5, 0.75], "size": [0, 1, 1], "uv": [0, 1]},
|
||||
{"origin": [-4.51, 6.5, 1.75], "size": [0, 1, 1], "uv": [0, 6]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,7 +119,6 @@
|
||||
"name": "eye_right",
|
||||
"parent": "eyes",
|
||||
"pivot": [-1.5, 5.75, -5.25],
|
||||
"rotation": [0, 0, 5],
|
||||
"cubes": [
|
||||
{"origin": [-2.5, 6, -5.26], "size": [1, 2, 0], "uv": [8, 19]}
|
||||
]
|
||||
@@ -152,7 +151,6 @@
|
||||
"name": "eye_left",
|
||||
"parent": "eyes",
|
||||
"pivot": [1.5, 5.75, -5.25],
|
||||
"rotation": [0, 0, -5],
|
||||
"cubes": [
|
||||
{"origin": [1.5, 6, -5.26], "size": [1, 2, 0], "uv": [8, 8]}
|
||||
]
|
||||
|
||||
+29
-21
@@ -112,7 +112,7 @@
|
||||
{
|
||||
"name": "head",
|
||||
"parent": "neck",
|
||||
"pivot": [0, 9, -0.25],
|
||||
"pivot": [0, 8.25, -0.25],
|
||||
"cubes": [
|
||||
{"origin": [-4, 7.5, -3.75], "size": [8, 6, 7], "uv": [0, 0]},
|
||||
{"origin": [-1.25, 9.25, -4.75], "size": [2, 2, 1], "inflate": 0.01, "uv": [23, 1]},
|
||||
@@ -151,67 +151,75 @@
|
||||
{
|
||||
"name": "eye_left",
|
||||
"parent": "eyes",
|
||||
"pivot": [2.75, 11, -3.76],
|
||||
"rotation": [0, 0, -7.5],
|
||||
"pivot": [2.75, 10.75, -3.76]
|
||||
},
|
||||
{
|
||||
"name": "iris_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2.75, 10.875, -3.765],
|
||||
"cubes": [
|
||||
{"origin": [2, 10, -3.76], "size": [1.5, 2, 0], "uv": [0, 0]}
|
||||
{"origin": [2, 9.75, -3.76], "size": [1.5, 2, 0], "uv": [0, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2.75, 11.25, -3.77],
|
||||
"parent": "iris_left",
|
||||
"pivot": [2.75, 11, -3.77],
|
||||
"cubes": [
|
||||
{"origin": [2.25, 10.5, -3.77], "size": [1, 1, 0], "uv": [2, 0]}
|
||||
{"origin": [2.25, 10.25, -3.77], "size": [1, 1, 0], "uv": [2, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye_left",
|
||||
"parent": "pupil_left",
|
||||
"pivot": [2.75, 11, -4],
|
||||
"pivot": [2.75, 10.75, -4],
|
||||
"locators": {
|
||||
"eye2": [2.75, 11, -4]
|
||||
"eye2": [2.75, 10.75, -4]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "eyelid_left",
|
||||
"parent": "eye_left",
|
||||
"pivot": [2.75, 11, -3.17],
|
||||
"pivot": [2.75, 10.75, -3.17],
|
||||
"cubes": [
|
||||
{"origin": [1.75, 10, -3.67], "size": [2, 2, 1], "inflate": 0.01, "uv": [1, 3]}
|
||||
{"origin": [1.75, 9.75, -3.67], "size": [2, 2, 1], "inflate": 0.01, "uv": [1, 3]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "eye_right",
|
||||
"parent": "eyes",
|
||||
"pivot": [-2.75, 11, -3.76],
|
||||
"rotation": [0, 0, 7.5],
|
||||
"pivot": [-2.75, 10.75, -3.76]
|
||||
},
|
||||
{
|
||||
"name": "iris_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2.75, 10.875, -3.765],
|
||||
"cubes": [
|
||||
{"origin": [-3.5, 10, -3.76], "size": [1.5, 2, 0], "uv": [0, 2], "mirror": true}
|
||||
{"origin": [-3.5, 9.75, -3.76], "size": [1.5, 2, 0], "uv": [0, 2], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pupil_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2.75, 11.25, -3.77],
|
||||
"parent": "iris_right",
|
||||
"pivot": [-2.75, 11, -3.77],
|
||||
"cubes": [
|
||||
{"origin": [-3.25, 10.5, -3.77], "size": [1, 1, 0], "uv": [2, 1], "mirror": true}
|
||||
{"origin": [-3.25, 10.25, -3.77], "size": [1, 1, 0], "uv": [2, 1], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "locator_eye_right",
|
||||
"parent": "pupil_right",
|
||||
"pivot": [-2.75, 11, -4],
|
||||
"pivot": [-2.75, 10.75, -4],
|
||||
"locators": {
|
||||
"eye1": [-2.75, 11, -4]
|
||||
"eye1": [-2.75, 10.75, -4]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "eyelid_right",
|
||||
"parent": "eye_right",
|
||||
"pivot": [-2.75, 11, -3.17],
|
||||
"pivot": [-2.75, 10.75, -3.17],
|
||||
"cubes": [
|
||||
{"origin": [-3.75, 10, -3.67], "size": [2, 2, 1], "inflate": 0.01, "uv": [1, 15], "mirror": true}
|
||||
{"origin": [-3.75, 9.75, -3.67], "size": [2, 2, 1], "inflate": 0.01, "uv": [1, 15], "mirror": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+5
-15
@@ -247,9 +247,7 @@
|
||||
"pivot": [0, 8.5, 0],
|
||||
"cubes": [
|
||||
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [31, 2]},
|
||||
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [17, 30]},
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [44, 0]},
|
||||
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [21, 29]}
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [44, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -267,9 +265,7 @@
|
||||
"rotation": [0, 0, 67.5],
|
||||
"cubes": [
|
||||
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [67, 2]},
|
||||
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [49, 30]},
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [80, 0]},
|
||||
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [37, 29]}
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [80, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -279,9 +275,7 @@
|
||||
"rotation": [0, 0, -67.5],
|
||||
"cubes": [
|
||||
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [49, 2]},
|
||||
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [33, 30]},
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [62, 0]},
|
||||
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [69, 29]}
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [62, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -299,9 +293,7 @@
|
||||
"rotation": [0, 0, -137.5],
|
||||
"cubes": [
|
||||
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [85, 2]},
|
||||
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [81, 30]},
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [98, 0]},
|
||||
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [85, 29]}
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [98, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -311,9 +303,7 @@
|
||||
"rotation": [0, 0, 137.5],
|
||||
"cubes": [
|
||||
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [103, 2]},
|
||||
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [65, 30]},
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [116, 0]},
|
||||
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [53, 29]}
|
||||
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [116, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"portraitScale": 2.1,
|
||||
"portraitTranslation": [ -0.55, -1.55, 0 ],
|
||||
"profileScale": 0.80,
|
||||
"profileTranslation": [ 0, 0.55, 0 ],
|
||||
"rootBone": "caterpie",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('caterpie', 'cry')",
|
||||
"faint": "q.bedrock_primary('caterpie', 'faint', q.curve('one'))"
|
||||
},
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "FLOAT", "PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('caterpie', 'ground_idle')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('caterpie', 'blink')"]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('caterpie', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('caterpie', 'blink')"]
|
||||
},
|
||||
"swimming": {
|
||||
"poseTypes": ["WALK","SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('caterpie', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('caterpie', 'blink')"]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_stateful('dummy', 'cry')"
|
||||
},
|
||||
"animations": ["q.bedrock('caterpie', 'sleep')"]
|
||||
},
|
||||
"shoulder_left": {
|
||||
"poseTypes": ["SHOULDER_LEFT"],
|
||||
"animations": ["q.look('head')", "q.bedrock('caterpie', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('caterpie', 'blink')"],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [3, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"shoulder_right": {
|
||||
"poseTypes": ["SHOULDER_RIGHT"],
|
||||
"animations": ["q.look('head')", "q.bedrock('caterpie', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('caterpie', 'blink')"],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [-3, 0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"portraitScale": 2.3,
|
||||
"portraitTranslation": [-0.53, -1.9, 0],
|
||||
"profileScale": 0.80,
|
||||
"profileTranslation": [0, 0.51, 0],
|
||||
"rootBone": "weedle",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('weedle', 'cry')",
|
||||
"faint": "q.bedrock_primary('weedle', 'faint', q.curve('one'))"
|
||||
},
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "FLOAT", "PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('weedle', 'ground_idle2')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('weedle', 'blink')"]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('weedle', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('weedle', 'blink')"]
|
||||
},
|
||||
"swimming": {
|
||||
"poseTypes": ["WALK","SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('weedle', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('weedle', 'blink')"]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"namedAnimations": {
|
||||
"cry": "q.bedrock_stateful('dummy', 'cry')"
|
||||
},
|
||||
"animations": ["q.bedrock('weedle', 'sleep')"]
|
||||
},
|
||||
"shoulder_left": {
|
||||
"poseTypes": ["SHOULDER_LEFT"],
|
||||
"animations": ["q.look('head')", "q.bedrock('weedle', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('weedle', 'blink')"],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [3.8, 0, -3]
|
||||
}
|
||||
]
|
||||
},
|
||||
"shoulder_right": {
|
||||
"poseTypes": ["SHOULDER_RIGHT"],
|
||||
"animations": ["q.look('head')", "q.bedrock('weedle', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('weedle', 'blink')"],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [-3.8, 0, -3]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-5
@@ -7,8 +7,9 @@
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "FLOAT", "PORTRAIT", "PROFILE"],
|
||||
"condition": "q.has_entity ? !q.in_air : 1.0",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('mime_jr', 'ground_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
@@ -19,7 +20,7 @@
|
||||
"poseTypes": ["WALK", "SWIM"],
|
||||
"condition": "!q.is_sprinting",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('mime_jr', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('mime_jr', 'blink')"]
|
||||
@@ -28,7 +29,7 @@
|
||||
"poseTypes": ["WALK", "SWIM"],
|
||||
"condition": "q.is_sprinting",
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('mime_jr', 'ground_run')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('mime_jr', 'blink')"]
|
||||
@@ -36,21 +37,33 @@
|
||||
"shoulder_left": {
|
||||
"poseTypes": ["SHOULDER_LEFT"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('mime_jr', 'shoulder_left')"
|
||||
],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('mime_jr', 'blink')"
|
||||
],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, -0.25, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"shoulder_right": {
|
||||
"poseTypes": ["SHOULDER_RIGHT"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('mime_jr', 'shoulder_right')"
|
||||
],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('mime_jr', 'blink')"
|
||||
],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, -0.25, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"portraitScale": 1.13,
|
||||
"portraitTranslation": [-0.56, 1.64, 0],
|
||||
"profileScale": 0.51,
|
||||
"profileTranslation": [0, 1.05, 0],
|
||||
"rootBone": "jellicent",
|
||||
"animations": {
|
||||
"recoil": "q.bedrock_stateful('jellicent', 'recoil')"
|
||||
},
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "FLOAT", "PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('jellicent', 'water_idle')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('jellicent', 'blink')"]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"animations": [
|
||||
"q.look('head')",
|
||||
"q.bedrock('jellicent', 'water_swim')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('jellicent', 'blink')"]
|
||||
},
|
||||
"flying": {
|
||||
"poseTypes": ["FLY", "SWIM"],
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head')",
|
||||
"q.bedrock('jellicent', 'water_swim')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('jellicent', 'blink')"]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"animations": ["q.bedrock('jellicent', 'sleep')"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -55,13 +55,7 @@
|
||||
"q.look('head_ai')",
|
||||
"q.bedrock('froakie', 'water_idle')"
|
||||
],
|
||||
"quirks": [],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, -5, 0]
|
||||
}
|
||||
]
|
||||
"quirks": []
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
|
||||
+46
-6
@@ -10,8 +10,26 @@
|
||||
"recoil": "q.bedrock_stateful('greninja', 'recoil')",
|
||||
"physical": "q.bedrock_primary('greninja', 'physical', q.curve('symmetrical'))",
|
||||
"lick": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"gunkshot": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"bounce": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"thief": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"pound": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"punch": "q.bedrock_primary('greninja', 'physical_tongue', q.curve('symmetrical'))",
|
||||
"kick": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"lowkick": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"lowsweep": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"acrobatics": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"takedown": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"gigaimpact": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"liquidation": "q.bedrock_primary('greninja', 'physical_kick', q.curve('symmetrical'))",
|
||||
"cut": "q.bedrock_primary('greninja', 'physical_katana', q.curve('symmetrical'))",
|
||||
"aerialace": "q.bedrock_primary('greninja', 'physical_katana', q.curve('symmetrical'))",
|
||||
"nightslash": "q.bedrock_primary('greninja', 'physical_katana', q.curve('symmetrical'))",
|
||||
"falseswipe": "q.bedrock_primary('greninja', 'physical_katana', q.curve('symmetrical'))",
|
||||
"watershuriken_2hit": "q.bedrock_primary('greninja', 'watershuriken_2hit', q.curve('symmetrical'))",
|
||||
"watershuriken_3hit": "q.bedrock_primary('greninja', 'watershuriken_3hit', q.curve('symmetrical'))",
|
||||
"watershuriken_4hit": "q.bedrock_primary('greninja', 'watershuriken_4hit', q.curve('symmetrical'))",
|
||||
"watershuriken_5hit": "q.bedrock_primary('greninja', 'watershuriken_5hit', q.curve('symmetrical'))",
|
||||
"special": "q.bedrock_primary('greninja', 'special', q.curve('symmetrical'))",
|
||||
"status": "q.bedrock_primary('greninja', 'status', q.curve('symmetrical'))"
|
||||
},
|
||||
@@ -21,7 +39,7 @@
|
||||
"isBattle": true,
|
||||
"isTouchingWater": false,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('head_ai', -1, 1, 0, 0, 45, -45)",
|
||||
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
|
||||
"q.bedrock('greninja', 'battle_idle')"
|
||||
],
|
||||
@@ -30,14 +48,22 @@
|
||||
},
|
||||
"quirks": ["q.bedrock_quirk('greninja', 'blink')","q.bedrock_quirk('greninja','battle_quirk', 20, 40, 1)"]
|
||||
},
|
||||
"profile": {
|
||||
"poseTypes": ["PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
|
||||
"q.bedrock('greninja', 'ground_idle')"
|
||||
]
|
||||
},
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"poseTypes": ["STAND", "NONE"],
|
||||
"isBattle": false,
|
||||
"isTouchingWater": false,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
|
||||
"q.bedrock('greninja', 'ground_idle')"
|
||||
"q.bedrock('greninja', math.random(0, 1) < 0.4 ? 'ground_idle_alt' : 'ground_idle')"
|
||||
],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('greninja', q.array('quirk_look_left', 'quirk_look_right'), 8, 30, 1)"
|
||||
@@ -75,7 +101,13 @@
|
||||
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
|
||||
"q.bedrock('greninja', 'water_swim')"
|
||||
],
|
||||
"quirks": []
|
||||
"quirks": [],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, 18, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"surface-float": {
|
||||
"poseTypes": ["STAND","FLOAT"],
|
||||
@@ -97,6 +129,7 @@
|
||||
"swimming": {
|
||||
"poseTypes": ["WALK","SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": [
|
||||
"q.pitch_tilt('body')",
|
||||
"q.look('head_ai')",
|
||||
@@ -107,19 +140,26 @@
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, 24, 0]
|
||||
"position": [0, 5, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"float": {
|
||||
"poseTypes": ["STAND","FLOAT"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": [
|
||||
"q.look('head_ai')",
|
||||
"q.look('tongue1', -1, 1, 70, -45, 0, 0)",
|
||||
"q.bedrock('greninja', 'water_idle')"
|
||||
],
|
||||
"quirks": []
|
||||
"quirks": [],
|
||||
"transformedParts": [
|
||||
{
|
||||
"part": "body",
|
||||
"position": [0, 5, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"portraitScale": 1.0,
|
||||
"portraitTranslation": [-0.55, 1.65, 0],
|
||||
"profileScale": 0.3,
|
||||
"profileTranslation": [0, 1.2, 0],
|
||||
"rootBone": "crabominable",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('crabominable', 'cry')"
|
||||
},
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "FLOAT", "PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.bedrock('crabominable', 'ground_idle')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('crabominable', 'blink')"]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK", "SWIM"],
|
||||
"animations": [
|
||||
"q.bedrock('crabominable', 'ground_idle')",
|
||||
"q.bedrock('crabominable', 'ground_walk')"
|
||||
],
|
||||
"quirks": ["q.bedrock_quirk('crabominable', 'blink')"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@
|
||||
"cobblemon.ui.pc.filter.tooltip": "Format: pikachu shiny held_item lvl=1...",
|
||||
"cobblemon.ui.pc.options": "Options",
|
||||
"cobblemon.ui.pc.release": "Release",
|
||||
"cobblemon.ui.pc.release_all": "Release All",
|
||||
"cobblemon.ui.sort.name": "Sort by name",
|
||||
"cobblemon.ui.sort.level": "Sort by level",
|
||||
"cobblemon.ui.sort.pokedex_number": "Sort by Pokédex number",
|
||||
@@ -1477,22 +1478,28 @@
|
||||
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_species": "Evolves when traded with %1$s",
|
||||
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_any_species": "Evolves when traded",
|
||||
"cobblemon.ui.pokedex.evolution.shedder.tooltip": "Also requires a spare Poké Ball and an empty party slot",
|
||||
"cobblemon.ui.pokedex.evolution.or": "OR",
|
||||
"cobblemon.ui.pokedex.evolution.one_of": "One of:",
|
||||
|
||||
"cobblemon.ui.pokedex.requirement.advancement.tooltip": "Player must have %1$s advancement",
|
||||
"cobblemon.ui.pokedex.requirement.battle_critical_hits.tooltip": "Must hit %1$s critical-hits in battle",
|
||||
"cobblemon.ui.pokedex.requirement.biome.anticondition.tooltip": "Must not be in the %1$s biome to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.biome.both.tooltip": "Must be in the %1$s biome and not in the %2$s biome to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.biome.tooltip": "Must be in the %1$s biome to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.biome.anticondition.tooltip": "Must not be in the %1$s biome",
|
||||
"cobblemon.ui.pokedex.requirement.biome.both.tooltip": "Must be in the %1$s biome and not in the %2$s biome",
|
||||
"cobblemon.ui.pokedex.requirement.biome.tooltip": "Must be in the %1$s biome",
|
||||
"cobblemon.ui.pokedex.requirement.blocks_traveled.tooltip": "Must travel %1$s blocks",
|
||||
"cobblemon.ui.pokedex.requirement.damage_taken.tooltip": "Must take %1$s damage in battle without fainting",
|
||||
"cobblemon.ui.pokedex.requirement.defeat.tooltip": "Must defeat %1$s in battle to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.friendship.tooltip": "Requires at least %1$s friendship",
|
||||
"cobblemon.ui.pokedex.requirement.has_move.tooltip": "Must know move %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.has_move_type.tooltip": "Must know a move of type %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.has_move_type.tooltip": "Must know a move of %1$s type",
|
||||
"cobblemon.ui.pokedex.requirement.held_item.tooltip": "Must be holding %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.level.tooltip.min": "Evolves starting at level %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.level.tooltip.between": "Evolves between levels %1$s and %2$s",
|
||||
"cobblemon.ui.pokedex.requirement.moon_phase.tooltip": "Must evolve in %1$s moon phase",
|
||||
"cobblemon.ui.pokedex.requirement.nature.toxtricity_amped": "Must have a §aHardy§r, §aBrave§r, §aAdamant§r, §aNaughty§r, §aDocile§r, §aImpish§r, §aLax§r, §aHasty§r, §aJolly§r, §aNaive§r, §aRash§r, §aSassy§r, or §aQuirky§r nature",
|
||||
"cobblemon.ui.pokedex.requirement.nature.toxtricity_low_key": "Must have a §aLonely§r, §aBold§r, §aRelaxed§r, §aTimid§r, §aSerious§r, §aModest§r, §aMild§r, §aQuiet§r, §aBashful§r, §aCalm§r, §aGentle§r, or §aCareful§r nature",
|
||||
"cobblemon.ui.pokedex.requirement.negate.tooltip": "Not: %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.nickname.malamar": "Must be named §aDinnerbone§r or §aGrumm§r",
|
||||
"cobblemon.ui.pokedex.requirement.party_member.anticondition.tooltip": "Party must not have a Pokémon with %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.party_member.tooltip": "Party must have a Pokémon with %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.pokemon_properties.tooltip": "Must be %1$s",
|
||||
@@ -1507,9 +1514,9 @@
|
||||
"cobblemon.ui.pokedex.requirement.recoil.tooltip": "Must suffer %1$s units of recoil in battle",
|
||||
"cobblemon.ui.pokedex.requirement.stat_compare.tooltip": "Must have its %1$s higher than its %2$s",
|
||||
"cobblemon.ui.pokedex.requirement.stat_equal.tooltip": "Must have its %1$s equals to its %2$s",
|
||||
"cobblemon.ui.pokedex.requirement.structure.anticondition.tooltip": "Must not be in the %1$s structure to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.structure.both.tooltip": "Must be in the %1$s structure and not in the %2$s structure to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.structure.tooltip": "Must be in the %1$s structure to evolve",
|
||||
"cobblemon.ui.pokedex.requirement.structure.anticondition.tooltip": "Must not be in the %1$s structure",
|
||||
"cobblemon.ui.pokedex.requirement.structure.both.tooltip": "Must be in the %1$s structure and not in the %2$s structure",
|
||||
"cobblemon.ui.pokedex.requirement.structure.tooltip": "Must be in the %1$s structure",
|
||||
"cobblemon.ui.pokedex.requirement.time_range.tooltip": "Must evolve during the %1$s",
|
||||
"cobblemon.ui.pokedex.requirement.use_move.tooltip": "Must use move %1$s in battle",
|
||||
"cobblemon.ui.pokedex.requirement.weather.tooltip.raining": "Must be in rain to evolve",
|
||||
@@ -3663,6 +3670,31 @@
|
||||
"tag.item.cobblemon.tall_flowers": "Tall Flowers",
|
||||
"tag.item.cobblemon.small_flowers": "Small Flowers",
|
||||
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.bergmite_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.bergmite_kalosbiome": "Kalosian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.cubone_alolabiome": "Alolan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.cubone_kantobiome": "Kantonian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.dartrix_alolabiome": "Alolan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.dartrix_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.dewott_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.dewott_unovabiome": "Unovan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.exeggcute_alolabiome": "Alolan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.exeggcute_kantobiome": "Kantonian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.goomy_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.goomy_kalosbiome": "Kalosian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.koffing_galarbiome": "Galarian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.koffing_kantobiome": "Kantonian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.mimejr_galarbiome": "Galarian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.mimejr_sinnohbiome": "Sinnohan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.petilil_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.petilil_unovabiome": "Unovan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.pikachu_alolabiome": "Alolan",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.pikachu_kantobiome": "Kantonian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.quilava_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.quilava_johtobiome": "Johtonian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.rufflet_hisuibiome": "Hisuian",
|
||||
"tag.worldgen.biome.cobblemon.evolution.regional.rufflet_unovabiome": "Unovan",
|
||||
|
||||
"cobblemon.entity.variable.challenge_cooldown.name": "Challenge Cooldown",
|
||||
"cobblemon.entity.variable.challenge_cooldown.desc": "How long the NPC will be un-challenge-able from that player's last challenge.",
|
||||
"cobblemon.entity.variable.player_win_command.name": "Player Win Command",
|
||||
@@ -6885,12 +6917,14 @@
|
||||
"cobblemon.ui.pokedex.info.form.latios-mega": "Mega Latios",
|
||||
"cobblemon.species.latios-mega.desc": "It flies at speeds exceeding Mach 4. It is among the top tier of all Pokémon in terms of aerial combat capability.",
|
||||
"cobblemon.species.kyogre.name": "Kyogre",
|
||||
"cobblemon.ui.pokedex.info.form.kyogre": "",
|
||||
"cobblemon.species.kyogre.desc": "Kyogre is said to be the personification of the sea itself. Legends tell of its many clashes against Groudon, as each sought to gain the power of nature.",
|
||||
"cobblemon.ui.pokedex.info.form.kyogre-primal": "Primal Kyogre",
|
||||
"cobblemon.ui.pokedex.info.form.kyogre-primal": "Primal Reversion",
|
||||
"cobblemon.species.kyogre-primal.desc": "Through Primal Reversion and with nature's full power, it will take back its true form. It can summon storms that cause the sea levels to rise.",
|
||||
"cobblemon.species.groudon.name": "Groudon",
|
||||
"cobblemon.ui.pokedex.info.form.groudon": "",
|
||||
"cobblemon.species.groudon.desc": "Groudon is said to be the personification of the land itself. Legends tell of its many clashes against Kyogre, as each sought to gain the power of nature.",
|
||||
"cobblemon.ui.pokedex.info.form.groudon-primal": "Primal Groudon",
|
||||
"cobblemon.ui.pokedex.info.form.groudon-primal": "Primal Reversion",
|
||||
"cobblemon.species.groudon-primal.desc": "Through Primal Reversion and with nature's full power, it will take back its true form. It can cause magma to erupt and expand the landmass of the world.",
|
||||
"cobblemon.species.rayquaza.name": "Rayquaza",
|
||||
"cobblemon.ui.pokedex.info.form.rayquaza": "",
|
||||
@@ -7699,7 +7733,6 @@
|
||||
"cobblemon.species.spewpa.name": "Spewpa",
|
||||
"cobblemon.species.spewpa.desc": "The beaks of bird Pokémon can't begin to scratch its stalwart body. To defend itself, it spews powder.",
|
||||
"cobblemon.species.vivillon.name": "Vivillon",
|
||||
"cobblemon.ui.pokedex.info.form.vivillon": "",
|
||||
"cobblemon.species.vivillon.desc": "The patterns on this Pokémon's wings depend on the climate and topography of its habitat. It scatters colorful scales.",
|
||||
"cobblemon.ui.pokedex.info.form.vivillon-icy snow": "Icy Snow Pattern",
|
||||
"cobblemon.species.vivillon-icy-snow.desc": "The patterns on this Pokémon depend on the climate and topography of the land it was born in. This form is from frigid lands.",
|
||||
@@ -8156,11 +8189,8 @@
|
||||
"cobblemon.ui.pokedex.info.form.silvally-fairy": "Type: Fairy",
|
||||
"cobblemon.species.silvally-fairy.desc": "Thanks to its awakened powers, it can change to the Fairy type to match the memory it has equipped.",
|
||||
"cobblemon.species.minior.name": "Minior",
|
||||
"cobblemon.ui.pokedex.info.form.minior": "Core",
|
||||
"cobblemon.species.minior.desc": "This is its form when its shell has fallen off. The color of its core depends on the materials that made up the food it ate.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-meteor": "Meteor Form",
|
||||
"cobblemon.species.minior-meteor.desc": "This Pokémon is born in the ozone layer. It falls to the ground once the outer shell enclosing its core grows heavy.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-red": "Red Core",
|
||||
"cobblemon.species.minior-red.desc": "This is its form when its shell has fallen off. The color of its core depends on the materials that made up the food it ate.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-orange": "Orange Core",
|
||||
"cobblemon.species.minior-orange.desc": "This is its form when its shell has fallen off. The color of its core depends on the materials that made up the food it ate.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-yellow": "Yellow Core",
|
||||
@@ -8173,6 +8203,8 @@
|
||||
"cobblemon.species.minior-indigo.desc": "This is its form when its shell has fallen off. The color of its core depends on the materials that made up the food it ate.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-violet": "Violet Core",
|
||||
"cobblemon.species.minior-violet.desc": "This is its form when its shell has fallen off. The color of its core depends on the materials that made up the food it ate.",
|
||||
"cobblemon.ui.pokedex.info.form.minior-meteor": "Meteor Form",
|
||||
"cobblemon.species.minior-meteor.desc": "This Pokémon is born in the ozone layer. It falls to the ground once the outer shell enclosing its core grows heavy.",
|
||||
"cobblemon.species.komala.name": "Komala",
|
||||
"cobblemon.species.komala.desc": "It remains asleep from birth to death as a result of the sedative properties of the leaves that form its diet.",
|
||||
"cobblemon.species.turtonator.name": "Turtonator",
|
||||
|
||||
@@ -5094,9 +5094,9 @@
|
||||
"cobblemon.species.trevenant.name": "Desséliande",
|
||||
"cobblemon.species.trevenant.desc": "Ses racines sont un véritable système nerveux qui lui permet de contrôler les arbres de la forêt. Il se montre très gentil envers les Pokémon vivant dans son écorce.",
|
||||
"cobblemon.species.pumpkaboo.name": "Pitrouille",
|
||||
"cobblemon.species.pumpkaboo.desc": "Il paraît qu'il accompagne les âmes des défunts jusque dans l'au-delà, pour qu'elles puissent goûter au repos éternel.",
|
||||
"cobblemon.species.pumpkaboo.desc": "Il a été confirmé récemment que chaque variété se distingue non seulement par sa taille, mais également par celle des âmes qu'elle enlève.",
|
||||
"cobblemon.species.gourgeist.name": "Banshitrouye",
|
||||
"cobblemon.species.gourgeist.desc": "Il enserre ses proies dans ses bras, semblables à de longues mèches de cheveux. Il se délecte de leur souffrance en chantonnant gaiement.",
|
||||
"cobblemon.species.gourgeist.desc": "Les nuits de nouvelle lune, ce Pokémon erre dans les rues en chantant d'une voix lugubre. Ceux qui l'entendent sont maudits.",
|
||||
"cobblemon.species.bergmite.name": "Grelaçon",
|
||||
"cobblemon.species.bergmite.desc": "Il gèle ses ennemis d'une bourrasque à -100 °C. Il vit en troupeau avec ses congénères, dans les neiges éternelles des hautes montagnes.",
|
||||
"cobblemon.species.avalugg.name": "Séracrawl",
|
||||
@@ -5220,7 +5220,7 @@
|
||||
"cobblemon.species.typenull.name": "Type:0",
|
||||
"cobblemon.species.typenull.desc": "On lui fait porter un masque qui limite sa puissance afin d'éviter qu'il n'en perde le contrôle et sème le chaos.",
|
||||
"cobblemon.species.silvally.name": "Silvallié",
|
||||
"cobblemon.species.silvally.desc": "Il a réussi à briser son masque grâce à la force mentale qu'il a acquise en établissant un lien puissant avec son Dresseur.",
|
||||
"cobblemon.species.silvally.desc": "Un lien fort avec son Dresseur lui a permis de libérer tout son potentiel.",
|
||||
"cobblemon.species.minior.name": "Météno",
|
||||
"cobblemon.species.minior.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
"cobblemon.species.komala.name": "Dodoala",
|
||||
@@ -5452,9 +5452,9 @@
|
||||
"cobblemon.species.zacian.name": "Zacian",
|
||||
"cobblemon.species.zacian.desc": "Également surnommé « héros légendaire », ce Pokémon absorbe du métal et se change en arme pour se battre.",
|
||||
"cobblemon.species.zamazenta.name": "Zamazenta",
|
||||
"cobblemon.species.zamazenta.desc": "Ce Pokémon sauva autrefois Galar en joignant ses forces à celles du roi des Hommes. Il absorbe du métal quand il passe au combat.",
|
||||
"cobblemon.species.zamazenta.desc": "Ce Pokémon, changé en statue, est resté pétrifié si longtemps qu'il a failli tomber dans l'oubli.",
|
||||
"cobblemon.species.eternatus.name": "Éthernatos",
|
||||
"cobblemon.species.eternatus.desc": "Il devient actif en absorbant l'énergie qui émerge du sol de Galar grâce au noyau situé sur sa poitrine.",
|
||||
"cobblemon.species.eternatus.desc": "Il se trouvait dans une météorite qui s'est écrasée il y a 20 000 ans. Il semble y avoir un lien entre ce Pokémon et le phénomène Dynamax.",
|
||||
"cobblemon.species.kubfu.name": "Wushours",
|
||||
"cobblemon.species.kubfu.desc": "Il suit un entraînement rigoureux pour parfaire ses techniques. La forme de son évolution dépend des capacités qu'il a assimilées.",
|
||||
"cobblemon.species.urshifu.name": "Shifours",
|
||||
@@ -5697,7 +5697,7 @@
|
||||
"item.cobblemon.strawberry_sweet.tooltip": "Évolue Crèmy en Charmilly avec une Fraise en Sucre",
|
||||
"item.cobblemon.clover_sweet.tooltip": "Évolue Crèmy en Charmilly avec un Trèfle en Sucre",
|
||||
"item.cobblemon.galarica_cuff.tooltip": "Évolue Ramoloss de Galar en Flagadoss de Galar",
|
||||
"item.cobblemon.link_cable.tooltip": "Évolue les Pokémon nécessitant un échange",
|
||||
"item.cobblemon.link_cable.tooltip": "Permet d'évoluer un Pokémon nécessitant un échange",
|
||||
"item.cobblemon.reaper_cloth.tooltip": "Évolue Téraclope en Noctunoir lorsque tenu lors d'un échange",
|
||||
"item.cobblemon.star_sweet.tooltip": "Évolue Crèmy en Charmilly avec une Étoile en Sucre",
|
||||
"cobblemon.config.ui.experience_share_multiplier.tooltip": "Multiplicateur de la part d'Expérience totale accordée à un Pokémon détenant un Multi Exp.",
|
||||
@@ -6090,7 +6090,7 @@
|
||||
"cobblemon.species.arceus-water.desc": "Dans la mythologie, ce Pokémon existait déjà avant la formation de l'univers.",
|
||||
"cobblemon.species.arceus-psychic.desc": "Dans la mythologie, ce Pokémon existait déjà avant la formation de l'univers.",
|
||||
"cobblemon.species.vivillon-garden.desc": "Ses motifs varient selon la topographie et le climat de l'endroit où il naît. Cette forme est originaire de terres verdoyantes.",
|
||||
"cobblemon.species.genesect-fire.desc": "En cours de recherche.",
|
||||
"cobblemon.species.genesect-fire.desc": "Ce Pokémon prend cette forme quand on l'équipe d'un module chargé en énergie de type Feu. Il dispose de griffes d'acier tranchantes.",
|
||||
"cobblemon.species.vivillon-tundra.desc": "Ses motifs varient selon la topographie et le climat de l'endroit où il naît. Cette forme est originaire de terres glaciales.",
|
||||
"cobblemon.species.vivillon-monsoon.desc": "Ses motifs varient selon la topographie et le climat de l'endroit où il naît. Cette forme est originaire de terres où s'abattent des pluies diluviennes.",
|
||||
"cobblemon.species.vivillon-modern.desc": "Ses motifs varient selon la topographie et le climat de l'endroit où il naît. Cette forme est originaire de terres très ensoleillées.",
|
||||
@@ -6140,8 +6140,8 @@
|
||||
"cobblemon.species.slowpoke-galar.desc": "Bien qu'il ait toujours l'air un peu absent, il arrive que son visage se crispe brusquement. Son alimentation serait à l'origine du phénomène.",
|
||||
"cobblemon.species.slowbro-mega.desc": "Il est complètement enveloppé dans le Kokiyas, qui forme un cocon impénétrable, mais somme toute plutôt confortable.",
|
||||
"cobblemon.species.slowbro-galar.desc": "Le stimulus de la morsure du Kokiyas a déclenché une réaction chimique des épices retenues dans le corps de Flagadoss, lui donnant le type Poison.",
|
||||
"cobblemon.species.farfetchd-galar.desc": "Les Canarticho ont pris cette forme à force de manier les poireaux de Galar, qui sont plus longs et plus larges que ceux des autres régions.",
|
||||
"cobblemon.species.grimer-alola.desc": "Ce glouton, capable de dévorer tout et n'importe quoi, a été introduit à Alola pour résoudre les problèmes de déchets.",
|
||||
"cobblemon.species.farfetchd-galar.desc": "À force de soulever son poireau lourd et massif, il a musclé son corps. Il compte sur la puissance destructrice d'une seule frappe pour gagner.",
|
||||
"cobblemon.species.grimer-alola.desc": "Les cristaux sur son corps sont des agrégats de toxines. S'ils se détachent, des poisons mortels commencent à se répandre.",
|
||||
"cobblemon.species.muk-alola.desc": "Ses crocs et ses griffes sont des toxines cristallisées. Il gangrène tout ce qu'il touche, alors n'approchez pas trop près.",
|
||||
"cobblemon.species.gengar-mega.desc": "Grâce à la Méga-Évolution, il a accès à une autre dimension. Son corps déborde de puissance occulte.",
|
||||
"cobblemon.species.gengar-gmax.desc": "Son corps est rempli d'énergie négative. Sa bouche gigantesque est un portail qui débouche sur l'autre monde.",
|
||||
@@ -6190,7 +6190,7 @@
|
||||
"cobblemon.species.unown-w.desc": "Ce Pokémon a la forme d'un caractère d'écriture antique. Personne ne sait si ces écritures antiques sont apparues avant les Zarbi ou le contraire. Des études sont en cours, mais aucun résultat n'a été annoncé.",
|
||||
"cobblemon.species.unown-y.desc": "Ce Pokémon a la forme d'un caractère d'écriture antique. Personne ne sait si ces écritures antiques sont apparues avant les Zarbi ou le contraire. Des études sont en cours, mais aucun résultat n'a été annoncé.",
|
||||
"cobblemon.species.unown-z.desc": "Ce Pokémon a la forme d'un caractère d'écriture antique. Personne ne sait si ces écritures antiques sont apparues avant les Zarbi ou le contraire. Des études sont en cours, mais aucun résultat n'a été annoncé.",
|
||||
"cobblemon.species.steelix-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.steelix-mega.desc": "Il contrôle par magnétisme les fragments qui se sont détachés de la surface de son corps et s'en sert pour parer les attaques.",
|
||||
"cobblemon.species.qwilfish-hisui.desc": "Il vit dans l'eau près des côtes froides. Ses épines empoisonnées sont plus épaisses et plus courtes que celle des Qwilfish des autres régions.",
|
||||
"cobblemon.species.scizor-mega.desc": "Ses pinces lui servent davantage à frapper qu'à couper. Elles sont si lourdes qu'il lui est difficile de tenir quand le combat s'éternise.",
|
||||
"cobblemon.species.heracross-mega.desc": "Le flot d'énergie décuple ses muscles, mais lui donne de terribles courbatures après avoir retrouvé sa forme d'origine.",
|
||||
@@ -6198,20 +6198,20 @@
|
||||
"cobblemon.species.corsola-galar.desc": "Il s'agit d'un Corayon mort il y a longtemps à cause d'un changement brutal de l'environnement. Il vole l'essence vitale des gens avec ses branches.",
|
||||
"cobblemon.species.houndoom-mega.desc": "Son corps tout entier devient fiévreux lors de la Méga-Évolution. Il réduit ses adversaires en cendres avec son souffle enflammé.",
|
||||
"cobblemon.species.tyranitar-mega.desc": "Il est encore plus violent en méga-évoluant, à tel point que l'on se demande s'il entend toujours les ordres de son Dresseur.",
|
||||
"cobblemon.species.sceptile-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.blaziken-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.swampert-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.sceptile-mega.desc": "Pour projeter le bout de sa queue, il fait exploser les graines situées sur son dos, qui sont chargées de l'énergie de la Méga-Évolution.",
|
||||
"cobblemon.species.blaziken-mega.desc": "Grâce au sang bouillant qui coule dans ses veines, ses techniques sont deux fois plus précises. Il soumet ses ennemis en un clin d'œil.",
|
||||
"cobblemon.species.swampert-mega.desc": "En utilisant le même principe qu'une pompe hydraulique, l'eau dans son corps renforce encore plus ses muscles déjà considérablement gonflés.",
|
||||
"cobblemon.species.zigzagoon-galar.desc": "Il court partout sans s'arrêter. Quand il rencontre un autre Pokémon, il fait exprès de lui rentrer dedans pour le provoquer.",
|
||||
"cobblemon.species.linoone-galar.desc": "Il provoque ses adversaires avec sa longue langue pour les mettre en colère avant de les plaquer au sol avec un puissant tacle.",
|
||||
"cobblemon.species.gardevoir-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.gardevoir-mega.desc": "Lorsqu'il déploie les plaques rouges sur sa poitrine et libère son esprit, il est capable de déchaîner ses plus grands pouvoirs psychiques.",
|
||||
"cobblemon.species.sableye-mega.desc": "Son joyau est devenu immense et très lourd. Il lui permet de se protéger contre toute attaque, mais ralentit beaucoup ses mouvements.",
|
||||
"cobblemon.species.mawile-mega.desc": "Ses deux gueules bougent violemment, comme mues par leur propre volonté. Elles peuvent pulvériser un rocher d'un seul claquement.",
|
||||
"cobblemon.species.aggron-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.medicham-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.aggron-mega.desc": "L'énergie de la Méga-Évolution a transformé le fer dans l'organisme de ce Pokémon en une armure d'acier qui couvre tout son corps.",
|
||||
"cobblemon.species.medicham-mega.desc": "Grâce à la Méga-Évolution, sa force spirituelle n'a plus de limites. Il matérialise des bras maléfiques par la pensée pour terrasser ses adversaires.",
|
||||
"cobblemon.species.manectric-mega.desc": "L'électricité accumulée dans son corps lui permet de se déplacer à la vitesse de l'éclair, mais elle le rend aussi colérique.",
|
||||
"cobblemon.species.sharpedo-mega.desc": "Quand il charge, des pics acérés surgissent sur sa tête ; il s'en sert pour blesser gravement ses adversaires.",
|
||||
"cobblemon.species.camerupt-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.altaria-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.camerupt-mega.desc": "Quand sa colère atteint un point critique, l'immense volcan sur son dos entre en violente éruption et projette de la lave.",
|
||||
"cobblemon.species.altaria-mega.desc": "Ses douces plumes si fragiles en apparence sont tellement robustes qu'une poignée suffit pour hisser un camion-benne.",
|
||||
"cobblemon.species.castform-rainy.desc": "Morphéo adopte cette apparence uniquement les jours de pluie. On a tenté de reproduire ce phénomène sous une douche, sans succès.",
|
||||
"cobblemon.species.castform-sunny.desc": "Morphéo adopte cette apparence uniquement les jours ensoleillés. On a tenté de reproduire ce phénomène avec un radiateur, sans succès.",
|
||||
"cobblemon.species.castform-snowy.desc": "Morphéo adopte cette apparence uniquement les jours enneigés. On a tenté de reproduire ce phénomène avec un congélateur, sans succès.",
|
||||
@@ -6220,14 +6220,14 @@
|
||||
"cobblemon.species.absol-mega.desc": "L'énergie de la Méga-Évolution a fait se hérisser tous les poils de son corps. Comme il ne s'agit pas d'ailes, il ne peut pas voler.",
|
||||
"cobblemon.species.salamence-mega.desc": "Il se met en position de vol en rangeant ses pattes avant dans sa carapace, et fonce en rase-mottes au-dessus des terrains accidentés.",
|
||||
"cobblemon.species.metagross-mega.desc": "Quand il voit qu'il ne peut pas gagner, il attrape son adversaire avec ses griffes et lance le compte à rebours avant explosion.",
|
||||
"cobblemon.species.latias-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.latios-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.latias-mega.desc": "Ses prouesses en vol et sa puissance de frappe se sont renforcées. Il disperse ses plumes transparentes pour perturber ses adversaires.",
|
||||
"cobblemon.species.latios-mega.desc": "Il vole à une vitesse dépassant Mach 4. Il compte parmi les Pokémon les plus doués en combat aérien.",
|
||||
"cobblemon.species.kyogre-primal.desc": "Grâce à l'énergie de la nature, il peut accomplir sa Primo-Résurgence pour retrouver son apparence originelle. Ce pouvoir lui permet d'appeler de terribles déluges pour étendre les mers.",
|
||||
"cobblemon.species.groudon-primal.desc": "Grâce à l'énergie de la nature, il peut accomplir sa Primo-Résurgence pour retrouver son apparence originelle. Ce pouvoir lui permet de créer du magma pour étendre les continents.",
|
||||
"cobblemon.species.rayquaza-mega.desc": "Un Pokémon qui vit dans la couche d'ozone et se nourrit des météorites qu'il intercepte. Leur énergie s'accumule dans son corps, ce qui lui permet de méga-évoluer.",
|
||||
"cobblemon.species.deoxys-attack.desc": "En cours de recherche.",
|
||||
"cobblemon.species.deoxys-defense.desc": "En cours de recherche.",
|
||||
"cobblemon.species.deoxys-speed.desc": "En cours de recherche.",
|
||||
"cobblemon.species.deoxys-attack.desc": "Deoxys a choisi lui-même d'avoir cette apparence agressive. Il trompe ses ennemis en changeant de forme à volonté.",
|
||||
"cobblemon.species.deoxys-defense.desc": "Une aurore apparaît quand il change de forme. Il absorbe les attaques en altérant sa structure cellulaire.",
|
||||
"cobblemon.species.deoxys-speed.desc": "Il est le résultat de la mutation d'un virus extraterrestre exposé à un rayon laser. Sa structure corporelle lui confère une agilité et une vitesse supérieures.",
|
||||
"cobblemon.species.burmy-sandy.desc": "Il pétrit du sable et de la boue avec les fils de soie qu'il génère pour se confectionner une cape. Mais le vent et la pluie pouvant abimer celle-ci, Cheniti se cache dans les crevasses et les grottes.",
|
||||
"cobblemon.species.burmy-trash.desc": "Lorsqu'il ne trouve pas de matière première adéquate pour confectionner sa cape, il utilise des détritus. Sa cape est d'ailleurs bien plus douillette qu'elle n'y parait.",
|
||||
"cobblemon.species.wormadam-sandy.desc": "Son épiderme de sable et de boue très solide peut aisément repousser les coups de bec des Étourmi.",
|
||||
@@ -6238,8 +6238,8 @@
|
||||
"cobblemon.species.lopunny-mega.desc": "Ce Pokémon au tempérament violent se sert de ses oreilles comme s'il s'agissait de fouets pour corriger ses adversaires.",
|
||||
"cobblemon.species.garchomp-mega.desc": "La Méga-Évolution l'a rendu plus brutal. Il taille en pièces ses ennemis à l'aide de ses bras en forme de faux.",
|
||||
"cobblemon.species.lucario-mega.desc": "Son instinct guerrier s'est réveillé après son exposition à une explosion d'énergie. Il n'a absolument aucune pitié pour ses ennemis.",
|
||||
"cobblemon.species.abomasnow-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.gallade-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.abomasnow-mega.desc": "Les bourgeons sur son dos ont donné naissance à d'imposantes épines de glace qui déclenchent des blizzards à −30 °C.",
|
||||
"cobblemon.species.gallade-mega.desc": "Il tire sa force du lien qui l'unit à son Dresseur ou à sa Dresseuse. Son corps s'est doté de plaques tranchantes et d'une cape protectrice.",
|
||||
"cobblemon.species.rotom-heat.desc": "Sous cette forme, Motisma adore utiliser la chaleur pour faire des bêtises, comme brûler les vêtements favoris des gens.",
|
||||
"cobblemon.species.rotom-wash.desc": "Sous cette forme, Motisma adore utiliser de l'eau pour faire des bêtises, comme complètement inonder les pièces à vivre.",
|
||||
"cobblemon.species.rotom-frost.desc": "Sous cette forme, Motisma adore utiliser l'air froid pour faire des bêtises, comme geler le bain chaud d'une personne avant qu'elle n'y mette le pied.",
|
||||
@@ -6263,7 +6263,7 @@
|
||||
"cobblemon.species.arceus-dragon.desc": "Dans la mythologie, ce Pokémon existait déjà avant la formation de l'univers.",
|
||||
"cobblemon.species.arceus-dark.desc": "Dans la mythologie, ce Pokémon existait déjà avant la formation de l'univers.",
|
||||
"cobblemon.species.samurott-hisui.desc": "Cette fine lame au tempérament impitoyable est une évolution rare qui ne se produit qu'à Hisui. Ses attaques sont aussi ravageuses que les vagues déferlantes.",
|
||||
"cobblemon.species.audino-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.audino-mega.desc": "Deux antennes ont poussé au cou de ce Pokémon. Il suffit de les toucher pour se retrouver plongé dans un profond sommeil.",
|
||||
"cobblemon.species.lilligant-hisui.desc": "Ce Pokémon doit ses jambes musclées à son habitat dans les montagnes couvertes de neige épaisse. La fleur sur sa couronne exhale un parfum stimulant tout être alentour.",
|
||||
"cobblemon.species.basculin-bluestriped.desc": "Ils forment des bancs entre spécimens de même couleur. Leurs plus grands ennemis sont les Bargantua rouges.",
|
||||
"cobblemon.species.basculin-white.desc": "Ces Pokémon vivent en bancs dans les océans glacés et se partagent la nourriture. Quand le temps est venu, ils retournent à leur fleuve natal.",
|
||||
@@ -6289,10 +6289,10 @@
|
||||
"cobblemon.species.kyurem-white.desc": "Il prédit un futur où humains et Pokémon vivront dans un monde où la Réalité prévaut. Il fait tout son possible pour protéger cet avenir.",
|
||||
"cobblemon.species.kyurem-black.desc": "On dit qu'il se bat pour défendre un monde Idéal dans lequel Pokémon et humains cohabiteront.",
|
||||
"cobblemon.species.keldeo-resolute.desc": "Le pouvoir qui sommeillait au plus profond de lui s'est concentré dans sa corne, qui est devenue une lame capable de fendre n'importe quoi.",
|
||||
"cobblemon.species.meloetta-pirouette.desc": "En cours de recherche.",
|
||||
"cobblemon.species.genesect-water.desc": "En cours de recherche.",
|
||||
"cobblemon.species.genesect-electric.desc": "En cours de recherche.",
|
||||
"cobblemon.species.genesect-ice.desc": "En cours de recherche.",
|
||||
"cobblemon.species.meloetta-pirouette.desc": "Meloetta a retrouvé un chant qui fut longtemps oublié. Ses pas de danse envoûtants peuvent prendre n'importe qui au piège.",
|
||||
"cobblemon.species.genesect-water.desc": "Ce Pokémon prend cette forme quand on l'équipe d'un module chargé en énergie de type Eau. Il peut se transformer pour voler.",
|
||||
"cobblemon.species.genesect-electric.desc": "Ce Pokémon prend cette forme quand on l'équipe d'un module chargé en énergie de type Électrik. Il peut tirer des boules d'énergie.",
|
||||
"cobblemon.species.genesect-ice.desc": "Ce Pokémon prend cette forme quand on l'équipe d'un module chargé en énergie de type Glace. Il n'éprouve alors plus aucune compassion.",
|
||||
"cobblemon.species.greninja-bond.desc": "En cours de recherche.",
|
||||
"cobblemon.species.greninja-ash.desc": "En cours de recherche.",
|
||||
"cobblemon.species.vivillon-polar.desc": "Ses motifs varient selon la topographie et le climat de l'endroit où il naît. Cette forme est originaire de terres enneigées.",
|
||||
@@ -6331,10 +6331,10 @@
|
||||
"cobblemon.species.furfrou-pharaoh.desc": "Il fut un temps où la noblesse organisait des concours pour déterminer quel Couafarel arborait la plus belle coupe.",
|
||||
"cobblemon.species.meowstic-f.desc": "Les femelles sont un peu plus agressives et égoïstes que les mâles. Quand elles sont fâchées, elles se vengent avec leurs pouvoirs psychiques.",
|
||||
"cobblemon.species.aegislash-blade.desc": "Sous cette forme, il excelle en attaque. Il utilise le poids et la puissance de l'acier pour détruire ses adversaires.",
|
||||
"cobblemon.species.silvally-ghost.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-fire.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-electric.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-dragon.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-ghost.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Spectre grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-fire.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Feu grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-electric.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Électrik grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-dragon.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Dragon grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.minior-yellow.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
"cobblemon.species.minior-meteor.desc": "Ce Pokémon vient de la couche d'ozone. Il s'écrase parfois au sol, lorsque la carapace qui enveloppe son noyau devient trop lourde.",
|
||||
"cobblemon.species.minior-indigo.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
@@ -6370,21 +6370,21 @@
|
||||
"cobblemon.species.klawf.desc": "Il se poste la tête en bas sur une falaise, dans l'attente d'une proie, mais il ne peut pas rester longtemps ainsi, car le sang lui monte à la tête.",
|
||||
"cobblemon.species.wiglett.desc": "Il détecte l'odeur de Délestin à plus de vingt mètres, ce qui lui donne le temps de s'enfouir dans le sable.",
|
||||
"cobblemon.species.flamigo.desc": "On pense qu'il fait un nœud à la base de son cou afin d'empêcher l'énergie qu'il accumule dans son ventre de s'échapper par son bec.",
|
||||
"cobblemon.species.sliggoo-hisui.desc": "Ce Pokémon est de nature plutôt mélancolique. Le fer contenu dans les eaux de Hisui a agi sur son mucus épidermique et a changé sa peau en carapace de métal.",
|
||||
"cobblemon.species.sliggoo-hisui.desc": "Sa coquille est devenue métallique en raison du fer contenu dans l'eau qu'il boit. Il n'en sort jamais lorsque le soleil brille.",
|
||||
"cobblemon.species.goodra-hisui.desc": "Il peut moduler la rigidité de sa carapace de métal à volonté. Il abhorre la solitude et enrage si un être qu'il affectionne profondément l'abandonne.",
|
||||
"cobblemon.species.pumpkaboo-small.desc": "Les Pitrouille Taille Mini aiment emporter l'âme des enfants vers l'au-delà.",
|
||||
"cobblemon.species.pumpkaboo-large.desc": "Les Pitrouille Taille Maxi aiment emporter l'âme des adultes vers l'au-delà.",
|
||||
"cobblemon.species.pumpkaboo-super.desc": "Les Pitrouille Taille Ultra adorent les esprits humains de très grande taille.",
|
||||
"cobblemon.species.pumpkaboo-small.desc": "Cette variété emmène vers l'au-delà les âmes des enfants, dont la petite taille correspond à celle de son propre corps.",
|
||||
"cobblemon.species.pumpkaboo-large.desc": "Cette variété emmène vers l'au-delà les âmes des adultes, dont la grande taille correspond à celle de son propre corps.",
|
||||
"cobblemon.species.pumpkaboo-super.desc": "Cette variété emmène vers l'au-delà les âmes gigantesques, dont la taille correspond à celle de son propre corps.",
|
||||
"cobblemon.species.gourgeist-small.desc": "Les Banshitrouye Taille Mini revêtent la forme d'enfants pour tromper les adultes et les emmener vers l'au-delà.",
|
||||
"cobblemon.species.gourgeist-large.desc": "Les Banshitrouye Taille Maxi revêtent la forme d'adultes et prennent la main des enfants pour les emmener vers l'au-delà.",
|
||||
"cobblemon.species.gourgeist-super.desc": "Les Banshitrouye Taille Ultra emmèneront de force n'importe qui vers l'au-delà, peu importe leur âge.",
|
||||
"cobblemon.species.gourgeist-super.desc": "Les Banshitrouye gigantesques sont capables d'emmener n'importe qui de force vers l'au-delà.",
|
||||
"cobblemon.species.avalugg-hisui.desc": "L'armure de glace qui enveloppe sa mâchoire inférieure peut briser des rocs plus durs que l'acier. Il se meut vélocement en fendant la neige épaisse des chemins de montagne.",
|
||||
"cobblemon.species.xerneas-active.desc": "D'après la légende, quand ses bois brillent de sept couleurs, cela signifie qu'il prodigue la vie éternelle.",
|
||||
"cobblemon.species.zygarde-10.desc": "La forme que Zygarde prend lorsqu'il rassemble 10% de ses Cellules éparpillées un peu partout. Il excelle au combat au corps-à-corps.",
|
||||
"cobblemon.species.zygarde-10c.desc": "La forme que Zygarde prend lorsqu'il rassemble 10% de ses Cellules éparpillées un peu partout. Il excelle au combat au corps-à-corps.",
|
||||
"cobblemon.species.zygarde-complete.desc": "La forme que Zygarde prend lorsqu'il rassemble 100% de ses Cellules. Sa puissance dépasse même celle de Xerneas ou d'Yveltal.",
|
||||
"cobblemon.species.zygarde-50c.desc": "La forme que Zygarde prend lorsqu'il rassemble 50% de ses Cellules. Sa mission est de surveiller l'écosystème.",
|
||||
"cobblemon.species.diancie-mega.desc": "En cours de recherche.",
|
||||
"cobblemon.species.diancie-mega.desc": "On l'appelle aussi « la princesse rose de l'élégance ». Le diamant resplendissant qui orne son front pèse pas moins de 2 000 carats.",
|
||||
"cobblemon.species.hoopa-unbound.desc": "Il possède une puissance considérable sous son apparence véritable. Une légende raconte qu'il désirait si fort un trésor caché dans un château qu'il déroba l'édifice tout entier.",
|
||||
"cobblemon.species.decidueye-hisui.desc": "Les plumes d'Archéduc le protègent de la froideur glaciale de Hisui grâce à l'air logé dans leur tige. Voici une preuve que l'environnement agit sur l'évolution des Pokémon.",
|
||||
"cobblemon.species.oricorio-pompom.desc": "Un Plumeline ayant bu du Nectar Jaune. Quand il aperçoit quelqu'un qui a une baisse de tension, il danse pour lui remonter le moral.",
|
||||
@@ -6394,19 +6394,19 @@
|
||||
"cobblemon.species.lycanroc-midnight.desc": "Cet habitué à la vie en solitaire n'obéit qu'aux Dresseurs qui savent exploiter tout le potentiel de sa force.",
|
||||
"cobblemon.species.lycanroc-dusk.desc": "Ce Lougaroc a subi une évolution spéciale en étant irradié par les rayons du soleil couchant. Son calme cache une combativité hors norme.",
|
||||
"cobblemon.species.wishiwashi-school.desc": "On l'appelle « le démon des mers ». Quand trop de Froussardine tombent sous les coups de l'ennemi, le banc reprend une activité normale.",
|
||||
"cobblemon.species.silvally-fighting.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-flying.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-poison.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-ground.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-rock.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-bug.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-steel.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-water.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-grass.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-psychic.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-ice.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-dark.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-fairy.desc": "Il a enfin libéré tout son pouvoir et peut changer de type à volonté. L'énergie qui afflue en lui le fait briller d'une lueur argentée.",
|
||||
"cobblemon.species.silvally-fighting.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Combat grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-flying.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Vol grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-poison.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Poison grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-ground.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Sol grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-rock.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Roche grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-bug.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Insecte grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-steel.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Acier grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-water.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Eau grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-grass.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Plante grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-psychic.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Psy grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-ice.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Glace grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-dark.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Ténèbres grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.silvally-fairy.desc": "Maintenant que son potentiel s'est éveillé, il peut adopter le type Fée grâce à la ROM dont il est équipé.",
|
||||
"cobblemon.species.minior-orange.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
"cobblemon.species.minior-green.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
"cobblemon.species.minior-blue.desc": "Météno se présente sous cette forme quand il perd sa carapace. La couleur de son noyau varie en fonction des composants de sa nourriture.",
|
||||
@@ -6807,13 +6807,13 @@
|
||||
"cobblemon.mark.ribbon_contest_super_master_cleverness": "Ruban Maître Intelligence",
|
||||
"cobblemon.mark.ribbon_contest_super_master_cleverness.title": "%1$s le Génie",
|
||||
"cobblemon.mark.ribbon_contest_super_master_coolness": "Ruban Maître Sang-froid",
|
||||
"cobblemon.mark.ribbon_contest_super_master_coolness.title": "%1$s l'Ancienne Star",
|
||||
"cobblemon.mark.ribbon_contest_super_master_coolness.title": "%1$s la Star",
|
||||
"cobblemon.mark.ribbon_contest_super_master_coolness.desc": "Ruban commémorant une incroyable démonstration de Sang-froid durant un concours.",
|
||||
"cobblemon.mark.ribbon_contest_super_master_cuteness": "Ruban Maître Grâce",
|
||||
"cobblemon.mark.ribbon_contest_super_master_cuteness.title": "%1$s la Grâce Incarnée",
|
||||
"cobblemon.mark.ribbon_contest_super_master_cuteness.desc": "Ruban commémorant une incroyable démonstration de Grâce durant un concours.",
|
||||
"cobblemon.mark.ribbon_contest_super_master_toughness": "Ruban Maître Robustesse",
|
||||
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "%1$s l'Ancien Gros Dur",
|
||||
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "%1$s le Gros Dur",
|
||||
"cobblemon.mark.ribbon_contest_super_master_toughness.desc": "Ruban commémorant une incroyable démonstration de Robustesse durant un concours.",
|
||||
"cobblemon.mark.ribbon_contest_super_star": "Ruban Star des Concours",
|
||||
"cobblemon.mark.ribbon_contest_super_star.title": "%1$s la Star de Légende",
|
||||
@@ -6830,7 +6830,7 @@
|
||||
"cobblemon.mark.ribbon_event_special.desc": "Ruban spécial pour un jour très particulier.",
|
||||
"cobblemon.mark.ribbon_event_mystery_zone_sky": "Ruban Ciel",
|
||||
"cobblemon.mark.ribbon_event_color_blue.desc": "Ruban commémoratif.",
|
||||
"cobblemon.mark.mark_titan.desc": "L'insigne d'un ancien Pokémon Dominant.",
|
||||
"cobblemon.mark.mark_titan.desc": "L'insigne d'un Pokémon Dominant.",
|
||||
"cobblemon.mark.mark_personality_kindly.desc": "L'insigne d'un Pokémon bienveillant.",
|
||||
"cobblemon.mark.mark_personality_slump.desc": "L'insigne d'un Pokémon blessé.",
|
||||
"cobblemon.mark.ribbon_master_rank.desc": "Ruban commémorant la victoire contre un Dresseur de niveau Master Ball en combat classé.",
|
||||
@@ -6947,8 +6947,8 @@
|
||||
"cobblemon.mark.ribbon_training": "Ruban Perfectionnement",
|
||||
"cobblemon.mark.ribbon_training.title": "%1$s le Surentraîné",
|
||||
"cobblemon.mark.mark_alpha": "Insigne Baron",
|
||||
"cobblemon.mark.mark_alpha.title": "%1$s l'Ancien Baron",
|
||||
"cobblemon.mark.mark_alpha.desc": "L'insigne d'un ancien Pokémon Baron.",
|
||||
"cobblemon.mark.mark_alpha.title": "%1$s le Baron",
|
||||
"cobblemon.mark.mark_alpha.desc": "L'insigne d'un Pokémon Baron.",
|
||||
"cobblemon.mark.mark_curry": "Insigne Curry",
|
||||
"cobblemon.mark.mark_curry.title": "%1$s le Gastronome",
|
||||
"cobblemon.mark.mark_curry.desc": "L'insigne d'un Pokémon gastronome.",
|
||||
@@ -6982,7 +6982,7 @@
|
||||
"cobblemon.mark.mark_revival.title": "%1$s le Ressuscité",
|
||||
"cobblemon.mark.mark_revival.desc": "L'insigne d'un Pokémon ressuscité.",
|
||||
"cobblemon.mark.mark_titan": "Insigne Dominant",
|
||||
"cobblemon.mark.mark_titan.title": "%1$s l'Ancien Dominant",
|
||||
"cobblemon.mark.mark_titan.title": "%1$s le Dominant",
|
||||
"cobblemon.mark.mark_uncommon": "Insigne Sociabilité",
|
||||
"cobblemon.mark.mark_uncommon.title": "%1$s le Sociable",
|
||||
"cobblemon.mark.mark_uncommon.desc": "L'insigne d'un Pokémon sociable.",
|
||||
@@ -7339,9 +7339,9 @@
|
||||
"cobblemon.ui.pokedex.info.form.pinsir": " ",
|
||||
"cobblemon.ui.pokedex.info.form.pinsir-mega": "Méga-Scarabrute",
|
||||
"cobblemon.ui.pokedex.info.form.tauros": " ",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeacombat": "Race Combative (Paldea)",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeablaze": "Race Flamboyante (Paldea)",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeaaqua": "Race Aquatique (Paldea)",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeacombat": "Forme de Paldea (Race Combative)",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeablaze": "Forme de Paldea (Race Flamboyante)",
|
||||
"cobblemon.ui.pokedex.info.form.tauros-paldeaaqua": "Forme de Paldea (Race Aquatique)",
|
||||
"cobblemon.ui.pokedex.info.form.gyarados": " ",
|
||||
"cobblemon.ui.pokedex.info.form.gyarados-mega": "Méga-Léviator",
|
||||
"cobblemon.ui.pokedex.info.form.lapras": " ",
|
||||
@@ -7530,9 +7530,9 @@
|
||||
"cobblemon.ui.pokedex.info.form.darumaka": " ",
|
||||
"cobblemon.ui.pokedex.info.form.darumaka-galar": "Forme de Galar",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan-zen": "Mode Transe",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan-galar": "Forme de Galar",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan-galar": "Forme de Galar du Mode Normal",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan": " ",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan-galarzen": "Mode Transe",
|
||||
"cobblemon.ui.pokedex.info.form.darmanitan-galarzen": "Forme de Galar du Mode Transe",
|
||||
"cobblemon.ui.pokedex.info.form.yamask": " ",
|
||||
"cobblemon.ui.pokedex.info.form.yamask-galar": "Forme de Galar",
|
||||
"cobblemon.ui.pokedex.info.form.garbodor": " ",
|
||||
@@ -7566,10 +7566,10 @@
|
||||
"cobblemon.ui.pokedex.info.form.keldeo-resolute": "Aspect Décidé",
|
||||
"cobblemon.ui.pokedex.info.form.meloetta": "Forme Chant",
|
||||
"cobblemon.ui.pokedex.info.form.meloetta-pirouette": "Forme Danse",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-water": "Forme de Genesect",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-electric": "Forme de Genesect",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-fire": "Forme de Genesect",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-ice": "Forme de Genesect",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-water": "Module Aqua",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-electric": "Module Choc",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-fire": "Module Pyro",
|
||||
"cobblemon.ui.pokedex.info.form.genesect-ice": "Module Cryo",
|
||||
"cobblemon.ui.pokedex.info.form.greninja": " ",
|
||||
"cobblemon.ui.pokedex.info.form.greninja-bond": " ",
|
||||
"cobblemon.ui.pokedex.info.form.greninja-ash": "Forme Sacha",
|
||||
@@ -7613,14 +7613,14 @@
|
||||
"cobblemon.ui.pokedex.info.form.sliggoo-hisui": "Forme de Hisui",
|
||||
"cobblemon.ui.pokedex.info.form.goodra": " ",
|
||||
"cobblemon.ui.pokedex.info.form.goodra-hisui": "Forme de Hisui",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo": "Taille Normale",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-small": "Taille Mini",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-large": "Taille Maxi",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-super": "Taille Ultra",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist": "Taille Normale",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-small": "Taille Mini",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-large": "Taille Maxi",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-super": "Taille Ultra",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo": "Variété Moyenne",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-small": "Variété Petite",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-large": "Variété Grande",
|
||||
"cobblemon.ui.pokedex.info.form.pumpkaboo-super": "Variété Giga",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist": "Variété Moyenne",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-small": "Variété Petite",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-large": "Variété Grande",
|
||||
"cobblemon.ui.pokedex.info.form.gourgeist-super": "Variété Giga",
|
||||
"cobblemon.ui.pokedex.info.form.bergmite": " ",
|
||||
"cobblemon.ui.pokedex.info.form.avalugg": " ",
|
||||
"cobblemon.ui.pokedex.info.form.avalugg-hisui": "Forme de Hisui",
|
||||
@@ -9198,5 +9198,10 @@
|
||||
"stat.cobblemon.riding_liquid": "Distance parcourue par Pokémon dans un liquide",
|
||||
"cobblemon.ui.ride_style.air.bird": "Oiseau",
|
||||
"effect.cobblemon.cleanse_all": "Nettoyage des effets",
|
||||
"effect.cobblemon.cleanse_negative": "Nettoyage des effets négatifs"
|
||||
"effect.cobblemon.cleanse_negative": "Nettoyage des effets négatifs",
|
||||
"item.cobblemon.sweet_heart": "Chococœur",
|
||||
"item.cobblemon.sweet_heart.tooltip": "Une friandise au chocolat sucrée",
|
||||
"item.cobblemon.technical_machine": "Capsule Technique",
|
||||
"item.cobblemon.blank_tm": "CT Vierge",
|
||||
"block.cobblemon.deepslate_crystal_core": "Cœur Cristal de profondoise"
|
||||
}
|
||||
|
||||
@@ -3342,7 +3342,7 @@
|
||||
"cobblemon.species.golbat.name": "ゴルバット",
|
||||
"cobblemon.species.golbat.desc": "小さな 脚で 器用に 歩く。 寝ている 獲物に 忍びより キバを 突きたて 血を すするのだ。",
|
||||
"cobblemon.species.oddish.name": "ナゾノクサ",
|
||||
"cobblemon.species.oddish.desc": "昼間は 太陽を 避けるため 冷たい 地面に もぐっている。 月の光を 浴びて 育つ。",
|
||||
"cobblemon.species.oddish.desc": "別名 §oアルキメンデス§r。 夜になると 2本の 根っこで 300メートルも 歩くという。",
|
||||
"cobblemon.species.gloom.name": "クサイハナ",
|
||||
"cobblemon.species.gloom.desc": "よだれのように 見える 甘い蜜。 とても ねばねば しており 触れると いつまでも まとわりつく。",
|
||||
"cobblemon.species.vileplume.name": "ラフレシア",
|
||||
@@ -3548,13 +3548,13 @@
|
||||
"cobblemon.species.zapdos.name": "サンダー",
|
||||
"cobblemon.species.zapdos.desc": "雷雲の 中に いると 言われる 伝説の ポケモン。 雷を 自在に 操る。",
|
||||
"cobblemon.species.moltres.name": "ファイヤー",
|
||||
"cobblemon.species.moltres.desc": "美しく 燃えあがる 翼で 山道を 照らし 遭難者を 助けたと 言い伝えられている。",
|
||||
"cobblemon.species.moltres.desc": "伝説の とりポケモンの 1匹。 ファイヤーが 姿を 見せると 春が 訪れると 言われている。",
|
||||
"cobblemon.species.dratini.name": "ミニリュウ",
|
||||
"cobblemon.species.dratini.desc": "ながく 幻と 言われていた。 額にある 小さな 突起は 成長途中の ツノ。",
|
||||
"cobblemon.species.dragonair.name": "ハクリュー",
|
||||
"cobblemon.species.dragonair.desc": "きれいな 海や 湖に 棲む。 天候を 操る 力で 風に 乗り 空へと 昇る。",
|
||||
"cobblemon.species.dragonite.name": "カイリュー",
|
||||
"cobblemon.species.dragonite.desc": "海の 化身と 呼ばれる。 カイリュー型の 彫像を 舳先に 付ける 船も 多い。",
|
||||
"cobblemon.species.dragonite.desc": "§o海の 化身§rと 呼ばれる。 カイリュー型の 彫像を 舳先に 付ける 船も 多い。",
|
||||
"cobblemon.species.mewtwo.name": "ミュウツー",
|
||||
"cobblemon.species.mewtwo.desc": "ミュウの 遺伝子を 組み替えて 生み出された。ポケモンで 一番 凶暴な 心を 持つという。",
|
||||
"cobblemon.species.mew.name": "ミュウ",
|
||||
@@ -3754,7 +3754,7 @@
|
||||
"cobblemon.species.tyranitar.name": "バンギラス",
|
||||
"cobblemon.species.tyranitar.desc": "地響きを 鳴らしながら 歩くと 大きな 山でさえ 崩れ まわりの 地形は 変わってしまう。",
|
||||
"cobblemon.species.lugia.name": "ルギア",
|
||||
"cobblemon.species.lugia.desc": "海の神様と 伝えられる ポケモン。 嵐の 夜 姿を 見たという 話が 伝えられる。",
|
||||
"cobblemon.species.lugia.desc": "§o海の神様§rと 伝えられる ポケモン。 嵐の 夜 姿を 見たという 話が 伝えられる。",
|
||||
"cobblemon.species.hooh.name": "ホウオウ",
|
||||
"cobblemon.species.hooh.desc": "体は 七色に 輝き 飛んだあとは 虹が できると 神話に 残されている ポケモン。",
|
||||
"cobblemon.species.celebi.name": "セレビィ",
|
||||
@@ -3894,7 +3894,7 @@
|
||||
"cobblemon.species.carvanha.name": "キバニア",
|
||||
"cobblemon.species.carvanha.desc": "鋭い キバと たくましい 顎を もつ。 船乗りたちは キバニアの すみかには けっして 近づかない。",
|
||||
"cobblemon.species.sharpedo.name": "サメハダー",
|
||||
"cobblemon.species.sharpedo.desc": "海のギャングと 呼ばれ 生息 海域に 入りこんでしまった 船は もれなく 襲われてしまう。",
|
||||
"cobblemon.species.sharpedo.desc": "§o海のギャング§rと 呼ばれ 生息 海域に 入りこんでしまった 船は もれなく 襲われてしまう。",
|
||||
"cobblemon.species.wailmer.name": "ホエルコ",
|
||||
"cobblemon.species.wailmer.desc": "海水を たくさん 飲みこむと 体が ボールの ように 弾む。 毎日 1トンの エサを 食べる。",
|
||||
"cobblemon.species.wailord.name": "ホエルオー",
|
||||
@@ -3916,7 +3916,7 @@
|
||||
"cobblemon.species.vibrava.name": "ビブラーバ",
|
||||
"cobblemon.species.vibrava.desc": "ハネを 成長 させるために 毎日 大量の 獲物を 消化液で 溶かして すする。",
|
||||
"cobblemon.species.flygon.name": "フライゴン",
|
||||
"cobblemon.species.flygon.desc": "はばたく 音が 女の人の 美しい 歌声に 似ているため 砂漠の精霊 と 呼ばれている。",
|
||||
"cobblemon.species.flygon.desc": "はばたく 音が 女の人の 美しい 歌声に 似ているため §o砂漠の精霊§r と 呼ばれている。",
|
||||
"cobblemon.species.cacnea.name": "サボネア",
|
||||
"cobblemon.species.cacnea.desc": "雨の 少ない 厳しい 環境 ほど きれいで 香りの 強い 花を 咲かせる。 トゲの ついた 腕を 振り回して 戦う。",
|
||||
"cobblemon.species.cacturne.name": "ノクタス",
|
||||
@@ -3994,7 +3994,7 @@
|
||||
"cobblemon.species.gorebyss.name": "サクラビス",
|
||||
"cobblemon.species.gorebyss.desc": "獲物の 体液を 吸う。 肉は 海底に 沈み 他の ポケモンの エサに なるのだ。",
|
||||
"cobblemon.species.relicanth.name": "ジーランス",
|
||||
"cobblemon.species.relicanth.desc": "深海調査で 発見された。 1億年間 姿が 変わらず 生きている化石 と 呼ばれている。",
|
||||
"cobblemon.species.relicanth.desc": "深海調査で 発見された。 1億年間 姿が 変わらず §o生きている化石§r と 呼ばれている。",
|
||||
"cobblemon.species.luvdisc.name": "ラブカス",
|
||||
"cobblemon.species.luvdisc.desc": "暖かい 海の サンゴ礁が 棲み処。 サニーゴの枝の 間で 眠るのが 特に お気に入り。",
|
||||
"cobblemon.species.bagon.name": "タツベイ",
|
||||
@@ -4020,9 +4020,9 @@
|
||||
"cobblemon.species.latios.name": "ラティオス",
|
||||
"cobblemon.species.latios.desc": "優しい 心の 持ち主にしか なつかない。 腕を 折り畳むと 空気抵抗が 減って ジェット機 よりも 速く 空を 飛べるぞ。",
|
||||
"cobblemon.species.kyogre.name": "カイオーガ",
|
||||
"cobblemon.species.kyogre.desc": "海の 化身 と 伝わる ポケモン。 自然のエネルギーを 求めて グラードンと 争いを 繰り返したという 伝説が ある。",
|
||||
"cobblemon.species.kyogre.desc": "§o海の 化身§r と 伝わる ポケモン。 自然のエネルギーを 求めて グラードンと 争いを 繰り返したという 伝説が ある。",
|
||||
"cobblemon.species.groudon.name": "グラードン",
|
||||
"cobblemon.species.groudon.desc": "大地の 化身 と 伝わる ポケモン。自然のエネルギーを 求めて カイオーガと 争いを 繰り返したという 伝説が ある。",
|
||||
"cobblemon.species.groudon.desc": "§o大地の 化身§r と 伝わる ポケモン。自然のエネルギーを 求めて カイオーガと 争いを 繰り返したという 伝説が ある。",
|
||||
"cobblemon.species.rayquaza.name": "レックウザ",
|
||||
"cobblemon.species.rayquaza.desc": "何億年も 生き続けていると いわれる。 グラードンと カイオーガの 争いを 治めたという 伝説が 残されている。",
|
||||
"cobblemon.species.jirachi.name": "ジラーチ",
|
||||
@@ -4160,7 +4160,7 @@
|
||||
"cobblemon.species.skorupi.name": "スコルピ",
|
||||
"cobblemon.species.skorupi.desc": "毒のある しっぽの ツメで 襲いかかる。 挟まれると 毒が 染みて 動けなくなる。",
|
||||
"cobblemon.species.drapion.name": "ドラピオン",
|
||||
"cobblemon.species.drapion.desc": "砂の悪魔と 呼ばれるほど 獰猛だが カバルドンには ケンカも 売らず おとなしい。",
|
||||
"cobblemon.species.drapion.desc": "§o砂の悪魔§rと 呼ばれるほど 獰猛だが カバルドンには ケンカも 売らず おとなしい。",
|
||||
"cobblemon.species.croagunk.name": "グレッグル",
|
||||
"cobblemon.species.croagunk.desc": "毒を 薄めると 薬に なる。 薬品会社の マスコットに なって 人気者に なった。",
|
||||
"cobblemon.species.toxicroak.name": "ドクロッグ",
|
||||
@@ -4232,7 +4232,7 @@
|
||||
"cobblemon.species.giratina.name": "ギラティナ",
|
||||
"cobblemon.species.giratina.desc": "この世の 裏側にある 世界に 住んでいると 言われる ポケモン。 古代の 墓場に 現れる。",
|
||||
"cobblemon.species.cresselia.name": "クレセリア",
|
||||
"cobblemon.species.cresselia.desc": "クレセリアの 羽を 持って 寝ると 楽しい 夢が 見られると いう。 三日月の化身 と 呼ばれている。",
|
||||
"cobblemon.species.cresselia.desc": "クレセリアの 羽を 持って 寝ると 楽しい 夢が 見られると いう。 §o三日月の化身§r と 呼ばれている。",
|
||||
"cobblemon.species.phione.name": "フィオネ",
|
||||
"cobblemon.species.phione.desc": "暖かい 海を 漂っている。 どんな 遠くに 流されても 生まれた 場所に かならず戻る。",
|
||||
"cobblemon.species.manaphy.name": "マナフィ",
|
||||
@@ -4316,7 +4316,7 @@
|
||||
"cobblemon.species.drilbur.name": "モグリュー",
|
||||
"cobblemon.species.drilbur.desc": "ツメで 地中を 掘り進むので 育てた 野菜が 傷むと 農業関係者は 嫌う。",
|
||||
"cobblemon.species.excadrill.name": "ドリュウズ",
|
||||
"cobblemon.species.excadrill.desc": "別名 ドリルキング。 地中を 掘り進む 速度は 時速150キロに 達する。",
|
||||
"cobblemon.species.excadrill.desc": "別名 §oドリルキング§r。 地中を 掘り進む 速度は 時速150キロに 達する。",
|
||||
"cobblemon.species.audino.name": "タブンネ",
|
||||
"cobblemon.species.audino.desc": "心優しい ポケモン。 触角を 押し当て 相手の 気持ちや 体調を 理解する。",
|
||||
"cobblemon.species.timburr.name": "ドッコラー",
|
||||
@@ -4834,13 +4834,13 @@
|
||||
"cobblemon.species.tapufini.name": "カプ・レヒレ",
|
||||
"cobblemon.species.tapufini.desc": "水を 操る 遠い島の 守り神。 けがれを 払う 清らかな 水を 生みだすと 伝えられている。",
|
||||
"cobblemon.species.cosmog.name": "コスモッグ",
|
||||
"cobblemon.species.cosmog.desc": "大昔は 星の子 という 名で 呼ばれた。 別世界の ポケモンと いわれているが 詳しくは 不明。",
|
||||
"cobblemon.species.cosmog.desc": "大昔は §o星の子§r という 名で 呼ばれた。 別世界の ポケモンと いわれているが 詳しくは 不明。",
|
||||
"cobblemon.species.cosmoem.name": "コスモウム",
|
||||
"cobblemon.species.cosmoem.desc": "死んだように まったく 動かないが 触れると ほのかに 温かい。 大昔は 星の繭と 呼ばれた。",
|
||||
"cobblemon.species.cosmoem.desc": "死んだように まったく 動かないが 触れると ほのかに 温かい。 大昔は §o星の繭§rと 呼ばれた。",
|
||||
"cobblemon.species.solgaleo.name": "ソルガレオ",
|
||||
"cobblemon.species.solgaleo.desc": "太陽を 食らいし 獣 と かつて 呼ばれた。 無尽蔵の 光エネルギーを 放出する。",
|
||||
"cobblemon.species.solgaleo.desc": "§o太陽を 食らいし 獣§r と かつて 呼ばれた。 無尽蔵の 光エネルギーを 放出する。",
|
||||
"cobblemon.species.lunala.name": "ルナアーラ",
|
||||
"cobblemon.species.lunala.desc": "月を 誘いし 獣 という 名前を もつ。 あらゆる 光を エネルギーに 変えて 生きている。",
|
||||
"cobblemon.species.lunala.desc": "§o月を 誘いし 獣§r という 名前を もつ。 あらゆる 光を エネルギーに 変えて 生きている。",
|
||||
"cobblemon.species.nihilego.name": "ウツロイド",
|
||||
"cobblemon.species.nihilego.desc": "謎に 包まれた ウルトラビーストの 一種。 町ゆく 人が 寄生され 暴れだす 姿が 目撃された。",
|
||||
"cobblemon.species.buzzwole.name": "マッシブーン",
|
||||
@@ -4972,7 +4972,7 @@
|
||||
"cobblemon.species.hattrem.name": "テブリム",
|
||||
"cobblemon.species.hattrem.desc": "頭の房で 相手を 殴り 黙らせる。 プロボクサーさえ 一発 KOの 破壊力。",
|
||||
"cobblemon.species.hatterene.name": "ブリムオン",
|
||||
"cobblemon.species.hatterene.desc": "別名は 森の 魔女。 騒ぎたてると 触手のツメで 引き裂かれるかも しれないぞ。",
|
||||
"cobblemon.species.hatterene.desc": "別名は §o森の 魔女§r。 騒ぎたてると 触手のツメで 引き裂かれるかも しれないぞ。",
|
||||
"cobblemon.species.impidimp.name": "ベロバー",
|
||||
"cobblemon.species.impidimp.desc": "民家に 忍びこみ 盗みを 働き さらに 悔しがる 人の マイナスエネルギーも いただくのだ。",
|
||||
"cobblemon.species.morgrem.name": "ギモー",
|
||||
@@ -5032,7 +5032,7 @@
|
||||
"cobblemon.species.dragapult.name": "ドラパルト",
|
||||
"cobblemon.species.dragapult.desc": "ツノに 入った ドラメシヤは マッハの スピードで 飛ばされるのを 心待ちに しているらしい。",
|
||||
"cobblemon.species.zacian.name": "ザシアン",
|
||||
"cobblemon.species.zacian.desc": "伝説の 英雄と 呼ばれる ポケモン。 金属を 取り込み 武具に 変化させ 戦う。",
|
||||
"cobblemon.species.zacian.desc": "§o伝説の 英雄§rと 呼ばれる ポケモン。 金属を 取り込み 武具に 変化させ 戦う。",
|
||||
"cobblemon.species.zamazenta.name": "ザマゼンタ",
|
||||
"cobblemon.species.zamazenta.desc": "石像の ような 姿で 忘れ去られるほどの あいだ 眠りに ついていた ポケモン。",
|
||||
"cobblemon.species.eternatus.name": "ムゲンダイナ",
|
||||
@@ -5224,29 +5224,29 @@
|
||||
"cobblemon.species.kingambit.name": "ドドゲザン",
|
||||
"cobblemon.species.kingambit.desc": "ドドゲザンに 進化できるのは 大軍勢の 頂点に 立った 1匹の キリキザンだけなのだ。",
|
||||
"cobblemon.species.greattusk.name": "イダイナキバ",
|
||||
"cobblemon.species.greattusk.desc": "近年 目撃例が ある。 イダイナキバという 名は ある本に 記された 生物から 取られた。",
|
||||
"cobblemon.species.greattusk.desc": "近年 目撃例が ある。 イダイナキバという 名は ある本に 記された 生物から 取られた。 ”パルデア未確認ファイル No.09 太古から 生き続ける 恐竜!? 謎の生物 イダイナキバ パルデア某所にある 乾燥地帯において 謎の生物の 目撃が 報告されている。 一見 ドンファンに 似た その生物は 巨大な牙と 強固な鱗を 備えており 好戦的な性質を 示したという。 現代に 生き残る 恐竜というのが 有力な説だが§r §oその正体は 不明。 イダイナキバ という名は かの奇書 スカーレットブックに 記された 謎の生物から 命名されたと いわれる。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.screamtail.name": "サケブシッポ",
|
||||
"cobblemon.species.screamtail.desc": "10億年前の プリンと オカルト雑誌が 紹介した 謎の ポケモンに 似ている。",
|
||||
"cobblemon.species.screamtail.desc": "10億年前の プリンと オカルト雑誌が 紹介した 謎の ポケモンに 似ている。 ”パルデア未確認ファイル No.10 10億年前の プリン 発見!? 謎の生物 サケブシッポ パルデア某所の 森で 目撃された 謎の生物が サケブシッポ である。 プリンに 酷似した 愛くるしさを 持っているが 攻撃的な性質で 近づくものに 襲いかかるという。 原始的な姿と 凶暴性から 一説には 10億年前の プリンと 噂されている。 奇書 スカーレットブックに 記された 叫ぶ尻尾と 呼ばれる 謎の生物が 名前の由来 である。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.brutebonnet.name": "アラブルタケ",
|
||||
"cobblemon.species.brutebonnet.desc": "怪しい 雑誌が 恐竜と キノコの 合成と 紹介した ポケモンに 少し 似ているのだ。",
|
||||
"cobblemon.species.brutebonnet.desc": "怪しい 雑誌が 恐竜と キノコの 合成と 紹介した ポケモンに 少し 似ているのだ。 ”パルデア未確認ファイル No.06 恐竜? モロバレル? 謎の生物 アラブルタケ 恐竜の特徴とモロバレルの特徴を あわせ持つと 噂される 奇妙な生物。 奇書と 名高い スカーレットブックで 紹介された 荒ぶる茸と 呼ばれる 謎の生物と おおむね 特徴が 一致。 そこから この未確認生物は アラブルタケと 呼ばれるように なった。 通常の モロバレルより はるかに 身体は 巨大だが 知性は低いようで 凶暴な ハードパンチャーらしい。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.fluttermane.name": "ハバタクカミ",
|
||||
"cobblemon.species.fluttermane.desc": "オカルト雑誌で 取り上げられた 翼竜の 幽霊と 特徴だけは 似ているのだ。",
|
||||
"cobblemon.species.fluttermane.desc": "オカルト雑誌で 取り上げられた 翼竜の 幽霊と 特徴だけは 似ているのだ。 ”パルデア未確認ファイル No.05 翼竜のゴースト!? 謎の生物 ハバタクカミその名は スカーレットブックと 呼ばれる 奇書の中に 登場する 謎の生物から 名づけられた。 長い体毛を くねらせ 夜空を ゆらゆらと 飛びまわると いわれる。 目撃者からの 証言によると 一見 巨大なムウマの ようだが 気性が とても荒く 好戦的とのこと。 古代に 生息した 翼竜の魂から 生まれた ゴーストという 説もある。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.slitherwing.name": "チヲハウハネ",
|
||||
"cobblemon.species.slitherwing.desc": "古い 本で チヲハウハネと 紹介されている 生物に 似た点が ある 謎のポケモン。",
|
||||
"cobblemon.species.slitherwing.desc": "古い 本で チヲハウハネと 紹介されている 生物に 似た点が ある 謎のポケモン。 ”パルデア未確認ファイル No.08 蘇った太古の ウルガモス!? 謎の生物 チヲハウハネ 目撃情報が少なく 極めて 謎の多い 未確認生物が チヲハウハネ である。 その名は 奇書として 知られる スカーレットブックに 記された 謎の生物に ちなんで 名づけられた。 かつて 本誌が§r §oとりあげた 原始時代の ウルガモスと 共通する特徴が あり 化石から 復元したとも 考えられる。 だが 過去に ウルガモスの化石が 発見された記録は 存在していない。§r” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.sandyshocks.name": "スナノケガワ",
|
||||
"cobblemon.species.sandyshocks.desc": "オカルト雑誌の 記事にあった 1万年 生きた レアコイルの 姿に やや 似ている。",
|
||||
"cobblemon.species.sandyshocks.desc": "オカルト雑誌の 記事にあった 1万年 生きた レアコイルの 姿に やや 似ている。 ”パルデア未確認ファイル No.07 寿命1万年の レアコイル!? 謎の生物 スナノケガワ 1万年生きた レアコイルの姿だと 主張する 科学者もいる 謎の生物。 パルデアの 乾燥地帯を 中心に 数件の 目撃報告が あるものの いまだ 捕獲されたという 記録はない。 攻撃的な性質で 目撃者が 襲われるケースも あるという。 世紀の奇書 スカーレットブックで 紹介された 砂の毛皮と 呼ばれる 謎の生物と 特徴が 一致している。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.irontreads.name": "テツノワダチ",
|
||||
"cobblemon.species.irontreads.desc": "オカルト雑誌が 紹介した 宇宙人が 送り込んできた 科学兵器に よく 似ている。",
|
||||
"cobblemon.species.irontreads.desc": "オカルト雑誌が 紹介した 宇宙人が 送り込んできた 科学兵器に よく 似ている。 ”パルデア未確認ファイル No.09 宇宙人の科学兵器か!? 謎の物体 テツノワダチ パルデア某所にある 乾燥地帯において 謎の生物の 目撃が 報告されている。 一見 ドンファンに 似た その生物は 突如 球体に 変化すると 高速で 回転し 襲いかかってきたという。 宇宙人の 科学兵器では ないかという 噂もあるが 真相は 不明。 テツノワダチ という名は かの奇書 バイオレットブックに 記された 謎の物体から 命名されたと いわれる。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironbundle.name": "テツノツツミ",
|
||||
"cobblemon.species.ironbundle.desc": "オカルト雑誌の 記事になった 太古の 文明が 生み出した ロボットに 形が 似ている。",
|
||||
"cobblemon.species.ironbundle.desc": "オカルト雑誌の 記事になった 太古の 文明が 生み出した ロボットに 形が 似ている。 ”パルデア未確認ファイル No.10 太古の文明が 生んだ ロボット!? 謎の物体 テツノツツミ 奇書 バイオレットブックに 書かれた 謎の物体が 名前の由来 である。 デリバードに 似た 形状をしており 球体の装置から 膨大な氷を 噴射し 雪原を 移動するという。 正体に 関しては 多くの説が あるが 超古代文明の産物 という説が 有力。 太古の文献に テツノツツミ らしき 機械を 設計し 使役していたという 記録が 残っているのだ。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironhands.name": "テツノカイナ",
|
||||
"cobblemon.species.ironhands.desc": "あるアスリートが 改造された 姿だと オカルト雑誌が スクープした サイボーグに 近い。",
|
||||
"cobblemon.species.ironhands.desc": "あるアスリートが 改造された 姿だと オカルト雑誌が スクープした サイボーグに 近い。 ”パルデア未確認ファイル No.05 その正体は サイボーグ!? 謎の物体 テツノカイナ 世紀の奇書 バイオレットブックに 記された 鉄の腕と 呼ばれる 謎の物体から 命名された。 自在に動く 掌で 高速で 走っていた 大型車両を 投げ飛ばしたという。 テツノカイナの 正体として 有力なのは 瀕死の重傷を 負った アスリートが サイボーグ化した という説である。 ただ 何故 ハリテヤマを 模した姿に なったのかは 謎に つつまれているのだ。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironjugulis.name": "テツノコウベ",
|
||||
"cobblemon.species.ironjugulis.desc": "ロボットに 恋した サザンドラの 子どもと オカルト雑誌が 取り上げた ポケモンに 似ている。",
|
||||
"cobblemon.species.ironjugulis.desc": "ロボットに 恋した サザンドラの 子どもと オカルト雑誌が 取り上げた ポケモンに 似ている。 ”パルデア未確認ファイル No.07 機械!? ポケモン!? 謎の物体 テツノコウベ パルデア某所にて 目撃された サザンドラに 似た 危険な 飛行物体。 高エネルギーを 放射し 建造物を 徹底的に 破壊すると 次の標的を 求めるように 飛び去っていったという。 サザンドラの凶暴性と 機械の冷酷さを あわせ持つため 機械と サザンドラの ハイブリッドなのではと 噂される。 奇書 バイオレットブックに 書かれた 謎の物体が 名前の由来 である。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironmoth.name": "テツノドクガ",
|
||||
"cobblemon.species.ironmoth.desc": "人類を 監視する UFOだと オカルト雑誌が 紹介した 未知の 物体に 似ている。",
|
||||
"cobblemon.species.ironmoth.desc": "人類を 監視する UFOだと オカルト雑誌が 紹介した 未知の 物体に 似ている。 ”パルデア未確認ファイル No.08 人類を監視する UFO!? 謎の物体 テツノドクガ 世紀の奇書 バイオレットブックに 登場する 謎の物体から 命名された。 ウルガモスに 似た 飛行物体であり 上空から 地上の人々を 追尾し 時に 襲いかかってくることが あるという。 攻撃的な性質を 持つ 理由として テツノドクガの 正体は 宇宙人が あやつる UFOだという 説がある。 テツノドクガを 使い 人類を 監視し 侵略の機会を うかがっているかもしれない。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironthorns.name": "テツノイバラ",
|
||||
"cobblemon.species.ironthorns.desc": "10億年後の バンギラスと 怪しい 雑誌が 取り上げていた ポケモンに 似た 部分が ある。",
|
||||
"cobblemon.species.ironthorns.desc": "10億年後の バンギラスと 怪しい 雑誌が 取り上げていた ポケモンに 似た 部分が ある。 ”パルデア未確認ファイル No.06 10億年後の バンギラス!? 謎の物体 テツノイバラ パルデア某所 とある洞くつで 目撃された 謎の物体が テツノイバラ である。 バンギラスに 酷似しているが 極めて 冷徹な性質を 持つとともに 無駄な争いを 好まないという。 金属質の装甲や 高い知性から 10億年後の バンギラスと 噂されている。 奇書 バイオレットブックに 記された 鉄の茨と 呼ばれる 謎の物体が 名前の由来に なっている。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.frigibax.name": "セビエ",
|
||||
"cobblemon.species.frigibax.desc": "背びれで 熱を 吸収して 氷エネルギーに 変換する。 高温ほど エネルギーが 溜まる。",
|
||||
"cobblemon.species.arctibax.name": "セゴール",
|
||||
@@ -5266,13 +5266,13 @@
|
||||
"cobblemon.species.chiyu.name": "イーユイ",
|
||||
"cobblemon.species.chiyu.desc": "多くの 争いの 火種となった 勾玉に 集まった 妬みが 炎を まとい ポケモンとなった。",
|
||||
"cobblemon.species.roaringmoon.name": "トドロクツキ",
|
||||
"cobblemon.species.roaringmoon.desc": "謎の 多い 探検記の中で トドロクツキという 名で 記された 生物の 可能性が ある。",
|
||||
"cobblemon.species.roaringmoon.desc": "謎の 多い 探検記の中で トドロクツキという 名で 記された 生物の 可能性が ある。 ”パルデア未確認ファイル No.04 原始の ボーマンダ!? 謎の生物 トドロクツキ 奇書 スカーレットブックに 書かれた 謎の生物が 名前の由来に なっている。 その姿は ほかの地方で ボーマンダに 発生する とある現象の 結果に 酷似しているが 関連性は 不明。 羽毛を まき散らしながら 高速で 飛びまわり 獲物を 襲う。 その 凶暴な性質は ボーマンダ以上と 考えられており 遭遇することが あっても 絶対に 接触を 避けるべきである。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.ironvaliant.name": "テツノブジン",
|
||||
"cobblemon.species.ironvaliant.desc": "オカルト雑誌の 記事に あった マッドサイエンティストの 発明と 近い 特徴が いくつかある。",
|
||||
"cobblemon.species.ironvaliant.desc": "オカルト雑誌の 記事に あった マッドサイエンティストの 発明と 近い 特徴が いくつかある。 ”パルデア未確認ファイル No.04 博士の 異常な発明!? 謎の物体 テツノブジン 奇書 バイオレットブックに 書かれた 謎の物体が 名前の由来に なっている。 最強の エスパーポケモンを 求める マッドサイエンティストに よって 造られた ロボットという 説がある。 数少ない 目撃者からの 証言によるとサーナイトと エルレイド どちらにも見えるような 奇妙な姿を しており対峙する者は 光りかがやく刃で 躊躇なく 切り捨てる 残酷さを 持っているという。” §o-謎のオカルト雑誌より引用§r",
|
||||
"cobblemon.species.koraidon.name": "コライドン",
|
||||
"cobblemon.species.koraidon.desc": "拳で 大地を 引き裂いたと 古い 探検記に 記された ツバサノオウの 正体らしい。",
|
||||
"cobblemon.species.koraidon.desc": "拳で 大地を 引き裂いたと 古い 探検記に 記された §oツバサノオウ§rの 正体らしい。",
|
||||
"cobblemon.species.miraidon.name": "ミライドン",
|
||||
"cobblemon.species.miraidon.desc": "古い 書物に 名が ある テツノオロチらしい。 雷で 大地を 灰に 変えたという。",
|
||||
"cobblemon.species.miraidon.desc": "古い 書物に 名が ある §oテツノオロチ§rらしい。 雷で 大地を 灰に 変えたという。",
|
||||
"cobblemon.species.walkingwake.name": "ウネルミナモ",
|
||||
"cobblemon.species.walkingwake.desc": "謎多き 凶暴な 生物。 古い 探検記に 記された 水の 怪物から 名付けられた。",
|
||||
"cobblemon.species.ironleaves.name": "テツノイサハ",
|
||||
@@ -5957,7 +5957,7 @@
|
||||
"item.cobblemon.galarica_nuts": "ガラナツのナッツ",
|
||||
"cobblemon.pokerod.apply": "右クリックでエサを付ける",
|
||||
"item.cobblemon.npc_editor": "NPCのトレーナーカード",
|
||||
"item.cobblemon.link_cable.tooltip": "なにかしらのつながりを感じさせる 不思議なエネルギーを秘めているヒモ。 ポケモン交換で進化するポケモンを進化させる。",
|
||||
"item.cobblemon.link_cable.tooltip": "ポケモン交換で進化するポケモンを進化させられるヒモ。",
|
||||
"item.cobblemon.dragon_scale.tooltip": "硬くて 丈夫な ウロコ。 シードラに持たせてポケモン交換すると キングドラに進化する。",
|
||||
"item.cobblemon.kings_rock.tooltip_1": "持たせると 攻撃して ダメージを 与えたときに 相手を ひるませることが ある。",
|
||||
"item.cobblemon.metal_coat.tooltip_1": "特殊な金属の 膜。 持たせると はがねタイプの 技の威力が 上がる。",
|
||||
@@ -5968,11 +5968,11 @@
|
||||
"item.cobblemon.deep_sea_scale.tooltip_2": "パールルに持たせてポケモン交換すると サクラビスに進化する。",
|
||||
"item.cobblemon.deep_sea_tooth.tooltip_1": "パールルに 持たせると 特攻が あがる キバ。",
|
||||
"item.cobblemon.deep_sea_tooth.tooltip_2": "パールルに持たせてポケモン交換すると ハンテールに進化する。",
|
||||
"item.cobblemon.electirizer.tooltip": "とてつもない 電気の エネルギーが 蓄えられている 箱。 エレブーに持たせてポケモン交換すると エレキブルに進化する。",
|
||||
"item.cobblemon.magmarizer.tooltip": "とてつもない マグマの エネルギーが 蓄えられている 箱。 ブーバーに持たせてポケモン交換すると ブーバーンに進化する。",
|
||||
"item.cobblemon.electirizer.tooltip": "電気が蓄えられた箱。 エレブーに持たせてポケモン交換すると エレキブルに進化する。",
|
||||
"item.cobblemon.magmarizer.tooltip": "マグマが蓄えられた箱。 ブーバーに持たせてポケモン交換すると ブーバーンに進化する。",
|
||||
"item.cobblemon.oval_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 たまのように まるい。",
|
||||
"item.cobblemon.reaper_cloth.tooltip": "おそろしく 強い霊力が こめられている 布。 サマヨールに持たせてポケモン交換すると ヨノワールに進化する。",
|
||||
"item.cobblemon.sachet.tooltip": "ちょっと きつめの 香りをだす 香料を 詰めた 袋。 シュシュプに持たせてポケモン交換すると フレフワンに進化する。",
|
||||
"item.cobblemon.sachet.tooltip": "きつめの 香料を 詰めた 袋。 シュシュプに持たせてポケモン交換すると フレフワンに進化する。",
|
||||
"item.cobblemon.strawberry_sweet.tooltip": "いちごの形をした アメ細工。 マホミルに使うと いちごのアメざいくを身に付けた マホイップになる。",
|
||||
"item.cobblemon.berry_sweet.tooltip": "ベリーの形をした アメ細工。 マホミルに使うと ベリーのアメざいくを身に付けた マホイップになる。",
|
||||
"item.cobblemon.clover_sweet.tooltip": "よつばの形をした アメ細工。 マホミルに使うと よつばのアメざいくを身に付けた マホイップになる。",
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"item.cobblemon.grass_gem.tooltip_2": "使うとなくなる。",
|
||||
"item.cobblemon.dragon_gem.tooltip_2": "使うとなくなる。",
|
||||
"item.cobblemon.ghost_gem.tooltip_2": "使うとなくなる。",
|
||||
"item.cobblemon.whipped_dream.tooltip": "ふんわり ふわふわに 泡立てた ほんのり 甘い クリーム。 ペロッパフに持たせてポケモン交換すると ペロリームに進化する。",
|
||||
"item.cobblemon.whipped_dream.tooltip": "ふわふわに 泡立てた クリーム。 ペロッパフに持たせてポケモン交換すると ペロリームに進化する。",
|
||||
"item.cobblemon.sun_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 太陽のように 赤い。",
|
||||
"item.cobblemon.prism_scale.tooltip": "にじ色に 輝く 不思議なウロコ。 ヒンバスに持たせてポケモン交換すると ミロカロスに進化する。",
|
||||
"item.cobblemon.love_sweet.tooltip": "ハートの形をした アメ細工。 マホミルに使うと ハートのアメざいくを身に付けた マホイップになる。",
|
||||
@@ -6115,7 +6115,7 @@
|
||||
"item.cobblemon.poison_barb.tooltip": "どくのある ちいさな ハリ。 持たせると どくタイプの 技の威力が あがる。",
|
||||
"item.cobblemon.punching_glove.tooltip": "こぶしを 保護する グローブ。 持たせると パンチ技の 威力が あがり 相手に 接触しない パンチに なる。",
|
||||
"item.cobblemon.quick_claw.tooltip": "軽くて 鋭い ツメ。 持たせると 相手より 先に 行動できることが ある。",
|
||||
"item.cobblemon.razor_fang.tooltip_1": "鋭く とがった キバ。持たせると ダメージを 与えたとき ひるませることが ある。",
|
||||
"item.cobblemon.razor_fang.tooltip_1": "鋭く とがった キバ。 持たせると ダメージを 与えたとき ひるませることが ある。",
|
||||
"item.cobblemon.razor_fang.tooltip_2": "グライガーに 持たせると、 夜にグライオンに進化する。",
|
||||
"item.cobblemon.red_card.tooltip_1": "不思議な ちからのある カード。 持たせると ダメージを 与えてきた 相手を 控えに 退場させることが できる。",
|
||||
"item.cobblemon.rocky_helmet.tooltip": "ポケモンに 持たせると 自分に さわった相手に ダメージを 与える。",
|
||||
@@ -6254,7 +6254,7 @@
|
||||
"cobblemon.trade.accept.receiver": "あなたは %1$s の交換リクエストを受け入れました!",
|
||||
"item.cobblemon.safety_goggles.tooltip": "天候の ダメージだけでなく 粉を だす 技の 効果も 防げる ゴーグル。",
|
||||
"item.cobblemon.shell_bell.tooltip": "持たせた ポケモンが 攻撃して 相手に ダメージを あたえたとき HPを 少し 回復できる。",
|
||||
"item.cobblemon.shell_helmet.tooltip": "とあるポケモンが身に付けていた殻。 カブルモに使うと シュバルゴに進化する。",
|
||||
"item.cobblemon.shell_helmet.tooltip": "とあるポケモンが 身に付けていた 殻。 カブルモに使うと シュバルゴに進化する。",
|
||||
"cobblemon.trade.expired.sender": "%1$s との交換リクエストがタイムアウトしました。",
|
||||
"item.cobblemon.ground_gem.tooltip_1": "じめんのタイプの ジュエル。 持たせると 1度だけ じめんの 技の威力が 強まる。",
|
||||
"item.cobblemon.x_attack.tooltip": "戦闘中の ポケモンの 攻撃を 2段階 あげる 道具。 ひっこめると 元に 戻る。",
|
||||
@@ -6495,7 +6495,7 @@
|
||||
"cobblemon.ui.pokedex.info.form.glalie-mega": "メガオニゴーリ",
|
||||
"cobblemon.species.glalie-mega.desc": "砕けた 口から 凄まじい 冷気を 吐くと あたり 一帯は ホワイトアウトに 陥ってしまう。",
|
||||
"cobblemon.ui.pokedex.info.form.salamence-mega": "メガボーマンダ",
|
||||
"cobblemon.species.salamence-mega.desc": "より 凶暴に なって 育ての トレーナーにも 襲いかかるほど。別名 血に 濡れた 三日月。",
|
||||
"cobblemon.species.salamence-mega.desc": "より 凶暴に なって 育ての トレーナーにも 襲いかかるほど。別名 §o血に 濡れた 三日月§r。",
|
||||
"cobblemon.ui.pokedex.info.form.metagross-mega": "メガメタグロス",
|
||||
"cobblemon.species.metagross-mega.desc": "メガシンカで 脳を 刺激され 勝利の ためには 手段を 選ばない 冷酷な 性格に。",
|
||||
"cobblemon.ui.pokedex.info.form.latias-mega": "メガラティアス",
|
||||
@@ -6537,7 +6537,7 @@
|
||||
"cobblemon.ui.pokedex.info.form.meloetta": "ボイスフォルム",
|
||||
"cobblemon.ui.pokedex.info.form.meloetta-pirouette": "ステップフォルム",
|
||||
"cobblemon.ui.pokedex.info.form.diancie-mega": "メガディアンシー",
|
||||
"cobblemon.species.diancie-mega.desc": "額で 眩く 輝く ダイヤは なんと 2000カラット。 別名 ロイヤルピンクプリンセス。",
|
||||
"cobblemon.species.diancie-mega.desc": "額で 眩く 輝く ダイヤは なんと 2000カラット。 別名 §oロイヤルピンクプリンセス§r。",
|
||||
"cobblemon.ui.pokedex.info.form.color-cyan": "青緑色",
|
||||
"cobblemon.ui.pokedex.info.form.vivillon-wings-forsaken": "みすてられたもよう",
|
||||
"cobblemon.ui.pokedex.info.form.snake-pattern-speed": "すばやさのもよう",
|
||||
@@ -7374,7 +7374,7 @@
|
||||
"cobblemon.ui.pokedex.info.form.alakazam": " ",
|
||||
"cobblemon.species.voltorb-hisui.desc": "モンスターボールと 空似せし 謎の ポケモン。気 昂るほど 腹に 蓄えし電流を 解き放ち 大笑す。",
|
||||
"cobblemon.species.eevee-gmax.desc": "キョダイマックス パワーで さらに もふもふした 首まわりの 綿毛で 敵を 包みこみ とりこにする。",
|
||||
"cobblemon.species.articuno-galar.desc": "凍りついたかのように 体の 自由を 奪う ビームを 撃ちだす フリーザーの 名を もつ ポケモン。",
|
||||
"cobblemon.species.articuno-galar.desc": "凍りついたかのように 体の 自由を 奪う ビームを 撃ちだす §oフリーザー§rの 名を もつ ポケモン。",
|
||||
"cobblemon.ui.pokedex.info.form.wooper-paldea": "パルデアのすがた",
|
||||
"cobblemon.species.venusaur-gmax.desc": "2本の ふとい ツルを 振りまわし 戦う。10階建ての ビルを かるく なぎ倒すほど パワフルだ。",
|
||||
"cobblemon.ui.pokedex.info.form.blastoise": " ",
|
||||
@@ -7493,10 +7493,10 @@
|
||||
"cobblemon.ui.pokedex.info.form.articuno-galar": "ガラルのすがた",
|
||||
"cobblemon.ui.pokedex.info.form.zapdos": " ",
|
||||
"cobblemon.ui.pokedex.info.form.zapdos-galar": "ガラルのすがた",
|
||||
"cobblemon.species.zapdos-galar.desc": "羽毛が 擦れるとき バチバチと 電気のような 音が することから サンダーと 呼ばれてきた。",
|
||||
"cobblemon.species.zapdos-galar.desc": "羽毛が 擦れるとき バチバチと 電気のような 音が することから §oサンダー§rと 呼ばれてきた。",
|
||||
"cobblemon.ui.pokedex.info.form.moltres": " ",
|
||||
"cobblemon.ui.pokedex.info.form.moltres-galar": "ガラルのすがた",
|
||||
"cobblemon.species.moltres-galar.desc": "伝説の とりポケモンの 1匹。 ファイヤーが 姿を 見せると 春が 訪れると 言われている。",
|
||||
"cobblemon.species.moltres-galar.desc": "邪悪な オーラを 炎のように 燃え上がらせる その 姿から §oファイヤー§rと 名づけられた。",
|
||||
"cobblemon.ui.pokedex.info.form.aerodactyl": " ",
|
||||
"cobblemon.ui.pokedex.info.form.cyndaquil": " ",
|
||||
"cobblemon.ui.pokedex.info.form.mewtwo": " ",
|
||||
@@ -7611,7 +7611,7 @@
|
||||
"cobblemon.species.orbeetle-gmax.desc": "脳を 中心に 巨大化。 圧倒的 知能と 膨大な サイコエネルギーを もっている。",
|
||||
"cobblemon.species.sandaconda-gmax.desc": "砂袋も 超巨大に。 体の まわりに 渦巻く 砂は 100万トンを 超える。",
|
||||
"cobblemon.species.centiskorch-gmax.desc": "キョダイマックスの パワーによって 体温は 摂氏1000度を 超え 熱波で 相手を 焼き焦がす。",
|
||||
"cobblemon.species.urshifu-gmax.desc": "怒りの化身 と 呼ばれている。 凄まじい 形相と 雄叫びで 世界の 邪気を 払うという。",
|
||||
"cobblemon.species.urshifu-gmax.desc": "§o怒りの化身§r と 呼ばれている。 凄まじい 形相と 雄叫びで 世界の 邪気を 払うという。",
|
||||
"cobblemon.cosmetic_item.give": "%1$sに%2$sを身に付けさせた!",
|
||||
"cobblemon.cosmetic_item.take": "%2$sから %1$sを 受け取った!",
|
||||
"cobblemon.cosmetic_item.already_wearing": "%1$sはもう %2$sを 身に付けている!",
|
||||
@@ -7774,7 +7774,7 @@
|
||||
"cobblemon.move.gmaxsweetness.desc": "キョダイマックスした タルップルが 繰りだす くさタイプの 攻撃。 味方の 状態異常を 回復する。",
|
||||
"cobblemon.move.gmaxvoltcrash.desc": "キョダイマックスした ピカチュウが 繰りだす でんきタイプの 攻撃。 相手を まひ状態に する。",
|
||||
"cobblemon.ui.pokedex.info.form.samurott-hisui": "ヒスイのすがた",
|
||||
"cobblemon.species.dialga-origin.desc": "神と畏れし伝説 古の地に あり。 誕生により うつし世の 壁 消え去り 延々と 際限なき空 出現したり。",
|
||||
"cobblemon.species.dialga-origin.desc": "光明 フォルムチェンジの 引き金。 創造神に 酷似する姿こそ 真なりと 思わざるを得ぬほどの 剛力 発揮す。",
|
||||
"cobblemon.move.gmaxtartness.desc": "キョダイマックスした アップリューが 繰りだす くさタイプの 攻撃。 相手の 回避率を 下げる。",
|
||||
"cobblemon.species.basculin-white.desc": "極寒の 海で 群れを 作り エサを 分け合って 暮らす。 時が 来ると 生まれた 川に 帰る。",
|
||||
"cobblemon.species.landorus-therian.desc": "霊獣の姿にて 天翔けしとき 大地に 豊穣もたらす。 衆人 これを 敬う。 一刻あれば 古の地を 縦断す。",
|
||||
@@ -8179,8 +8179,8 @@
|
||||
"cobblemon.ui.pokedex.info.form.eiscue-noiceface": "ナイスフェイス",
|
||||
"cobblemon.pokedex.variation.face_spot_1": "顔のブチ1",
|
||||
"cobblemon.pokedex.variation.face_spot_2": "顔のブチ2",
|
||||
"cobblemon.species.zacian-crowned.desc": "あらゆるものを 切り捨てるさまから 妖精王の剣 と 呼ばれ 敵味方に 恐れ崇められた。",
|
||||
"cobblemon.species.zamazenta-crowned.desc": "いかなる 攻撃も 弾き返す 姿は 格闘王の盾 と 呼ばれ 恐れ 崇められた。",
|
||||
"cobblemon.species.zacian-crowned.desc": "あらゆるものを 切り捨てるさまから §o妖精王の剣§r と 呼ばれ 敵味方に 恐れ崇められた。",
|
||||
"cobblemon.species.zamazenta-crowned.desc": "いかなる 攻撃も 弾き返す 姿は §o格闘王の盾§r と 呼ばれ 恐れ 崇められた。",
|
||||
"cobblemon.ui.pokedex.info.form.calyrex-ice": "はくばじょう",
|
||||
"cobblemon.species.gimmighoul-roaming.desc": "古い コインを 背負い さまよう。 コインを 拾おうとした 人の 生気を 吸い取って 生きている。",
|
||||
"cobblemon.species.archaludon.desc": "まわりから 静電気を 集める。 四つん這いの 体勢で 撃ち出す ビームは 絶大な 威力。",
|
||||
@@ -9466,7 +9466,7 @@
|
||||
"cobblemon.species.victreebel-mega.desc": "メガシンカにより 増量した 溶解液が 口内を 満たす。 気を抜くと 口から 溢れだす。",
|
||||
"cobblemon.species.starmie-mega.desc": "動きが 人間らしくなってきた。 意思疎通を 図ろうとしているのか 人に 成り代わるつもりかは 謎。",
|
||||
"cobblemon.species.dragonite-mega.desc": "メガシンカのエネルギーが 優しい 気持ちを 過剰に パワーアップ。 慈悲の 心で 敵を 葬る。",
|
||||
"cobblemon.species.meganium-mega.desc": "4輪の 花から 放たれる ソーラービームは 威力絶大。 別名 メガソーラー砲。",
|
||||
"cobblemon.species.meganium-mega.desc": "4輪の 花から 放たれる ソーラービームは 威力絶大。 別名 §oメガソーラー砲§r。",
|
||||
"cobblemon.species.feraligatr-mega.desc": "フードのような ヒレと 両腕で 巨大な 顎を 作り 噛みつく 威力は 10倍 アップした。",
|
||||
"cobblemon.species.skarmory-mega.desc": "飛行速度は 音速を 超える。 衝撃波を 巻き起こして 敵を 吹き飛ばし ツメで とどめを 刺す。",
|
||||
"cobblemon.species.chimecho-mega.desc": "全身を 震わせて あらゆる 方向を 音波で 攻撃。 聴いていると 自分を 見失う。",
|
||||
|
||||
@@ -2920,7 +2920,7 @@
|
||||
"cobblemon.move.meteorbeam": "메테오빔",
|
||||
"cobblemon.move.meteorbeam.desc": "1턴째에 우주의 힘을 모아서 특수공격을 올리고 2턴째에 상대를 공격한다.",
|
||||
"cobblemon.move.meteormash": "코멧펀치",
|
||||
"cobblemon.move.meteormash.desc": "혜성과 같은 펀치를 날려서 상대를 공격한다. 20%의 확률로 자신의 공격이 2랭크 오른다.",
|
||||
"cobblemon.move.meteormash.desc": "혜성과 같은 펀치를 날려서 상대를 공격한다. 20%의 확률로 자신의 공격이 1랭크 오른다.",
|
||||
"cobblemon.move.metronome": "손가락흔들기",
|
||||
"cobblemon.move.metronome.desc": "손가락을 흔들어 자신의 뇌를 자극해서 모든 기술 중 어느 하나를 날린다.",
|
||||
"cobblemon.move.milkdrink": "우유마시기",
|
||||
@@ -5699,7 +5699,7 @@
|
||||
"item.cobblemon.blunder_policy.tooltip_2": "사용 시 소모된다",
|
||||
"item.cobblemon.cell_battery.tooltip_1": "지니게 하고 전기 기술을 받으면 공격이 올라간다",
|
||||
"item.cobblemon.cell_battery.tooltip_2": "사용 시 소모된다",
|
||||
"item.cobblemon.charcoal_stick.tooltip": "물건을 태우는 연료. 지니게 하면 불꽃건을 태우는 연료. 지니게 하면 불꽃타입 기술의 위력이 올라간다",
|
||||
"item.cobblemon.charcoal_stick.tooltip": "물건을 태우는 연료. 지니게 하면 불꽃타입 기술의 위력이 올라간다",
|
||||
"item.cobblemon.choice_band.tooltip": "기술을 구애받는 머리띠. 지니게 하면 공격은 올라가지만 똑같은 기술밖에 쓰지 못한다",
|
||||
"item.cobblemon.choice_scarf.tooltip": "기술을 구애받는 스카프. 지니게 하면 스피드는 올라가지만 같은 기술밖에 쓸 수 없다",
|
||||
"item.cobblemon.cleanse_tag.tooltip": "효과가 없다",
|
||||
|
||||
@@ -9408,9 +9408,9 @@
|
||||
"cobblemon.ui.pokedex.info.form.glimmora-mega": "Mega Glimmora",
|
||||
"cobblemon.ui.pokedex.info.form.tatsugiri-mega": "Mega Tatsugiri Forma Curvada",
|
||||
"cobblemon.species.tatsugiri-mega.desc": "O cérebro de Tatsugiri foi energizado pela Mega Evolução, tornando-o mais astuto. Pode criar e comandar cópias de si mesmo.",
|
||||
"cobblemon.ui.pokedex.info.form.tatsugiri-droopymega": "Mega Tatsuguri Forma Molenga",
|
||||
"cobblemon.ui.pokedex.info.form.tatsugiri-droopymega": "Mega Tatsuguri Forma Pendular",
|
||||
"cobblemon.species.tatsugiri-droopymega.desc": "Solidifica a energia da Mega Evolução, construindo uma pilha excessiva para lançar como projéteis. Esses projéteis explodem ao primeiro contato.",
|
||||
"cobblemon.ui.pokedex.info.form.tatsugiri-stretchymega": "Mega Tatsugiri Forma Elástica",
|
||||
"cobblemon.ui.pokedex.info.form.tatsugiri-stretchymega": "Mega Tatsugiri Forma Estendida",
|
||||
"cobblemon.species.tatsugiri-stretchymega.desc": "Usando a energia da Mega Evolução, cria um prato onde repousar, permitindo com que se mova com mobilidade total até mesmo pelo ar.",
|
||||
"cobblemon.ui.pokedex.info.form.baxcalibur-mega": "Mega Baxcalibur",
|
||||
"cobblemon.species.baxcalibur-mega.desc": "A lâmina dorsal de Baxcalibur ficou ainda maior graças à Mega Evolução. Esse Pokémon dispara feixes do cabo localizado em seu peito."
|
||||
|
||||
@@ -3500,15 +3500,15 @@
|
||||
"cobblemon.species.machamp.name": "Мачамп",
|
||||
"cobblemon.species.machamp.desc": "Мачамп известен как покемон, в совершенстве овладевший всеми видами боевых искусств. Если он схватит противника своими четырьмя руками, битву можно считать практически законченной. Несчастный противник будет отброшен далеко за горизонт.",
|
||||
"cobblemon.species.bellsprout.name": "Беллспраут",
|
||||
"cobblemon.species.bellsprout.desc": "Prefers hot and humid places. It ensnares tiny bugs with its vines and devours them.",
|
||||
"cobblemon.species.bellsprout.desc": "Тонкое и гибкое тело Беллспраута позволяет ему изгибаться и раскачиваться, чтобы уклоняться от любой атаки, какой бы сильной она ни была. Этот покемон извергает из своего рта едкую жидкость, способную растворить даже железо.",
|
||||
"cobblemon.species.weepinbell.name": "Випинбелл",
|
||||
"cobblemon.species.weepinbell.desc": "When hungry, it swallows anything that moves. Its hapless prey is dissolved by strong acids.",
|
||||
"cobblemon.species.weepinbell.desc": "На задней части тела Випинбелла есть большой крючок. Ночью этот покемон цепляется к ветке дерева и засыпает. Если он шевелится во сне, то, проснувшись, может обнаружить, что он оказался на земле.",
|
||||
"cobblemon.species.victreebel.name": "Виктрибелл",
|
||||
"cobblemon.species.victreebel.desc": "Lures prey with the sweet aroma of honey. Swallowed whole, the prey is dissolved in a day, bones and all.",
|
||||
"cobblemon.species.victreebel.desc": "У Виктрибела из головы растёт длинная лиана. Он машет ею и взмахивает, имитируя животное, чтобы привлечь добычу. Когда ничего не подозревающая добыча подходит поближе, этот покемон проглатывает её целиком.",
|
||||
"cobblemon.species.tentacool.name": "Тентакул",
|
||||
"cobblemon.species.tentacool.desc": "They fire beams from the glassy, magenta orbs that resemble eyes atop their heads, and they drift in shallow seas. During low tide, they can sometimes be found on beaches, desiccated.",
|
||||
"cobblemon.species.tentacool.desc": "Тентакул поглощает солнечный свет и преломляет его, используя воду, находящуюся внутри его тела, чтобы преобразовать его в лучевую энергию. Этот покемон стреляет лучами из небольшого круглого органа, расположенного над глазами.",
|
||||
"cobblemon.species.tentacruel.name": "Тентакрул",
|
||||
"cobblemon.species.tentacruel.desc": "It has 80 tentacles, each with a venomous tip. These tentacles are also extendible, lengthening when Tentacruel attempts to catch prey. Use caution.",
|
||||
"cobblemon.species.tentacruel.desc": "У Тентакрула есть щупальца, которые он может свободно удлинять и укорачивать по собственному желанию. Он опутывает добычу своими щупальцами и ослабляет её, впрыскивая в неё сильный яд. Он может поймать до 80 особей одновременно.",
|
||||
"cobblemon.species.geodude.name": "Геодуд",
|
||||
"cobblemon.species.geodude.desc": "Makes its home in mountainous regions, using its arms to climb along harsh mountain roads. Can be troublesome—carelessly kicking one will cause it to fly into a rage and chase after you.",
|
||||
"cobblemon.species.graveler.name": "Гравелер",
|
||||
@@ -8392,7 +8392,7 @@
|
||||
"item.cobblemon.sweet_heart": "Сладкое сердце",
|
||||
"item.cobblemon.sweet_heart.tooltip": "Сладкое шоколадное лакомство",
|
||||
"item.cobblemon.technical_machine": "Техническое устройство (ТУ)",
|
||||
"item.cobblemon.blank_tm": "Пустое ТУ",
|
||||
"item.cobblemon.blank_tm": "Пустая ТМ",
|
||||
"block.cobblemon.deepslate_crystal_core": "Глубинный сланец с кристальным ядром",
|
||||
"block.cobblemon.normal_gem_block": "Блок нормального самоцвета",
|
||||
"block.cobblemon.fire_gem_block": "Блок огненного самоцвета",
|
||||
@@ -8432,16 +8432,16 @@
|
||||
"block.cobblemon.fairy_gem_cluster": "Друза волшебного самоцвета",
|
||||
"cobblemon.item_class.technical_machine": "Техническое устройство",
|
||||
"block.cobblemon.damaged_monitor": "Повреждённый отслеживатель данных",
|
||||
"block.cobblemon.tm_machine": "ТУ станок",
|
||||
"block.cobblemon.tm_machine": "ТМ станок",
|
||||
"block.cobblemon.disc_shelf": "Полка для дисков",
|
||||
"cobblemon.fishing_bait_effects.mark_chance.tooltip": "%1$s%% - +%3$s%% шанс метки",
|
||||
"cobblemon.ui.sort.discovered": "Сортировать по статусу открытия",
|
||||
"cobblemon.fishing_bait_effects.alpha_chance.tooltip": "%1$s%% - привлекает альфа покемонов",
|
||||
"cobblemon.fishing_bait_effects.size.tooltip": "%1$s%% - меняет размер на %3$s%%",
|
||||
"cobblemon.technical_machine_effect_header": "О техническом устройстве:",
|
||||
"cobblemon.command.technicalmachine.invalid-tm": "Неправильное ТУ",
|
||||
"cobblemon.command.technicalmachine.invalid-tm": "Неправильная ТМ",
|
||||
"cobblemon.ui.generic.question_marks": "???",
|
||||
"cobblemon.container.tm_machine": "ТУ станок",
|
||||
"cobblemon.container.tm_machine": "ТМ станок",
|
||||
"cobblemon.ui.edit.habitat": "Редактор среды",
|
||||
"cobblemon.ui.edit.habitat.mimic_id": "Идентификатор копируемого блока",
|
||||
"cobblemon.ui.edit.habitat.phase_order": "Фаза порядка: %s",
|
||||
@@ -8567,20 +8567,20 @@
|
||||
"advancements.cobblemon.construct_note_block_sequencer.description": "Создайте аудиосеквенсор из нотного блока и полки для дисков",
|
||||
"advancements.cobblemon.download_porygon": "Технические неполадки",
|
||||
"advancements.cobblemon.download_porygon.description": "Вы же не будете скачивать Поригона",
|
||||
"cobblemon.ui.moves.learnset.tm.discovered": "Обнаружен",
|
||||
"cobblemon.ui.moves.learnset.tm.discovered": "Обнаружена",
|
||||
"cobblemon.ui.moves.level": "Уровень",
|
||||
"cobblemon.ui.moves.egg": "Яйцо",
|
||||
"cobblemon.ui.moves.tm": "ТУ",
|
||||
"cobblemon.ui.tm_machine.can_learn": "Выучиваемый",
|
||||
"cobblemon.ui.tm_machine.cannot_learn": "Не выучиваемый",
|
||||
"cobblemon.ui.tm_machine.learned": "Выучен",
|
||||
"cobblemon.ui.moves.tm": "ТМ",
|
||||
"cobblemon.ui.tm_machine.can_learn": "Выучиваемая",
|
||||
"cobblemon.ui.tm_machine.cannot_learn": "Не выучиваемая",
|
||||
"cobblemon.ui.tm_machine.learned": "Выучена",
|
||||
"cobblemon.tms.unknown_move": "Неизвестный приём",
|
||||
"cobblemon.tms.already_known": "%1$s уже знает %2$s!",
|
||||
"cobblemon.tms.teach_move": "%1$s выучивает %2$s!",
|
||||
"cobblemon.tms.cannot_learn": "%1$s не может выучить %2$s!",
|
||||
"cobblemon.tms.unlock_tm": "Вы разблокировали ТУ для %1$s!",
|
||||
"cobblemon.tms.new_tms_learned": "Выучены новые ТУ!",
|
||||
"cobblemon.tms.check_tmm": "Проверьте ТУ станок",
|
||||
"cobblemon.tms.unlock_tm": "Вы разблокировали ТМ для %1$s!",
|
||||
"cobblemon.tms.new_tms_learned": "Выучены новые ТМ!",
|
||||
"cobblemon.tms.check_tmm": "Проверьте ТМ станок",
|
||||
"cobblemon.ui.party.party_select_title": "Изменить выбор команды",
|
||||
"cobblemon.ui.party.party_select_description": "Нажмите %1$s/%2$s или удерживайте %3$s и прокрутите.",
|
||||
"cobblemon.ui.category": "Категория",
|
||||
@@ -8592,7 +8592,7 @@
|
||||
"cobblemon.ui.pokedex.filter.seen": "Просмотрен",
|
||||
"cobblemon.ui.pokedex.filter.unregistered": "Незарегестрирован",
|
||||
"cobblemon.ui.pokedex.filter.rideable": "Ездовой",
|
||||
"cobblemon.ui.pokedex.filter.undiscovered_tm_move": "Необнаруженный ТУ приём",
|
||||
"cobblemon.ui.pokedex.filter.undiscovered_tm_move": "Необнаруженный ТМ приём",
|
||||
"cobblemon.habitat.abandoned_fortress.name": "Заброшенная крепость",
|
||||
"cobblemon.habitat.abandoned_village_house.name": "Заброшенный деревенский дом",
|
||||
"cobblemon.habitat.ancient_wellspring.name": "Древний источник",
|
||||
@@ -8641,16 +8641,16 @@
|
||||
"cobblemon.habitat.volcanic_plume.name": "Вулканический шлейф",
|
||||
"cobblemon.habitat.warped_fungal_dwelling.name": "Искажённое грибное жилище",
|
||||
"cobblemon.habitat.zen_garden.name": "Сад дзен",
|
||||
"cobblemon.subtitle.tm.use": "Использовано техническое устройство",
|
||||
"cobblemon.subtitle.block.tm_machine.burn_loop": "ТУ станок печатает ТУ",
|
||||
"cobblemon.subtitle.block.tm_machine.start": "ТУ станок начинает печатать ТУ",
|
||||
"cobblemon.subtitle.block.tm_machine.craft": "ТУ станок заканчивает печатать ТУ",
|
||||
"cobblemon.subtitle.block.tm_machine.open": "Крышка ТУ станка открывается",
|
||||
"cobblemon.subtitle.block.tm_machine.close": "Крышка ТУ станка закрывается",
|
||||
"cobblemon.subtitle.block.tm_machine.tm_insert": "Пустое ТУ вставлено в ТУ станок",
|
||||
"cobblemon.subtitle.block.tm_machine.tm_retrieve": "ТУ извлечено из ТУ станка",
|
||||
"cobblemon.subtitle.block.tm_machine.item_insert": "Предмет вставлен в ТУ станок",
|
||||
"cobblemon.subtitle.block.tm_machine.item_retrieve": "Предмет извлечён из ТУ станка",
|
||||
"cobblemon.subtitle.tm.use": "Использована техническая машина",
|
||||
"cobblemon.subtitle.block.tm_machine.burn_loop": "ТМ станок печатает ТМ",
|
||||
"cobblemon.subtitle.block.tm_machine.start": "ТМ станок начинает печатать ТМ",
|
||||
"cobblemon.subtitle.block.tm_machine.craft": "ТМ станок заканчивает печатать ТМ",
|
||||
"cobblemon.subtitle.block.tm_machine.open": "Крышка ТМ станка открывается",
|
||||
"cobblemon.subtitle.block.tm_machine.close": "Крышка ТМ станка закрывается",
|
||||
"cobblemon.subtitle.block.tm_machine.tm_insert": "Пустая ТМ вставлена в ТМ станок",
|
||||
"cobblemon.subtitle.block.tm_machine.tm_retrieve": "ТМ извлечена из ТМ станка",
|
||||
"cobblemon.subtitle.block.tm_machine.item_insert": "Предмет вставлен в ТМ станок",
|
||||
"cobblemon.subtitle.block.tm_machine.item_retrieve": "Предмет извлечён из ТМ станка",
|
||||
"cobblemon.ui.exp.number": "+%1$s §o опыта",
|
||||
"cobblemon.config.ui.award_experience_to_fainted_pokemon": "Выдавать опыт поверженным покемонам",
|
||||
"cobblemon.config.ui.award_experience_to_fainted_pokemon.tooltip": "Поверженные покемоны получают опыт за противников, которых они помогли победить до того, как были повержены.",
|
||||
@@ -8687,9 +8687,9 @@
|
||||
"cobblemon.config.ui.minimum_riding_scale": "Минимальный модификатор размера покемона для езды",
|
||||
"cobblemon.config.ui.minimum_riding_scale.tooltip": "Размер, при котором нельзя кататься на покемоне.",
|
||||
"cobblemon.config.ui.unlock_all_move_dex_moves_by_default": "Разблокировать все приёмы",
|
||||
"cobblemon.config.ui.unlock_all_move_dex_moves_by_default.tooltip": "Если эта опция включена, ТУ и приёмы, получаемые при повышении уровня, становятся доступными и можно их найти в ТУ машине и в разделе покедекса для приёмов.",
|
||||
"cobblemon.config.ui.infinite_tm_uses": "Бесконечное использование ТУ",
|
||||
"cobblemon.config.ui.infinite_tm_uses.tooltip": "ТУ не пропадают после использования.",
|
||||
"cobblemon.config.ui.unlock_all_move_dex_moves_by_default.tooltip": "Если эта опция включена, ТМ и приёмы, получаемые при повышении уровня, становятся доступными и можно их найти в ТМ машине и в разделе с приёмами в покедексе.",
|
||||
"cobblemon.config.ui.infinite_tm_uses": "Бесконечное использование ТМ",
|
||||
"cobblemon.config.ui.infinite_tm_uses.tooltip": "ТМ не пропадают после использования.",
|
||||
"cobblemon.battle.combine": "Два приёма стали одним! Это совместный приём!",
|
||||
"cobblemon.battle.waiting": "%1$s ожидает приёма от %2$s...",
|
||||
"cobblemon.battle.start.alphaboost": "Альфа %1$s наполняется дикой силой! Его сила возрастает!",
|
||||
@@ -9013,5 +9013,13 @@
|
||||
"cobblemon.species.growlithe-hisui.desc": "Они патрулируют свою территорию парами. Я полагаю, что наличие магматических пород в шерсти этого вида является результатом вулканической деятельности в его среде обитания.",
|
||||
"cobblemon.species.arcanine-hisui.desc": "Набрасывается на своих врагов с окутанными ярким пламенем клыками. Несмотря на свои внушительные размеры, он ловко делает манёвры во всех стороны, увлекая противников в обманчиво весёлую погоню, словно танцуя вокруг них.",
|
||||
"cobblemon.species.alakazam-mega.desc": "Потеряв свои мышцы, истинную мощь Алаказама была высвобождена. Используя свои психические способности он может предвидеть всё.",
|
||||
"cobblemon.species.machamp-gmax.desc": "Гигантамакс энергия, текущая в его руках, придаёт его ударам силу, сравнимую с взрывом бомбы."
|
||||
"cobblemon.species.machamp-gmax.desc": "Гигантамакс энергия, текущая в его руках, придаёт его ударам силу, сравнимую с взрывом бомбы.",
|
||||
"cobblemon.ui.starter.random": "Случайный",
|
||||
"advancements.cobblemon.obtain_tm": "Покажи, что ты можешь",
|
||||
"cobblemon.ui.starter.random_description": "Случайный покемон из списка доступных вариантов. Невозможно узнать, кто им будет, пока не выбрана эта опция.",
|
||||
"cobblemon.config.ui.world_spawning_blocklist": "Список запрещённых появлений на мир",
|
||||
"cobblemon.config.ui.world_spawning_blocklist.tooltip": "Миры, в которых отключается принцип появления покемонов.",
|
||||
"advancements.cobblemon.obtain_tm.description": "Найдите или напечатайте ТМ",
|
||||
"cobblemon.species.victreebel-mega.desc": "В результате Мега эволюции объём кислоты у этого покемона увеличился, заполняя весь его рот. Если он не будет осторожен, кислота переполнится и выльется наружу.",
|
||||
"cobblemon.ui.pokedex.info.form.victreebel-mega": "Мега Виктрибелл"
|
||||
}
|
||||
|
||||
@@ -7347,5 +7347,6 @@
|
||||
"cobblemon.mark.ribbon_day_downcast": "Стрічка смутку",
|
||||
"cobblemon.mark.ribbon_day_downcast.desc": "Стрічка на згадку про почуття смутку, що додали життю барв.",
|
||||
"cobblemon.mark.ribbon_day_downcast.title": "Приголомшений %1$s",
|
||||
"cobblemon.mark.ribbon_day_relax": "Стрічка відпочинку"
|
||||
"cobblemon.mark.ribbon_day_relax": "Стрічка відпочинку",
|
||||
"cobblemon.mark.ribbon_day_relax.title": "%1$s відпочив"
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -4,32 +4,54 @@
|
||||
"displayAspects": [],
|
||||
"conditionAspects": [],
|
||||
"forms": [
|
||||
{
|
||||
"displayForm": "Normal",
|
||||
"unlockForms": [
|
||||
"Normal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Meteor",
|
||||
"unlockForms": [
|
||||
"Meteor"
|
||||
]
|
||||
}
|
||||
],
|
||||
"variations": [
|
||||
},
|
||||
{
|
||||
"displayName": "cobblemon.pokedex.variation.color",
|
||||
"icon": "cobblemon:textures/gui/pokedex/variation/color.png",
|
||||
"aspects": [
|
||||
"red-core",
|
||||
"orange-core",
|
||||
"yellow-core",
|
||||
"green-core",
|
||||
"blue-core",
|
||||
"indigo-core",
|
||||
"violet-core"
|
||||
"displayForm": "Red",
|
||||
"unlockForms": [
|
||||
"Red"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Orange",
|
||||
"unlockForms": [
|
||||
"Orange"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Yellow",
|
||||
"unlockForms": [
|
||||
"Yellow"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Green",
|
||||
"unlockForms": [
|
||||
"Green"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Blue",
|
||||
"unlockForms": [
|
||||
"Blue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Indigo",
|
||||
"unlockForms": [
|
||||
"Indigo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Violet",
|
||||
"unlockForms": [
|
||||
"Violet"
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"variations": []
|
||||
}
|
||||
@@ -4,12 +4,6 @@
|
||||
"displayAspects": [],
|
||||
"conditionAspects": [],
|
||||
"forms": [
|
||||
{
|
||||
"displayForm": "Normal",
|
||||
"unlockForms": [
|
||||
"Normal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayForm": "Icy Snow",
|
||||
"unlockForms": [
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"neededInstalledMods": [],
|
||||
"neededUninstalledMods": [],
|
||||
"spawns": [
|
||||
{
|
||||
"presets": [
|
||||
"water"
|
||||
],
|
||||
"type": "empty",
|
||||
"spawnablePositionType": "surface",
|
||||
"bucket": "common",
|
||||
"weight": 200.0,
|
||||
"condition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_ocean"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_deep_ocean"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"presets": [
|
||||
"lava"
|
||||
],
|
||||
"type": "empty",
|
||||
"spawnablePositionType": "surface",
|
||||
"bucket": "common",
|
||||
"weight": 200.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -37,7 +37,9 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_spooky"
|
||||
"#cobblemon:is_beach",
|
||||
"#cobblemon:is_spooky",
|
||||
"#cobblemon:is_tropical_island"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_spooky"
|
||||
"#cobblemon:is_beach",
|
||||
"#cobblemon:is_spooky",
|
||||
"#cobblemon:is_tropical_island"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
"#cobblemon:is_jungle",
|
||||
"#cobblemon:is_savanna"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_beach",
|
||||
"#cobblemon:is_tropical_island"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
"#cobblemon:is_jungle",
|
||||
"#cobblemon:is_savanna"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_beach",
|
||||
"#cobblemon:is_tropical_island"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
"#cobblemon:is_badlands",
|
||||
"#cobblemon:is_desert"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_volcanic"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -76,7 +81,8 @@
|
||||
},
|
||||
"condition": {
|
||||
"biomes": [
|
||||
"#cobblemon:nether/is_desert"
|
||||
"#cobblemon:nether/is_desert",
|
||||
"#cobblemon:nether/is_soul_fire"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
"#cobblemon:is_badlands",
|
||||
"#cobblemon:is_desert"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_volcanic"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -76,7 +81,8 @@
|
||||
},
|
||||
"condition": {
|
||||
"biomes": [
|
||||
"#cobblemon:nether/is_desert"
|
||||
"#cobblemon:nether/is_desert",
|
||||
"#cobblemon:nether/is_soul_fire"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
"biomes": [
|
||||
"#cobblemon:is_overworld"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_magical",
|
||||
"#cobblemon:is_spooky"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -71,6 +77,12 @@
|
||||
"structures": [
|
||||
"#minecraft:village"
|
||||
]
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_magical",
|
||||
"#cobblemon:is_spooky"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_taiga",
|
||||
"#cobblemon:is_spooky"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_taiga",
|
||||
"#cobblemon:is_spooky"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_taiga",
|
||||
"#cobblemon:is_spooky"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
},
|
||||
"anticondition": {
|
||||
"biomes": [
|
||||
"#cobblemon:is_spooky"
|
||||
"#cobblemon:is_beach",
|
||||
"#cobblemon:is_spooky",
|
||||
"#cobblemon:is_tropical_island"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "rowlet-hisui-3",
|
||||
"id": "rowlet-hisui-2",
|
||||
"pokemon": "rowlet region_bias=hisui",
|
||||
"presets": [
|
||||
"natural",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dartrix-hisui-3",
|
||||
"id": "dartrix-hisui-2",
|
||||
"pokemon": "dartrix region_bias=hisui",
|
||||
"presets": [
|
||||
"natural",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "decidueye-hisuian-3",
|
||||
"id": "decidueye-hisuian-2",
|
||||
"pokemon": "decidueye hisuian",
|
||||
"presets": [
|
||||
"natural",
|
||||
|
||||
@@ -217,27 +217,6 @@
|
||||
{
|
||||
"variant": "level",
|
||||
"minLevel": 28
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_volcanic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_beach"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#minecraft:is_nether"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -261,20 +240,6 @@
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/cubone_alolabiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_arid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#minecraft:is_nether"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -342,21 +307,7 @@
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_volcanic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_beach"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#minecraft:is_nether"
|
||||
"biomeCondition": "#cobblemon:evolution/regional/cubone_alolabiome"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -377,20 +328,6 @@
|
||||
{
|
||||
"variant": "time_range",
|
||||
"range": "night"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_arid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#minecraft:is_nether"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -453,4 +390,4 @@
|
||||
"willDefendOwner": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,17 +165,6 @@
|
||||
"special:sing"
|
||||
],
|
||||
"evolutions": [
|
||||
{
|
||||
"id": "eevee_jolteon",
|
||||
"variant": "item_interact",
|
||||
"result": "jolteon",
|
||||
"consumeHeldItem": false,
|
||||
"learnableMoves": [
|
||||
"thundershock"
|
||||
],
|
||||
"requirements": [],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
},
|
||||
{
|
||||
"id": "eevee_vaporeon",
|
||||
"variant": "item_interact",
|
||||
@@ -187,6 +176,17 @@
|
||||
"requirements": [],
|
||||
"requiredContext": "cobblemon:water_stone"
|
||||
},
|
||||
{
|
||||
"id": "eevee_jolteon",
|
||||
"variant": "item_interact",
|
||||
"result": "jolteon",
|
||||
"consumeHeldItem": false,
|
||||
"learnableMoves": [
|
||||
"thundershock"
|
||||
],
|
||||
"requirements": [],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
},
|
||||
{
|
||||
"id": "eevee_flareon",
|
||||
"variant": "item_interact",
|
||||
@@ -237,26 +237,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "eevee_sylveon",
|
||||
"variant": "level_up",
|
||||
"result": "sylveon",
|
||||
"consumeHeldItem": false,
|
||||
"learnableMoves": [
|
||||
"fairywind",
|
||||
"disarmingvoice"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "friendship",
|
||||
"amount": 160
|
||||
},
|
||||
{
|
||||
"variant": "has_move_type",
|
||||
"type": "fairy"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "eevee_leafeon",
|
||||
"variant": "item_interact",
|
||||
@@ -278,6 +258,26 @@
|
||||
],
|
||||
"requirements": [],
|
||||
"requiredContext": "cobblemon:ice_stone"
|
||||
},
|
||||
{
|
||||
"id": "eevee_sylveon",
|
||||
"variant": "level_up",
|
||||
"result": "sylveon",
|
||||
"consumeHeldItem": false,
|
||||
"learnableMoves": [
|
||||
"fairywind",
|
||||
"disarmingvoice"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "friendship",
|
||||
"amount": 160
|
||||
},
|
||||
{
|
||||
"variant": "has_move_type",
|
||||
"type": "fairy"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"forms": [
|
||||
|
||||
@@ -233,22 +233,6 @@
|
||||
"learnableMoves": [
|
||||
"stomp"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_beach"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_tropical_island"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:leaf_stone"
|
||||
},
|
||||
{
|
||||
@@ -301,6 +285,13 @@
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/exeggcute_kantobiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/exeggcute_alolabiome"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:leaf_stone"
|
||||
@@ -313,25 +304,9 @@
|
||||
"learnableMoves": [
|
||||
"dragonhammer"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_jungle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_savanna"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:leaf_stone"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,20 +217,6 @@
|
||||
{
|
||||
"variant": "level",
|
||||
"minLevel": 35
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_magical"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_spooky"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -290,6 +276,13 @@
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/koffing_kantobiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/koffing_galarbiome"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -305,17 +298,10 @@
|
||||
{
|
||||
"variant": "level",
|
||||
"minLevel": 35
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:nether/is_toxic"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,36 +297,6 @@
|
||||
"learnableMoves": [
|
||||
"thunderpunch"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_beach"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_tropical_island"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "aether:skyroot_forest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "aether:skyroot_woodland"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
},
|
||||
{
|
||||
@@ -341,13 +311,6 @@
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/pikachu_alolabiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_forest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
@@ -424,37 +387,16 @@
|
||||
"thunderpunch"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_beach"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_tropical_island"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "aether:skyroot_forest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "aether:skyroot_woodland"
|
||||
}
|
||||
},
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/pikachu_kantobiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/pikachu_alolabiome"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
@@ -467,18 +409,9 @@
|
||||
"learnableMoves": [
|
||||
"psychic"
|
||||
],
|
||||
"requirements": [
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:is_forest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredContext": "cobblemon:thunder_stone"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
"baseFriendship": 50,
|
||||
"baseScale": 1,
|
||||
"hitbox": {
|
||||
"width": 0.6,
|
||||
"height": 1,
|
||||
"width": 0.65,
|
||||
"height": 1.35,
|
||||
"fixed": false
|
||||
},
|
||||
"behaviour": {
|
||||
|
||||
@@ -281,6 +281,13 @@
|
||||
{
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/quilava_johtobiome"
|
||||
},
|
||||
{
|
||||
"variant": "negate",
|
||||
"inner": {
|
||||
"variant": "biome",
|
||||
"biomeCondition": "#cobblemon:evolution/regional/quilava_hisuibiome"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -302,4 +309,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"implemented": true,
|
||||
"nationalPokedexNumber": 460,
|
||||
"name": "Abomasnow",
|
||||
"primaryType": "grass",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user