forked from mirrors/cobblemon
Compare commits
319
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c9ef35805 | ||
|
|
4a3f3b0d3f | ||
|
|
bc423515fb | ||
|
|
13e8e39d43 | ||
|
|
8dd6446b6a | ||
|
|
8fc9b46ce7 | ||
|
|
832d315501 | ||
|
|
d4da62adb5 | ||
|
|
f7f6e9d2ee | ||
|
|
8a375d5e81 | ||
|
|
cf36db419d | ||
|
|
f634d7fae0 | ||
|
|
dddb3b3d48 | ||
|
|
2468f8a8e6 | ||
|
|
c6ce359736 | ||
|
|
3f35ca5bd2 | ||
|
|
e053d2864e | ||
|
|
e098426a6d | ||
|
|
069f483552 | ||
|
|
9a8c7dc8bf | ||
|
|
82ba0334a7 | ||
|
|
bfed3ad52f | ||
|
|
149a59ffbf | ||
|
|
a7dd139c14 | ||
|
|
3866e888de | ||
|
|
5089ea5027 | ||
|
|
840762c00d | ||
|
|
b38c44321e | ||
|
|
1ba7ed425e | ||
|
|
9645a1dd17 | ||
|
|
232d871bef | ||
|
|
ce0b5b77bd | ||
|
|
aaae400f0a | ||
|
|
ba42daa83e | ||
|
|
c6cb98cabd | ||
|
|
95f56fc1f8 | ||
|
|
a328c54dda | ||
|
|
93515777b8 | ||
|
|
16e327bd27 | ||
|
|
0edb9ad115 | ||
|
|
8189e5d819 | ||
|
|
72234e6260 | ||
|
|
48e341aca6 | ||
|
|
f2aed673ee | ||
|
|
51d214d45e | ||
|
|
fa67e21a76 | ||
|
|
d2bbf12598 | ||
|
|
e58ffb9a00 | ||
|
|
0281dd2e94 | ||
|
|
2ae1c9f657 | ||
|
|
9889307981 | ||
|
|
9a18dcadd4 | ||
|
|
7e6864764f | ||
|
|
e6636bb6af | ||
|
|
78706548ab | ||
|
|
da6455fd33 | ||
|
|
074073a933 | ||
|
|
f82712e6b4 | ||
|
|
5745ff547c | ||
|
|
8f5617c986 | ||
|
|
02f69779a1 | ||
|
|
a2bfc55e96 | ||
|
|
1f9c632883 | ||
|
|
7fecdb1126 | ||
|
|
f88ec39ec7 | ||
|
|
f8b4b2fc2a | ||
|
|
271aef9821 | ||
|
|
ce9970ca1a | ||
|
|
bf47299b2f | ||
|
|
e56b399c59 | ||
|
|
0f505ea3f8 | ||
|
|
478859d0ed | ||
|
|
cf95f62185 | ||
|
|
067e9d42e7 | ||
|
|
ebdffb44e8 | ||
|
|
6cc609fdfc | ||
|
|
864a4f5c09 | ||
|
|
d2f365504b | ||
|
|
024ec427da | ||
|
|
935ea3ad53 | ||
|
|
f270e479e6 | ||
|
|
ce5d3e75a0 | ||
|
|
51be1364d3 | ||
|
|
27706a766e | ||
|
|
058c06f56b | ||
|
|
28bee4189a | ||
|
|
3f0e21b6b3 | ||
|
|
9ca2d47562 | ||
|
|
94f0914aa8 | ||
|
|
60101876b5 | ||
|
|
b8a4dfbcb4 | ||
|
|
fbc5959c67 | ||
|
|
49f20fe1a4 | ||
|
|
3c4288d7fc | ||
|
|
e03bb51a74 | ||
|
|
8545de321f | ||
|
|
5e353e9a6d | ||
|
|
c1fd257f63 | ||
|
|
ea0ff3bfb9 | ||
|
|
9350960457 | ||
|
|
1b3daa2740 | ||
|
|
6cfe3fd39d | ||
|
|
d4b6e36aab | ||
|
|
338cb819af | ||
|
|
1a75d4b2e8 | ||
|
|
5c4c7b2995 | ||
|
|
0fb721702d | ||
|
|
0e5053b787 | ||
|
|
f3867e0b1d | ||
|
|
a4fcd1ae7b | ||
|
|
ed9aff2448 | ||
|
|
8497a2a083 | ||
|
|
b389a95b5e | ||
|
|
c310027ce1 | ||
|
|
5ddb01df36 | ||
|
|
5a6f49aad5 | ||
|
|
793efcfa3d | ||
|
|
d671c5a8b8 | ||
|
|
69b31dd9b9 | ||
|
|
f785c5405f | ||
|
|
fc94bbac4c | ||
|
|
f7d315fa33 | ||
|
|
7c30fd81f3 | ||
|
|
7f1704d573 | ||
|
|
0c2ec3ca81 | ||
|
|
33d3e156cc | ||
|
|
415642a8ba | ||
|
|
dd12081cd1 | ||
|
|
b7de84acfd | ||
|
|
2dfca3ff89 | ||
|
|
8efda8c47b | ||
|
|
6baf96f83b | ||
|
|
009a9c3f15 | ||
|
|
fc0a6c0c8b | ||
|
|
041e080cd4 | ||
|
|
65bbadcfa8 | ||
|
|
a70d5e200a | ||
|
|
4d0ee751a3 | ||
|
|
d87438e53d | ||
|
|
3efef07afa | ||
|
|
9ff227fbef | ||
|
|
55ef5fd537 | ||
|
|
b3cdfb579c | ||
|
|
29588f1fde | ||
|
|
24c10d1a4f | ||
|
|
ac0d9d4d74 | ||
|
|
d33974b19e | ||
|
|
1dcdfe309e | ||
|
|
6ce1990145 | ||
|
|
1203721889 | ||
|
|
333672f993 | ||
|
|
f0f9a9596f | ||
|
|
80b8aa2b8c | ||
|
|
b919e447d8 | ||
|
|
3075b7fd73 | ||
|
|
412e3fcb8a | ||
|
|
32253fd462 | ||
|
|
4de018a209 | ||
|
|
2204a4b700 | ||
|
|
22a27cbbd7 | ||
|
|
e202e7bf2f | ||
|
|
03104b3a3d | ||
|
|
280e1ae820 | ||
|
|
ee5653bfba | ||
|
|
a9c3c14367 | ||
|
|
9cdc979067 | ||
|
|
4b45fdde3f | ||
|
|
5bf7cc6aef | ||
|
|
7cf1f5a4e5 | ||
|
|
0fe2b0f60c | ||
|
|
667376226b | ||
|
|
5506e076f6 | ||
|
|
f8799efd9d | ||
|
|
bb642fbf29 | ||
|
|
e19aa02283 | ||
|
|
e65010e289 | ||
|
|
4b4a715868 | ||
|
|
26ec5717f1 | ||
|
|
446d4771d8 | ||
|
|
9d817b3f77 | ||
|
|
21213c4fce | ||
|
|
cebf105dd5 | ||
|
|
123d3291c6 | ||
|
|
935a39c578 | ||
|
|
d53e67b55c | ||
|
|
ec0766ddcd | ||
|
|
917577f7a8 | ||
|
|
01de2f71af | ||
|
|
0779251581 | ||
|
|
14d4c6c2e4 | ||
|
|
de82d36da3 | ||
|
|
ae2704e218 | ||
|
|
a235c1286c | ||
|
|
ce584bd403 | ||
|
|
1c25861e04 | ||
|
|
006cc21ebb | ||
|
|
5ab9072f94 | ||
|
|
f7023b9737 | ||
|
|
987a7d0ccc | ||
|
|
d49c0a0ec6 | ||
|
|
d4a910bf26 | ||
|
|
25b75231ad | ||
|
|
0db1f372e3 | ||
|
|
1ddffc1c0d | ||
|
|
5fe04aad83 | ||
|
|
03b74d4b72 | ||
|
|
a5f150af9a | ||
|
|
b3b5e47cc9 | ||
|
|
1d0aa06dc4 | ||
|
|
1e5c0f5137 | ||
|
|
7bafd53f58 | ||
|
|
bdbdf238f5 | ||
|
|
6cd71050df | ||
|
|
2047f4f461 | ||
|
|
0aaed4bb84 | ||
|
|
3779b4c0b3 | ||
|
|
74aaa16a0d | ||
|
|
332ef2fddd | ||
|
|
f29c5c5f6d | ||
|
|
c46375aafb | ||
|
|
a5e16ccf65 | ||
|
|
4cc83560e8 | ||
|
|
a7f4ef8449 | ||
|
|
edaafa2263 | ||
|
|
0162bdae5f | ||
|
|
da82eb8d61 | ||
|
|
34fc434883 | ||
|
|
74949a02de | ||
|
|
1617c1b087 | ||
|
|
4b1c180538 | ||
|
|
cba6f51706 | ||
|
|
9b9fbedaf7 | ||
|
|
8c3acd9a0e | ||
|
|
4ab52cac0e | ||
|
|
68805a5dd1 | ||
|
|
5a0b4e8f99 | ||
|
|
3e9d3a307f | ||
|
|
7c4d3ecb71 | ||
|
|
e91fd5596a | ||
|
|
f9d218adf8 | ||
|
|
05d70b28e7 | ||
|
|
6755462eb0 | ||
|
|
7ef3facac8 | ||
|
|
2dc93f3336 | ||
|
|
b7c16324bd | ||
|
|
e8864418d4 | ||
|
|
7ccd0bbe11 | ||
|
|
e1cc9c7aba | ||
|
|
79e821a438 | ||
|
|
d289880cc8 | ||
|
|
19dd57feed | ||
|
|
6609c7d038 | ||
|
|
88afe05c16 | ||
|
|
e739b57a08 | ||
|
|
99aa25e1bf | ||
|
|
76faa50035 | ||
|
|
8ce989cb6b | ||
|
|
02030950aa | ||
|
|
82b418d54d | ||
|
|
6148b58fdc | ||
|
|
2044762b72 | ||
|
|
77117e83c7 | ||
|
|
55f4e6e738 | ||
|
|
1e4936aeac | ||
|
|
15ea72e777 | ||
|
|
3c3d4e4552 | ||
|
|
796e416578 | ||
|
|
7608dfde94 | ||
|
|
b2b871617a | ||
|
|
bc4c8d13b7 | ||
|
|
0f9c51f7dd | ||
|
|
2c2623e0f9 | ||
|
|
8ec85e7d2f | ||
|
|
d5a08314eb | ||
|
|
062c32be2a | ||
|
|
09590b49cd | ||
|
|
420cbd2c99 | ||
|
|
0380013f37 | ||
|
|
6c1fcc103a | ||
|
|
59b01c3988 | ||
|
|
678fa2d0ce | ||
|
|
94abd79923 | ||
|
|
0a1931aaae | ||
|
|
85d76dcc29 | ||
|
|
bd0a9ef654 | ||
|
|
7a702e276c | ||
|
|
3f9a2825cb | ||
|
|
d1462bc27b | ||
|
|
211b14dbd0 | ||
|
|
47e83003c3 | ||
|
|
59134c4212 | ||
|
|
44b434562c | ||
|
|
7af9b0854a | ||
|
|
344b0750f9 | ||
|
|
10d9d97c11 | ||
|
|
94bcfba076 | ||
|
|
69a75ffcd4 | ||
|
|
cc1317dd06 | ||
|
|
e15ac73b1b | ||
|
|
6c6576c117 | ||
|
|
ebdfa7edc0 | ||
|
|
297e8eae77 | ||
|
|
ea8179018d | ||
|
|
14fccfae1d | ||
|
|
26386638ad | ||
|
|
5d1d99b64a | ||
|
|
a3c5a6c377 | ||
|
|
abb5346305 | ||
|
|
9466f66721 | ||
|
|
716ea55bc7 | ||
|
|
15f0ad1821 | ||
|
|
0d433ff394 | ||
|
|
a16975c750 | ||
|
|
c0e6d87c40 | ||
|
|
91078b917e | ||
|
|
b7e27fa52a | ||
|
|
dc87ffd2a8 | ||
|
|
cbeda361d4 | ||
|
|
079a2fb50d |
@@ -16,6 +16,7 @@ check_assets_cache:
|
||||
stage: preprocessing
|
||||
script:
|
||||
- echo "Checking if cached hash matches current hash"
|
||||
- yum install -y findutils
|
||||
|
||||
# Calculate the current hash
|
||||
- find common/src/main/resources/assets common/src/main/resources/data -type f -exec sha256sum {} + | sort -k 2 | sha256sum > current_hash.txt
|
||||
@@ -148,6 +149,7 @@ build:
|
||||
dependencies:
|
||||
- replace_resources
|
||||
script:
|
||||
- yum install -y findutils
|
||||
- export GRADLE_OPTS="-Xmx4G -Xms4G"
|
||||
- chmod +x ./gradlew
|
||||
- ./gradlew build
|
||||
@@ -163,6 +165,7 @@ publish:
|
||||
rules:
|
||||
- if: '$CI_PROJECT_PATH == "cable-mc/cobblemon" && $CI_COMMIT_BRANCH == "main"'
|
||||
script:
|
||||
- yum install -y findutils
|
||||
- export GRADLE_OPTS="-Xmx4G -Xms4G"
|
||||
- chmod +x ./gradlew
|
||||
- ./gradlew publish
|
||||
@@ -176,6 +179,7 @@ deploy_artifacts:
|
||||
dependencies:
|
||||
- build
|
||||
script:
|
||||
- yum install -y findutils
|
||||
- echo "Collecting artifacts..."
|
||||
- find neoforge/build/libs/ -type f -name "*.jar" | grep -vE "dev-shadow|sources|javadoc" | xargs -I {} mv {} ./
|
||||
- find fabric/build/libs/ -type f -name "*.jar" | grep -vE "dev-shadow|sources|javadoc" | xargs -I {} mv {} ./
|
||||
|
||||
+87
-24
@@ -2,6 +2,7 @@
|
||||
## [1.8.0 (MONTH Xth, 2026)](#1-8-0)
|
||||
|
||||
### Additions
|
||||
- Added `/locatefeature` command, a `/locate` equivalent for placed features such as fossil sites, habitats, and ruins. It finds candidate chunks in unexplored terrain by replaying the world seed's decoration randomness, then confirms each one by really generating it and observing the placement, so every reported site is one where the feature genuinely generated. Reports up to 5 nearest sites as clickable teleport coordinates; an optional radius argument (in chunks, up to 512) adjusts the default 400-chunk search. Placements are also remembered as chunks generate while the server runs, so repeated searches stay consistent and cover explored terrain. Terrain generated in earlier sessions or before this update is answered with seed-based predictions, which are exact as long as the world's generation config hasn't changed since that terrain generated
|
||||
- Added config options to award experience to fainted Pokémon for opponents they helped defeat (`awardExperienceToFaintedPokemon`) and to still award experience for defeated enemies even after battle loss/forfeit (`awardExperienceOnBattleLoss`)
|
||||
- Party Overlay Exp Gained Animation will now display the amount of EXP the Pokémon gained
|
||||
- Added a toast to notify players of how they can scroll through their party. Did you know you can hold R and scroll instead of using arrow keys??!
|
||||
@@ -21,7 +22,7 @@
|
||||
- Added Move Dex to Pokédex
|
||||
- Added the Habitat Block, a spawner block for servers and adventure maps that controls spawning in an area.
|
||||
- Added Disk Rack for storing disks and being an audio sequencer for Noteblocks
|
||||
- Added intrinsic scaling to all mons (+-5%). Some rendering cases, such as shoulder mounting, revert to 1.0 scaling to preserve animation accuracy.
|
||||
- Added intrinsic scaling to all Pokémon (+-5%). Some rendering cases, such as shoulder mounting, revert to 1.0 scaling to preserve animation accuracy.
|
||||
- Added scaling to "baby" Pokémon (smaller (-20%) at level 1 → normally sized at level 10)
|
||||
- Added conditional seats for riding. Seats can be gated by molang such as "is_alpha".
|
||||
- Added Alpha Pokémon
|
||||
@@ -42,9 +43,8 @@
|
||||
- All ruin structures gilded chest loot tables have been updated to include a guaranteed TM not learned naturally by any Pokémon through their level-up moveset. Each ruin gets its own specific TM, so you can now go hunting ruins to complete your move dex!
|
||||
- All fossil structures have been transferred over to biome features, allowing for better placement in generation.
|
||||
- The prehistoric_underwater_fissure & prehistoric_submerged_impact fossil structures now use the biome tag `#cobblemon:is_temperate_ocean`.
|
||||
- A new Biome tag called `#cobblemon:is_stony_beach` has been added.
|
||||
- Gimmighoul towers now generate at ground level rather than sinking one block into the ground.
|
||||
- 1 New shipwreck cove structure called the "magma_shipwreck_cove" has been added.
|
||||
- A new shipwreck cove structure called the "magma_shipwreck_cove" has been added.
|
||||
- Shipwreck coves now generate slightly more frequently.
|
||||
- Added equipment loot tables for shipwreck cove enemies.
|
||||
- Maps from abandoned fishing boats leading to shipwreck coves now will skip explored chunks, allowing the player to find more shipwreck coves easier.
|
||||
@@ -57,15 +57,18 @@
|
||||
- Pokémon cries now play when clicking Pokémon in the summary screen.
|
||||
- Pressing the Summary key while either the starter selection or summary screen are open now closes those screens
|
||||
- Ice type Pokémon are now immune to Packed Snow
|
||||
- Held item visibility can now be controlled by the held_item_visible command argument.
|
||||
|
||||
### New rideable Pokémon
|
||||
- Drampa
|
||||
- Archeops
|
||||
- Skarmory
|
||||
- Crobat
|
||||
- Goodra
|
||||
- Hisuian Goodra
|
||||
- Skarmory
|
||||
- Milotic
|
||||
- Archeops
|
||||
- Goodra
|
||||
- Goodra (Hisuian Form)
|
||||
- Drampa
|
||||
- Duraludon
|
||||
- Archaludon
|
||||
|
||||
### Pokémon Added
|
||||
#### Generation 3
|
||||
@@ -162,7 +165,10 @@
|
||||
- Cofagrigus
|
||||
- Tyranitar
|
||||
- Turtonator
|
||||
- Golett
|
||||
- Corsola
|
||||
- Arbok (New Patterns: Angry, Cartoon, Clown, Comedic, Crow, Grin, Ink, Modern, Rain, Scribble, Silence, Sloth, Suspicious, Will)
|
||||
- ... and Substitute
|
||||
|
||||
#### Model changes to the regional bias resource pack:
|
||||
|
||||
@@ -171,6 +177,26 @@
|
||||
- Changed models for every existing regional bias
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
|
||||
- Kakuna
|
||||
- Grimer
|
||||
- Nidoran♀ (+ New shoulder mount)
|
||||
- Nidorina
|
||||
- Nidoran♂ (+ New shoulder mount)
|
||||
- Sandshrew
|
||||
- Diglett
|
||||
- Dugtrio
|
||||
- Graveler
|
||||
- Happiny
|
||||
- Chansey
|
||||
- Blissey
|
||||
- Poliwhirl
|
||||
- Poliwrath
|
||||
- Zubat
|
||||
- Vulpix
|
||||
- Drowzee
|
||||
- Hypno
|
||||
- Noctowl
|
||||
- Skarmory
|
||||
- Skitty
|
||||
- Flygon
|
||||
@@ -202,8 +228,19 @@
|
||||
- Yamask
|
||||
- Cofagrigus
|
||||
- Luvdisc
|
||||
- Staryu
|
||||
- Starmie
|
||||
- Togetic
|
||||
- Rellor
|
||||
- Rabsca
|
||||
- Yungoos
|
||||
- Gumshoos
|
||||
- Cottonee
|
||||
- Whimsicott
|
||||
- Corsola
|
||||
|
||||
#### Added sounds to the following moves
|
||||
|
||||
- Absorb
|
||||
- Aurora Beam
|
||||
- Double Team
|
||||
@@ -229,13 +266,8 @@
|
||||
### Changes
|
||||
- Stat increase and decrease particles have been changed, with the addition of alpha boost particles.
|
||||
- Dragonite's mailbag cosmetic can now also be obtained with a chest in the cosmetic slot
|
||||
|
||||
### Fixes
|
||||
- Adjusted Croagunk's walkspeed
|
||||
- Fixed Blitzle's base scale being `1` rather than the intended `0.8`
|
||||
- Fixed Magnezone's emissive layer for the shiny having the wrong name, thus displaying wrongly
|
||||
- Fixed Litleo not blinking
|
||||
- Fixed Garchomp T-posing when sleeping while out of battle.
|
||||
- Adjusted Aerodactyl's walkspeed
|
||||
- Sharp Beak can now be crafted
|
||||
- Metal Alloy can now be crafted
|
||||
- Ability Capsules can now be brewed
|
||||
@@ -256,6 +288,7 @@
|
||||
- Factor in the weight of Pokémon when calculating pushing forces between hitboxes.
|
||||
- Remade the Starter Selection Screen with new assets
|
||||
- Refactored berry trees to be less impactful on TPS (more performant)
|
||||
- Indexed party/PC stores by UUID so lookups no longer scan the whole store, reducing MSPT with many pastured Pokémon
|
||||
- Changed the bait effects of the following items: (Vanilla) Sweet & Glow Berries, Golden & Enchanted Golden Apples (Cobblemon) Custap, Eggant, Hopo & Micle Berries, Sweet Hearts
|
||||
- Wild Pokémon now reliably have at least one offensive move if they can have offensive moves at that level.
|
||||
- Data Monitor can accept Disks (TMs, Music Disks, Upgrade, Dubious Disk, etc.) to change what's being displayed on the screen
|
||||
@@ -288,24 +321,19 @@
|
||||
- Hearty Grains can be milled like Farmer's Delight Rice Panicles if both Farmer's Delight and Create are installed
|
||||
- Big Roots and Revival Herbs can be milled to their respective powders
|
||||
- Pep-Up Flowers, Medicinal Leeks, and all 70 berries can be milled in Create's Millstone for additional dye drops
|
||||
- Auspicious Armor and Upgrades can be Haunted using Create's crafting systems
|
||||
- Auspicious Armour and Upgrades can be Haunted using Create's crafting systems
|
||||
- Applin Apples can be used to make Honeyed Apples in Create
|
||||
- Golden Apples can now be crafted using the Applin Apples
|
||||
- Prismarine Crystals and Amethyst Shards can now be used to craft Pokedexes
|
||||
- Updated Pokedex Screens item tag to support tagged variants of Redstone and Glowstone Dust
|
||||
- Sounds for interacting with various Cobblemon blocks now play from the center of the block, rather than the corner
|
||||
- Updated Pokédex Screens item tag to support tagged variants of Redstone and Glowstone Dust
|
||||
- Sounds for interacting with various Cobblemon blocks now play from the centre of the block, rather than the corner
|
||||
- The `/pc` command no longer plays PC activation sounds
|
||||
- Lowered the volume of Blitzle and Zebstrika's cry
|
||||
- Fixed Raichu (male) and Alolan Raichu (both genders) not displaying the correct Partner Cap when Pewter Crunchies are in the cosmetic slot.
|
||||
- Regional Foods will now prioritize being eaten instead of used for healing Pokémon, shift clicking will use it as healing
|
||||
- Resolved Z-Fighting on Pokédex Models
|
||||
- Restored Ninjask's ability to do barrel rolls
|
||||
|
||||
### Fixes
|
||||
- Fixed Croagunk's walkspeed
|
||||
- Fixed Blitzle's base scale being `1` rather than the intended `0.8`
|
||||
- Fixed Magnezone's emissive layer for the shiny having the wrong name, thus displaying wrongly
|
||||
- Fixed Litleo not blinking
|
||||
- Fixed Omanyte and Omastar incorrectly using water animations on land.
|
||||
- Fixed Pokédex layout for genderless variations
|
||||
- Fixed odd stacking behaviour with the poke_bait item.
|
||||
- Fixed a compatibility issue with World Game Rules which caused some log spam in specific cases.
|
||||
@@ -347,9 +375,39 @@
|
||||
- Fixed Exploit where you could take out the bait or drop your Pokérod with bait to avoid consuming bait, now the bobber will just disappear if you do so
|
||||
- Fixed Apricorn and Saccharine boats incorrectly using chest boat models
|
||||
- Fixed wild and trainer battle AI refusing to select moves with the `adjacentAlly` target type, even when it's their only option
|
||||
- Fixed Guilded chests being more accessible than intended
|
||||
- Fixed gilded chests being more accessible than intended
|
||||
- Fixed fished up Pokémon not being added as "seen" to the Pokedex
|
||||
- Fixed surprised Gimmighoul encounters not being added as "seen" to the Pokedex
|
||||
- Fixed a crash involving berry trees that have been world edited.
|
||||
- Fixed visual desync in multiplayer for players mounting Pokémon outside other players' loaded chunks
|
||||
- Fixed Pokémon entities leveled by rare candy not getting stronger as Minecraft entities unless recalled.
|
||||
- Fixed a freeze during game load that occurred when multiple mods tried to load Cobblemon API classes at the same time.
|
||||
- Fixed random tick crashes from berry trees
|
||||
- Lowered the volume of Blitzle and Zebstrika's cry
|
||||
- Regional Foods will now prioritise being eaten instead of used for healing Pokémon, shift clicking will use it as healing
|
||||
- Resolved Z-Fighting on Pokédex Models
|
||||
- Restored Ninjask's ability to do barrel rolls
|
||||
- Fixed Raichu (male) and Alolan Raichu (both genders) not displaying the correct Partner Cap when Pewter Crunchies are in the cosmetic slot.
|
||||
- Fixed a crash caused by adding enchanted items to the Resurrection Machine
|
||||
- Fixed a crash that could occur when starting a PvN battle with only fainted Pokémon.
|
||||
- Fixed the Remember Riding Camera config not being respected when dismounting and resolved the incompatibility with the Auto Third Person mod
|
||||
- Fixed Full Heal block not dropping Full Heals
|
||||
- Fixed status cure items not returning an empty bottle when used
|
||||
- Fixed Panpour consuming its held item when evolving with a Water Stone
|
||||
- Fixed Smoked Tail Curry returning a Wooden Bowl when consumed despite it not being included in the recipe
|
||||
- Fixed `/giveallpokemon` not respecting the min and max parameters
|
||||
- Fixed the choose starter toast not disappearing when capturing a Pokémon instead of opening the starter selection screen
|
||||
- Fixed an issue where certain Sinister Tea seasonings were only applying as instant effects and would not apply over time
|
||||
- Long config option labels now scroll instead of overflowing
|
||||
- Eggant Berries can now be composted properly on NeoForge
|
||||
- Composting chances are now the same on NeoForge as on Fabric
|
||||
- Fixed problem where furnaces which had smelted Revival Herbs into Heal Powder in older versions would glitch out on trying to get the experience out of the block
|
||||
- Fixed the Battle AI not recognizing Surging Strikes as a multistrike move
|
||||
- Fixed some z-fighting and clipping on Dewott
|
||||
- Fixed multiple Pokémon having their cries missing
|
||||
- Fixed Tentacool not using its swim animation when on water surface
|
||||
- Fixed Eevee using its left shoulder pose when in battle
|
||||
- The Magikarp and Gyarados Jump Pattern resourcepacks should now stop replacing shiny textures of addons targeting Magikarp or Gyarados.
|
||||
|
||||
### Developer
|
||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
||||
@@ -360,6 +418,9 @@
|
||||
- Separated all the functions of MoLangFunctions.kt into their own files.
|
||||
- Spawn buckets and their base weights are now provided by the spawner, with different base weights for world, fishing, snack, and habitat spawn buckets.
|
||||
- Removed "SpawnBucket" class in favour of just storing maps of bucket names to weights.
|
||||
- Fixed nicknames not being applied to Pokémon spawned from `spawn_pool_world` files.
|
||||
- Added support for `profilePokedexScale`, `profilePokedexTranslation`, `profileSummaryScale`, and `profileSummaryTranslation` in poser files for finer control over profile displays.
|
||||
- Fixed riding camera offsets defined on Pokémon forms not being applied
|
||||
|
||||
### Molang & Datapacks
|
||||
- Added `moveset_builders` datapack folder for different styles of movesets.
|
||||
@@ -370,6 +431,7 @@
|
||||
- Added `q.item.is_enchanted()`
|
||||
- Added `q.item.has_enchantment(minecraft:sharpness, 3)`
|
||||
- Added `has_chosen_starter` & `get_starter_uuid` as available Molang functions
|
||||
- Added `has_tm_move_unlocked`, `unlock_tm_move`, & `lock_tm_move` as available Molang functions for Players
|
||||
- Added `marks`, `has_mark`, & `remove_marks` as available Molang functions for Pokémon
|
||||
- Added Data Component support for species drops, eg `"components": {"minecraft:custom_model_data": 123}`
|
||||
- Added the new `sortOrder` field to mark entries, (defaults to 0 if not specified) which controls the order in which marks are rendered on the HUD, with higher numbers being rendered on top of lower numbers
|
||||
@@ -460,6 +522,7 @@
|
||||
- German
|
||||
- Spanish
|
||||
- Ecuadorian Spanish
|
||||
- Portuguese
|
||||
- Brazilian Portuguese
|
||||
- Simplified Chinese
|
||||
- Traditional Chinese
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.world.feature.PlacedFeatureLocator;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* Marks each chunk in {@code CobblemonPlacedFeatureIndex} once its decoration completes, making the index
|
||||
* authoritative for that chunk: any locatable feature it doesn't list there verifiably did not generate.
|
||||
* Runs at TAIL so placements (recorded per-feature) are always written before the chunk is marked.
|
||||
*/
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public abstract class ChunkGeneratorMixin {
|
||||
|
||||
@Inject(method = "applyBiomeDecoration", at = @At("TAIL"))
|
||||
private void cobblemon$markChunkDecorated(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager, CallbackInfo ci) {
|
||||
PlacedFeatureLocator.onChunkDecorated(level.getLevel(), chunk.getPos());
|
||||
}
|
||||
}
|
||||
@@ -1,111 +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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
|
||||
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.*;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(JigsawPlacement.class)
|
||||
public class JigsawPlacementMixin {
|
||||
|
||||
@Inject(
|
||||
method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;ILnet/minecraft/world/level/levelgen/structure/pools/alias/PoolAliasLookup;Lnet/minecraft/world/level/levelgen/structure/pools/DimensionPadding;Lnet/minecraft/world/level/levelgen/structure/templatesystem/LiquidSettings;)Ljava/util/Optional;",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true
|
||||
)
|
||||
private static void onAddPieces(
|
||||
Structure.GenerationContext context,
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
Optional<ResourceLocation> startJigsawName,
|
||||
int maxDepth,
|
||||
BlockPos pos,
|
||||
boolean useExpansionHack,
|
||||
Optional<Heightmap.Types> projectStartToHeightmap,
|
||||
int maxDistanceFromCenter,
|
||||
PoolAliasLookup aliasLookup,
|
||||
DimensionPadding dimensionPadding,
|
||||
LiquidSettings liquidSettings,
|
||||
CallbackInfoReturnable<Optional<Structure.GenerationStub>> cir
|
||||
) {
|
||||
Optional<Structure.GenerationStub> result = cir.getReturnValue();
|
||||
if (result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BlockPos spawnPos = result.get().position();
|
||||
boolean canPlace = cobblemon$canAnyStartElementPlace(context, startPool, spawnPos);
|
||||
|
||||
if (canPlace) {
|
||||
return;
|
||||
}
|
||||
|
||||
cir.setReturnValue(Optional.empty());
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static boolean cobblemon$canAnyStartElementPlace(
|
||||
Structure.GenerationContext generationContext,
|
||||
Holder<StructureTemplatePool> startPool,
|
||||
BlockPos startPos
|
||||
) {
|
||||
for (StructurePoolElement element : startPool.value().templates) {
|
||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
|
||||
|
||||
if (heightRangeProcessor.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
|
||||
boolean valid = processor.isValidPlacement(
|
||||
generationContext.chunkGenerator(),
|
||||
generationContext.heightAccessor(),
|
||||
generationContext.randomState(),
|
||||
startPos
|
||||
);
|
||||
|
||||
if (valid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
|
||||
if (!(element instanceof SinglePoolElement)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
|
||||
for (StructureProcessor processor : processorList.list()) {
|
||||
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
|
||||
return Optional.of(heightRangeStructureProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.world.feature.PlacedFeatureLocator;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* Reports successful feature placements to {@link PlacedFeatureLocator}, which keeps a session-lifetime,
|
||||
* per-dimension index of locatable Cobblemon features for `/locatefeature` to answer from.
|
||||
*/
|
||||
@Mixin(PlacedFeature.class)
|
||||
public abstract class PlacedFeatureMixin {
|
||||
|
||||
@Inject(method = "placeWithContext", at = @At("RETURN"))
|
||||
private void cobblemon$recordPlacement(PlacementContext context, RandomSource random, BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (cir.getReturnValueZ()) {
|
||||
PlacedFeatureLocator.onFeaturePlaced((PlacedFeature) (Object) this, context, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
|
||||
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.PoolElementStructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(Structure.class)
|
||||
public abstract class StructureMixin {
|
||||
|
||||
/**
|
||||
* Discards a structure start when any of its pieces carries a {@link HeightRangeStructureProcessor}
|
||||
* whose range the piece does not fit in.
|
||||
* Crab Note: We have to make this has to happen here rather than in the processor itself. Terrain adaptation and {@code /locate}
|
||||
* both read the start, so by the time processors run the terrain has already been generated and the
|
||||
* structure is already on the map which previously were left behdind when we were trying to make some structures not generate via processor. Now
|
||||
* Returning {@link StructureStart#INVALID_START} keeps the start from ever existing, which makes sure that weird generation isn't left behind.
|
||||
*/
|
||||
@Inject(
|
||||
method = "generate",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/StructureStart;isValid()Z"),
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$rejectStartsOutsideHeightRange(
|
||||
RegistryAccess registryAccess, ChunkGenerator chunkGenerator, BiomeSource biomeSource,
|
||||
RandomState randomState, StructureTemplateManager structureTemplateManager, long seed,
|
||||
ChunkPos chunkPos, int references, LevelHeightAccessor heightAccessor,
|
||||
Predicate<Holder<Biome>> validBiome,
|
||||
CallbackInfoReturnable<StructureStart> cir,
|
||||
@Local StructureStart structureStart
|
||||
) {
|
||||
for (StructurePiece piece : structureStart.getPieces()) {
|
||||
if (!(piece instanceof PoolElementStructurePiece poolPiece)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(poolPiece.getElement());
|
||||
if (heightRangeProcessor.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean valid = heightRangeProcessor.get().isValidPlacement(
|
||||
chunkGenerator,
|
||||
heightAccessor,
|
||||
randomState,
|
||||
piece.getBoundingBox()
|
||||
);
|
||||
|
||||
if (!valid) {
|
||||
cir.setReturnValue(StructureStart.INVALID_START);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
|
||||
if (!(element instanceof SinglePoolElement)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
|
||||
for (StructureProcessor processor : processorList.list()) {
|
||||
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
|
||||
return Optional.of(heightRangeStructureProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
+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://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.accessor;
|
||||
|
||||
import net.minecraft.world.level.biome.FeatureSorter;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public interface ChunkGeneratorAccessor {
|
||||
@Accessor("featuresPerStep")
|
||||
Supplier<List<FeatureSorter.StepFeatureData>> getFeaturesPerStep();
|
||||
}
|
||||
@@ -108,6 +108,7 @@ import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.HeldItemVisibleProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.LabelProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
|
||||
@@ -350,6 +351,7 @@ object Cobblemon {
|
||||
CustomPokemonProperty.register(UnaspectPropertyType)
|
||||
CustomPokemonProperty.register(FreezeFrameProperty)
|
||||
CustomPokemonProperty.register(NoAIProperty)
|
||||
CustomPokemonProperty.register(HeldItemVisibleProperty)
|
||||
|
||||
CobblemonEvents.POKEMON_PROPERTY_INITIALISED.emit(Unit)
|
||||
|
||||
|
||||
@@ -73,9 +73,10 @@ object CobblemonCommands {
|
||||
PcTakeCommand.register(dispatcher)
|
||||
GiveTmCommand.register(dispatcher)
|
||||
TmCommand.register(dispatcher)
|
||||
LocateFeatureCommand.register(dispatcher)
|
||||
|
||||
// Possibly lock down registration if and only if under dev environment or running in an environment
|
||||
// with a certain system environment variable set
|
||||
CobblemonInfoCommand.register(dispatcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,7 +405,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val BIG_MALASADA = regionalFoodItem("big_malasada", 64, 7, 0.3f, false)
|
||||
@JvmField
|
||||
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 64, 10, 0.6f, false, ItemStack(Items.BOWL, 1))
|
||||
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 64, 10, 0.6f, false)
|
||||
@JvmField
|
||||
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 64, 7, 0.3f, false)
|
||||
@JvmField
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SetActiveTMPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SetTMMachineContainerDataPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SynchronizeActiveTMHandler
|
||||
import com.cobblemon.mod.common.client.net.habitat.OpenHabitatBlockEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
|
||||
@@ -147,6 +148,7 @@ import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SetActiveTMPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SetTMMachineContainerDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SynchronizeActiveTMPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengeResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
|
||||
@@ -375,6 +377,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(PlayerInteractOptionsPacket.ID, PlayerInteractOptionsPacket::decode, PlayerInteractOptionsHandler))
|
||||
list.add(PacketRegisterInfo(PokedexUIPacket.ID, PokedexUIPacket::decode, PokedexUIPacketHandler))
|
||||
list.add(PacketRegisterInfo(ExpGainedDataPacket.ID, ExpGainedDataPacket::decode, ExpGainedDataPacketHandler))
|
||||
list.add(PacketRegisterInfo(SynchronizeActiveTMPacket.ID, SynchronizeActiveTMPacket::decode, SynchronizeActiveTMHandler))
|
||||
|
||||
// Starter packets
|
||||
list.add(PacketRegisterInfo(OpenStarterUIPacket.ID, OpenStarterUIPacket::decode, StarterUIPacketHandler))
|
||||
|
||||
+10
-1
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking.effects
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectCategory
|
||||
import net.minecraft.world.entity.Entity
|
||||
@@ -18,5 +19,13 @@ class CleanseAllEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF) {
|
||||
override fun applyInstantenousEffect(source: Entity?, indirect: Entity?, target: LivingEntity, amplifier: Int, proximity: Double) {
|
||||
target.removeAllEffects()
|
||||
}
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
|
||||
|
||||
override fun applyEffectTick(livingEntity: LivingEntity, amplifier: Int): Boolean {
|
||||
if (livingEntity is ServerPlayer){
|
||||
livingEntity.removeAllEffects()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = true
|
||||
}
|
||||
+15
-1
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking.effects
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectCategory
|
||||
import net.minecraft.world.entity.Entity
|
||||
@@ -23,5 +24,18 @@ class CleanseNegativeEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
|
||||
|
||||
override fun applyEffectTick(livingEntity: LivingEntity, amplifier: Int): Boolean {
|
||||
if (livingEntity is ServerPlayer){
|
||||
val snapshot = livingEntity.activeEffects.toList()
|
||||
for (ei in snapshot) {
|
||||
if (ei.effect.value().category == MobEffectCategory.HARMFUL) {
|
||||
livingEntity.removeEffect(ei.effect)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = true
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class HabitatPool {
|
||||
pool.spawns = spawns
|
||||
return pool
|
||||
} else {
|
||||
return HabitatPools.habitatPoolsById[poolId] ?: HabitatPool.default()
|
||||
return HabitatPools.habitatPoolsById[poolId] ?: default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,14 @@ class HabitatPool {
|
||||
return spawns.mapNotNull { it.createSpawnDetail(habitatBlockEntity) }
|
||||
}
|
||||
|
||||
fun getPhaseCount(): Int {
|
||||
return spawns
|
||||
.flatMap { it.phases?.ranges?.flatten() ?: emptySet() }
|
||||
.toSet()
|
||||
.count()
|
||||
.coerceAtLeast(1)
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(id)
|
||||
buffer.writeUtf(name)
|
||||
|
||||
@@ -65,7 +65,7 @@ class HabitatSpawn {
|
||||
/** The maximum light level that the Pokémon can spawn in. */
|
||||
var maxLight: Int? = null
|
||||
|
||||
open fun writeToNBT(nbt: CompoundTag) {
|
||||
fun writeToNBT(nbt: CompoundTag) {
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_SPECIES, species.resourceIdentifier.toString())
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE, spawnablePositionType)
|
||||
nbt.putFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT, weight)
|
||||
@@ -78,7 +78,7 @@ class HabitatSpawn {
|
||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_BUCKET, bucket)
|
||||
}
|
||||
|
||||
open fun readFromNBT(nbt: CompoundTag) {
|
||||
fun readFromNBT(nbt: CompoundTag) {
|
||||
species = PokemonSpecies.getByIdentifier(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_SPECIES).asIdentifierDefaultingNamespace())!!
|
||||
spawnablePositionType = nbt.getString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE)
|
||||
weight = nbt.getFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT)
|
||||
@@ -91,7 +91,7 @@ class HabitatSpawn {
|
||||
bucket = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_BUCKET)) nbt.getString(DataKeys.HABITAT_POOL_SPAWN_BUCKET) else "common"
|
||||
}
|
||||
|
||||
open fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(species.resourceIdentifier)
|
||||
buffer.writeUtf(spawnablePositionType)
|
||||
buffer.writeFloat(weight)
|
||||
@@ -104,7 +104,7 @@ class HabitatSpawn {
|
||||
buffer.writeUtf(bucket)
|
||||
}
|
||||
|
||||
open fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
species = PokemonSpecies.getByIdentifier(buffer.readResourceLocation())!!
|
||||
spawnablePositionType = buffer.readUtf()
|
||||
weight = buffer.readFloat()
|
||||
@@ -118,7 +118,7 @@ class HabitatSpawn {
|
||||
}
|
||||
|
||||
/** Creates the [PokemonSpawnDetail] that will be used in the spawner. This is done per habitat block. */
|
||||
open fun createSpawnDetail(habitatBlockEntity: HabitatBlockEntity): PokemonSpawnDetail? {
|
||||
fun createSpawnDetail(habitatBlockEntity: HabitatBlockEntity): PokemonSpawnDetail? {
|
||||
val spawnDetail = PokemonSpawnDetail()
|
||||
|
||||
// If the habitat block specifies a level range, it restricts how and if this spawn exists
|
||||
|
||||
@@ -17,7 +17,6 @@ import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class HabitatSettingsDTO() {
|
||||
var numberOfPhases = 1
|
||||
var phaseOrder = HabitatPhaseOrder.SIMPLE
|
||||
lateinit var levelRange: IntRange
|
||||
var modifiers: String = ""
|
||||
@@ -28,7 +27,6 @@ class HabitatSettingsDTO() {
|
||||
var naturalSettings: NaturalHabitatSettingsDTO? = null
|
||||
|
||||
constructor(habitatBlockEntity: HabitatBlockEntity) : this() {
|
||||
this.numberOfPhases = habitatBlockEntity.numberOfPhases
|
||||
this.phaseOrder = habitatBlockEntity.phaseOrder
|
||||
this.levelRange = habitatBlockEntity.levelRange
|
||||
this.modifiers = habitatBlockEntity.modifiers.asString()
|
||||
@@ -44,7 +42,6 @@ class HabitatSettingsDTO() {
|
||||
}
|
||||
|
||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeInt(numberOfPhases)
|
||||
buffer.writeEnum(phaseOrder)
|
||||
buffer.writeInt(levelRange.first)
|
||||
buffer.writeInt(levelRange.last)
|
||||
@@ -60,7 +57,6 @@ class HabitatSettingsDTO() {
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
this.numberOfPhases = buffer.readInt()
|
||||
this.phaseOrder = buffer.readEnum(HabitatPhaseOrder::class.java)
|
||||
val levelRangeStart = buffer.readInt()
|
||||
val levelRangeEnd = buffer.readInt()
|
||||
|
||||
+20
@@ -17,6 +17,8 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.api.moves.Moves
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
@@ -44,6 +46,7 @@ import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.pc
|
||||
import com.cobblemon.mod.common.util.pokedex
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.cobblemon.mod.common.util.tmList
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -312,6 +315,23 @@ object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
|
||||
}
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
map["has_tm_move_unlocked"] = put@{ params ->
|
||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
||||
}
|
||||
map["unlock_tm_move"] = put@{ params ->
|
||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
||||
player.tmList().syncTMFromMove(move)
|
||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
||||
}
|
||||
map["lock_tm_move"] = put@{ params ->
|
||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
||||
player.tmList().syncTMLockFromMove(move)
|
||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 0.0 else 1.0)
|
||||
}
|
||||
map["start_battle"] = put@{ params ->
|
||||
val opponentValue = params.get<MoValue>(0)
|
||||
val opponent = if (opponentValue is ObjectValue<*>) {
|
||||
|
||||
@@ -44,6 +44,9 @@ object CobblemonPermissions {
|
||||
@JvmStatic
|
||||
val LEVEL_UP_OTHER = this.create("$LEVEL_UP_BASE.other", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
|
||||
|
||||
@JvmStatic
|
||||
val LOCATE_FEATURE = this.create("${COMMAND_PREFIX}locatefeature", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
|
||||
|
||||
@JvmStatic
|
||||
val OPEN_STARTER_SCREEN = this.create("${COMMAND_PREFIX}openstarterscreen", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
|
||||
@JvmStatic
|
||||
|
||||
@@ -759,6 +759,7 @@ open class PokemonProperties {
|
||||
shiny?.let { json.addProperty(DataKeys.POKEMON_SHINY, it) }
|
||||
gender?.let { json.addProperty(DataKeys.POKEMON_GENDER, it.name) }
|
||||
species?.let { json.addProperty(DataKeys.POKEMON_SPECIES_TEXT, it) }
|
||||
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, it.string) }
|
||||
form?.let { json.addProperty(DataKeys.POKEMON_FORM_ID, it) }
|
||||
friendship?.let { json.addProperty(DataKeys.POKEMON_FRIENDSHIP, it) }
|
||||
fullness?.let { json.addProperty(DataKeys.POKEMON_FULLNESS, it) }
|
||||
@@ -795,6 +796,7 @@ open class PokemonProperties {
|
||||
shiny = json.get(DataKeys.POKEMON_SHINY)?.asBoolean
|
||||
gender = json.get(DataKeys.POKEMON_GENDER)?.asString?.let { Gender.valueOf(it) }
|
||||
species = json.get(DataKeys.POKEMON_SPECIES_TEXT)?.asString
|
||||
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let(Component::literal)
|
||||
form = json.get(DataKeys.POKEMON_FORM_ID)?.asString
|
||||
friendship = json.get(DataKeys.POKEMON_FRIENDSHIP)?.asInt
|
||||
fullness = json.get(DataKeys.POKEMON_FULLNESS)?.asInt
|
||||
|
||||
+1
@@ -32,6 +32,7 @@ import com.cobblemon.mod.common.api.spawning.selection.SpawnSelectionData
|
||||
class EmptySpawnDetail : SpawnDetail() {
|
||||
companion object {
|
||||
val TYPE = "empty"
|
||||
val EMPTY = EmptySpawnDetail()
|
||||
}
|
||||
|
||||
override val type: String = TYPE
|
||||
|
||||
+44
-23
@@ -11,14 +11,19 @@ package com.cobblemon.mod.common.api.spawning.detail
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.drop.DropTable
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePosition
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import com.cobblemon.mod.common.api.spawning.selection.SpawnSelectionData
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.weightedSelection
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.Mth.clamp
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import kotlin.math.ceil
|
||||
|
||||
/**
|
||||
* A spawn detail that spawns a herd of Pokémon. This relies on the same [PokemonSpawnAction]s as
|
||||
@@ -36,7 +41,6 @@ import net.minecraft.world.item.Items
|
||||
class PokemonHerdSpawnDetail : SpawnDetail() {
|
||||
companion object {
|
||||
val TYPE = "pokemon-herd"
|
||||
const val HERD_LEADER = "leader"
|
||||
}
|
||||
|
||||
override val type: String = TYPE
|
||||
@@ -50,14 +54,14 @@ class PokemonHerdSpawnDetail : SpawnDetail() {
|
||||
get() = "${id}__LEVEL"
|
||||
|
||||
class Herdable {
|
||||
var pokemon: PokemonProperties = PokemonProperties()
|
||||
var pokemon = PokemonProperties()
|
||||
val levelRange: IntRange? = null
|
||||
var levelRangeOffset: IntRange? = null
|
||||
val herdLevelRange: IntRange? = null
|
||||
var dropTable: DropTable? = null
|
||||
var isLeader: Boolean = false
|
||||
var isFollower: Boolean = true
|
||||
var weight: Float = 1F
|
||||
var isLeader = false
|
||||
var isFollower = true
|
||||
var weight = 1F
|
||||
var maxTimes = 10
|
||||
var heldItem: ResourceLocation? = null
|
||||
}
|
||||
@@ -69,22 +73,23 @@ class PokemonHerdSpawnDetail : SpawnDetail() {
|
||||
selectionData: SpawnSelectionData
|
||||
) {
|
||||
selectionData.removeSpawnDetails { it != this }
|
||||
selectionData.guaranteedBucket = bucket
|
||||
selectionData.removeSpawnablePositions { _, pos -> pos.distanceTo(spawnablePosition) < minDistanceBetweenSpawns }
|
||||
|
||||
val herdSpawnCount = selectionData.spawnActions.count { it.detail == this } + 1
|
||||
val lacksPossibleLeader = lacksPossibleLeader(selectionData)
|
||||
|
||||
if (herdSpawnCount >= maxHerdSize || getValidHerdMembers(selectionData).isEmpty()) {
|
||||
if (herdSpawnCount >= maxHerdSize || getValidHerdMembersForRole(selectionData, useLeaderRole = lacksPossibleLeader).isEmpty()) {
|
||||
// We can't spawn any more in the herd so remove this spawn from the selection pool.
|
||||
selectionData.removeSpawnDetails { it == this }
|
||||
}
|
||||
}
|
||||
|
||||
fun lacksPossibleLeader(selectionData: SpawnSelectionData): Boolean {
|
||||
val level = getOrSetHerdLevel(selectionData)
|
||||
val herdable = getValidHerdMembers(selectionData)
|
||||
val herdCounts = getHerdMemberCounts(selectionData)
|
||||
|
||||
val leaderIsPossible = herdable.any { it.herdLevelRange?.contains(level) != false && it.isLeader }
|
||||
val leaderIsPossible = herdable.any { it.isLeader }
|
||||
val leaderIsSelected = herdCounts.any { it.key?.isLeader == true && it.value > 0 }
|
||||
return leaderIsPossible && !leaderIsSelected
|
||||
}
|
||||
@@ -97,27 +102,47 @@ class PokemonHerdSpawnDetail : SpawnDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getValidHerdMembersForRole(selectionData: SpawnSelectionData, useLeaderRole: Boolean): List<Herdable> {
|
||||
return getValidHerdMembers(selectionData).filter { (useLeaderRole && it.isLeader) || (!useLeaderRole && it.isFollower) }
|
||||
}
|
||||
|
||||
override fun createSpawnAction(
|
||||
spawnablePosition: SpawnablePosition,
|
||||
bucket: String,
|
||||
selectionData: SpawnSelectionData
|
||||
): PokemonSpawnAction {
|
||||
val validHerdMembers = getValidHerdMembers(selectionData)
|
||||
var searchedForLeader = false
|
||||
val herdable = if (lacksPossibleLeader(selectionData)) {
|
||||
searchedForLeader = true
|
||||
validHerdMembers.filter { it.isLeader }
|
||||
} else {
|
||||
validHerdMembers.filter { it.isFollower }
|
||||
}.weightedSelection { it.weight } ?: herdablePokemon[0]
|
||||
): SpawnAction<*> {
|
||||
val herdable = getValidHerdMembersForRole(
|
||||
selectionData = selectionData,
|
||||
useLeaderRole = lacksPossibleLeader(selectionData)
|
||||
).weightedSelection { it.weight } ?: herdablePokemon[0]
|
||||
|
||||
val level = selectionData.context[herdLevelKey] as? Int ?: 1
|
||||
val levelRange = herdable.levelRangeOffset?.let { offset ->
|
||||
var levelRange = herdable.levelRangeOffset?.let { offset ->
|
||||
val min = level + offset.first
|
||||
val max = level + offset.last
|
||||
min..max
|
||||
} ?: level..level
|
||||
|
||||
// Attempt to do more detailed anti-wall-spawn logic. Herd members could spawn in walls because
|
||||
// we've just been assuming they're 1 block wide (or at least, all in the herd have the same size).
|
||||
// Some pokemon are not that though.
|
||||
if (spawnablePosition is AreaSpawnablePosition) {
|
||||
val species = herdable.pokemon.species?.let { PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
|
||||
if (species != null) {
|
||||
val height = ceil(species.hitbox.height * species.baseScale).toInt()
|
||||
val width = ceil(species.hitbox.width * species.baseScale).toInt()
|
||||
if (!spawnablePosition.hasSpace(width, height)) {
|
||||
return EmptySpawnAction(spawnablePosition, bucket, EmptySpawnDetail.EMPTY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
herdable.levelRange?.let {
|
||||
val clampedMin = clamp(it.first, levelRange.first, levelRange.last)
|
||||
val clampedMax = clamp(it.last, levelRange.first, levelRange.last)
|
||||
levelRange = clampedMin..clampedMax
|
||||
}
|
||||
|
||||
val heldItem = herdable.heldItem?.let { heldItemId ->
|
||||
val item = spawnablePosition.world.registryAccess().registryOrThrow(Registries.ITEM).get(heldItemId)
|
||||
if (item == Items.AIR) {
|
||||
@@ -136,11 +161,7 @@ class PokemonHerdSpawnDetail : SpawnDetail() {
|
||||
drops = herdable.dropTable,
|
||||
heldItem = heldItem,
|
||||
levelRange = levelRange
|
||||
).also {
|
||||
if (herdable.isLeader && searchedForLeader) {
|
||||
it.labels += HERD_LEADER
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun getHerdMemberCounts(selectionData: SpawnSelectionData): Map<Herdable?, Int> {
|
||||
|
||||
+27
-22
@@ -53,34 +53,39 @@ open class AreaSpawnablePosition(
|
||||
*/
|
||||
open fun isSafeSpace(world: ServerLevel, pos: BlockPos, state: BlockState): Boolean = !state.isSolid
|
||||
|
||||
fun hasSpace(width: Int, height: Int): Boolean {
|
||||
val sizeX = width.takeIf { it > 0 } ?: 1
|
||||
val sizeY = height.takeIf { it > 0 } ?: 1
|
||||
|
||||
val minX = floor(position.x + 0.5 - (sizeX - 1) / 2F).toInt() - 1
|
||||
val maxX = ceil(position.x + 0.5 + (sizeX + 1) / 2F).toInt() + 1
|
||||
|
||||
val maxY = ceil(position.y + (sizeY + 1) / 2F).toInt() + 1
|
||||
|
||||
val minZ = floor(position.z + 0.5 - (sizeX - 1) / 2F).toInt() - 1
|
||||
val maxZ = ceil(position.z + 0.5 + (sizeX + 1) / 2F).toInt() + 1
|
||||
|
||||
val mutable = BlockPos.MutableBlockPos()
|
||||
for (x in minX until maxX) {
|
||||
for (y in (position.y + 1)..maxY) {
|
||||
for (z in minZ until maxZ) {
|
||||
val state = zone.getBlockState(mutable.set(x, y, z))
|
||||
if (!isSafeSpace(world, mutable, state)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun postFilter(detail: SpawnDetail): Boolean {
|
||||
if (!super.postFilter(detail)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (detail.width > 1 || detail.height > 1) {
|
||||
val sizeX = detail.width.takeIf { it > 0 } ?: 1
|
||||
val sizeY = detail.height.takeIf { it > 0 } ?: 1
|
||||
|
||||
val minX = floor(position.x + 0.5 - (sizeX - 1) / 2F).toInt() - 1
|
||||
val maxX = ceil(position.x + 0.5 + (sizeX + 1) / 2F).toInt() + 1
|
||||
|
||||
val maxY = ceil(position.y + (sizeY + 1) / 2F).toInt() + 1
|
||||
|
||||
val minZ = floor(position.z + 0.5 - (sizeX - 1) / 2F).toInt() - 1
|
||||
val maxZ = ceil(position.z + 0.5 + (sizeX + 1) / 2F).toInt() + 1
|
||||
|
||||
val mutable = BlockPos.MutableBlockPos()
|
||||
for (x in minX until maxX) {
|
||||
for (y in (position.y + 1)..maxY) {
|
||||
for (z in minZ until maxZ) {
|
||||
val state = zone.getBlockState(mutable.set(x, y, z))
|
||||
if (!isSafeSpace(world, mutable, state)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasSpace(detail.width, detail.height)
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
@@ -89,6 +89,7 @@ open class FlatSelector : SpawningSelector<FlatSelector.SpawnablePositionSelecti
|
||||
val spawnablePositions: List<SpawnablePosition>,
|
||||
val selectingSpawnInformation: MutableMap<String, SpawnablePositionBucketSelectionData>,
|
||||
): SpawnSelectionData {
|
||||
override var guaranteedBucket: String? = null
|
||||
override val spawnActions = mutableListOf<SpawnAction<*>>()
|
||||
override val context = mutableMapOf<String, Any>()
|
||||
|
||||
|
||||
+1
@@ -101,6 +101,7 @@ open class FlatSpawnablePositionWeightedSelector : SpawningSelector<FlatSpawnabl
|
||||
val spawner: Spawner,
|
||||
val spawnablePositions: List<SpawnablePosition>
|
||||
) : SpawnSelectionData {
|
||||
override var guaranteedBucket: String? = null
|
||||
override val spawnActions = mutableListOf<SpawnAction<*>>()
|
||||
override val context = mutableMapOf<String, Any>()
|
||||
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
* @since April 21st, 2025
|
||||
*/
|
||||
interface SpawnSelectionData {
|
||||
var guaranteedBucket: String?
|
||||
val context: MutableMap<String, Any>
|
||||
val spawnActions: MutableList<SpawnAction<*>>
|
||||
fun removeSpawnDetails(shouldRemove: (SpawnDetail) -> Boolean)
|
||||
@@ -28,6 +29,7 @@ interface SpawnSelectionData {
|
||||
|
||||
companion object {
|
||||
val EMPTY = object : SpawnSelectionData {
|
||||
override var guaranteedBucket: String? = null
|
||||
override val context: MutableMap<String, Any> = mutableMapOf()
|
||||
override val spawnActions: MutableList<SpawnAction<*>> = mutableListOf()
|
||||
override fun removeSpawnDetails(shouldRemove: (SpawnDetail) -> Boolean) {}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ interface SpawningSelector<T : SpawnSelectionData> {
|
||||
val spawnActions = selectionData.spawnActions
|
||||
|
||||
while (spawnActions.size < maxSpawns) {
|
||||
val bucket = bucketSelector()
|
||||
val bucket = selectionData.guaranteedBucket ?: bucketSelector()
|
||||
val spawnAction = selectSpawnAction(
|
||||
spawner = spawner,
|
||||
bucket = bucket,
|
||||
|
||||
@@ -46,6 +46,7 @@ open class BottomlessStore(override val uuid: UUID) : PokemonStore<BottomlessPos
|
||||
pokemon.forEachIndexed { index, pokemon ->
|
||||
pokemon.storeCoordinates.set(StoreCoordinates(this, BottomlessPosition(index)))
|
||||
}
|
||||
rebuildPokemonByUuid()
|
||||
}
|
||||
|
||||
override fun saveToNBT(nbt: CompoundTag, registryAccess: RegistryAccess): CompoundTag {
|
||||
|
||||
@@ -53,7 +53,7 @@ abstract class PokemonStore<T : StorePosition> : Iterable<Pokemon> {
|
||||
* Runs initialization logic for this store, knowing that it has just been constructed in a [PokemonStoreFactory].
|
||||
*
|
||||
* The minimum of what this function should do is iterate over all the Pokémon in this store and set their store
|
||||
* coordinates.
|
||||
* coordinates. Built-in stores then rebuild the UUID index via [rebuildPokemonByUuid].
|
||||
*
|
||||
* If this does not get called, or it does not do its job properly, serious de-sync issues may follow.
|
||||
*/
|
||||
@@ -99,6 +99,7 @@ abstract class PokemonStore<T : StorePosition> : Iterable<Pokemon> {
|
||||
|
||||
setAtPosition(position, pokemon)
|
||||
pokemon.storeCoordinates.set(StoreCoordinates(this, position))
|
||||
pokemonByUuid[pokemon.uuid] = pokemon
|
||||
}
|
||||
|
||||
/** Swaps the Pokémon at the specified positions. If one of the spaces is empty, it will simply move the not-null one to that space. */
|
||||
@@ -147,10 +148,26 @@ abstract class PokemonStore<T : StorePosition> : Iterable<Pokemon> {
|
||||
pokemon.recall()
|
||||
pokemon.storeCoordinates.set(null)
|
||||
setAtPosition(currentPosition.position, null)
|
||||
pokemonByUuid.remove(pokemon.uuid)
|
||||
return true
|
||||
}
|
||||
|
||||
operator fun get(uuid: UUID) = find { it.uuid.equals(uuid) }
|
||||
/** In-memory UUID index. Not serialized; rebuilt by [rebuildPokemonByUuid]. */
|
||||
private val pokemonByUuid = hashMapOf<UUID, Pokemon>()
|
||||
|
||||
/** Gets the [Pokemon] with this UUID, or null if it is not in this store. */
|
||||
operator fun get(uuid: UUID): Pokemon? = pokemonByUuid[uuid]
|
||||
|
||||
/**
|
||||
* Rebuilds the UUID index from the store's current contents.
|
||||
*
|
||||
* Call after load or any structural mutation that does not go through [set] / [remove], such as
|
||||
* filling slots directly from NBT/JSON or shrinking a PC.
|
||||
*/
|
||||
protected fun rebuildPokemonByUuid() {
|
||||
pokemonByUuid.clear()
|
||||
forEach { pokemonByUuid[it.uuid] = it }
|
||||
}
|
||||
|
||||
open fun handleInvalidSpeciesNBT(nbt: CompoundTag) {
|
||||
Cobblemon.LOGGER.error("Failed to read unknown species: ${nbt.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)}")
|
||||
|
||||
@@ -138,6 +138,7 @@ open class PartyStore(override val uuid: UUID) : PokemonStore<PartyPosition>() {
|
||||
val pokemon = get(slot) ?: continue
|
||||
pokemon.storeCoordinates.set(StoreCoordinates(this, PartyPosition(slot)))
|
||||
}
|
||||
rebuildPokemonByUuid()
|
||||
}
|
||||
|
||||
override fun onPokemonChanged(pokemon: Pokemon) {
|
||||
|
||||
@@ -105,6 +105,7 @@ open class PCStore(
|
||||
override fun initialize() {
|
||||
boxes.forEach { it.initialize() }
|
||||
backupStore.initialize()
|
||||
rebuildPokemonByUuid()
|
||||
}
|
||||
|
||||
fun relocateEvictedBoxPokemon(pokemon: Pokemon) {
|
||||
@@ -135,6 +136,7 @@ open class PCStore(
|
||||
|
||||
tryRestoreBackedUpPokemon()
|
||||
}
|
||||
rebuildPokemonByUuid()
|
||||
pcChangeObservable.emit(Unit)
|
||||
}
|
||||
|
||||
@@ -142,6 +144,7 @@ open class PCStore(
|
||||
this.lockedSize = lockNewSize
|
||||
boxes.removeAll(boxList)
|
||||
boxList.flatMap { it.asIterable() }.forEach(overflowHandler)
|
||||
rebuildPokemonByUuid()
|
||||
pcChangeObservable.emit(Unit)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ object CobblemonBiomeTags {
|
||||
val IS_WARM_OCEAN = create("is_warm_ocean")
|
||||
@JvmField
|
||||
val IS_DEEP_DARK = create("is_deep_dark")
|
||||
@JvmField
|
||||
val IS_MOUNTAIN = create("is_mountain")
|
||||
|
||||
// Has Block tags
|
||||
@JvmField
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.api.tms
|
||||
|
||||
import com.cobblemon.mod.common.tms.obtain.DefaultObtainMethod
|
||||
import com.cobblemon.mod.common.tms.obtain.ImpossibleObtainMethod
|
||||
import com.cobblemon.mod.common.tms.obtain.PlayerHasAdvancementObtainMethod
|
||||
import com.cobblemon.mod.common.tms.obtain.PlayerYObtainMethod
|
||||
import com.cobblemon.mod.common.tms.obtain.UnlockableObtainMethod
|
||||
@@ -36,6 +37,7 @@ interface ObtainMethod {
|
||||
val variant = buffer.readUtf()
|
||||
return when (variant) {
|
||||
"cobblemon:unlockable" -> UnlockableObtainMethod()
|
||||
"cobblemon:impossible" -> ImpossibleObtainMethod()
|
||||
"cobblemon:default" -> DefaultObtainMethod()
|
||||
"cobblemon:advancement" -> {
|
||||
val advancement = buffer.readResourceLocation()
|
||||
|
||||
@@ -14,6 +14,8 @@ import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.criterion.CountableContext
|
||||
import com.cobblemon.mod.common.advancement.criterion.LearnAllTMContext
|
||||
import com.cobblemon.mod.common.advancement.criterion.LearnTMContext
|
||||
import com.cobblemon.mod.common.api.abilities.Ability
|
||||
import com.cobblemon.mod.common.api.abilities.AbilityPool
|
||||
import com.cobblemon.mod.common.api.moves.MoveTemplate
|
||||
import com.cobblemon.mod.common.api.scheduling.ScheduledTask
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
@@ -50,6 +52,11 @@ class TMMoveManager(
|
||||
learn(listOf(tmId))
|
||||
}
|
||||
|
||||
fun syncTMLockFromMove(moveTemplate: MoveTemplate) {
|
||||
val tmId = TechnicalMachines.moveToTM[moveTemplate]?.id ?: return
|
||||
unlearn(listOf(tmId))
|
||||
}
|
||||
|
||||
fun getLearnableTMsFromPokemon(pokemon: Pokemon): Collection<ResourceLocation> {
|
||||
val learnableMoves = pokemon.allAccessibleMoves.toMutableSet()
|
||||
learnableMoves.addAll(pokemon.moveSet.map { it.template })
|
||||
|
||||
@@ -42,10 +42,12 @@ class ElementalType(
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
val BY_STRING_CODEC: Codec<ElementalType> = CodecUtils.createByStringCodec(
|
||||
ElementalTypes::get,
|
||||
{it.showdownId}
|
||||
) { id -> "No ElementalType for ID $id" }
|
||||
val BY_STRING_CODEC: Codec<ElementalType> by lazy {
|
||||
CodecUtils.createByStringCodec(
|
||||
ElementalTypes::get,
|
||||
{ it.showdownId }
|
||||
) { id -> "No ElementalType for ID $id" }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,11 +349,12 @@ object BattleBuilder {
|
||||
npcPartyStores.add(npcParty)
|
||||
}
|
||||
|
||||
if (playerActor.pokemonList.size < battleFormat.battleType.slotsPerActor) {
|
||||
val playerAvailablePokemon = playerActor.pokemonList.count { it.health > 0 }
|
||||
if (playerAvailablePokemon < battleFormat.battleType.slotsPerActor) {
|
||||
errors.participantErrors[playerActor] += BattleStartError.insufficientPokemon(
|
||||
actorEntity = player,
|
||||
requiredCount = battleFormat.battleType.slotsPerActor,
|
||||
hadCount = playerActor.pokemonList.size
|
||||
hadCount = playerAvailablePokemon
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ object AIUtility {
|
||||
"geargrind" to Pair(2, 2),
|
||||
"twinbeam" to Pair(2, 2),
|
||||
"twineedle" to Pair(2, 2),
|
||||
"suringstrikes" to Pair(3, 3),
|
||||
"surgingstrikes" to Pair(3, 3),
|
||||
"tripledive" to Pair(3, 3),
|
||||
"watershuriken" to Pair(3, 3),
|
||||
|
||||
|
||||
+4
-2
@@ -163,7 +163,8 @@ class TrackerActor(val uuid: UUID) {
|
||||
//we assume that AI knows it all about our allies
|
||||
trackerActor.party.addAll(actor.pokemonList.map { createAllied(it) })
|
||||
actor.activePokemon.forEach {
|
||||
val active = trackerActor.party.first { trackMon -> trackMon.id == it.battlePokemon!!.uuid }
|
||||
val battlePokemon = it.battlePokemon ?: return@forEach
|
||||
val active = trackerActor.party.first { trackMon -> trackMon.id == battlePokemon.uuid }
|
||||
trackerActor.party.remove(active)
|
||||
trackerActor.activePokemon.add(active)
|
||||
}
|
||||
@@ -176,7 +177,8 @@ class TrackerActor(val uuid: UUID) {
|
||||
//only know basics of what we see right now
|
||||
trackerActor.party.addAll(actor.pokemonList.map { createOpposing(it) })
|
||||
actor.activePokemon.forEach {
|
||||
val active = trackerActor.party.first { trackMon -> trackMon.id == it.battlePokemon!!.uuid }
|
||||
val battlePokemon = it.battlePokemon ?: return@forEach
|
||||
val active = trackerActor.party.first { trackMon -> trackMon.id == battlePokemon.uuid }
|
||||
trackerActor.party.remove(active)
|
||||
trackerActor.activePokemon.add(active)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.block
|
||||
|
||||
//import dev.lambdaurora.lambdynlights.util.SodiumDynamicLightHandler.pos
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.berry.Berries
|
||||
import com.cobblemon.mod.common.api.berry.Berry
|
||||
@@ -40,7 +39,11 @@ import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.LevelReader
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.BaseEntityBlock
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.Blocks
|
||||
import net.minecraft.world.level.block.BonemealableBlock
|
||||
import net.minecraft.world.level.block.RenderShape
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
@@ -70,7 +73,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
|
||||
if (!player.isCreative && state.getValue(AGE) == FRUIT_AGE) {
|
||||
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
|
||||
treeEntity.harvest(world, state, pos, player).forEach { drop -> Block.popResource(world, pos, drop) }
|
||||
treeEntity.harvest(world, state, pos, player).forEach { drop -> popResource(world, pos, drop) }
|
||||
}
|
||||
return super.playerWillDestroy(world, pos, state, player)
|
||||
}
|
||||
@@ -92,7 +95,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
// Random Tick handler: uses time compensation to ensure correct growth speed
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun randomTick(state: BlockState, world: ServerLevel, pos: BlockPos, random: RandomSource) {
|
||||
val blockEntity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return
|
||||
val blockEntity = world.getBlockEntity(pos) as? BerryBlockEntity? ?: return
|
||||
|
||||
// processTick calculates elapsed time and updates timer, returns whether growth is needed
|
||||
if (blockEntity.processTick(world, pos, state) && !world.getBlockTicks().hasScheduledTick(pos, this)) {
|
||||
@@ -128,7 +131,10 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
val newAge = curAge + 1
|
||||
if (newAge > FRUIT_AGE) return
|
||||
val newState = state.setValue(AGE, newAge)
|
||||
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
|
||||
val treeEntity = world.getBlockEntity(pos) as? BerryBlockEntity? ?: run {
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), UPDATE_CLIENTS)
|
||||
return
|
||||
}
|
||||
if (curAge == MATURE_AGE) {
|
||||
treeEntity.generateGrowthPoints(world, newState, pos, null)
|
||||
determineMutation(world, random, pos, newState)
|
||||
@@ -146,7 +152,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
for (direction in this.lookupDirections) {
|
||||
val redirectedPos = pos.offset(direction.normal)
|
||||
val redirectedState = world.getBlockState(redirectedPos)
|
||||
val berryBlock = redirectedState.block as? BerryBlock ?: continue
|
||||
val berryBlock = redirectedState.block as? BerryBlock? ?: continue
|
||||
val berry = berryBlock.berry() ?: continue
|
||||
val mutation = this.berry()?.mutationWith(berry) ?: continue
|
||||
mutations += mutation
|
||||
@@ -160,7 +166,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
treeEntity.decrementMulchDuration(world, pos, state)
|
||||
}
|
||||
val mutation = if (random.nextInt(1000) < mutateChance) mutations.random() else null
|
||||
(world.getBlockEntity(pos) as? BerryBlockEntity)?.let { blockEntity ->
|
||||
(world.getBlockEntity(pos) as? BerryBlockEntity?)?.let { blockEntity ->
|
||||
CobblemonEvents.BERRY_MUTATION_RESULT.post(BerryMutationResultEvent(berry, world, state, pos, berryMutationOffer.mutations, mutation)) { berryMutationResult ->
|
||||
berryMutationResult.pickedMutation?.let { mutation -> blockEntity.mutate(mutation) }
|
||||
}
|
||||
@@ -178,7 +184,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
): Boolean {
|
||||
val underBlockState = world.getBlockState(pos.below())
|
||||
val validSoil = state.getValue(IS_ROOTED) || underBlockState.`is`(CobblemonBlockTags.BERRY_SOIL)
|
||||
val treeEntity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return false
|
||||
val treeEntity = world.getBlockEntity(pos) as? BerryBlockEntity? ?: return false
|
||||
return getMulch(treeEntity) == MulchVariant.NONE && state.getValue(AGE) < FLOWER_AGE && validSoil
|
||||
}
|
||||
|
||||
@@ -353,7 +359,7 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
fun getMulch(entity: BerryBlockEntity) = entity.mulchVariant
|
||||
|
||||
fun convertMulchToEntity(world: ServerLevel, state: BlockState, pos: BlockPos) {
|
||||
val entity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return
|
||||
val entity = world.getBlockEntity(pos) as? BerryBlockEntity? ?: return
|
||||
if (state.getValue(MULCH) != MulchVariant.NONE && state.getValue(MULCH) != entity.mulchVariant) {
|
||||
entity.mulchVariant = state.getValue(MULCH)
|
||||
world.setBlockAndUpdate(pos, state.setValue(MULCH, MulchVariant.NONE))
|
||||
@@ -370,9 +376,9 @@ class BerryBlock(private val berryIdentifier: ResourceLocation, settings: Proper
|
||||
}
|
||||
|
||||
private fun harvestBerry(world: Level, state: BlockState, pos: BlockPos, player: Player? = null): Boolean {
|
||||
val blockEntity = world.getBlockEntity(pos) as? BerryBlockEntity ?: return false
|
||||
val blockEntity = world.getBlockEntity(pos) as? BerryBlockEntity? ?: return false
|
||||
blockEntity.harvest(world, state, pos, player).forEach { drop ->
|
||||
Block.popResource(world, pos, drop)
|
||||
popResource(world, pos, drop)
|
||||
}
|
||||
|
||||
val sound = if (player != null) CobblemonSounds.BERRY_HARVEST else SoundEvents.SHEEP_SHEAR
|
||||
|
||||
+5
-27
@@ -16,24 +16,20 @@ import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.component.DataComponents
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.ContainerHelper
|
||||
import net.minecraft.world.Containers
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.ItemInteractionResult
|
||||
import net.minecraft.world.WorldlyContainer
|
||||
import net.minecraft.world.*
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.level.gameevent.GameEvent
|
||||
import java.util.OptionalInt
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import java.util.*
|
||||
import kotlin.math.pow
|
||||
|
||||
class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(CobblemonBlockEntities.DISC_SHELF, pos, state), WorldlyContainer {
|
||||
@@ -134,25 +130,7 @@ class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobbl
|
||||
return stack.item is TechnicalMachineItem
|
||||
|| stack.item == CobblemonItems.UPGRADE
|
||||
|| stack.item == CobblemonItems.DUBIOUS_DISC
|
||||
|| stack.item == Items.MUSIC_DISC_13
|
||||
|| stack.item == Items.MUSIC_DISC_CAT
|
||||
|| stack.item == Items.MUSIC_DISC_BLOCKS
|
||||
|| stack.item == Items.MUSIC_DISC_CHIRP
|
||||
|| stack.item == Items.MUSIC_DISC_FAR
|
||||
|| stack.item == Items.MUSIC_DISC_MALL
|
||||
|| stack.item == Items.MUSIC_DISC_MELLOHI
|
||||
|| stack.item == Items.MUSIC_DISC_STAL
|
||||
|| stack.item == Items.MUSIC_DISC_STRAD
|
||||
|| stack.item == Items.MUSIC_DISC_WARD
|
||||
|| stack.item == Items.MUSIC_DISC_11
|
||||
|| stack.item == Items.MUSIC_DISC_WAIT
|
||||
|| stack.item == Items.MUSIC_DISC_OTHERSIDE
|
||||
|| stack.item == Items.MUSIC_DISC_5
|
||||
|| stack.item == Items.MUSIC_DISC_RELIC
|
||||
|| stack.item == Items.MUSIC_DISC_PRECIPICE
|
||||
|| stack.item == Items.MUSIC_DISC_CREATOR
|
||||
|| stack.item == Items.MUSIC_DISC_CREATOR_MUSIC_BOX
|
||||
|| stack.item == Items.MUSIC_DISC_PIGSTEP
|
||||
|| stack.has(DataComponents.JUKEBOX_PLAYABLE)
|
||||
}
|
||||
|
||||
fun onNoteBlockPulse(level: Level, noteBlockPos: BlockPos, soundEvent: SoundEvent) {
|
||||
|
||||
+1
-3
@@ -14,7 +14,6 @@ import com.cobblemon.mod.common.api.multiblock.MultiblockEntity
|
||||
import com.cobblemon.mod.common.api.multiblock.MultiblockStructure
|
||||
import com.cobblemon.mod.common.api.multiblock.builder.MultiblockStructureBuilder
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.block.MonitorBlock
|
||||
import com.cobblemon.mod.common.block.multiblock.FossilMultiblockStructure
|
||||
@@ -307,8 +306,7 @@ open class FossilMultiblockEntity(
|
||||
private fun unlockTmForPlayer(player: ServerPlayer, stack: ItemStack) {
|
||||
if (stack.item !is TechnicalMachineItem) return
|
||||
val move = TMMoveComponent.getTMMove(stack) ?: return
|
||||
val tmId = TechnicalMachines.moveToTM[move]?.id ?: return
|
||||
player.tmList()?.learn(listOf(tmId))
|
||||
player.tmList().syncTMFromMove(move)
|
||||
}
|
||||
|
||||
private fun updateMonitorScreen() {
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.world.level.block.SoundType
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.entity.CommandBlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
@@ -80,11 +81,13 @@ class HabitatBlock(properties: Properties) : Block(properties), EntityBlock {
|
||||
}
|
||||
|
||||
override fun useWithoutItem(state: BlockState, level: Level, pos: BlockPos, player: Player, hitResult: BlockHitResult): InteractionResult {
|
||||
if (!level.isClientSide) {
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return be.onUse(player, hitResult)
|
||||
val blockEntity = level.getBlockEntity(pos)
|
||||
val be = level.getBlockEntity(pos) as? HabitatBlockEntity ?: return InteractionResult.PASS
|
||||
return if (blockEntity is HabitatBlockEntity && player.canUseGameMasterBlocks()) {
|
||||
be.onUse(player, hitResult)
|
||||
} else {
|
||||
InteractionResult.PASS
|
||||
}
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
override fun getDrops(state: BlockState, params: LootParams.Builder): MutableList<ItemStack> {
|
||||
|
||||
@@ -60,10 +60,12 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
|
||||
var spawningStyle: HabitatSpawningStyle = ActivatedHabitatSpawning(this)
|
||||
|
||||
var numberOfPhases: Int = 1
|
||||
var phaseOrder = HabitatPhaseOrder.SIMPLE
|
||||
var currentPhase = 1
|
||||
|
||||
val numberOfPhases: Int
|
||||
get() = pool.getPhaseCount()
|
||||
|
||||
var levelRange: IntRange = 1..Cobblemon.config.maxPokemonLevel
|
||||
var modifiers: PokemonProperties = PokemonProperties()
|
||||
var pool: HabitatPool = HabitatPool.default()
|
||||
@@ -139,7 +141,6 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
val activatedSettings = habitatSettingsDTO.activatedSettings
|
||||
val naturalSettings = habitatSettingsDTO.naturalSettings
|
||||
val isActivated = habitatSettingsDTO.isActivatedSpawning
|
||||
this.numberOfPhases = habitatSettingsDTO.numberOfPhases
|
||||
this.phaseOrder = habitatSettingsDTO.phaseOrder
|
||||
this.levelRange = habitatSettingsDTO.levelRange
|
||||
this.modifiers = PokemonProperties.parse(habitatSettingsDTO.modifiers)
|
||||
@@ -169,7 +170,6 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
override fun saveAdditional(tag: CompoundTag, registryLookup: HolderLookup.Provider) {
|
||||
super.saveAdditional(tag, registryLookup)
|
||||
tag.putString(DataKeys.HABITAT_MIMIC, mimicId.toString())
|
||||
tag.putInt(DataKeys.HABITAT_PHASE_COUNT, numberOfPhases)
|
||||
tag.putString(DataKeys.HABITAT_PHASE_ORDER, phaseOrder.toString())
|
||||
// Only save the level range when it's a non-trivial one
|
||||
if (levelRange.first != 1 || levelRange.last != Cobblemon.config.maxPokemonLevel) {
|
||||
@@ -201,7 +201,6 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
return // Client doesn't need to try loading the rest
|
||||
}
|
||||
|
||||
numberOfPhases = tag.getInt(DataKeys.HABITAT_PHASE_COUNT)
|
||||
phaseOrder = HabitatPhaseOrder.valueOf(tag.getString(DataKeys.HABITAT_PHASE_ORDER))
|
||||
levelRange = tag.getString(DataKeys.HABITAT_LEVEL_RANGE).takeIf { it.isNotBlank() }?.let(IntRangeAdapter::deserialize) ?: 1..Cobblemon.config.maxPokemonLevel
|
||||
modifiers = tag.getString(DataKeys.HABITAT_MODIFIERS).takeIf { it.isNotBlank() }?.let(PokemonProperties::parse) ?: PokemonProperties()
|
||||
@@ -279,7 +278,7 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
override fun injectSpawns(bucket: String, spawnablePosition: SpawnablePosition): List<SpawnDetail>? {
|
||||
val spawningStyle = spawningStyle
|
||||
return if (spawningStyle is NaturalHabitatSpawning) {
|
||||
spawnDetails.filter { it.spawnablePositionType.clazz == spawnablePosition::class.java && it.isSatisfiedBy(spawnablePosition) }
|
||||
spawnDetails.filter { it.bucket == bucket && it.spawnablePositionType.clazz == spawnablePosition::class.java && it.isSatisfiedBy(spawnablePosition) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
+6
-2
@@ -630,7 +630,8 @@ class FossilMultiblockStructure (
|
||||
result.putInt(DataKeys.ORGANIC_MATERIAL, organicMaterialInside)
|
||||
val fossilInv = ListTag()
|
||||
|
||||
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(NbtOps.INSTANCE, it).orThrow) }
|
||||
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
|
||||
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(ops, it).getOrThrow()) }
|
||||
result.put(DataKeys.FOSSIL_INVENTORY, fossilInv)
|
||||
result.putString(DataKeys.CONNECTOR_DIRECTION, tankConnectorDirection?.toString())
|
||||
|
||||
@@ -669,7 +670,10 @@ class FossilMultiblockStructure (
|
||||
|
||||
val fossilInv = if (nbt.contains(DataKeys.FOSSIL_INVENTORY)) { (nbt.get(DataKeys.FOSSIL_INVENTORY) as ListTag) } else ListTag()
|
||||
val actualFossilList = mutableListOf<ItemStack>()
|
||||
fossilInv.forEach { ItemStack.parse(registryLookup, it).ifPresent(actualFossilList::add) }
|
||||
|
||||
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
|
||||
fossilInv.forEach { ItemStack.CODEC.parse(ops, it).result().ifPresent(actualFossilList::add) }
|
||||
|
||||
result.fossilInventory = actualFossilList
|
||||
result.tankConnectorDirection = Direction.byName(nbt.getString(DataKeys.CONNECTOR_DIRECTION))
|
||||
|
||||
|
||||
@@ -10,11 +10,13 @@ package com.cobblemon.mod.common.block.tmmachine
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.CobblemonMenuType
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.moves.Moves
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachine
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||
import com.cobblemon.mod.common.block.entity.TMMachineBlockEntity
|
||||
import com.cobblemon.mod.common.util.itemRegistry
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SynchronizeActiveTMPacket
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.SimpleContainer
|
||||
@@ -35,38 +37,20 @@ class TMMachineMenu(menuType: MenuType<*>, syncId: Int) : AbstractContainerMenu(
|
||||
var inventory: Container? = null
|
||||
var containerData: ContainerData? = null
|
||||
|
||||
var currentlySelectedTM: TechnicalMachine? = null
|
||||
private var lastSelectedTM: TechnicalMachine? = null
|
||||
|
||||
var onSelectedTMUpdate: (TechnicalMachine?) -> Unit = {}
|
||||
|
||||
constructor(syncId: Int, playerInventory: Inventory) : this(CobblemonMenuType.TM_MACHINE, syncId) {
|
||||
this.playerInventory = playerInventory
|
||||
this.inventory = SimpleContainer(5)
|
||||
this.containerData = SimpleContainerData(6)
|
||||
this.tmMachineEntity = (inventory as? TMMachineBlockEntity.TMMachineBlockInventory)?.blockEntity
|
||||
|
||||
this.addDataSlots(containerData!!)
|
||||
inventory?.startOpen(playerInventory.player)
|
||||
|
||||
val startX = 15
|
||||
val startY = 144
|
||||
val slotWidth = 18
|
||||
val slotHeight = 18
|
||||
|
||||
for (row in 0..2) {
|
||||
for (col in 0..8) {
|
||||
this.addSlot(Slot(playerInventory, 9 + (row * 9) + col, startX + (slotWidth * col), startY + (slotHeight * row)))
|
||||
}
|
||||
}
|
||||
for (col in 0..8) {
|
||||
this.addSlot(Slot(playerInventory, col, startX + (slotWidth * col), startY + 58))
|
||||
}
|
||||
|
||||
val container = inventory
|
||||
container?.let {
|
||||
this.addSlot(TMResultSlot(container, RESULT_SLOT, startX + 37, startY - 28)) // Output slot
|
||||
this.addSlot(BlankTMSlot(container, BLANK_TM_SLOT, startX + 90, startY - 28)) // Blank TM
|
||||
for (index in INGREDIENT_SLOTS) {
|
||||
this.addSlot(Slot(container, index, startX + 114 + (18 * (index - INGREDIENT_SLOTS.first)), startY - 28))
|
||||
}
|
||||
}
|
||||
this.addSlotListener(this)
|
||||
initiateSlots()
|
||||
}
|
||||
|
||||
constructor(syncId: Int, playerInventory: Inventory, inventory: Container, containerData: ContainerData) : this(CobblemonMenuType.TM_MACHINE, syncId) {
|
||||
@@ -78,6 +62,20 @@ class TMMachineMenu(menuType: MenuType<*>, syncId: Int) : AbstractContainerMenu(
|
||||
this.addDataSlots(containerData)
|
||||
inventory.startOpen(playerInventory.player)
|
||||
|
||||
initiateSlots()
|
||||
|
||||
tmMachineEntity?.let {
|
||||
val move = Moves.getByName(it.activeMove)
|
||||
move.let {
|
||||
currentlySelectedTM = TechnicalMachines.moveToTM[it]
|
||||
synchronizeSelectedTM()
|
||||
}
|
||||
}
|
||||
|
||||
this.addSlotListener(this)
|
||||
}
|
||||
|
||||
private fun initiateSlots() {
|
||||
val startX = 15
|
||||
val startY = 144
|
||||
val slotWidth = 18
|
||||
@@ -92,7 +90,7 @@ class TMMachineMenu(menuType: MenuType<*>, syncId: Int) : AbstractContainerMenu(
|
||||
this.addSlot(Slot(playerInventory, col, startX + (slotWidth * col), startY + 58))
|
||||
}
|
||||
|
||||
val container = inventory
|
||||
val container = inventory!!
|
||||
container.let {
|
||||
this.addSlot(TMResultSlot(container, RESULT_SLOT, startX + 37, startY - 28)) // Output slot
|
||||
this.addSlot(BlankTMSlot(container, BLANK_TM_SLOT, startX + 90, startY - 28)) // Blank TM
|
||||
@@ -100,7 +98,6 @@ class TMMachineMenu(menuType: MenuType<*>, syncId: Int) : AbstractContainerMenu(
|
||||
this.addSlot(Slot(container, index, startX + 114 + (18 * (index - INGREDIENT_SLOTS.first)), startY - 28))
|
||||
}
|
||||
}
|
||||
this.addSlotListener(this)
|
||||
}
|
||||
|
||||
override fun quickMoveStack(player: Player, index: Int): ItemStack {
|
||||
@@ -207,4 +204,25 @@ class TMMachineMenu(menuType: MenuType<*>, syncId: Int) : AbstractContainerMenu(
|
||||
override fun dataChanged(containerMenu: AbstractContainerMenu, dataSlotIndex: Int, value: Int) {
|
||||
broadcastChanges()
|
||||
}
|
||||
|
||||
fun synchronizeSelectedTM() {
|
||||
val serverPlayer = playerInventory?.player as? ServerPlayer ?: return
|
||||
serverPlayer.sendPacket(SynchronizeActiveTMPacket(currentlySelectedTM))
|
||||
lastSelectedTM = currentlySelectedTM
|
||||
}
|
||||
|
||||
override fun sendAllDataToRemote() {
|
||||
super.sendAllDataToRemote()
|
||||
synchronizeSelectedTM()
|
||||
}
|
||||
|
||||
override fun broadcastChanges() {
|
||||
super.broadcastChanges()
|
||||
if (lastSelectedTM != currentlySelectedTM) synchronizeSelectedTM()
|
||||
}
|
||||
|
||||
fun clientSetSelectedTM(tm: TechnicalMachine?) {
|
||||
currentlySelectedTM = tm
|
||||
onSelectedTMUpdate(tm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ object MountedCameraTypeHandler {
|
||||
return
|
||||
}
|
||||
val currentCameraType = mc.options.cameraType
|
||||
if (currentCameraType != unmountedCameraType) {
|
||||
if (Cobblemon.config.rememberRidingCamera && currentCameraType != unmountedCameraType) {
|
||||
mc.options.cameraType = unmountedCameraType
|
||||
}
|
||||
val data = ClientPersistedData.ridingPerspectives
|
||||
|
||||
@@ -130,20 +130,25 @@ class PartyOverlay : Gui(Minecraft.getInstance()) {
|
||||
val party = CobblemonClient.storage.party
|
||||
val matrices = context.pose()
|
||||
if (party.slots.none { it != null }) {
|
||||
if (CobblemonClient.clientPlayerData.promptStarter &&
|
||||
if (!this.attachedToast &&
|
||||
CobblemonClient.clientPlayerData.promptStarter &&
|
||||
!CobblemonClient.clientPlayerData.starterLocked &&
|
||||
!CobblemonClient.clientPlayerData.starterSelected &&
|
||||
!CobblemonClient.checkedStarterScreen
|
||||
) {
|
||||
if (!this.attachedToast) {
|
||||
// Adding starter toast on start and connect of client to server.
|
||||
minecraft.toasts.addToast(this.starterToast)
|
||||
this.attachedToast = true
|
||||
}
|
||||
// Adding starter toast on start and connect of client to server.
|
||||
minecraft.toasts.addToast(this.starterToast)
|
||||
this.attachedToast = true
|
||||
}
|
||||
return // Don't render the stuff below if no Pokémon in party
|
||||
}
|
||||
|
||||
// Without this simply capturing a Pokémon instead of opening the starter screen won't dismiss the toast
|
||||
if (!CobblemonClient.checkedStarterScreen) {
|
||||
CobblemonClient.checkedStarterScreen = true
|
||||
starterToast.nextVisibility = Toast.Visibility.HIDE
|
||||
}
|
||||
|
||||
val totalHeight = party.slots.size * SLOT_HEIGHT
|
||||
val midY = minecraft.window.guiScaledHeight / 2
|
||||
val startY = (midY - totalHeight / 2) - ((SLOT_SPACING * 5) / 2)
|
||||
|
||||
@@ -27,10 +27,18 @@ import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.atan
|
||||
|
||||
enum class ProfileTransformType {
|
||||
PROFILE,
|
||||
NONE,
|
||||
POKEDEX,
|
||||
SUMMARY,
|
||||
}
|
||||
|
||||
fun drawProfilePokemon(
|
||||
renderablePokemon: RenderablePokemon,
|
||||
matrixStack: PoseStack,
|
||||
@@ -39,7 +47,7 @@ fun drawProfilePokemon(
|
||||
state: PosableState,
|
||||
partialTicks: Float,
|
||||
scale: Float = 20F,
|
||||
applyProfileTransform: Boolean = true,
|
||||
profileTransformType: ProfileTransformType = ProfileTransformType.PROFILE,
|
||||
applyBaseScale: Boolean = false,
|
||||
r: Float = 1F,
|
||||
g: Float = 1F,
|
||||
@@ -56,7 +64,7 @@ fun drawProfilePokemon(
|
||||
state = state.also { it.currentAspects = renderablePokemon.aspects },
|
||||
partialTicks = partialTicks,
|
||||
scale = scale,
|
||||
applyProfileTransform = applyProfileTransform,
|
||||
profileTransformType = profileTransformType,
|
||||
applyBaseScale = applyBaseScale,
|
||||
r = r,
|
||||
g = g,
|
||||
@@ -75,7 +83,7 @@ fun drawProfilePokemon(
|
||||
state: PosableState,
|
||||
partialTicks: Float,
|
||||
scale: Float = 20F,
|
||||
applyProfileTransform: Boolean = true,
|
||||
profileTransformType: ProfileTransformType = ProfileTransformType.PROFILE,
|
||||
applyBaseScale: Boolean = false,
|
||||
doQuirks: Boolean = false,
|
||||
r: Float = 1F,
|
||||
@@ -114,18 +122,38 @@ fun drawProfilePokemon(
|
||||
state.setPoseToFirstSuitable(poseType)
|
||||
state.updatePartialTicks(partialTicks)
|
||||
|
||||
if (applyProfileTransform) {
|
||||
matrixStack.translate(
|
||||
model.profileTranslation.x,
|
||||
model.profileTranslation.y + 1.5 * model.profileScale,
|
||||
model.profileTranslation.z - 4.0
|
||||
)
|
||||
matrixStack.scale(model.profileScale, model.profileScale, 1 / model.profileScale)} else {
|
||||
if (profileTransformType == ProfileTransformType.NONE) {
|
||||
matrixStack.translate(0F, 0F, -4.0F)
|
||||
if (applyBaseScale) {
|
||||
matrixStack.scale(baseScale, baseScale, 1 / baseScale)
|
||||
}
|
||||
} else {
|
||||
var profileScale: Float
|
||||
var profileTranslation: Vec3
|
||||
|
||||
when (profileTransformType) {
|
||||
ProfileTransformType.POKEDEX -> {
|
||||
profileScale = model.profilePokedexScale ?: model.profileScale
|
||||
profileTranslation = model.profilePokedexTranslation ?: model.profileTranslation
|
||||
}
|
||||
ProfileTransformType.SUMMARY -> {
|
||||
profileScale = model.profileSummaryScale ?: model.profileScale
|
||||
profileTranslation = model.profileSummaryTranslation ?: model.profileTranslation
|
||||
}
|
||||
else -> {
|
||||
profileScale = model.profileScale
|
||||
profileTranslation = model.profileTranslation
|
||||
}
|
||||
}
|
||||
|
||||
matrixStack.translate(
|
||||
profileTranslation.x,
|
||||
profileTranslation.y + 1.5 * profileScale,
|
||||
profileTranslation.z - 4.0
|
||||
)
|
||||
matrixStack.scale(profileScale, profileScale, 1 / profileScale)
|
||||
}
|
||||
|
||||
matrixStack.mulPose(rotation)
|
||||
|
||||
model.applyAnimations(null, state, 0F, 0F, 0F, headYaw, headPitch)
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
fun handleProfileDebugKeys(keyCode: Int, poserResourceLocation: ResourceLocation, state: FloatingState) {
|
||||
if (!Cobblemon.config.enableDebugKeys) {
|
||||
return
|
||||
}
|
||||
val model = VaryingModelRepository.getPoser(poserResourceLocation, state)
|
||||
|
||||
val delta = when (keyCode) {
|
||||
InputConstants.KEY_UP -> Vec3(0.0, -0.01, 0.0)
|
||||
InputConstants.KEY_DOWN -> Vec3(0.0, 0.01, 0.0)
|
||||
InputConstants.KEY_LEFT -> Vec3(-0.01, 0.0, 0.0)
|
||||
InputConstants.KEY_RIGHT -> Vec3(0.01, 0.0, 0.0)
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (delta != null) {
|
||||
model.profileTranslation = model.profileTranslation.add(delta)
|
||||
model.profileSummaryTranslation = model.profileSummaryTranslation?.add(delta)
|
||||
model.profilePokedexTranslation = model.profilePokedexTranslation?.add(delta)
|
||||
}
|
||||
|
||||
val scaleDelta = when (keyCode) {
|
||||
InputConstants.KEY_EQUALS -> 0.01F
|
||||
InputConstants.KEY_MINUS -> -0.01F
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (scaleDelta != null) {
|
||||
model.profileScale += scaleDelta
|
||||
model.profileSummaryScale = model.profileSummaryScale?.plus(scaleDelta)
|
||||
model.profilePokedexScale = model.profilePokedexScale?.plus(scaleDelta)
|
||||
}
|
||||
}
|
||||
|
||||
fun logProfileTranslations(poserResourceLocation: ResourceLocation, state: FloatingState) {
|
||||
if (!Cobblemon.config.enableDebugKeys) {
|
||||
return
|
||||
}
|
||||
|
||||
val model = VaryingModelRepository.getPoser(poserResourceLocation, state)
|
||||
val player = Minecraft.getInstance().player
|
||||
|
||||
fun Double.f2() = "%.2f".format(this)
|
||||
fun Float.f2() = "%.2f".format(this)
|
||||
|
||||
fun sendTranslation(name: String, translation: Vec3) {
|
||||
player?.sendSystemMessage(Component.literal("$name Translation: (${translation.x.f2()}, ${translation.y.f2()}, ${translation.z.f2()})"))
|
||||
}
|
||||
|
||||
fun sendScale(name: String, scale: Float) {
|
||||
player?.sendSystemMessage(Component.literal("$name Scale: ${scale.f2()}"))
|
||||
}
|
||||
|
||||
fun logTranslation(name: String, translation: Vec3) {
|
||||
Cobblemon.LOGGER.info("override var ${name.replaceFirstChar(Char::lowercase)}Translation = Vec3(${translation.x.f2()}, ${translation.y.f2()}, ${translation.z.f2()})")
|
||||
}
|
||||
|
||||
fun logScale(name: String, scale: Float) {
|
||||
Cobblemon.LOGGER.info("override var ${name.replaceFirstChar(Char::lowercase)}Scale = ${scale.f2()}F")
|
||||
}
|
||||
|
||||
sendTranslation("Profile", model.profileTranslation)
|
||||
sendScale("Profile", model.profileScale)
|
||||
|
||||
model.profileSummaryTranslation?.let { sendTranslation("Summary Profile", it) }
|
||||
model.profileSummaryScale?.let { sendScale("Summary Profile", it) }
|
||||
|
||||
model.profilePokedexTranslation?.let { sendTranslation("Pokedex Profile", it) }
|
||||
model.profilePokedexScale?.let { sendScale("Pokedex Profile", it) }
|
||||
|
||||
logTranslation("Profile", model.profileTranslation)
|
||||
logScale("Profile", model.profileScale)
|
||||
|
||||
model.profileSummaryTranslation?.let { logTranslation("ProfileSummary", it) }
|
||||
model.profileSummaryScale?.let { logScale("ProfileSummary", it) }
|
||||
|
||||
model.profilePokedexTranslation?.let { logTranslation("ProfilePokedex", it) }
|
||||
model.profilePokedexScale?.let { logScale("ProfilePokedex", it) }
|
||||
}
|
||||
+1
@@ -41,6 +41,7 @@ class CobblemonConfigScreen(
|
||||
const val WIDGET_HEIGHT = SLOT_HEIGHT - PADDING
|
||||
const val LABEL_Y_OFFSET = 4
|
||||
const val WIDGET_Y_OFFSET = 0
|
||||
const val LABEL_MAX_WIDTH = SLOT_WIDTH - RESET_SLOT_WIDTH - WIDGET_WIDTH - PADDING * 2
|
||||
}
|
||||
|
||||
val clonedConfig = Cobblemon.config.clone()
|
||||
|
||||
+12
-8
@@ -8,17 +8,18 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.config.variable
|
||||
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.LABEL_MAX_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.RESET_SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.SLOT_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigScreen.Companion.WIDGET_Y_OFFSET
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList
|
||||
import com.cobblemon.mod.common.client.gui.config.CobblemonConfigVariableList.CobblemonConfigVariableListEntry
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.drawScrollingText
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import com.cobblemon.mod.common.config.CobblemonConfigField
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.components.Tooltip
|
||||
@@ -91,12 +92,15 @@ abstract class CobblemonConfigVariable(
|
||||
val x = getX(left)
|
||||
val y = getY(top)
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
text = labelLang,
|
||||
x = getX(left),
|
||||
y = getY(top) + LABEL_Y_OFFSET,
|
||||
shadow = true
|
||||
drawScrollingText(
|
||||
context,
|
||||
Minecraft.getInstance().font,
|
||||
labelLang,
|
||||
x,
|
||||
y + WIDGET_Y_OFFSET,
|
||||
x + LABEL_MAX_WIDTH,
|
||||
y + WIDGET_Y_OFFSET + WIDGET_HEIGHT,
|
||||
-1
|
||||
)
|
||||
|
||||
resetButton.x = x + SLOT_WIDTH - RESET_SLOT_WIDTH
|
||||
|
||||
+18
-29
@@ -115,35 +115,19 @@ class HabitatEditGUI(
|
||||
addOptionWidget(mimicInput)
|
||||
y += spacing
|
||||
|
||||
labels.add(lang("ui.edit.habitat.phase_number") to (10 to y))
|
||||
y += 12
|
||||
val phasesInput = EditBox(font, 10, y, buttonWidth, 20, "Phases".text())
|
||||
phasesInput.value = habitatSettingsDTO.numberOfPhases.toString()
|
||||
phasesInput.setResponder { value ->
|
||||
val phases = value.toIntOrNull()
|
||||
val valid = phases != null && phases > 0
|
||||
if (valid) {
|
||||
habitatSettingsDTO.numberOfPhases = phases
|
||||
}
|
||||
phasesInput.setTextColor(if (valid) validTextColor else invalidTextColor)
|
||||
setFieldValidity("phases", valid, "ui.edit.habitat.validation.phases")
|
||||
// Phase setting only visible if there's more than one phase
|
||||
val phaseCount = habitatSettingsDTO.pool.toHabitatPool()?.getPhaseCount() ?: 1
|
||||
if (phaseCount > 1) {
|
||||
phaseOrderButton = addOptionWidget(
|
||||
Button.builder(getPhaseOrderText()) {
|
||||
val orders = HabitatPhaseOrder.entries
|
||||
val currentIndex = orders.indexOf(habitatSettingsDTO.phaseOrder)
|
||||
habitatSettingsDTO.phaseOrder = orders[(currentIndex + 1) % orders.size]
|
||||
refresh()
|
||||
}.bounds(10, y, buttonWidth, 20).build()
|
||||
)
|
||||
y += spacing
|
||||
}
|
||||
val initialPhases = phasesInput.value.toIntOrNull()
|
||||
val initialPhasesValid = initialPhases != null && initialPhases > 0
|
||||
phasesInput.setTextColor(if (initialPhasesValid) validTextColor else invalidTextColor)
|
||||
setFieldValidity("phases", initialPhasesValid, "ui.edit.habitat.validation.phases")
|
||||
addOptionWidget(phasesInput)
|
||||
y += spacing
|
||||
|
||||
phaseOrderButton = addOptionWidget(
|
||||
Button.builder(getPhaseOrderText()) {
|
||||
val orders = HabitatPhaseOrder.entries
|
||||
val currentIndex = orders.indexOf(habitatSettingsDTO.phaseOrder)
|
||||
habitatSettingsDTO.phaseOrder = orders[(currentIndex + 1) % orders.size]
|
||||
refresh()
|
||||
}.bounds(10, y, buttonWidth, 20).build()
|
||||
)
|
||||
y += spacing
|
||||
|
||||
labels.add(lang("ui.edit.habitat.level_range") to (10 to y))
|
||||
y += 12
|
||||
@@ -390,7 +374,10 @@ class HabitatEditGUI(
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
phaseOrderButton.message = getPhaseOrderText()
|
||||
val phaseCount = habitatSettingsDTO.pool.toHabitatPool()?.getPhaseCount() ?: 1
|
||||
if (phaseCount > 1 && ::phaseOrderButton.isInitialized) {
|
||||
phaseOrderButton.message = getPhaseOrderText()
|
||||
}
|
||||
spawnModeButton.message = getSpawnModeText()
|
||||
poolSelectorButton.message = getPoolText()
|
||||
viewPoolButton.message = getViewPoolText()
|
||||
@@ -439,6 +426,7 @@ class HabitatEditGUI(
|
||||
}
|
||||
habitatSettingsDTO.pool = newCustomPool
|
||||
}
|
||||
rebuildWidgets()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -451,6 +439,7 @@ class HabitatEditGUI(
|
||||
}
|
||||
|
||||
habitatSettingsDTO.pool = selectedPool
|
||||
rebuildWidgets()
|
||||
}
|
||||
|
||||
private fun validateLevelRangeInputs() {
|
||||
|
||||
+4
-6
@@ -45,7 +45,6 @@ class HabitatSpawnEditorGUI(
|
||||
private val actionButtonBottomMargin = 10
|
||||
private val validTextColor = 0xFFFFFF
|
||||
private val invalidTextColor = 0xFF5555
|
||||
private val moonPhaseRange = 0..7
|
||||
private lateinit var positionTypeButton: Button
|
||||
private lateinit var bucketButton: Button
|
||||
private lateinit var timeOfDayButton: Button
|
||||
@@ -185,7 +184,7 @@ class HabitatSpawnEditorGUI(
|
||||
phasesInput.setTextColor(validTextColor)
|
||||
setFieldValidity("phases_list", true, "ui.edit.habitat.validation.phases_list")
|
||||
} else {
|
||||
val parsed = parseMoonPhases(value)
|
||||
val parsed = parsePhases(value)
|
||||
val valid = parsed != null
|
||||
if (valid) {
|
||||
spawn.phases = parsed
|
||||
@@ -194,7 +193,7 @@ class HabitatSpawnEditorGUI(
|
||||
setFieldValidity("phases_list", valid, "ui.edit.habitat.validation.phases_list")
|
||||
}
|
||||
}
|
||||
val initialPhasesValid = phasesInput.value.isBlank() || parseMoonPhases(phasesInput.value) != null
|
||||
val initialPhasesValid = phasesInput.value.isBlank() || parsePhases(phasesInput.value) != null
|
||||
phasesInput.setTextColor(if (initialPhasesValid) validTextColor else invalidTextColor)
|
||||
setFieldValidity("phases_list", initialPhasesValid, "ui.edit.habitat.validation.phases_list")
|
||||
addOptionWidget(phasesInput)
|
||||
@@ -332,7 +331,7 @@ class HabitatSpawnEditorGUI(
|
||||
return runCatching { PokemonSpecies.getByName(lowered) }.getOrNull()
|
||||
}
|
||||
|
||||
private fun parseMoonPhases(raw: String): IntRanges? {
|
||||
private fun parsePhases(raw: String): IntRanges? {
|
||||
val ranges = mutableListOf<IntRange>()
|
||||
val tokens = raw.split(",").map(String::trim)
|
||||
if (tokens.isEmpty() || tokens.any { it.isEmpty() }) {
|
||||
@@ -344,13 +343,12 @@ class HabitatSpawnEditorGUI(
|
||||
val range = when (parts.size) {
|
||||
1 -> {
|
||||
val value = parts[0].toIntOrNull() ?: return null
|
||||
if (value !in moonPhaseRange) return null
|
||||
value..value
|
||||
}
|
||||
2 -> {
|
||||
val start = parts[0].toIntOrNull() ?: return null
|
||||
val end = parts[1].toIntOrNull() ?: return null
|
||||
if (start !in moonPhaseRange || end !in moonPhaseRange || start > end) {
|
||||
if (start > end) {
|
||||
return null
|
||||
}
|
||||
start..end
|
||||
|
||||
@@ -32,6 +32,8 @@ import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.client.gui.handleProfileDebugKeys
|
||||
import com.cobblemon.mod.common.client.gui.logProfileTranslations
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_HEIGHT
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
|
||||
@@ -427,6 +429,11 @@ class PokedexGUI private constructor(
|
||||
override fun onClose() {
|
||||
if (blockPos != null) AdjustBlockEntityViewerCountPacket(blockPos, false).sendToServer()
|
||||
playSound(CobblemonSounds.POKEDEX_CLOSE)
|
||||
|
||||
selectedEntry?.speciesId?.let { speciesId ->
|
||||
logProfileTranslations(speciesId, pokemonInfoWidget.state)
|
||||
}
|
||||
|
||||
super.onClose()
|
||||
}
|
||||
|
||||
@@ -757,6 +764,12 @@ class PokedexGUI private constructor(
|
||||
return true
|
||||
}
|
||||
|
||||
if (!searchWidget.isFocused) {
|
||||
selectedEntry?.speciesId?.let { speciesId ->
|
||||
handleProfileDebugKeys(keyCode, speciesId, pokemonInfoWidget.state)
|
||||
}
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -22,6 +22,7 @@ import com.cobblemon.mod.common.api.types.ElementalType
|
||||
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.ProfileTransformType
|
||||
import com.cobblemon.mod.common.client.gui.TypeIcon
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
|
||||
@@ -386,7 +387,8 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
|
||||
partialTicks = delta,
|
||||
rotation = Quaternionf().fromEulerXYZDegrees(rotationVector),
|
||||
state = state,
|
||||
blockLight = 15
|
||||
blockLight = 15,
|
||||
profileTransformType = ProfileTransformType.POKEDEX,
|
||||
)
|
||||
|
||||
matrices.popPose()
|
||||
|
||||
+2
-1
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.gui.pokedex.widgets
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.ProfileTransformType
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
|
||||
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_DESCRIPTION_HEIGHT
|
||||
@@ -90,7 +91,7 @@ class SizeWidget(val pX: Int, val pY: Int) : SoundlessWidget(
|
||||
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(0F, 0F, 0F)),
|
||||
state = FloatingState(),
|
||||
scale = modelScale,
|
||||
applyProfileTransform = false,
|
||||
profileTransformType = ProfileTransformType.NONE,
|
||||
applyBaseScale = true,
|
||||
r = 0F,
|
||||
g = 0F,
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.gui.summary
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendToServer
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
@@ -21,14 +20,8 @@ import com.cobblemon.mod.common.api.text.bold
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.CobblemonResources
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.client.gui.ExitButton
|
||||
import com.cobblemon.mod.common.client.gui.TypeIcon
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.EvolutionSelectScreen
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.MarkingsWidget
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.ModelWidget
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.NicknameEntryWidget
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.PartyWidget
|
||||
import com.cobblemon.mod.common.client.gui.*
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.*
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.SummaryTab
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.info.InfoWidget
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.marks.MarksWidget
|
||||
@@ -37,7 +30,6 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves.MovesWi
|
||||
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.StatWidget
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.SummaryBinding
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
|
||||
@@ -715,27 +707,9 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
) {
|
||||
this.focused = null
|
||||
}
|
||||
if (Cobblemon.config.enableDebugKeys) {
|
||||
val model = VaryingModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, modelWidget.state)
|
||||
if (keyCode == InputConstants.KEY_UP) {
|
||||
model.profileTranslation = model.profileTranslation.add(0.0, -0.01, 0.0)
|
||||
}
|
||||
if (keyCode == InputConstants.KEY_DOWN) {
|
||||
model.profileTranslation = model.profileTranslation.add(0.0, 0.01, 0.0)
|
||||
}
|
||||
if (keyCode == InputConstants.KEY_LEFT) {
|
||||
model.profileTranslation = model.profileTranslation.add(-0.01, 0.0, 0.0)
|
||||
}
|
||||
if (keyCode == InputConstants.KEY_RIGHT) {
|
||||
model.profileTranslation = model.profileTranslation.add(0.01, 0.0, 0.0)
|
||||
}
|
||||
if (keyCode == InputConstants.KEY_EQUALS) {
|
||||
model.profileScale += 0.01F
|
||||
}
|
||||
if (keyCode == InputConstants.KEY_MINUS) {
|
||||
model.profileScale -= 0.01F
|
||||
}
|
||||
}
|
||||
|
||||
handleProfileDebugKeys(keyCode, selectedPokemon.species.resourceIdentifier, modelWidget.state)
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||
}
|
||||
|
||||
@@ -744,13 +718,8 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
||||
}
|
||||
|
||||
override fun onClose() {
|
||||
if (Cobblemon.config.enableDebugKeys) {
|
||||
val model = VaryingModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, modelWidget.state)
|
||||
Minecraft.getInstance().player?.sendSystemMessage(Component.literal("Profile Translation: ${model.profileTranslation}"))
|
||||
Minecraft.getInstance().player?.sendSystemMessage(Component.literal("Profile Scale: ${model.profileScale}"))
|
||||
Cobblemon.LOGGER.info("override var profileTranslation = Vec3d(${model.profileTranslation.x}, ${model.profileTranslation.y}, ${model.profileTranslation.z})")
|
||||
Cobblemon.LOGGER.info("override var profileScale = ${model.profileScale}F")
|
||||
}
|
||||
logProfileTranslations(selectedPokemon.species.resourceIdentifier, modelWidget.state)
|
||||
|
||||
super.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.gui.summary.widgets
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.client.gui.ProfileTransformType
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.gui.calculateHeadYawAndPitch
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
|
||||
@@ -116,7 +117,8 @@ class ModelWidget(
|
||||
partialTicks = partialTicks,
|
||||
headYaw = currentYawAndPitch.first,
|
||||
headPitch = currentYawAndPitch.second,
|
||||
blockLight = blockLight
|
||||
blockLight = blockLight,
|
||||
profileTransformType = ProfileTransformType.SUMMARY,
|
||||
)
|
||||
|
||||
heldItemRenderer.renderOnModel(
|
||||
|
||||
+50
-71
@@ -120,7 +120,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
fun getLogoResource(langCode: String?): ResourceLocation =
|
||||
logoResourceMap.entries.find { it.value.contains(langCode?.substringBefore("_")) }?.key ?: logo
|
||||
}
|
||||
var selectedTM: TechnicalMachine? = null
|
||||
|
||||
var heldStackMove: MoveTemplate? = null
|
||||
var tmList: SettableObservable<MutableList<TechnicalMachine>> = SettableObservable(mutableListOf())
|
||||
var output: ItemStack? = null
|
||||
@@ -159,6 +159,8 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
var oldIngredientItems: Array<Item> = arrayOf(Items.AIR, Items.AIR, Items.AIR)
|
||||
var oldResultTmSlotItem: Item = Items.AIR
|
||||
|
||||
var moveInfoTM: TechnicalMachine? = null
|
||||
|
||||
override fun init() {
|
||||
imageWidth = WIDTH
|
||||
imageHeight = HEIGHT
|
||||
@@ -171,6 +173,8 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
logoPosY = topPos + 1
|
||||
scanPosY = topPos + 1
|
||||
|
||||
menu.onSelectedTMUpdate = { updateSelectedTM(it) }
|
||||
|
||||
partySlotList.clear()
|
||||
CobblemonClient.storage.party.forEachIndexed { index, pokemon ->
|
||||
partySlotList.add(TMPartySlotWidget(
|
||||
@@ -226,7 +230,14 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
pX = leftPos + 4,
|
||||
pY = topPos + 29,
|
||||
tmList,
|
||||
setTM = { tm, clicked -> setSelectedTM(tm, clicked) }
|
||||
setTM = { tm, clicked ->
|
||||
if (clicked) {
|
||||
if (tm != menu.currentlySelectedTM) SetActiveTMPacket(tm).sendToServer()
|
||||
setScreenFromMode(TM_BURN_MODE)
|
||||
} else {
|
||||
updateMoveInformation(tm)
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!children().contains(movesScrollingList)) addRenderableWidget(movesScrollingList)
|
||||
|
||||
@@ -252,24 +263,21 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
selectedMoveButton = MoveSlotButton(
|
||||
leftPos + 6,
|
||||
topPos + 6,
|
||||
move = selectedTM?.moveName,
|
||||
pp = selectedTM?.moveName?.pp ?: 0,
|
||||
move = menu.currentlySelectedTM?.moveName,
|
||||
pp = menu.currentlySelectedTM?.moveName?.pp ?: 0,
|
||||
ppAsFraction = false
|
||||
) {
|
||||
if ((it as MoveSlotButton).enabled) {
|
||||
if (::movesScrollingList.isInitialized && movesScrollingList.children().isEmpty()) setMoveList()
|
||||
playSound(CobblemonSounds.GUI_CLICK)
|
||||
setScreenFromMode(MOVE_SELECT_MODE)
|
||||
|
||||
// Clear active TM
|
||||
CobblemonNetwork.sendToServer(SetActiveTMPacket(null))
|
||||
}
|
||||
}
|
||||
if (!children().contains(selectedMoveButton)) addRenderableWidget(selectedMoveButton)
|
||||
|
||||
startButton = StartButton(leftPos + 5F, topPos + 35F) {
|
||||
if (!(it as StartButton).disabled) {
|
||||
selectedTM?.let {
|
||||
menu.currentlySelectedTM?.let {
|
||||
val burnActive = menu.containerData?.get(TMMachineBlockEntity.BURN_ACTIVE_INDEX) ?: 0
|
||||
CobblemonNetwork.sendToServer(SetTMMachineContainerDataPacket(
|
||||
TMMachineBlockEntity.BURN_ACTIVE_INDEX,
|
||||
@@ -284,17 +292,14 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
))
|
||||
}*/
|
||||
|
||||
CobblemonNetwork.sendToServer(SetActiveTMPacket(it))
|
||||
//CobblemonNetwork.sendToServer(SetActiveTMPacket(it))
|
||||
if (burnActive != 1) playSound(CobblemonSounds.TM_MACHINE_START)
|
||||
inventory.setChanged()
|
||||
menu.broadcastChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!children().contains(startButton)) addRenderableWidget(startButton)
|
||||
|
||||
setScreenFromMode(mode)
|
||||
initScreen = false
|
||||
|
||||
updateSlotItemMemory()
|
||||
}
|
||||
@@ -306,7 +311,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
if (scanPosY + 1 >= (topPos + SCREEN_SAVER_HEIGHT) * 2) scanPosY = 0
|
||||
|
||||
if (mode == TM_BURN_MODE) {
|
||||
selectedTM?.let { tm ->
|
||||
menu.currentlySelectedTM?.let { tm ->
|
||||
val resultStack = menu.inventory!!.getItem(TMMachineMenu.RESULT_SLOT)
|
||||
val craftedTmStack = ItemStack(CobblemonItems.TECHNICAL_MACHINE)
|
||||
.also { TMMoveComponent.setTMMove(it, tm.moveName) }
|
||||
@@ -339,7 +344,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
}
|
||||
|
||||
if (::selectedMoveButton.isInitialized) {
|
||||
selectedMoveButton.enabled = !isBurnActive() && (heldStackMove == null || heldStackMove == selectedTM?.moveName)
|
||||
selectedMoveButton.enabled = (heldStackMove == null || heldStackMove == menu.currentlySelectedTM?.moveName)
|
||||
}
|
||||
|
||||
if (isBurnActive()) {
|
||||
@@ -350,9 +355,6 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check if screen should be switched upon opening UI
|
||||
if (!initScreen) loadBurnScreenData()
|
||||
}
|
||||
|
||||
if (heldMoveItemChanged) {
|
||||
@@ -400,32 +402,6 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
return wasScreenSaverActive
|
||||
}
|
||||
|
||||
private fun loadBurnScreenData() {
|
||||
var tm: TechnicalMachine? = null
|
||||
|
||||
val blockPos = menu.containerData?.let {
|
||||
val x = it.get(TMMachineBlockEntity.POSITION_X_INDEX)
|
||||
val y = it.get(TMMachineBlockEntity.POSITION_Y_INDEX)
|
||||
val z = it.get(TMMachineBlockEntity.POSITION_Z_INDEX)
|
||||
BlockPos(x, y, z)
|
||||
}
|
||||
|
||||
inventory.player.level().getBlockEntity(blockPos)?.let { blockEntity ->
|
||||
if (blockEntity is TMMachineBlockEntity) {
|
||||
Moves.getByName(blockEntity.activeMove)?.let {
|
||||
tm = TechnicalMachines.moveToTM[it]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If burn currently in progress or if active TM set, set to burn screen
|
||||
if (isBurnActive() || tm != null) {
|
||||
setSelectedTM(tm, true)
|
||||
}
|
||||
|
||||
initScreen = true
|
||||
}
|
||||
|
||||
private fun isBurnActive(): Boolean = (menu.containerData?.get(TMMachineBlockEntity.BURN_ACTIVE_INDEX) ?: 0) == 1
|
||||
|
||||
private fun setScreenFromMode(screen: Int) {
|
||||
@@ -467,7 +443,6 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
|
||||
private fun toggleTypeSelect(isVisible: Boolean) {
|
||||
if (isVisible) {
|
||||
setSelectedTM(null, false)
|
||||
if (::moveSearchWidget.isInitialized) moveSearchWidget.value = ""
|
||||
if (selectedPokemon != null) selectedPokemon = null
|
||||
sortType = null
|
||||
@@ -505,7 +480,6 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
}
|
||||
|
||||
private fun toggleTMBurn(isVisible: Boolean) {
|
||||
if (!isVisible) setSelectedTM(null, false)
|
||||
if (::selectedMoveButton.isInitialized) selectedMoveButton.visible = isVisible
|
||||
if (::startButton.isInitialized) startButton.visible = isVisible
|
||||
}
|
||||
@@ -516,35 +490,40 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
return if (learnableMoves.contains(move)) TMPartySlotWidget.CAN_LEARN else TMPartySlotWidget.CANNOT_LEARN
|
||||
}
|
||||
|
||||
fun setSelectedTM(tm: TechnicalMachine?, clicked: Boolean) {
|
||||
if (selectedTM != tm) {
|
||||
selectedTM = tm
|
||||
updatePartySlotStatus(tm?.moveName)
|
||||
fun updateSelectedTM(tm: TechnicalMachine?) {
|
||||
if (!initScreen) {
|
||||
initScreen = true
|
||||
tm?.let {
|
||||
setScreenFromMode(TM_BURN_MODE)
|
||||
sortType = ElementalTypes.get(tm.type)
|
||||
setMoveList()
|
||||
}
|
||||
}
|
||||
|
||||
if (::movesScrollingList.isInitialized) {
|
||||
movesScrollingList.setSlotHighlighted(if (clicked) null else selectedTM?.id)
|
||||
if (mode == TM_BURN_MODE) updateMoveInformation(tm)
|
||||
|
||||
tm?.let {
|
||||
if (::selectedMoveButton.isInitialized) {
|
||||
selectedMoveButton.apply {
|
||||
move = it.moveName
|
||||
pp = it.moveName.pp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateMoveInformation(tm: TechnicalMachine?) {
|
||||
moveInfoTM = tm
|
||||
|
||||
if (::moveDescriptionWidget.isInitialized) {
|
||||
val selectedDescription = selectedTM?.moveName?.description?.string
|
||||
val selectedDescription = tm?.moveName?.description?.string
|
||||
moveDescriptionWidget.setText(
|
||||
if (selectedDescription != null) listOf(selectedDescription) else emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
if (clicked) {
|
||||
CobblemonNetwork.sendToServer(SetActiveTMPacket(tm))
|
||||
|
||||
selectedTM?.let {
|
||||
if (::selectedMoveButton.isInitialized) {
|
||||
selectedMoveButton.apply {
|
||||
move = it.moveName
|
||||
pp = it.moveName.pp
|
||||
}
|
||||
setScreenFromMode(TM_BURN_MODE)
|
||||
}
|
||||
}
|
||||
if (::movesScrollingList.isInitialized) {
|
||||
movesScrollingList.setSlotHighlighted(tm?.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,7 +536,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
}
|
||||
|
||||
fun renderDiscTypeOverlay(poseStack: PoseStack, isDiscRotating: Boolean, alpha: Float = 1F) {
|
||||
selectedTM?.let {
|
||||
menu.currentlySelectedTM?.let {
|
||||
val primaryRgb = it.moveName.elementalType.primaryColor.toRGB()
|
||||
val secondaryRgb = it.moveName.elementalType.secondaryColor.toRGB()
|
||||
blitk(
|
||||
@@ -706,7 +685,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
}
|
||||
|
||||
fun renderMoveInfo(context: GuiGraphics, mouseX: Int, mouseY: Int) {
|
||||
val moveTemplate = selectedTM?.moveName
|
||||
val moveTemplate = moveInfoTM?.moveName
|
||||
|
||||
blitk(
|
||||
matrixStack = context.pose(),
|
||||
@@ -1057,7 +1036,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
movesScrollingList.setDisabled(true, TechnicalMachines.moveToTM[heldStackMove])
|
||||
if (mode == MOVE_SELECT_MODE) {
|
||||
val heldStackTm = TechnicalMachines.moveToTM[heldStackMove]
|
||||
setSelectedTM(if (tmList.get().contains(heldStackTm)) heldStackTm else null, false)
|
||||
updateMoveInformation(if (tmList.get().contains(heldStackTm)) heldStackTm else null)
|
||||
|
||||
// Scroll to move if moves list contains held TM move
|
||||
if (tmList.get().contains(heldStackTm)) {
|
||||
@@ -1077,8 +1056,8 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
heldStackMove = null
|
||||
|
||||
// Reset selected move on move select screen
|
||||
if (mode == MOVE_SELECT_MODE) setSelectedTM(null, false)
|
||||
updatePartySlotStatus(selectedTM?.moveName)
|
||||
if (mode == MOVE_SELECT_MODE) updateMoveInformation(null)
|
||||
updatePartySlotStatus(menu.currentlySelectedTM?.moveName)
|
||||
|
||||
if (::movesScrollingList.isInitialized) {
|
||||
movesScrollingList.setDisabled(false)
|
||||
@@ -1155,7 +1134,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
if (isInventoryKeyPressed(minecraft, keyCode, scanCode)) {
|
||||
if (searchFocused) { return true }
|
||||
else {
|
||||
Minecraft.getInstance().setScreen(null)
|
||||
onClose()
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1166,7 +1145,7 @@ class TMMachineScreen(containerMenu: TMMachineMenu, val inventory: Inventory, ti
|
||||
this.focused = null
|
||||
return true
|
||||
} else {
|
||||
Minecraft.getInstance().setScreen(null)
|
||||
onClose()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -19,7 +19,6 @@ import net.minecraft.world.level.block.Block
|
||||
object SetActiveTMPacketHandler : ServerNetworkPacketHandler<SetActiveTMPacket> {
|
||||
override fun handle(packet: SetActiveTMPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val menu = player.containerMenu as? TMMachineMenu ?: return
|
||||
val inventory = menu.inventory ?: return
|
||||
val tmData = Cobblemon.playerDataManager.getTMData(player)
|
||||
|
||||
if (packet.tm != null && (!packet.tm.isPassivelyObtained() && packet.tm.id !in tmData.learnedTMs)) {
|
||||
@@ -30,9 +29,17 @@ object SetActiveTMPacketHandler : ServerNetworkPacketHandler<SetActiveTMPacket>
|
||||
blockEntity.activeMove = packet.tm?.moveName?.name ?: ""
|
||||
blockEntity.setChanged()
|
||||
player.level().sendBlockUpdated(blockEntity.blockPos, blockEntity.blockState, blockEntity.blockState, Block.UPDATE_CLIENTS)
|
||||
}
|
||||
|
||||
inventory.setChanged()
|
||||
menu.broadcastChanges()
|
||||
blockEntity.burnActive = false
|
||||
blockEntity.burnProgress = 0
|
||||
|
||||
player.level().players().forEach { thePlayer -> //Update all players with matching menu/blockentity
|
||||
val tmmMenu = thePlayer.containerMenu as? TMMachineMenu ?: return@forEach
|
||||
if (tmmMenu.tmMachineEntity == blockEntity) {
|
||||
tmmMenu.currentlySelectedTM = packet.tm
|
||||
tmmMenu.broadcastChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.net.gui
|
||||
|
||||
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineMenu
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SynchronizeActiveTMPacket
|
||||
import net.minecraft.client.Minecraft
|
||||
|
||||
object SynchronizeActiveTMHandler: ClientNetworkPacketHandler<SynchronizeActiveTMPacket> {
|
||||
override fun handle(packet: SynchronizeActiveTMPacket, client: Minecraft) {
|
||||
val tmmMenu = client.player?.containerMenu as? TMMachineMenu ?: return
|
||||
tmmMenu.clientSetSelectedTM(packet.tm)
|
||||
}
|
||||
}
|
||||
@@ -18,17 +18,23 @@ import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.Font
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun renderScaledGuiItemIcon(itemStack: ItemStack, x: Double, y: Double, scale: Double = 1.0, zTranslation: Float = 100.0F, matrixStack: PoseStack? = null) {
|
||||
val itemRenderer = Minecraft.getInstance().itemRenderer
|
||||
@@ -97,6 +103,55 @@ fun getDepletableRedGreen(
|
||||
return r.toFloat() to g.toFloat()
|
||||
}
|
||||
|
||||
fun drawScrollingText(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val fittedMaxX = if (textWidth <= maxX - minX) minX + textWidth else maxX
|
||||
renderScrollingString(context, font, text, minX, minY, fittedMaxX, maxY, colour, minScrollVelocity)
|
||||
}
|
||||
|
||||
/** Copied from [net.minecraft.client.gui.components.AbstractWidget.renderScrollingString] **/
|
||||
fun renderScrollingString(
|
||||
context: GuiGraphics,
|
||||
font: Font,
|
||||
text: Component,
|
||||
minX: Int,
|
||||
minY: Int,
|
||||
maxX: Int,
|
||||
maxY: Int,
|
||||
colour: Int,
|
||||
minScrollVelocity: Double? = 10.0
|
||||
) {
|
||||
val textWidth = font.width(text)
|
||||
val centerY = (minY + maxY - 9) / 2 + 1
|
||||
val boxWidth = maxX - minX
|
||||
if (textWidth <= boxWidth) {
|
||||
val centerX = Mth.clamp((minX + maxX) / 2, minX + textWidth / 2, maxX - textWidth / 2)
|
||||
context.drawCenteredString(font, text, centerX, centerY, colour)
|
||||
return
|
||||
}
|
||||
|
||||
val overflow = textWidth - boxWidth
|
||||
var period = (overflow * 0.5).coerceAtLeast(3.0)
|
||||
if (minScrollVelocity != null) {
|
||||
period = period.coerceAtMost(2 * overflow / minScrollVelocity)
|
||||
}
|
||||
val time = Util.getMillis() / 1000.0
|
||||
val easedProgress = sin((Math.PI / 2) * cos(2 * Math.PI * time / period)) / 2.0 + 0.5
|
||||
val offset = Mth.lerp(easedProgress, 0.0, overflow.toDouble())
|
||||
context.enableScissor(minX, minY, maxX, maxY)
|
||||
context.drawString(font, text, minX - offset.toInt(), centerY, colour)
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
fun drawScaledText(
|
||||
context: GuiGraphics,
|
||||
|
||||
+10
-3
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.LevelRenderer
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
@@ -39,13 +40,13 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
private val leftMargin = 1f
|
||||
private val rightMargin = 1f
|
||||
private val topMargin = 1f
|
||||
private val bottomMargin = 1f
|
||||
private val interRowSpacing = 0f
|
||||
private val tmOverlayDepthOffset = -0.0002f
|
||||
private val slotBrightnessMultiplier = 0.65f
|
||||
|
||||
private val tmBaseTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_base.png")
|
||||
private val tmOverlayTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_overlay.png")
|
||||
private val musicDiscUnknownTexture = cobblemonResource("textures/block/disc_shelf/music_disc_unknown.png")
|
||||
|
||||
override fun render(
|
||||
entity: DiscShelfBlockEntity,
|
||||
@@ -77,7 +78,6 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
val slotWidth = slotWidthPixels / textureSize
|
||||
val slotHeight = slotHeightPixels / textureSize
|
||||
val verticalSpacing = (slotHeightPixels + interRowSpacing) / textureSize
|
||||
val totalHeight = slotHeight * 7 + interRowSpacing * 6 / textureSize
|
||||
val startY = topMargin / textureSize
|
||||
|
||||
for ((index, item) in entity.items.withIndex()) {
|
||||
@@ -188,6 +188,13 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
|
||||
|
||||
private fun getItemTexture(itemStack: ItemStack): ResourceLocation {
|
||||
val id = BuiltInRegistries.ITEM.getKey(itemStack.item)
|
||||
return cobblemonResource("textures/block/disc_shelf/${id.path}.png")
|
||||
val resource = cobblemonResource("textures/block/disc_shelf/${id.path}.png")
|
||||
|
||||
val resourceManager = Minecraft.getInstance().resourceManager
|
||||
if (resourceManager.getResource(resource).isEmpty) {
|
||||
return musicDiscUnknownTexture
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -72,7 +72,8 @@ object MountedCameraRenderer {
|
||||
val rollable = vehicle as OrientationControllable
|
||||
val vehicleController = rollable.getOrientationController()
|
||||
|
||||
val model = getPoser(vehicle.pokemon.species.resourceIdentifier, FloatingState())
|
||||
val state = FloatingState().also { it.currentAspects = vehicle.pokemon.aspects }
|
||||
val model = getPoser(vehicle.pokemon.species.resourceIdentifier, state)
|
||||
|
||||
val locatorName = delegate.getSeatLocator(driver)
|
||||
val locator = delegate.locatorStates[locatorName] ?: return null
|
||||
|
||||
+6
-2
@@ -34,7 +34,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.quirk.ModelQuirk
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.quirk.SimpleQuirk
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
|
||||
import com.cobblemon.mod.common.client.util.exists
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
|
||||
@@ -134,6 +133,11 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
|
||||
*/
|
||||
open var profileTranslation = Vec3(0.0, 0.0, 0.0)
|
||||
|
||||
open var profilePokedexScale: Float? = null
|
||||
open var profilePokedexTranslation: Vec3? = null
|
||||
open var profileSummaryScale: Float? = null
|
||||
open var profileSummaryTranslation: Vec3? = null
|
||||
|
||||
var red = 1F
|
||||
var green = 1F
|
||||
var blue = 1F
|
||||
@@ -251,7 +255,7 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
|
||||
}
|
||||
|
||||
fun setLayerContext(buffer: MultiBufferSource, state: PosableState, layers: Iterable<ModelLayer>) {
|
||||
currentLayers = layers
|
||||
currentLayers = layers.sortedBy { it.translucent }
|
||||
bufferProvider = buffer
|
||||
currentState = state
|
||||
}
|
||||
|
||||
-85
@@ -1,85 +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.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class ChanseyModel(root: ModelPart) : PokemonPosableModel(root), BipedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("chansey")
|
||||
override val leftLeg = getPart("left_foot")
|
||||
override val rightLeg = getPart("right_foot")
|
||||
|
||||
override var portraitScale = 1.5F
|
||||
override var portraitTranslation = Vec3(-0.35, 0.3, 0.0)
|
||||
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var battleIdle: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("chansey", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("chansey", "blink") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(
|
||||
bedrock("chansey", "sleep")
|
||||
)
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
transformTicks = 10,
|
||||
animations = arrayOf(
|
||||
bedrock("chansey", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("chansey", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleIdle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
condition = { it.isBattling },
|
||||
transformTicks = 10,
|
||||
animations = arrayOf(
|
||||
bedrock("chansey", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("chansey", "faint")
|
||||
}
|
||||
-74
@@ -1,74 +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.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class DiglettAlolanModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("diglett_alolan")
|
||||
|
||||
override var portraitScale = 1.8F
|
||||
override var portraitTranslation = Vec3(-0.06, -0.86, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.32, 0.0)
|
||||
|
||||
lateinit var stand: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("diglett_alolan", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("diglett_alolan", "blink")}
|
||||
val quirk = quirk { bedrockStateful("diglett_alolan", "quirk_idle")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("diglett_alolan", "sleep"))
|
||||
)
|
||||
|
||||
stand = registerPose(
|
||||
poseName = "stand",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink,quirk),
|
||||
animations = arrayOf(bedrock("diglett_alolan", "ground_idle"))
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(bedrock("diglett_alolan", "ground_idle"))
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battleidle",
|
||||
poseTypes = STATIONARY_POSES,
|
||||
condition = { it.isBattling },
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(bedrock("diglett_alolan", "battle_idle"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("diglett_alolan", "faint")
|
||||
}
|
||||
-71
@@ -1,71 +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.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
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 DiglettModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("diglett")
|
||||
|
||||
override var portraitScale = 1.8F
|
||||
override var portraitTranslation = Vec3(-0.06, -0.86, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.32, 0.0)
|
||||
|
||||
lateinit var stand: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("diglett", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("diglett", "blink")}
|
||||
val quirk = quirk { bedrockStateful("diglett", "quirk_idle")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("diglett", "sleep"))
|
||||
)
|
||||
|
||||
stand = registerPose(
|
||||
poseName = "stand",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
quirks = arrayOf(blink, quirk),
|
||||
animations = arrayOf(bedrock("diglett", "ground_idle"))
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(bedrock("diglett", "ground_walk"))
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battleidle",
|
||||
poseTypes = STATIONARY_POSES,
|
||||
quirks = arrayOf(blink, quirk),
|
||||
animations = arrayOf(bedrock("diglett", "battle_idle"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("diglett", "faint")
|
||||
}
|
||||
-79
@@ -1,79 +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.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class DugtrioAlolanModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("dugtrio_alolan")
|
||||
|
||||
override var portraitScale = 1.3F
|
||||
override var portraitTranslation = Vec3(-0.11, -0.1, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.29, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walking: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("dugtrio_alolan", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("dugtrio_alolan", "blink")}
|
||||
val blink2 = quirk { bedrockStateful("dugtrio_alolan", "blink2")}
|
||||
val blink3 = quirk { bedrockStateful("dugtrio_alolan", "blink3")}
|
||||
|
||||
val quirk = quirk { bedrockStateful("dugtrio_alolan", "quirk_idle")}
|
||||
val quirk2 = quirk { bedrockStateful("dugtrio_alolan", "quirk_idle2")}
|
||||
val quirk3 = quirk { bedrockStateful("dugtrio_alolan", "quirk_idle3")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("dugtrio_alolan", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "stand",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink, blink2, blink3, quirk, quirk2, quirk3),
|
||||
animations = arrayOf(bedrock("dugtrio_alolan", "ground_idle"))
|
||||
)
|
||||
|
||||
walking = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink, blink2, blink3),
|
||||
animations = arrayOf(bedrock("dugtrio_alolan", "ground_idle"))
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battleidle",
|
||||
poseTypes = STATIONARY_POSES,
|
||||
condition = { it.isBattling },
|
||||
quirks = arrayOf(blink, blink2, blink3, quirk, quirk2, quirk3),
|
||||
animations = arrayOf(bedrock("dugtrio_alolan", "battle_idle"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("dugtrio_alolan", "faint")
|
||||
}
|
||||
-99
@@ -1,99 +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.animation.SingleBoneLookAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class DugtrioModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("dugtrio")
|
||||
override val head = getPart("body3")
|
||||
|
||||
val lefthead = object : HeadedFrame {
|
||||
override val rootPart = this@DugtrioModel.rootPart
|
||||
override val head: ModelPart = getPart("body2")
|
||||
}
|
||||
val righthead = object : HeadedFrame {
|
||||
override val rootPart = this@DugtrioModel.rootPart
|
||||
override val head: ModelPart = getPart("body1")
|
||||
}
|
||||
|
||||
override var portraitScale = 1.3F
|
||||
override var portraitTranslation = Vec3(-0.11, -0.1, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.29, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walking: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("dugtrio", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("dugtrio", "blink")}
|
||||
val blink2 = quirk { bedrockStateful("dugtrio", "blink2")}
|
||||
val blink3 = quirk { bedrockStateful("dugtrio", "blink3")}
|
||||
|
||||
val quirk = quirk { bedrockStateful("dugtrio", "quirk_idle")}
|
||||
val quirk2 = quirk { bedrockStateful("dugtrio", "quirk_idle2")}
|
||||
val quirk3 = quirk { bedrockStateful("dugtrio", "quirk_idle3")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("dugtrio", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "stand",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink, blink2, blink3, quirk, quirk2, quirk3),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(pitchMultiplier = 0.6F, yawMultiplier = 0.4F, maxPitch = 10F, minPitch = -30F),
|
||||
SingleBoneLookAnimation(lefthead, false, false, false, false, 1F, 1.4F, 0F, -30F, 20F, -45F),
|
||||
SingleBoneLookAnimation(righthead, false, false, false, false, 1F, 1.4F, 0F, -30F, 45F, -25F),
|
||||
bedrock("dugtrio", "ground_idle"))
|
||||
)
|
||||
|
||||
walking = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink, blink2, blink3),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(pitchMultiplier = 0.6F, yawMultiplier = 0.4F, maxPitch = 10F, minPitch = -30F),
|
||||
SingleBoneLookAnimation(lefthead, false, false, false, false, 1F, 1.4F, 0F, -30F, 20F, -45F),
|
||||
SingleBoneLookAnimation(righthead, false, false, false, false, 1F, 1.4F, 0F, -30F, 45F, -25F),
|
||||
bedrock("dugtrio", "ground_walk"))
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battleidle",
|
||||
poseTypes = STATIONARY_POSES,
|
||||
condition = { it.isBattling },
|
||||
quirks = arrayOf(blink, blink2, blink3, quirk, quirk2, quirk3),
|
||||
animations = arrayOf(bedrock("dugtrio", "battle_idle"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("dugtrio", "faint")
|
||||
}
|
||||
-66
@@ -1,66 +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.animation.BipedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class GravelerModel(root: ModelPart) : PokemonPosableModel(root), BipedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("graveler")
|
||||
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
override var portraitScale = 1.4F
|
||||
override var portraitTranslation = Vec3(-0.1, -0.28, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.37, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("graveler", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("graveler", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("graveler", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
BipedWalkAnimation(this, periodMultiplier = 1.1F),
|
||||
bedrock("graveler", "ground_idle")
|
||||
//bedrock("graveler", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("graveler", "faint") else null
|
||||
}
|
||||
-52
@@ -1,52 +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.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.ALL_POSES
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class KakunaModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("kakuna")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 1.7F
|
||||
override var portraitTranslation = Vec3(0.1, -0.4, 0.0)
|
||||
override var profileScale = 0.96F
|
||||
override var profileTranslation = Vec3(0.0, 0.35, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("kakuna", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("kakuna", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = ALL_POSES - PoseType.SLEEP,
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("kakuna", "ground_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("kakuna", "faint")
|
||||
}
|
||||
-73
@@ -1,73 +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.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
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 NidoranfModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("nidoran_f")
|
||||
override val head = getPart("head")
|
||||
override val foreLeftLeg = getPart("leg_front_left")
|
||||
override val foreRightLeg = getPart("leg_front_right")
|
||||
override val hindLeftLeg = getPart("leg_back_left")
|
||||
override val hindRightLeg = getPart("leg_back_right")
|
||||
|
||||
override var portraitScale = 2.0F
|
||||
override var portraitTranslation = Vec3(-0.16, -0.85, 0.0)
|
||||
|
||||
override var profileScale = 1.03F
|
||||
override var profileTranslation = Vec3(0.02, 0.21, 0.0)
|
||||
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoranf", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoranf", "blink") }
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidoranf", "idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidoranf", "idle"),
|
||||
QuadrupedWalkAnimation(this)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("nidoranf", "faint") else null
|
||||
}
|
||||
-73
@@ -1,73 +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.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
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 NidoranmModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("nidoran_m")
|
||||
override val head = getPart("head")
|
||||
override val foreLeftLeg = getPart("leg_front_left")
|
||||
override val foreRightLeg = getPart("leg_front_right")
|
||||
override val hindLeftLeg = getPart("leg_back_left")
|
||||
override val hindRightLeg = getPart("leg_back_right")
|
||||
|
||||
override var portraitScale = 1.97F
|
||||
override var portraitTranslation = Vec3(-0.18, -1.28, 0.0)
|
||||
|
||||
override var profileScale = 1.05F
|
||||
override var profileTranslation = Vec3(0.03, 0.11, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidoranm", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidoranm", "blink") }
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidoranm", "idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidoranm", "idle"),
|
||||
QuadrupedWalkAnimation(this)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("nidoranm", "faint") else null
|
||||
}
|
||||
-92
@@ -1,92 +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.animation.QuadrupedWalkAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class NidorinaModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("nidorina")
|
||||
override val head = getPart("head")
|
||||
override val foreLeftLeg= getPart("left_upper_arm")
|
||||
override val foreRightLeg = getPart("right_upper_arm")
|
||||
override val hindLeftLeg = getPart("left_leg")
|
||||
override val hindRightLeg = getPart("right_leg")
|
||||
|
||||
override var portraitScale = 2.13F
|
||||
override var portraitTranslation = Vec3(-0.05, -0.71, 0.0)
|
||||
|
||||
override var profileScale = 1.0F
|
||||
override var profileTranslation = Vec3(0.0, 0.21, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("nidorina", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("nidorina", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidorina", "idle3")
|
||||
)
|
||||
)
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("nidorina", "idle2"))
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidorina", "idle2"),
|
||||
QuadrupedWalkAnimation(this)
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("nidorina", "idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("nidorina", "faint") else null
|
||||
}
|
||||
-206
@@ -1,206 +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.createTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.parabolaFunction
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class PidgeottoModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("pidgeotto")
|
||||
override val head = getPart("neck")
|
||||
|
||||
override val leftWing = getPart("wing_closed_left")
|
||||
override val rightWing = getPart("wing_closed_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
private val tail = getPart("tail")
|
||||
|
||||
private val wingOpenRight = getPart("wing_open_right")
|
||||
private val wingOpenLeft = getPart("wing_open_left")
|
||||
private val wingClosedRight = getPart("wing_closed_right")
|
||||
private val wingClosedLeft = getPart("wing_closed_left")
|
||||
|
||||
override var portraitScale = 2.8F
|
||||
override var portraitTranslation = Vec3(-0.4, -0.9, 0.0)
|
||||
override var profileScale = 1.1F
|
||||
override var profileTranslation = Vec3(0.0, 0.1, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var stand: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var hover: Pose
|
||||
lateinit var fly: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("pidgeotto", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("pidgeotto", "blink")}
|
||||
val flyQuirk1 = quirk { bedrockStateful("pidgeotto", "air_fly_quirk") }
|
||||
val flyQuirk2 = quirk { bedrockStateful("pidgeotto", "air_fly_quirk2") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
animations = arrayOf(bedrock("pidgeotto", "sleep_PLACEHOLDER"))
|
||||
)
|
||||
|
||||
stand = registerPose(
|
||||
poseName = "stand",
|
||||
poseTypes = STATIONARY_POSES - PoseType.HOVER + UI_POSES,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgeotto", "ground_idle_PLACEHOLDER")
|
||||
)
|
||||
)
|
||||
walk = registerPose(
|
||||
poseName = "hover",
|
||||
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgeotto", "ground_idle_PLACEHOLDER"),
|
||||
rootPart.translation(
|
||||
function = parabolaFunction(
|
||||
peak = -4F,
|
||||
period = 0.4F
|
||||
),
|
||||
timeVariable = { state, _, _ -> state.animationSeconds },
|
||||
axis = ModelPartTransformation.Y_AXIS
|
||||
),
|
||||
head.translation(
|
||||
function = sineFunction(
|
||||
amplitude = (-20F).toRadians(),
|
||||
period = 1F,
|
||||
verticalShift = (-10F).toRadians()
|
||||
),
|
||||
axis = ModelPartTransformation.X_AXIS,
|
||||
timeVariable = { state, _, _ -> state.animationSeconds }
|
||||
),
|
||||
leftLeg.rotation(
|
||||
function = parabolaFunction(
|
||||
tightness = -20F,
|
||||
phaseShift = 0F,
|
||||
verticalShift = (30F).toRadians()
|
||||
),
|
||||
axis = ModelPartTransformation.X_AXIS,
|
||||
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
|
||||
),
|
||||
rightLeg.rotation(
|
||||
function = parabolaFunction(
|
||||
tightness = -20F,
|
||||
phaseShift = 0F,
|
||||
verticalShift = (30F).toRadians()
|
||||
),
|
||||
axis = ModelPartTransformation.X_AXIS,
|
||||
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
|
||||
),
|
||||
tail.rotation(
|
||||
function = sineFunction(
|
||||
amplitude = (-5F).toRadians(),
|
||||
period = 1F
|
||||
),
|
||||
axis = ModelPartTransformation.X_AXIS,
|
||||
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
|
||||
),
|
||||
wingFlap(
|
||||
flapFunction = sineFunction(
|
||||
amplitude = (-5F).toRadians(),
|
||||
period = 0.4F,
|
||||
phaseShift = 0.00F,
|
||||
verticalShift = (-20F).toRadians()
|
||||
),
|
||||
timeVariable = { state, _, _ -> state.animationSeconds },
|
||||
axis = ModelPartTransformation.Z_AXIS
|
||||
),
|
||||
rightWing.translation(
|
||||
function = parabolaFunction(
|
||||
tightness = -10F,
|
||||
phaseShift = 30F,
|
||||
verticalShift = (25F).toRadians()
|
||||
),
|
||||
axis = ModelPartTransformation.Y_AXIS,
|
||||
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
|
||||
),
|
||||
leftWing.translation(
|
||||
function = parabolaFunction(
|
||||
tightness = -10F,
|
||||
phaseShift = 30F,
|
||||
verticalShift = (25F).toRadians()
|
||||
),
|
||||
axis = ModelPartTransformation.Y_AXIS,
|
||||
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
|
||||
),
|
||||
)
|
||||
)
|
||||
hover = registerPose(
|
||||
poseName = "fly",
|
||||
poseType = PoseType.HOVER,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgeotto", "air_idle")
|
||||
)
|
||||
)
|
||||
fly = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.FLY,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink, flyQuirk1, flyQuirk2),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgeotto", "air_fly")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
-131
@@ -1,131 +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.animation.PitchTiltAnimation
|
||||
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.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.SHOULDER_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 PidgeyModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("pidgey")
|
||||
override val head = getPart("head")
|
||||
|
||||
private val wingOpenRight = getPart("wing_open_right")
|
||||
private val wingOpenLeft = getPart("wing_open_left")
|
||||
private val wingClosedRight = getPart("wing_closed_right")
|
||||
private val wingClosedLeft = getPart("wing_closed_left")
|
||||
|
||||
override var portraitScale = 3.5F
|
||||
override var portraitTranslation = Vec3(-0.1, -2.1, 0.0)
|
||||
|
||||
override var profileScale = 1.2F
|
||||
override var profileTranslation = Vec3(0.0, -0.01, 0.0)
|
||||
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var stand: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var hover: CobblemonPose
|
||||
lateinit var fly: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("pidgey", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("pidgey", "blink") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleeping",
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("pidgey", "sleep_PLACEHOLDER"))
|
||||
)
|
||||
|
||||
stand = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = SHOULDER_POSES + UI_POSES + PoseType.STATIONARY_POSES - PoseType.HOVER,
|
||||
transformTicks = 10,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgey", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
hover = registerPose(
|
||||
poseName = "hover",
|
||||
poseType = PoseType.HOVER,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
PitchTiltAnimation(bone = getPart("body"), maxChangePerTick = 1F),
|
||||
singleBoneLook(),
|
||||
bedrock("pidgey", "air_idle")
|
||||
)
|
||||
)
|
||||
|
||||
fly = registerPose(
|
||||
poseName = "fly",
|
||||
poseType = PoseType.FLY,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
PitchTiltAnimation(bone = getPart("body"), maxChangePerTick = 1F),
|
||||
singleBoneLook(),
|
||||
bedrock("pidgey", "air_fly")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walking",
|
||||
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
|
||||
transformedParts = arrayOf(
|
||||
wingClosedLeft.createTransformation().withVisibility(visibility = true),
|
||||
wingClosedRight.createTransformation().withVisibility(visibility = true),
|
||||
wingOpenLeft.createTransformation().withVisibility(visibility = false),
|
||||
wingOpenRight.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("pidgey", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +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.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class RattataAlolanModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("rattata")
|
||||
override val foreLeftLeg= getPart("leg_front_left")
|
||||
override val foreRightLeg = getPart("leg_front_right")
|
||||
override val hindLeftLeg = getPart("leg_back_left")
|
||||
override val hindRightLeg = getPart("leg_back_right")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.2F
|
||||
override var portraitTranslation = Vec3(-0.2, -1.4, 0.0)
|
||||
|
||||
override var profileScale = 1.1F
|
||||
override var profileTranslation = Vec3(0.0, 0.1, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
// override val cryAnimation = CryProvider { bedrockStateful("rattata", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("rattata", "blink")}
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("rattata", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = setOf(PoseType.NONE, PoseType.PROFILE, PoseType.STAND, PoseType.FLOAT, PoseType.PORTRAIT, PoseType.SHOULDER_LEFT, PoseType.SHOULDER_RIGHT),
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("rattata", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("rattata", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("rattata", "faint")
|
||||
}
|
||||
-71
@@ -1,71 +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.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class RattataModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("rattata")
|
||||
override val foreLeftLeg= getPart("leg_front_left")
|
||||
override val foreRightLeg = getPart("leg_front_right")
|
||||
override val hindLeftLeg = getPart("leg_back_left")
|
||||
override val hindRightLeg = getPart("leg_back_right")
|
||||
override val head = getPart("head")
|
||||
|
||||
override var portraitScale = 2.2F
|
||||
override var portraitTranslation = Vec3(-0.2, -1.4, 0.0)
|
||||
|
||||
override var profileScale = 1.1F
|
||||
override var profileTranslation = Vec3(0.0, 0.1, 0.0)
|
||||
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
// override val cryAnimation = CryProvider { bedrockStateful("rattata", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("rattata", "sleep"))
|
||||
)
|
||||
|
||||
val blink = quirk { bedrockStateful("rattata", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = setOf(PoseType.NONE, PoseType.PROFILE, PoseType.STAND, PoseType.FLOAT, PoseType.PORTRAIT, PoseType.SHOULDER_LEFT, PoseType.SHOULDER_RIGHT),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("rattata", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseType = PoseType.WALK,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("rattata", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("rattata", "faint")
|
||||
}
|
||||
-93
@@ -1,93 +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.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isInWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class TentacoolModel(root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("tentacool")
|
||||
|
||||
override var portraitScale = 1.2F
|
||||
override var portraitTranslation = Vec3(0.1, 1.1, 0.0)
|
||||
|
||||
override var profileScale = 0.6F
|
||||
override var profileTranslation = Vec3(0.0, 0.8, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var swim: CobblemonPose
|
||||
lateinit var float: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var watersleep: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("tentacool", "blink")}
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseType = PoseType.STAND,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseType = PoseType.WALK,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "ground_idle")
|
||||
//bedrock("tentacool", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
float = registerPose(
|
||||
poseName = "float",
|
||||
poseTypes = UI_POSES + PoseType.FLOAT,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swim = registerPose(
|
||||
poseName = "swim",
|
||||
poseType = PoseType.SWIM,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("tentacool", "water_swim")
|
||||
)
|
||||
)
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { !it.isInWater },
|
||||
animations = arrayOf(bedrock("tentacool", "sleep"))
|
||||
)
|
||||
|
||||
watersleep = registerPose(
|
||||
poseName = "watersleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { it.isInWater },
|
||||
animations = arrayOf(bedrock("tentacool", "water_sleep"))
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("tentacool", "faint") else null
|
||||
}
|
||||
+1
-1
@@ -30,7 +30,7 @@ class WartortleModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
|
||||
override var portraitTranslation = Vec3(-0.17, 0.54, 0.0)
|
||||
|
||||
override var profileScale = 0.69F
|
||||
override var profileTranslation = Vec3(-0.04, 0.69, 0.0)
|
||||
override var profileTranslation = Vec3(0.0, 0.69, 0.0)
|
||||
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var standing: CobblemonPose
|
||||
|
||||
-86
@@ -1,86 +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.gen2
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
|
||||
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class BlisseyModel(root: ModelPart) : PokemonPosableModel(root), BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("blissey")
|
||||
|
||||
override val leftLeg = getPart("left_foot")
|
||||
override val rightLeg = getPart("right_foot")
|
||||
override val leftArm = getPart("left_arm")
|
||||
override val rightArm = getPart("right_arm")
|
||||
|
||||
override var portraitScale = 1.5F
|
||||
override var portraitTranslation = Vec3(-0.6, 0.9, 0.0)
|
||||
|
||||
override var profileScale = 0.7F
|
||||
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var battle_idle: CobblemonPose
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("blissey", "blink") }
|
||||
val eggQuirk = quirk { bedrockStateful("blissey", "eggadjust_quirk") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(
|
||||
bedrock("blissey", "sleep")
|
||||
)
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = STATIONARY_POSES + UI_POSES,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink, eggQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("blissey", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("blissey", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battle_idle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = STATIONARY_POSES,
|
||||
condition = { it.isBattling },
|
||||
quirks = arrayOf(blink, eggQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("blissey", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState) = bedrockStateful("blissey", "faint")
|
||||
}
|
||||
-127
@@ -1,127 +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.gen2
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import com.cobblemon.mod.common.util.isUnderWater
|
||||
import com.cobblemon.mod.common.util.isInWater
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class ChinchouModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("chinchou")
|
||||
|
||||
override var portraitScale = 1.75F
|
||||
override var portraitTranslation = Vec3(-0.3, -0.8, 0.0)
|
||||
|
||||
override var profileScale = 0.65F
|
||||
override var profileTranslation = Vec3(-0.05, 0.45, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var floating: CobblemonPose
|
||||
lateinit var swimming: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var watersleep: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
lateinit var waterbattleidle: CobblemonPose
|
||||
|
||||
// override val cryAnimation = CryProvider { bedrockStateful("chinchou", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("chinchou", "blink")}
|
||||
val idleQuirk = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("chinchou", "ground_quirk")}
|
||||
val waterQuirk = quirk(secondsBetweenOccurrences = 60F to 120F) { bedrockStateful("chinchou", "water_idle_quirk")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleeping",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { !it.isInWater },
|
||||
animations = arrayOf(bedrock("chinchou", "sleep"))
|
||||
)
|
||||
|
||||
watersleep = registerPose(
|
||||
poseName = "water_sleeping",
|
||||
poseType = PoseType.SLEEP,
|
||||
condition = { it.isInWater },
|
||||
animations = arrayOf(bedrock("chinchou", "water_sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.UI_POSES + PoseType.STAND,
|
||||
transformTicks = 10,
|
||||
condition = { !it.isBattling && !it.isInWater && !it.isUnderWater},
|
||||
quirks = arrayOf(blink, idleQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
transformTicks = 10,
|
||||
poseType = PoseType.WALK,
|
||||
condition = { !it.isInWater && !it.isUnderWater},
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
floating = registerPose(
|
||||
poseName = "floating",
|
||||
transformTicks = 10,
|
||||
poseType = PoseType.FLOAT,
|
||||
condition = { it.isInWater },
|
||||
quirks = arrayOf(blink, waterQuirk),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
swimming = registerPose(
|
||||
poseName = "swimming",
|
||||
transformTicks = 10,
|
||||
condition = { it.isInWater },
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_swim"),
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling && !it.isInWater },
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "battle_idle")
|
||||
)
|
||||
)
|
||||
|
||||
waterbattleidle = registerPose(
|
||||
poseName = "water_battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling && it.isInWater },
|
||||
animations = arrayOf(
|
||||
bedrock("chinchou", "water_battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("chinchou", "faint") else if (state.isPosedIn( waterbattleidle, watersleep, floating, swimming )) bedrockStateful("chinchou", "water_faint") else null
|
||||
}
|
||||
-81
@@ -1,81 +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.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class DarumakaModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("darumaka")
|
||||
|
||||
override var portraitScale = 1.96F
|
||||
override var portraitTranslation = Vec3(-0.18, -0.84, 0.0)
|
||||
|
||||
override var profileScale = 0.76F
|
||||
override var profileTranslation = Vec3(0.0, 0.57, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
lateinit var sleep: CobblemonPose
|
||||
lateinit var battleidle: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("darumaka", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("darumaka", "blink") }
|
||||
val quirk = quirk(secondsBetweenOccurrences = 15F to 100F) { bedrockStateful("darumaka", "quirk") }
|
||||
val quirk2 = quirk(secondsBetweenOccurrences = 20F to 360F) { bedrockStateful("darumaka","quirk2")}
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("darumaka", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink, quirk, quirk2),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
bedrock("darumaka", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink, quirk),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
bedrock("darumaka", "battle_idle")
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink, quirk),
|
||||
animations = arrayOf(
|
||||
bedrock("darumaka", "ground_walk")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// override fun getFaintAnimation(
|
||||
// pokemonEntity: PokemonEntity,
|
||||
// state: PosableState<PokemonEntity>
|
||||
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("darumaka", "faint") else null
|
||||
}
|
||||
-118
@@ -1,118 +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.createTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class DewottModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("dewott")
|
||||
override val head = getPart("head")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
val scalchop_body_right = getPart("scalchop_skirt_right")
|
||||
val scalchop_body_left = getPart("scalchop_skirt_left")
|
||||
val scalchop_right = getPart("scalchop_hand_right")
|
||||
val scalchop_left = getPart("scalchop_hand_left")
|
||||
|
||||
override var portraitScale = 2.0F
|
||||
override var portraitTranslation = Vec3(-0.15, 0.8, 0.0)
|
||||
override var profileScale = 0.7F
|
||||
override var profileTranslation = Vec3(0.0, 0.69, 0.0)
|
||||
|
||||
lateinit var battleidle: Pose
|
||||
lateinit var sleep: Pose
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("dewott", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("dewott", "blink") }
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
transformTicks = 10,
|
||||
condition = { !it.isBattling },
|
||||
transformedParts = arrayOf(
|
||||
scalchop_right.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_left.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_body_right.createTransformation().withVisibility(visibility = true),
|
||||
scalchop_body_left.createTransformation().withVisibility(visibility = true)
|
||||
|
||||
),
|
||||
animations = arrayOf(bedrock("dewott", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = setOf(PoseType.NONE, PoseType.STAND, PoseType.PORTRAIT, PoseType.PROFILE),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { !it.isBattling },
|
||||
transformedParts = arrayOf(
|
||||
scalchop_right.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_left.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_body_right.createTransformation().withVisibility(visibility = true),
|
||||
scalchop_body_left.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("dewott", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walking",
|
||||
poseTypes = setOf(PoseType.SWIM, PoseType.WALK),
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { !it.isBattling },
|
||||
transformedParts = arrayOf(
|
||||
scalchop_right.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_left.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_body_right.createTransformation().withVisibility(visibility = true),
|
||||
scalchop_body_left.createTransformation().withVisibility(visibility = true)
|
||||
),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("dewott", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling },
|
||||
transformedParts = arrayOf(
|
||||
scalchop_right.createTransformation().withVisibility(visibility = true),
|
||||
scalchop_left.createTransformation().withVisibility(visibility = true),
|
||||
scalchop_body_right.createTransformation().withVisibility(visibility = false),
|
||||
scalchop_body_left.createTransformation().withVisibility(visibility = false)
|
||||
),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("dewott", "ground_idle")
|
||||
)
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
-76
@@ -1,76 +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.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.ActiveAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class GolettModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("golett")
|
||||
override val head = getPart("head")
|
||||
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
|
||||
override var portraitScale = 3.0F
|
||||
override var portraitTranslation = Vec3(-0.15, -0.45, 0.0)
|
||||
|
||||
override var profileScale = 0.8F
|
||||
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walk: Pose
|
||||
lateinit var sleep: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("golett", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("golett", "blink") }
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("golett", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("golett", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
sleep = registerPose(
|
||||
poseName = "sleep",
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("golett", "sleep"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFaintAnimation(state: PosableState): ActiveAnimation? {
|
||||
return if (state.isNotPosedIn(sleep, standing, walk)) bedrockStateful("golett", "faint") else null
|
||||
}
|
||||
}
|
||||
-20
@@ -224,16 +224,9 @@ object VaryingModelRepository {
|
||||
inbuilt("metapod", ::MetapodModel)
|
||||
inbuilt("butterfree", ::ButterfreeModel)
|
||||
inbuilt("weedle", ::WeedleModel)
|
||||
inbuilt("kakuna", ::KakunaModel)
|
||||
inbuilt("beedrill", ::BeedrillModel)
|
||||
inbuilt("rattata", ::RattataModel)
|
||||
inbuilt("raticate", ::RaticateModel)
|
||||
inbuilt("rattata_alolan", ::RattataAlolanModel)
|
||||
inbuilt("raticate_alolan", ::RaticateAlolanModel)
|
||||
inbuilt("pidgey", ::PidgeyModel)
|
||||
inbuilt("pidgeotto", ::PidgeottoModel)
|
||||
inbuilt("diglett", ::DiglettModel)
|
||||
inbuilt("dugtrio", ::DugtrioModel)
|
||||
inbuilt("krabby", ::KrabbyModel)
|
||||
inbuilt("paras", ::ParasModel)
|
||||
inbuilt("mankey", ::MankeyModel)
|
||||
@@ -248,7 +241,6 @@ object VaryingModelRepository {
|
||||
inbuilt("machop", ::MachopModel)
|
||||
inbuilt("machoke", ::MachokeModel)
|
||||
inbuilt("machamp", ::MachampModel)
|
||||
inbuilt("chansey", ::ChanseyModel)
|
||||
inbuilt("cubone", ::CuboneModel)
|
||||
inbuilt("dodrio", ::DodrioModel)
|
||||
inbuilt("doduo", ::DoduoModel)
|
||||
@@ -261,7 +253,6 @@ object VaryingModelRepository {
|
||||
inbuilt("geodude", ::GeodudeModel)
|
||||
inbuilt("golduck", ::GolduckModel)
|
||||
inbuilt("golem", ::GolemModel)
|
||||
inbuilt("graveler", ::GravelerModel)
|
||||
inbuilt("hitmonchan", ::HitmonchanModel)
|
||||
inbuilt("hitmonlee", ::HitmonleeModel)
|
||||
inbuilt("kabuto", ::KabutoModel)
|
||||
@@ -272,9 +263,6 @@ object VaryingModelRepository {
|
||||
inbuilt("marowak", ::MarowakModel)
|
||||
inbuilt("meowth", ::MeowthModel)
|
||||
inbuilt("nidoqueen", ::NidoqueenModel)
|
||||
inbuilt("nidoranf", ::NidoranfModel)
|
||||
inbuilt("nidoranm", ::NidoranmModel)
|
||||
inbuilt("nidorina", ::NidorinaModel)
|
||||
inbuilt("nidorino", ::NidorinoModel)
|
||||
inbuilt("persian", ::PersianModel)
|
||||
inbuilt("pinsir", ::PinsirModel)
|
||||
@@ -285,14 +273,12 @@ object VaryingModelRepository {
|
||||
inbuilt("rapidash", ::RapidashModel)
|
||||
inbuilt("sandslash", ::SandslashModel)
|
||||
inbuilt("tangela", ::TangelaModel)
|
||||
inbuilt("tentacool", ::TentacoolModel)
|
||||
inbuilt("venomoth", ::VenomothModel)
|
||||
inbuilt("venonat", ::VenonatModel)
|
||||
inbuilt("elekid", ::ElekidModel)
|
||||
inbuilt("hitmontop", ::HitmontopModel)
|
||||
inbuilt("electivire", ::ElectivireModel)
|
||||
inbuilt("tangrowth", ::TangrowthModel)
|
||||
inbuilt("blissey", ::BlisseyModel)
|
||||
inbuilt("piloswine", ::PiloswineModel)
|
||||
inbuilt("quagsire", ::QuagsireModel)
|
||||
inbuilt("swinub", ::SwinubModel)
|
||||
@@ -341,7 +327,6 @@ object VaryingModelRepository {
|
||||
inbuilt("lotad", :: LotadModel)
|
||||
inbuilt("lombre", :: LombreModel)
|
||||
inbuilt("ludicolo", :: LudicoloModel)
|
||||
inbuilt("golett", :: GolettModel)
|
||||
inbuilt("stantler", :: StantlerModel)
|
||||
inbuilt("bergmite", :: BergmiteModel)
|
||||
inbuilt("avalugg", :: AvaluggModel)
|
||||
@@ -372,7 +357,6 @@ object VaryingModelRepository {
|
||||
inbuilt("thwackey", ::ThwackeyModel)
|
||||
inbuilt("rillaboom", ::RillaboomModel)
|
||||
inbuilt("oshawott", ::OshawottModel)
|
||||
inbuilt("dewott", ::DewottModel)
|
||||
inbuilt("samurott", ::SamurottModel)
|
||||
inbuilt("snivy", ::SnivyModel)
|
||||
inbuilt("servine", ::ServineModel)
|
||||
@@ -381,7 +365,6 @@ object VaryingModelRepository {
|
||||
inbuilt("magcargo", ::MagcargoModel)
|
||||
inbuilt("slugma_shiny", ::SlugmaShinyModel)
|
||||
inbuilt("magcargo_shiny", ::MagcargoShinyModel)
|
||||
inbuilt("chinchou", ::ChinchouModel)
|
||||
inbuilt("clamperl", ::ClamperlModel)
|
||||
inbuilt("huntail", ::HuntailModel)
|
||||
inbuilt("gorebyss", ::GorebyssModel)
|
||||
@@ -535,7 +518,6 @@ object VaryingModelRepository {
|
||||
inbuilt("lilligant", ::LilligantModel)
|
||||
inbuilt("petilil_hisui_bias", ::PetililHisuiBiasModel)
|
||||
inbuilt("lilligant_hisuian", ::LilligantHisuianModel)
|
||||
inbuilt("darumaka", ::DarumakaModel)
|
||||
inbuilt("cufant", ::CufantModel)
|
||||
inbuilt("copperajah", ::CopperajahModel)
|
||||
inbuilt("budew", ::BudewModel)
|
||||
@@ -549,8 +531,6 @@ object VaryingModelRepository {
|
||||
inbuilt("beartic", ::BearticModel)
|
||||
inbuilt("dreepy", ::DreepyModel)
|
||||
inbuilt("drakloak", ::DrakloakModel)
|
||||
inbuilt("diglett_alolan", ::DiglettAlolanModel)
|
||||
inbuilt("dugtrio_alolan", ::DugtrioAlolanModel)
|
||||
inbuilt("makuhita", ::MakuhitaModel)
|
||||
inbuilt("hariyama", ::HariyamaModel)
|
||||
inbuilt("alomomola", ::AlomomolaModel)
|
||||
|
||||
@@ -45,6 +45,9 @@ object GiveAllPokemon {
|
||||
val orderedSpeces = PokemonSpecies.implemented.sortedBy { it.nationalPokedexNumber }
|
||||
|
||||
for (species in orderedSpeces) {
|
||||
if (species.nationalPokedexNumber !in range) {
|
||||
continue
|
||||
}
|
||||
val pokemon = species.create()
|
||||
pokemon.setOriginalTrainer(player.uuid)
|
||||
pc.add(pokemon)//.sendOut(player.level() as ServerWorld, player.pos)
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.command
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.permission.CobblemonPermissions
|
||||
import com.cobblemon.mod.common.util.commandLang
|
||||
import com.cobblemon.mod.common.util.permission
|
||||
import com.cobblemon.mod.common.world.feature.PlacedFeatureLocator
|
||||
import com.mojang.brigadier.Command
|
||||
import com.mojang.brigadier.CommandDispatcher
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider
|
||||
import kotlin.math.sqrt
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.commands.CommandSourceStack
|
||||
import net.minecraft.commands.Commands
|
||||
import net.minecraft.commands.SharedSuggestionProvider
|
||||
import net.minecraft.commands.arguments.ResourceLocationArgument
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.chat.ClickEvent
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.ComponentUtils
|
||||
import net.minecraft.network.chat.HoverEvent
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.util.Mth
|
||||
|
||||
/**
|
||||
* `/locatefeature <placed_feature> [radiusChunks]`
|
||||
*
|
||||
* The `/locate` equivalent for placed features. Works on unloaded and ungenerated chunks by replaying the
|
||||
* world seed's decoration randomness (see [PlacedFeatureLocator]); the reported coordinates are where the
|
||||
* feature attempts to place, which real terrain can still veto.
|
||||
*/
|
||||
object LocateFeatureCommand {
|
||||
|
||||
private const val DEFAULT_RADIUS_CHUNKS = 400
|
||||
private const val MAX_RADIUS_CHUNKS = 512
|
||||
|
||||
private val UNKNOWN_FEATURE = DynamicCommandExceptionType { commandLang("locatefeature.unknown", it.toString()) }
|
||||
private val UNSUPPORTED_MODIFIER = Dynamic2CommandExceptionType { id, modifier -> commandLang("locatefeature.unsupported", id.toString(), modifier.toString()) }
|
||||
private val NOT_FOUND = Dynamic2CommandExceptionType { id, radius -> commandLang("locatefeature.notfound", id.toString(), radius.toString()) }
|
||||
private val NOT_IN_DIMENSION = DynamicCommandExceptionType { commandLang("locatefeature.notindimension", it.toString()) }
|
||||
|
||||
private val SUGGESTIONS = SuggestionProvider<CommandSourceStack> { context, builder ->
|
||||
val registry = context.source.registryAccess().registryOrThrow(Registries.PLACED_FEATURE)
|
||||
SharedSuggestionProvider.suggestResource(
|
||||
registry.keySet().filter(PlacedFeatureLocator::isLocatable),
|
||||
builder
|
||||
)
|
||||
}
|
||||
|
||||
fun register(dispatcher: CommandDispatcher<CommandSourceStack>) {
|
||||
dispatcher.register(
|
||||
Commands.literal("locatefeature")
|
||||
.permission(CobblemonPermissions.LOCATE_FEATURE)
|
||||
.then(
|
||||
Commands.argument("feature", ResourceLocationArgument.id())
|
||||
.suggests(SUGGESTIONS)
|
||||
.executes { execute(it, DEFAULT_RADIUS_CHUNKS) }
|
||||
.then(
|
||||
Commands.argument("radiusChunks", IntegerArgumentType.integer(1, MAX_RADIUS_CHUNKS))
|
||||
.executes { execute(it, IntegerArgumentType.getInteger(it, "radiusChunks")) }
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun execute(context: CommandContext<CommandSourceStack>, radiusChunks: Int): Int {
|
||||
val source = context.source
|
||||
val id = ResourceLocationArgument.getId(context, "feature")
|
||||
val registry = source.registryAccess().registryOrThrow(Registries.PLACED_FEATURE)
|
||||
val holder = registry.getHolder(ResourceKey.create(Registries.PLACED_FEATURE, id)).orElseThrow { UNKNOWN_FEATURE.create(id) }
|
||||
|
||||
PlacedFeatureLocator.firstUnreplayableModifier(holder.value())?.let { modifier ->
|
||||
val modifierId = BuiltInRegistries.PLACEMENT_MODIFIER_TYPE.getKey(modifier.type())
|
||||
throw UNSUPPORTED_MODIFIER.create(id, modifierId ?: modifier.javaClass.simpleName)
|
||||
}
|
||||
|
||||
val origin = BlockPos.containing(source.position)
|
||||
val result = PlacedFeatureLocator.locate(source.level, holder, origin, radiusChunks)
|
||||
if (result is PlacedFeatureLocator.LocateResult.NotInDimension) {
|
||||
throw NOT_IN_DIMENSION.create(id)
|
||||
}
|
||||
val sites = (result as? PlacedFeatureLocator.LocateResult.Found)?.sites ?: throw NOT_FOUND.create(id, radiusChunks)
|
||||
|
||||
sites.forEachIndexed { i, site ->
|
||||
val dx = (site.pos.x - origin.x).toDouble()
|
||||
val dz = (site.pos.z - origin.z).toDouble()
|
||||
val distance = Mth.floor(sqrt(dx * dx + dz * dz))
|
||||
val coordinates = clickableCoordinates(site.pos)
|
||||
val line = if (i == 0) {
|
||||
commandLang("locatefeature.success", id.toString(), coordinates, distance)
|
||||
} else {
|
||||
commandLang("locatefeature.also", coordinates, distance)
|
||||
}
|
||||
if (!site.confirmed) {
|
||||
line.append(commandLang("locatefeature.predicted").withStyle(ChatFormatting.GRAY))
|
||||
}
|
||||
source.sendSuccess({ line }, false)
|
||||
}
|
||||
return Command.SINGLE_SUCCESS
|
||||
}
|
||||
|
||||
/** Same presentation as vanilla /locate: green clickable coords that put a /tp in the chat bar. */
|
||||
private fun clickableCoordinates(pos: BlockPos) =
|
||||
ComponentUtils.wrapInSquareBrackets(Component.translatable("chat.coordinates", pos.x, "~", pos.z))
|
||||
.withStyle { style ->
|
||||
style.withColor(ChatFormatting.GREEN)
|
||||
.withClickEvent(ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tp @s ${pos.x} ~ ${pos.z}"))
|
||||
.withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.coordinates.tooltip")))
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -14,7 +14,6 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.OrientationControllable
|
||||
import com.cobblemon.mod.common.api.entity.PokemonSender
|
||||
import com.cobblemon.mod.common.api.entity.PokemonSideDelegate
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addPokemonEntityFunctions
|
||||
@@ -31,7 +30,6 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.activestate.ActivePokemonState
|
||||
import com.cobblemon.mod.common.pokemon.activestate.SentOutState
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.syncher.EntityDataAccessor
|
||||
@@ -43,8 +41,6 @@ import net.minecraft.world.entity.ai.attributes.Attributes
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.pathfinder.PathType
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Vector3f
|
||||
import java.util.*
|
||||
import kotlin.math.*
|
||||
|
||||
@@ -52,6 +48,7 @@ import kotlin.math.*
|
||||
class PokemonServerDelegate : PokemonSideDelegate {
|
||||
lateinit var entity: PokemonEntity
|
||||
var acknowledgedHPValue = -1
|
||||
var acknowledgedLevel = -1
|
||||
val passengerOffsets = mutableMapOf<Int, Vec3>()
|
||||
|
||||
/** Mocked properties exposed to the client [PokemonEntity]. */
|
||||
@@ -301,6 +298,11 @@ class PokemonServerDelegate : PokemonSideDelegate {
|
||||
if (entity.ownerUUID == null) entity.ownerUUID = entity.pokemon.getOwnerUUID()
|
||||
}
|
||||
|
||||
if (acknowledgedLevel != entity.pokemon.level) {
|
||||
acknowledgedLevel = entity.pokemon.level
|
||||
updateAttributes(entity.pokemon)
|
||||
}
|
||||
|
||||
val tethering = entity.tethering
|
||||
if (tethering != null && entity.pokemon.tetheringId != tethering.tetheringId) {
|
||||
return entity.discard()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.item
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.block.TypeGemClusterBlock
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.InteractionResult
|
||||
@@ -29,7 +30,7 @@ class GemItem(settings: Properties, val block: Block): Item(settings) {
|
||||
if (state.isFaceSturdy(world, pos, direction)) {
|
||||
if (!world.getBlockState(pos.relative(direction)).isAir) return InteractionResult.FAIL
|
||||
context.itemInHand.consume(1, context.player)
|
||||
world.setBlockAndUpdate(pos.relative(direction), block.defaultBlockState().setValue(DirectionalBlock.FACING, direction))
|
||||
world.setBlockAndUpdate(pos.relative(direction), block.defaultBlockState().setValue(DirectionalBlock.FACING, direction).setValue(TypeGemClusterBlock.STAGE, 1))
|
||||
world.playSound(null, pos, CobblemonSounds.TYPE_GEM_CLUSTER_SOUNDS.placeSound, SoundSource.BLOCKS)
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
@@ -316,7 +316,6 @@ object CobblemonItemGroups {
|
||||
entries.accept(CobblemonItems.PASTURE)
|
||||
entries.accept(CobblemonItems.TM_MACHINE)
|
||||
entries.accept(CobblemonItems.DISC_SHELF)
|
||||
entries.accept(CobblemonItems.HABITAT_BLOCK)
|
||||
|
||||
entries.accept(CobblemonItems.GILDED_CHEST)
|
||||
entries.accept(CobblemonItems.YELLOW_GILDED_CHEST)
|
||||
|
||||
@@ -40,7 +40,7 @@ class SinisterTeaItem : Item(
|
||||
val holder = inst.effect
|
||||
val effect = holder.value()
|
||||
|
||||
if (effect.isInstantenous) {
|
||||
if (effect.isInstantenous && (inst.duration <= 1)) {
|
||||
effect.applyInstantenousEffect(user as? Player, null, user, inst.amplifier, 1.0)
|
||||
} else {
|
||||
user.addEffect(inst)
|
||||
|
||||
@@ -36,7 +36,7 @@ import net.minecraft.world.level.block.Block
|
||||
class StatusCureItem(val itemName: String, vararg val status: Status, block: Block) : ItemNameBlockItem(block, Properties()), PokemonSelectingItem {
|
||||
override val bagItem = object : BagItem {
|
||||
override val itemName = this@StatusCureItem.itemName
|
||||
override val returnItem = Items.AIR
|
||||
override val returnItem = Items.GLASS_BOTTLE
|
||||
override fun canUse(stack: ItemStack, battle: PokemonBattle, target: BattlePokemon) = canUseOnPokemon(stack, target.effectedPokemon)
|
||||
override fun getShowdownInput(actor: BattleActor, battlePokemon: BattlePokemon, data: String?) = "cure_status${status.takeIf { it.isNotEmpty() }?.let { " ${it.joinToString(separator = " ") { it.showdownName } }" } ?: "" }"
|
||||
}
|
||||
|
||||
+9
@@ -64,6 +64,7 @@ class SpawnPokemonPacket(
|
||||
var rideStamina: Float,
|
||||
var isAlpha: Boolean,
|
||||
var silent: Boolean,
|
||||
var riders: List<Int>,
|
||||
vanillaSpawnPacket: ClientboundAddEntityPacket,
|
||||
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
|
||||
|
||||
@@ -98,6 +99,7 @@ class SpawnPokemonPacket(
|
||||
entity.entityData.get(PokemonEntity.RIDE_STAMINA),
|
||||
entity.entityData.get(PokemonEntity.IS_ALPHA),
|
||||
entity.isSilent,
|
||||
entity.occupiedSeats.map { entry -> entry.value.id }.toList(),
|
||||
vanillaSpawnPacket
|
||||
)
|
||||
|
||||
@@ -134,6 +136,7 @@ class SpawnPokemonPacket(
|
||||
buffer.writeFloat(rideStamina)
|
||||
buffer.writeBoolean(isAlpha)
|
||||
buffer.writeBoolean(silent)
|
||||
buffer.writeCollection(this.riders) { pb, value -> pb.writeInt(value) }
|
||||
}
|
||||
|
||||
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
|
||||
@@ -184,6 +187,10 @@ class SpawnPokemonPacket(
|
||||
|
||||
entity.tickSpawned = this.tickSpawned
|
||||
entity.delegate.updateAge(this.tickSpawned)
|
||||
|
||||
if (this.riders.isNotEmpty()) {
|
||||
this.riders.forEach { level.getEntity(it)?.startRiding(entity) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun checkType(entity: Entity): Boolean = entity is PokemonEntity
|
||||
@@ -222,6 +229,7 @@ class SpawnPokemonPacket(
|
||||
val rideStamina = buffer.readFloat()
|
||||
val isAlpha = buffer.readBoolean()
|
||||
val silent = buffer.readBoolean()
|
||||
val riders = buffer.readList { it.readInt() }.toList()
|
||||
val vanillaPacket = decodeVanillaPacket(buffer)
|
||||
|
||||
return SpawnPokemonPacket(
|
||||
@@ -253,6 +261,7 @@ class SpawnPokemonPacket(
|
||||
rideStamina,
|
||||
isAlpha,
|
||||
silent,
|
||||
riders,
|
||||
vanillaPacket
|
||||
)
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.ui
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachine
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class SynchronizeActiveTMPacket(val tm: TechnicalMachine?): NetworkPacket<SynchronizeActiveTMPacket> {
|
||||
override val id = ID
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeNullable(tm?.id) { pb, value -> pb.writeResourceLocation(value) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("synchronize_active_tm")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): SynchronizeActiveTMPacket {
|
||||
val resourceLocation = buffer.readNullable { it.readResourceLocation() }
|
||||
if (resourceLocation == null) return SynchronizeActiveTMPacket(null)
|
||||
val tm = TechnicalMachines.tmMap[resourceLocation]
|
||||
return SynchronizeActiveTMPacket(tm)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,7 +327,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
if (experienceGroup.getLevel(experience) != boundedValue || value == Cobblemon.config.maxPokemonLevel) {
|
||||
experience = experienceGroup.getExperience(boundedValue)
|
||||
}
|
||||
// _level.emit(value)
|
||||
|
||||
currentHealth = ceil(hpRatio * maxHealth).coerceIn(0..maxHealth)
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ class OmniPathNodeMaker : NodeEvaluator() {
|
||||
|
||||
// Hitbox thing looks confusing but if the hitbox volume is more than like, 5, it starts getting pretty
|
||||
// fucking slow to use the findAcceptedNodeWalk function
|
||||
val strictlyWalkPathing = !canFly() && !mob.isInWater && mob.boundingBox.size < MAX_HITBOX_SIZE_FOR_WALKING
|
||||
val strictlyWalkPathing = !canFly() && !mob.isInWater
|
||||
val doVerticalNeighbourChecks = (canFly() || mob.isInWater) && mob.boundingBox.size < MAX_HITBOX_FOR_VERTICAL_NEIGHBOURS
|
||||
|
||||
// Non-diagonal surroundings in 3d space
|
||||
@@ -623,9 +623,11 @@ class OmniPathNodeMaker : NodeEvaluator() {
|
||||
|
||||
override fun getPathTypeOfMob(pfContext: PathfindingContext, x: Int, y: Int, z: Int, mob: Mob): PathType {
|
||||
val set = EnumSet.noneOf(PathType::class.java)
|
||||
val sizeX = (mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1
|
||||
val sizeY = (mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1
|
||||
val sizeZ = (mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1
|
||||
// Capping the observed size of hitboxes here to put an upper limit on the cost of larger hitbox mobs
|
||||
// Mobs larger than these caps will inevitably become stuck on obstacles as their pathing will be flawed
|
||||
val sizeX = ((mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1).coerceAtMost(2)
|
||||
val sizeY = ((mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1).coerceAtMost(3)
|
||||
val sizeZ = ((mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1).coerceAtMost(2)
|
||||
|
||||
// TODO -- This is experimental code to see if this is meaningful. We should clean this up later when time permits.
|
||||
val returnedEarlyPathType = mutableListOf<PathType>()
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.pokemon.properties
|
||||
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType
|
||||
|
||||
object HeldItemVisibleProperty : CustomPokemonPropertyType<BooleanProperty> {
|
||||
override val keys = setOf("held_item_visible")
|
||||
override val needsKey = true
|
||||
|
||||
override fun fromString(value: String?) =
|
||||
when {
|
||||
value == null || value.lowercase() in listOf("true", "yes") -> heldItemVisible(true)
|
||||
value.lowercase() in listOf("false", "no") -> heldItemVisible(false)
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun heldItemVisible(value: Boolean) = BooleanProperty(
|
||||
key = keys.first(),
|
||||
value = value,
|
||||
pokemonApplicator = { pokemon, _ -> pokemon.heldItemVisible = value },
|
||||
entityApplicator = { pokemonEntity, _ -> pokemonEntity.pokemon.heldItemVisible = value },
|
||||
pokemonMatcher = { pokemon, _ -> pokemon.heldItemVisible == value },
|
||||
entityMatcher = { pokemonEntity, _ -> pokemonEntity.pokemon.heldItemVisible == value }
|
||||
)
|
||||
|
||||
override fun examples() = setOf("yes", "no")
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.tms.obtain
|
||||
|
||||
import com.cobblemon.mod.common.api.tms.ObtainMethod
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
/**
|
||||
* An [ObtainMethod] for TMs that cannot be unlocked through gameplay triggers.
|
||||
* These TMs are intended to be granted manually by command or MoLang only.
|
||||
*/
|
||||
class ImpossibleObtainMethod : ObtainMethod {
|
||||
override val passive = false
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("impossible")
|
||||
|
||||
fun readFromBuffer(buffer: RegistryFriendlyByteBuf): ImpossibleObtainMethod {
|
||||
return ImpossibleObtainMethod()
|
||||
}
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer) = false
|
||||
|
||||
override fun writeToBuffer(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeUtf("cobblemon:impossible")
|
||||
}
|
||||
}
|
||||
@@ -115,8 +115,26 @@ object TradeManager : RequestManager<TradeManager.TradeRequest>() {
|
||||
}
|
||||
|
||||
CobblemonEvents.TRADE_EVENT_PRE.postThen(TradeEvent.Pre(player1, pokemon2, player2, pokemon1)) {
|
||||
party1.remove(pokemon1)
|
||||
party2.remove(pokemon2)
|
||||
val party1 = player1.party
|
||||
val party2 = player2.party
|
||||
|
||||
val player1Removed = party1.remove(pokemon1)
|
||||
val player2Removed = party2.remove(pokemon2)
|
||||
|
||||
if (!player1Removed || !player2Removed) {
|
||||
if (!player1Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon1.species.resourceIdentifier} from ${player1.name.string}(${player1.uuid}). Aborting trade with ${player2.name.string}(${player2.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
if (!player2Removed) {
|
||||
Cobblemon.LOGGER.warn("Failed to remove traded Pokémon ${pokemon2.species.resourceIdentifier} from ${player2.name.string}(${player2.uuid}). Aborting trade with ${player1.name.string}(${player1.uuid}), potential exploit abused.")
|
||||
}
|
||||
|
||||
// Revert any changes if one of the removals failed
|
||||
if (player1Removed) party1.add(pokemon1)
|
||||
if (player2Removed) party2.add(pokemon2)
|
||||
return@postThen
|
||||
}
|
||||
|
||||
// If player1 is the OT, keep track of the friendship
|
||||
pokemon1.cacheFriendship(player1.uuid)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user